Skip to content

feat(cli): nodes search --expand-top N - #707

Merged
skishore23 merged 1 commit into
fix/validate-lowers-ui-to-apifrom
kishore/v1-017-expand-top
Aug 14, 2026
Merged

feat(cli): nodes search --expand-top N#707
skishore23 merged 1 commit into
fix/validate-lowers-ui-to-apifrom
kishore/v1-017-expand-top

Conversation

@skishore23

@skishore23 skishore23 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Linear: BE-7150 (V1-017) · Layer 1/4 of the V1 hop-killer stack (707 → 708 → 709 → 710), stacked on fix/validate-lowers-ui-to-api.

The hop it kills

Measured on prod agent traces: nodes searchnodes show × N, ×76 occurrences, with ~92% of the show args a verbatim copy of the search hit. One flag folds the show payloads into the search envelope.

Semantics

  • comfy nodes search <q> --expand-top N re-resolves the top-N returned rows through the exact catalog path nodes show uses (graph.nodemorphism_to_dict) and attaches them under data.expanded[], each entry {class_type, ...full show payload} (inputs with options.default/min/max, enum choices, outputs, output_types, …) — the grounded show field vocabulary, not a new one.
  • --expand-top 0 / omitted → payload byte-identical to today (no expanded key).
  • Per-hit catalog miss degrades to a per-hit error entry {class_type, error: {code: "expand_miss", …}} inside expanded[]; the search itself never fails. expand_miss is registered in error_codes.REGISTRY (advisory, surfaced in-data).
  • Close-name fallback rows (typo queries) expand the same way.

Test evidence

tests/comfy_cli/command/test_nodes_search_expand.py — TDD: captured red first (7/7 fail: unknown option + unregistered code), then green.

  • top-hit schema (defaults, choices, outputs) — green
  • top-N rank order; omitted/0 byte-identical; zero-matches baseline (expanded: [])
  • per-hit miss degrades (expand_miss entry, sibling hits still expand); close-match rows expand
  • neighbors: test_nodes_introspect.py, test_error_code_registry.py, test_discovery.py green; ruff + format clean on touched files

Sibling-PR notes

🤖 Generated with Claude Code

Kill the measured search -> show xN agent loop (x76, ~92% of show args are a
verbatim copy of the search hit): --expand-top N re-resolves the top-N
returned hits through the exact catalog path nodes show uses
(graph.node -> morphism_to_dict) and attaches each show payload under
data.expanded[] with a class_type join key.

- --expand-top 0 / omitted: payload byte-identical to today.
- per-hit catalog miss degrades to a per-hit expand_miss error entry inside
  expanded[]; the search itself never fails.
- expand_miss registered in the error-code registry (advisory, in-data).

Linear: BE-7150

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 467bc7d0-41e3-4d9e-b9e5-19245bf5727e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@skishore23 skishore23 changed the title kishore/v1 017 expand top feat(cli): nodes search --expand-top N Aug 12, 2026
@skishore23
skishore23 merged commit 0672d99 into fix/validate-lowers-ui-to-api Aug 14, 2026
5 checks passed
skishore23 added a commit that referenced this pull request Aug 14, 2026
Brings four independent PR chains, all rooted on this branch, plus 32
commits of main drift.

Chains (tip merges bring the whole chain):
  #704 op-vocab-freeze -> #715 bulk-op-emission -> #718 connect-LWW
  #705 --select -> #714 widget-catalog
  #706 --ack
  #707 expand-top -> #708 templates-get -> #709 path --emit-ops -> #710 delete-nodes

All four merged with zero textual conflicts and zero test regressions.
Op vocabulary doc is coherent at v1.2 (DEFERRED_OPS empty, reset_doc
promoted in v1.1, concrete-input LWW in v1.2).

origin/main conflicted in 8 files / 21 hunks. Five were not either/or --
both sides had added different things at the same spot, so keeping one
side would have silently deleted the other's work:

  error_codes.py   both new codes (expand_miss + path_bounds_invalid)
  nodes.py         both dict keys (ops + support)
  loader.py        main: kept `import time`, dropped urllib (dead after _net.py)
  registry/api.py  both: 511's lazy `import requests` + main's timeout=
                   DEFAULT_HTTP_TIMEOUT (main had already timed out the
                   other three call sites in this file)
  preview.py       main's CWD binary-planting guard + ffprobe/render
                   timeouts, with 511's ffprobe-optional and
                   imageio-ffmpeg fallbacks restored inside it. Both
                   fallbacks fire only on a genuinely ABSENT binary; an
                   untrusted PATH match is still refused, so the planting
                   guard is intact.
  test_preview.py  both test bodies
  cmdline.py       main's deprecation of `comfy validate` into the shared
                   validate_api_workflow, plus 511-only api_node_id
                   (57:3 -> 57/3 subgraph remap) ported into that helper,
                   which main lacked
  cql/engine.py    hunk-by-hunk. None of 511's ten engine commits are in
                   main, so taking main's file would have deleted the
                   upload-backed enum fix, the MATCHTYPE wildcard, the
                   reachability check and the SHA-256 subgraph fork id.
                   Took main's dynamic-combo machinery (#574 / BE-3371,
                   a superset) and its 6-tuple _parse_input_spec arity;
                   restored Graph.widget_defaults and 511's structural
                   {key,inputs} detection at the new arity.

widgets_values guard: main's new code reads `node.get("widgets_values")
or []` and then indexes positionally. A dict is truthy, so VHS_* nodes
(which serialize widgets_values as a named dict) would raise KeyError: 0
again -- the defect behind 38 failures / 24% of in-scope in one 24h
window, surfacing as "Could not extract slots: 0". Every read site now
goes through _widgets_as_list, including two on main's NON-conflicting
lines that the merge never flagged.

Test tuning: two @patch targets in test_utils/test_standalone pointed at
comfy_cli.utils.requests, which does not exist under the lazy import
(verified: importing comfy_cli.utils does not load requests). Repointed
to "requests.get" -- the pattern the same file already used elsewhere.
Behaviour is unchanged; the timeout main added is still asserted.

KNOWN FAILING (10) -- two clusters, both design decisions, not splices:

 1. Dynamic-combo widget order (8). Two implementations of one feature.
    511 expands sub-widgets in the static widget_order; main moved
    expansion into the value-aware _expand_widget_entries/_WidgetEntry.
    Tests from 511, main AND #714 each assert their own model, so no
    single side passes all three. Needs a call on which model wins.
 2. run cloud lifecycle (2, plus test_run_prompt). The tests invoke a
    nonexistent wf.json expecting the mocked execute_cloud to
    short-circuit; a workflow_not_found check now fires first.

Baselines measured, not assumed: 511 = 29 failed / 4603 passed;
origin/main = 29 failed / 4617 passed. Lint is 19 errors, all UP038
style, zero F-class -- unchanged in kind from both baselines.
@skishore23
skishore23 deleted the kishore/v1-017-expand-top branch August 14, 2026 19:32
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant