Address code-review feedback:
* Fix pre-existing bug surfaced by this work: a V3 node returning a bare
ExecutionBlocker (normalized to NodeOutput(block_execution=msg) with no
positional/named result) was silently dropped in get_output_from_returns.
block_execution now takes precedence and shapes the blocker tuple to the
active output count first.
* Reject malformed linked-input source node ids (non-string) up front in
validate_inputs as 'bad_linked_input' instead of letting them fall into
the type resolver.
* Schema.validate(): reject duplicate DynamicOutputs group ids.
* Drop a couple of over-defensive / restating comments.
New tests: blocker sizing through both the NodeOutput and bare-blocker paths
for dynamic nodes, and duplicate-group-id schema rejection.
Amp-Thread-ID: https://ampcode.com/threads/T-019e8568-f382-743d-a97f-0de3ff29d501
Co-authored-by: Amp <amp@ampcode.com>
Introduce a per-prompt finalized output list for V3 nodes whose active
output shape depends on a literal input. First slice:
* Schema:
- io.DynamicOutputs.ByKey(id, selector, options=[io.DynamicOutputs.Option(...)])
- Validates: selector input exists; output ids unique within and across
static + dynamic branches; no overlap between branches.
- get_v1_info() advertises dynamic groups separately via NodeInfoV1.dynamic_outputs;
static RETURN_TYPES / OUTPUT_IS_LIST stay as the always-present prefix.
* NodeOutput:
- New NodeOutput.from_named({id: value}) for dynamic nodes; engine reorders
against the finalized active output list. Mixing positional+named raises.
* Execution:
- execute() computes FinalizedOutputs once per attempt and threads it
through initial / pending-async / pending-subgraph output paths.
- merge_result_data / get_output_data / get_output_from_returns size
blocker tuples and concat behaviour against the finalized list.
- validate_inputs rejects positional links whose slot index is outside
the upstream node's active output count as 'bad_linked_output'.
* TypeResolver:
- resolve_output_type and is_output_list consult the finalized output
list when present; finalized_output_count() exposes the active count
for validation.
Covered by new unit tests under tests-unit/comfy_api_test and
tests-unit/execution_test.
Amp-Thread-ID: https://ampcode.com/threads/T-019e8568-f382-743d-a97f-0de3ff29d501
Co-authored-by: Amp <amp@ampcode.com>