20 files, each +2 lines: the label icon and 标准模式 in the banner — the DOM
the label fix makes appear for sessions created in-tab, which these goldens
recorded the absence of.
The doc-typecheck opt-out ratio gate now fails at 74/146 after merging
master. The model and branded-ID blocks are self-contained, so check
them as ordinary ts fences (72/146 remain opted out); re-record the
pairing sidecar.
modeFor read only the exact scope's layer, so a `code`-preset session
advertised the native catalog: the mode is declared on the preset's STANDING
scope, and the agent only parents to it. Nearest scope wins along the chain —
the mode decides what the model SEES, which is the class of fact the chain
inherits. Caught live (the model politely computed with bash and said
run_code was not in its list); the chain test pins it.
The client half of the label fix: the create echo and the session-added
frame's agentPreset now reach the session list (newest wins in the upsert —
every producer of the field reports the CURRENT composition), and a confirmed
blank-session switch publishes through the new ISessions.noteAgentPreset, so
the header label moves with the composition instead of waiting for a reload.
session.create's reply named only the id, and the session-added frame's
agentPreset — which the server already derives via sessionListFields — was
stripped by the wire schema it never joined. A client therefore could not
label a session it just created (or learned live) until the next full list
refresh: the header's preset label rendered nothing for exactly the sessions
made in this tab. The create reply is the commit point that knows the
RESOLVED composition (a caller that named none gets the default the header
recorded), so both carriers now say it.
interrupt_agent(agent_id) passes the calling agent as the ancestor
authority for ctx.subagents.interrupt(); the service verifies live
registry identity and recorded lineage, so a direct child or deeper
descendant stops with the same generic parameter while send_message keeps
its exact-direct-parent authority.
Discovery: list_agents gains an optional scope. descendants walks the new
SubagentService.listDescendants() — one lineage trace flattened in stable
pre-order across ordinary and one-shot intermediates, each entry carrying
its verified parentId and depth — and every status now comes from the
live Agent registry (running/idle/complete).
Refs #1535
The composer's single primary action now stops a running continuable
child: Session.cancel() routes a continuable address through
subagent.interrupt (ordinary sessions keep session.cancel; one-shot
addresses stay uncancellable), and InputBar switches the same Send button
to Stop while a continuable child runs. A running parent-offline child
keeps the default composer with disabled input so that Stop stays
reachable; the read-only takeover returns once it stops.
Refs #1535