feat(runtimes): strands subagent delegation demo with standard SUBAGENT_* emission - #956
Merged
Conversation
…sion Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…arch to a specialist Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… at the bridge boundary Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l fallback Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ter map key
chat-tool-calls looked up subagents via subs.has(tc.id) — the adapter's
map KEY. Adapters key subagents() differently (LangGraph by toolCallId,
AG-UI activities by messageId, AG-UI native SUBAGENT_* by subagentRunId,
e.g. `<toolCallId>-sub`), so a Strands delegation streamed correct
SUBAGENT_* wire events yet rendered as a plain tool-call chip. Re-index
by the contract field Subagent.toolCallId ("Tool call ID that spawned
this subagent"), which is the only guaranteed anchor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…play Three hand-written aimock fixtures cover the delegation turn's LLM calls: orchestrator tool-call (research_availability), the specialist (matched on its distinctive "availability researcher" system prompt), and the orchestrator continuation (hasToolResult discriminator ordered before the looser same-message entry). The spec asserts the inline <chat-subagent-card> renders with the specialist's name and the final bubble proposes a slot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t card Live-model run (real key) driven headlessly: the delegation prompt renders an inline chat-subagent-card (availability_researcher, wire toolCallId, status badge) whose text streams mid-run — innerText polled at 150ms grew 144→643 chars while status stayed `running`, then settled to `complete` — before the orchestrator's own summary bubble. Screenshot committed under e2e/manual/. Matrix cell evidence: subagent streaming = yes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The two existing anchoring tests key the subagents map identically to the
toolCallId, so they pass with or without the field-based lookup. This one
keys the map by an AG-UI-style subagentRunId ('call_t-sub') while the
wrapper's toolCallId is 'call_t', and asserts the card still anchors to
the spawning call (mutation-checked: red on reverting the component fix).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…demo Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
blove
enabled auto-merge (squash)
September 2, 2026 16:30
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second PR of the runtime-subagents arc (adapter landed in #955).
availability_researcherspecialist via an async-generator agents-as-tools@toolthat re-yields the specialist's stream.src/subagent_emitter.pyrides the bridge'sToolBehavior.tool_stream_event_handlerseam:SUBAGENT_STARTED(parentToolCallId = the delegation tool-use id) → real streamed child deltas assubagentRunId-attributedTEXT_MESSAGE_*→SUBAGENT_FINISHED;SUBAGENT_ERRORon failure/force-stop. Pydanticag_ui.coreevent classes throughout (the Python SDK already ships them). Hardened for provider tool-use-id reuse (reset-on-init_event_loopwith generation-suffixed message ids) and capped session bookkeeping.cockpit/runtimes/aws-strands/python/docs/wire-capture-subagents.md: pre-emitter capture (bridge drops child text today), post-emitter capture (89 streamed child deltas across two delegations), and a live browser verification — the card streams mid-run (innerText 144→643 chars whilerunning) with a committed screenshot.chat-tool-callsanchored subagent cards by thesubagents()map key; the neutral contract carries the spawning id in theSubagent.toolCallIdfield (AG-UI keys the map bysubagentRunId). Fixed with an O(n) re-index + a mutation-verified regression test in libs/chat; LangGraph behavior byte-equivalent (field == key there).deployments/ag-ui-devregenerated via the generator.Testing
hasToolResult-first ordering).🤖 Generated with Claude Code