Skip to content
Type
All releases
  1. v1.0.0-rc.3

    Apr 8, 2026
    🎉 First-time contributors@michaelruelas@opieter-aws

    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 seconds
    setTimeout(() => agent.cancel(), 5000);
    const result = await agent.invoke('Do something long');
    console.log(result.stopReason); // 'cancelled'
    // Or use AbortSignal.timeout for declarative timeouts
    const 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 options
    const 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 automatically
    await graph.invoke('Write about AI');
    // Second invocation — state restored from snapshot
    await 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 breakPR#796: When a consumer broke out of for-await-of on agent.stream(), the runtime called .return() on the generator. The finally block tried to drain remaining events via yield, but with no consumer to resume the generator, it suspended permanently. The lock disposable never ran, leaving _isInvoking stuck at true and causing ConcurrentInvocationError on any subsequent call. Drain events are now only yielded when the consumer may still be iterating.

    • Bedrock thinking + forced tool_choice conflictPR#798: When using structuredOutputSchema with 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 the thinking key from additionalRequestFields when toolChoice forces tool use (any or tool variants), preserving thinking for auto and unset tool choice.

    • Bedrock context window overflow detectionPR#782: Synced BEDROCK_CONTEXT_WINDOW_OVERFLOW_MESSAGES with the Python SDK to include the 'prompt is too long' error pattern, ensuring consistent overflow detection across both SDKs.

    ✦ Features 5

    ⊘ Fixes 5