The assistant was structurally blind to containers: the plan/connections
JSON schema was flat, and every connection-resolution helper was typed
to Block<?>, so a container could never be a plan entry or a connection
endpoint. This wires up a first, deliberately scoped version: only
GenericContainer (plain grouping, no iteration/loop semantics), one
level deep (nesting stays unsupported), inner blocks always fully
(re)generated rather than incrementally diffed across FIX/REFINE
rounds.
- AssistantFlowPlan gains a "containers" array alongside "blocks";
each entry (AssistantContainerPlan) carries its own nested "blocks"
list using the exact same shape as top-level blocks.
- validateAndNormalizePlan now normalizes containers too: id
uniqueness (shared namespace with block ids), containerType must be
exactly "GenericContainer", inner blocks non-empty with unique ids
and no nested container types, KEEP/UPDATE/REMOVE resolved against
currentFlow.getContainers() the same way blocks resolve against
currentFlow.getBlocks().
- The connection-resolution machinery (toValidConnections, toConnection,
resolveConnectionBlock, inferBlockByIo, resolveConnectionOutputName/
InputName, registerNodeAlias) is retyped from Block<?> to the shared
FlowNode interface (Block and Container both implement it, exposing
id/name/inputs/outputs) - a mechanical, behavior-preserving change
that lets containers slot into the exact same connection-wiring path
blocks already used, with no new logic needed there.
- assembleGenericContainer assembles a container's inner blocks (their
own BLOCK_CONFIG calls) and inner connections (a CONNECTIONS call
scoped to just that container, reusing buildConnectionsPrompt with a
synthetic inner AssistantFlowPlan), then hands the resulting subflow
to GenericContainerFactory, which auto-derives the container's
exposed inputs/outputs from whatever inner handles are left
unconnected - the assistant never has to declare them itself.
- Prompt updates: the PLAN schema/rules explain the "containers" array,
when grouping is actually useful, and that only GenericContainer is
currently authorable; the CONNECTIONS rules clarify that containers
are valid endpoints via their own id and auto-derived I/O, and that
inner blocks are never reachable from outside their container.
- isTargetedBlockRepairEligible now bails out whenever currentFlow has
any containers, since the targeted-repair plan reconstruction only
rebuilds the block list and would otherwise silently drop them.
Added a regression test covering the full path: a plan with a
top-level block plus a 2-block container, verifying the container's
subflow, its auto-derived exposed input/output names, and the single
top-level connection into it.
Deliberately out of scope for this pass: IteratorContainer/LoopContainer
(need iteration/guard semantics the assistant doesn't author),
incremental inner-block diffing across FIX/REFINE rounds, and nested
containers (still architecturally unsupported).