feat(delegate): wire agent connections through Agent.as_tool - #80
Merged
Conversation
- delegate to an agent through the strands-native adapter - add connections[].preserve_context, so a delegate can start every call from a clean baseline - reject preserve_context: false for a nested orchestration - keep one wrapper - multiagent_as_tool - carry text from citationsContent blocks across the delegation boundary - drop the converters package
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.
Description
Delegate connections to an agent now go through
strands.Agent.as_tool()instead of a hand-rolled@toolwrapper. The wrapper's biggest problem was interrupts: it turned a sub-agent's interrupt into an empty success, so a pending approval looked granted to the coordinator.Agent.as_tool()propagates the interrupt properly and lets it be answered and resumed.That native adapter also owns
preserve_context, so it's now exposed asconnections[].preserve_contexton a delegate connection. Setting itfalseresets the delegate to its construction-time baseline before every call — the only way to bound a stateless delegate's history in a long-lived session, since orchestrations share one live agent object across calls. It's rejected for a connection to a nested orchestration (no baseline to reset to) and for an agent carrying a session manager (persisting and wiping every call are contradictory) — both left to surface as-is rather than reimplemented, so the messages stay accurate if upstream's rules ever change.A
Swarm/Graphtarget has noas_tool()upstream, so it keeps a single hand-rolled wrapper (multiagent_as_tool, replacingnode_as_tool/node_as_async_tool), which now also reports an interrupt raised inside the orchestration as a tool error instead of silently succeeding.Also in this PR:
extract_block_textreadscitationsContentblocks, so a cited answer's text now crosses the delegation boundary instead of being droppedconverterspackage (StreamConverter,OpenAIStreamConverter,RawStreamConverter) is removed — framingStreamEvents into a wire format is a transport-layer concern, not something this library should ownstrands-agentsfloor bumped to1.52.0for theas_tool()behaviour this relies onRelated Issues
N/A
Type of Change
YAML / API Impact
Config schema:
connections[].preserve_context: bool(defaulttrue) on delegate connectionsPublic Python API (
strands_compose):node_as_tool,node_as_async_toolmultiagent_as_tool(replaces both forSwarm/Graphtargets; anAgenttarget now goes throughstrands.Agent.as_tool()directly)strands_compose.converters(StreamConverter,OpenAIStreamConverter,RawStreamConverter)Not backwards-compatible: any code importing
node_as_tool,node_as_async_tool, orstrands_compose.convertersbreaks. A delegate tool's result now carries text blocks only (previously alsoimage/document/json, which a model cannot itself emit into its own final message, so this had no live use). Requiresstrands-agents>=1.52.0,<2.0.0.Testing
uv run just check(lint + type check)uv run just testfor overall testingexamples/still workChecklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.