Features
Mid-Execution Cancellation — PR#781
The SDK now supports cooperative cancellation of running agent invocations. Callers can stop an agent mid-execution via agent.cancel(), AbortSignal.timeout(), or any external AbortSignal (e.g., from an HTTP framework). Cancellation is checked between model stream events and before each tool execution, and running tools are never forcibly interrupted — they complete unless the tool itself checks the cancellation signal.
import { Agent } from '@strands-agents/sdk';
const agent = new Agent({ model, tools });
// Cancel after 5 secondssetTimeout(() => agent.cancel(), 5000);const result = await agent.invoke('Do something long');console.log(result.stopReason); // 'cancelled'
// Or use AbortSignal.timeout for declarative timeoutsconst result = await agent.invoke('Hello', { cancellationSignal: AbortSignal.timeout(5000),});
// Framework-driven cancellation (e.g., Express)app.post('/chat', async (req, res) => { const result = await agent.invoke(req.body.message, { cancellationSignal: req.signal, }); res.json(result);});Tools can participate in cooperative cancellation by checking context.agent.cancellationSignal:
callback: async ({ url }, context) => { // Signal forwarding — fetch aborts if agent is cancelled const res = await fetch(url, { signal: context.agent.cancellationSignal }); return res.text();};⚠️ Type change: StopReason union now includes 'cancelled'.
Agent-as-Tool — PR#768
Agents can now be used as tools for other agents via agent.asTool() or by passing agents directly in the tools array (auto-wrapped). This enables hierarchical multi-agent architectures where a parent agent delegates subtasks to specialized child agents. The preserveContext option controls whether the sub-agent retains conversation history across invocations.
const researcher = new Agent({ name: 'researcher', description: 'Finds information on a topic', tools: [searchTool], printer: false,});
// Pass agents directly in tools array (auto-wrapped)const writer = new Agent({ tools: [researcher],});await writer.invoke('Write an article about quantum computing');
// Or wrap explicitly with optionsconst tool = researcher.asTool({ preserveContext: true });Multi-Agent Session Persistence — PR#764
SessionManager now implements MultiAgentPlugin, enabling Graph and Swarm orchestrators to automatically save and restore execution state. After each orchestrator invocation, the multi-agent state (node statuses, results, steps, app state) is persisted. On the next invocation, the snapshot is restored before the first node executes.
import { SessionManager, FileStorage, Graph } from '@strands-agents/sdk';
const session = new SessionManager({ sessionId: 'my-session', storage: { snapshot: new FileStorage() },});
const graph = new Graph({ id: 'my-graph', nodes: [researcher, writer, editor], edges: [['researcher', 'writer'], ['writer', 'editor']], plugins: [session],});
// First invocation — snapshot saved automaticallyawait graph.invoke('Write about AI');
// Second invocation — state restored from snapshotawait graph.invoke('Continue');Scope isolation between agent and multi-agent snapshots is maintained. A shared SessionManager across multiple orchestrators restores each one independently.
Multi-Agent Snapshot Primitives — PR#756
Adds internal snapshot take/load support for multi-agent orchestrators (Graph and Swarm). takeSnapshot() captures orchestrator ID and serialized execution state; loadSnapshot() validates scope, schema version, and orchestrator ID before restoring state. Also adds scope validation to agent loadSnapshot — passing a multi-agent snapshot to the agent loader now throws instead of silently no-oping.
Bug Fixes
-
Invocation lock leak on stream break — PR#796: When a consumer broke out of
for-await-ofonagent.stream(), the runtime called.return()on the generator. Thefinallyblock tried to drain remaining events viayield, but with no consumer to resume the generator, it suspended permanently. The lock disposable never ran, leaving_isInvokingstuck attrueand causingConcurrentInvocationErroron any subsequent call. Drain events are now only yielded when the consumer may still be iterating. -
Bedrock thinking + forced tool_choice conflict — PR#798: When using
structuredOutputSchemawith extended thinking enabled, the agent hit a Bedrock API error: “Thinking may not be enabled when tool_choice forces tool use.” The SDK now strips thethinkingkey fromadditionalRequestFieldswhentoolChoiceforces tool use (anyortoolvariants), preserving thinking forautoand unset tool choice. -
Bedrock context window overflow detection — PR#782: Synced
BEDROCK_CONTEXT_WINDOW_OVERFLOW_MESSAGESwith the Python SDK to include the'prompt is too long'error pattern, ensuring consistent overflow detection across both SDKs.
✦ Features 5
- add browser-based agent example
- add multiagent snapshot
- add AgentAsTool internal class
- enable session manager in multiagent (P0, resume logic will be in separate PR)
- add mid-execution cancellation