Doramagic Project Pack · Human Manual

harness-sdk

A model-driven approach to building AI agents in just a few lines of code.

Monorepo Architecture & SDKs Overview

Related topics: Agent Loop, Tools & Hooks, Plugins, Bidirectional Streaming & WASM Interop

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Component Responsibilities

Continue reading this section for the full explanation and source context.

Section WIT Contract

Continue reading this section for the full explanation and source context.

Section Bootstrap and Build

Continue reading this section for the full explanation and source context.

Related topics: Agent Loop, Tools & Hooks, Plugins, Bidirectional Streaming & WASM Interop

Monorepo Architecture & SDKs Overview

Purpose and Scope

The Strands Agents harness-sdk repository is a multi-package monorepo that hosts the Strands agent framework across several language targets, build systems, and supporting tooling. Its primary purpose is to provide a single source of truth from which Python-native, TypeScript-native, and WebAssembly-bridged SDKs are derived, along with the documentation, design proposals, and team policies that govern them.

The repository coordinates three first-class surfaces:

  1. A pure Python SDK (strands-py) — the original Strands implementation and the canonical reference for the agent loop, model providers, and tool ecosystem.
  2. A TypeScript SDK (strands-ts) — written in TypeScript and published to the npm ecosystem.
  3. A WASM-bridged package (strands-py-wasm + strands-wasm) — a WebAssembly component built from the TypeScript SDK that is loaded and driven by Python through wasmtime-py, enabling Python users to consume the TypeScript agent implementation.

Around these core SDKs, the monorepo also houses the documentation site (site/), the design-proposal process (designs/), the team's internal doctrine (team/), and developer tooling such as the strandly toolchain. Source: README.md.

Community alignment. Multiple open feature requests target the breadth of language targets and interop surface: a TypeScript/Node SDK (#156), a Go SDK (#616), a Java SDK (#240), and AG-UI protocol support (#140). The monorepo structure already accommodates the TS direction; Go and Java remain future work.

High-Level Repository Layout

The repository is organized into discrete top-level packages, each with a focused responsibility. The table below summarizes the layout that can be derived from the README and package contents.

PathRoleNotes
strands-py/Pure Python SDKThe original, canonical Strands implementation; pip install strands-agents.
strands-ts/TypeScript SDKPublished to npm; defines streaming, models, and tools.
strands-wasm/WASM build toolingMonorepo developer guide; describes WIT contracts and the build pipeline.
strands-py-wasm/Python wrapper around the WASM componentInstalled as strands-py-wasm; exposes generated Python bindings.
strandly/Toolchain CLILinked to PATH by the bootstrap script.
site/Documentation site (Astro + Starlight)Builds API references for both Python and TypeScript SDKs.
designs/RFC-style design proposalsCaptures context, decision, and consequences for large features.
team/Internal team doctrineTenets, decisions, API bar, agent guidelines.

Source: README.md, strands-wasm/README.md, team/README.md.

Architecture Overview

The monorepo is intentionally layered. The diagram below illustrates the relationship between language targets, the WASM bridge, the documentation site, and the governance process.

graph TD
    Repo[harness-sdk Monorepo]
    Py[strands-py: Python SDK]
    TS[strands-ts: TypeScript SDK]
    WASMTool[strands-wasm: Build Tooling]
    WASMPy[strands-py-wasm: Python + WASM]
    Site[site: Astro/Starlight Docs]
    Designs[designs: RFCs]
    Team[team: Tenets & Decisions]
    Strandly[strandly: CLI Toolchain]

    Repo --> Py
    Repo --> TS
    Repo --> WASMTool
    Repo --> WASMPy
    Repo --> Site
    Repo --> Designs
    Repo --> Team
    Repo --> Strandly

    TS -->|compiled to| WASMTool
    WASMTool -->|produces .wasm| WASMPy
    WASMPy -->|loaded by| Py
    Site -->|clones & generates| Py
    Site -->|clones & generates| TS
    Designs -->|feeds| Repo
    Team -->|guides| Repo
    Strandly -->|builds & links| WASMTool

Source: strands-wasm/README.md, site/package.json.

Component Responsibilities

  • strands-py is the public Python package. It exposes the Agent class, tool decorators, and a large family of model providers. The README's "Quick Start" example uses from strands import Agent and pip install strands-agents strands-agents-tools. Source: README.md.
  • strands-ts is the TypeScript counterpart. It defines streaming event types (e.g. ToolUseInputDelta, ReasoningContentDelta, CitationsDelta, Usage) and base model configuration (BaseModelConfig, StreamOptions). Source: strands-ts/src/models/streaming.ts, strands-ts/src/models/model.ts.
  • strands-wasm is the build-time tooling and developer guide that explains how the TS SDK is compiled into a WebAssembly component (strands-agent.wasm) and how Python loads it via wasmtime-py. Source: strands-wasm/README.md.
  • strands-py-wasm is the Python distribution that re-exports a generated _generated module and a curated types surface, allowing Python code to call into the WASM guest. Source: strands-py-wasm/src/strands/_generated/__init__.py, strands-py-wasm/src/strands/types.py.
  • site/ is the documentation site built with Astro and Starlight. Its package.json defines scripts to clone both SDKs and regenerate API references for each. Source: site/package.json.
  • designs/ formalizes the design-proposal process. It documents the template, lifecycle, and "no designs have been accepted yet" current state. Source: designs/README.md.
  • team/ contains the project's doctrine: TENETS.md, DECISIONS.md, API_BAR_RAISING.md, and AGENT_GUIDELINES.md. Source: team/README.md.
  • strandly/ provides the CLI toolchain that the bootstrap workflow links into PATH. Source: strands-wasm/README.md.

The WASM Bridge

The most architecturally distinctive piece of the monorepo is the bridge that lets Python host a TypeScript agent. The TS SDK is compiled to a WebAssembly component; Python loads this component via wasmtime-py and drives it. Source: strands-wasm/README.md.

WIT Contract

The contract between the WASM "guest" (TypeScript) and the Python "host" is defined in a single WIT file. It separates responsibilities cleanly:

  • Exports (TS implements, Python calls): The api interface — agent construction, streaming, conversation management. All model provider HTTP calls (Bedrock, Anthropic, OpenAI, Gemini) happen inside the WASM guest.
  • Imports (Python implements, TS calls back into): tool-provider for executing Python-defined tools, and host-log for routing log entries to Python's logging framework.

When the TS agent loop decides a tool needs to run, it calls the tool-provider import which crosses the WASM boundary back to Python where the actual tool function lives. Source: strands-wasm/README.md.

graph LR
    PyAgent[Python host: Agent loop & tools]
    WIT[wit/agent.wit contract]
    TSAgent[TypeScript guest: agent loop]
    Models[Model providers in WASM]
    Tools[Python-defined tools]
    Logs[Python logging]

    PyAgent -->|drives| TSAgent
    WIT --> PyAgent
    WIT --> TSAgent
    TSAgent --> Models
    TSAgent -->|tool-provider import| Tools
    PyAgent -->|exports api| WIT
    TSAgent -->|host-log import| Logs

Source: strands-wasm/README.md.

Bootstrap and Build

The first-time setup is a single command. From the repository root:

git clone https://github.com/strands-agents/sdk-python.git
cd sdk-python
npm install
npm run dev -- bootstrap

bootstrap installs toolchains, links strandly to PATH, generates type bindings, builds all layers, installs strands-py-wasm, and runs all tests. Source: strands-wasm/README.md.

Generated Python Bindings

strands-py-wasm exposes a large generated surface from _generated/. The list of re-exported names includes content block types (TextBlock, ImageBlock, VideoBlock, DocumentBlock, CitationsBlock), tool types (ToolUseBlock, ToolResultBlock, ToolSpec), model types (BedrockModel, AnthropicModel, OpenaiModel, GoogleModel, CustomModel), multi-agent types (SwarmConfig, GraphConfig, HandoffEvent), retry types (ExponentialBackoff, ConstantBackoff), session types (SessionManager, SlidingWindowConversationManager, SummarizingConversationManager), and many more. Source: strands-py-wasm/src/strands/_generated/__init__.py.

The curated public surface is narrowed in types.py. Some stream-oriented types are intentionally dropped from the public re-export because they are not part of the host API:

Dropped symbolReason / category
Datetime, Duration, InstantTime primitives not surfaced at the boundary.
ErrorUnderlying error primitive; users import the typed exceptions instead.
InputStream, OutputStream, PollableAsync I/O primitives used internally by the WASM layer.

The curated surface then re-exports the remaining symbols and adds convenience union types such as ModelInput, ConversationManagerInput, VendedToolInput, and VendedPluginInput. Source: strands-py-wasm/src/strands/types.py.

Model Provider Surface

Both language targets expose a family of model providers behind a consistent abstract base. The Python side uses lazy loading so that optional provider dependencies are not imported until the user actually instantiates that provider. Source: strands-py/src/strands/models/__init__.py.

Python Provider Catalog

Provider classModuleLazy loaded
BedrockModelbedrock.pyEager
AnthropicModelanthropic.pyYes (via __getattr__)
GeminiModelgemini.pyYes
LiteLLMModellitellm.pyYes
LlamaAPIModelllamaapi.pyYes
LlamaCppModelllamacpp.pyYes
MistralModelmistral.pyYes
OllamaModelollama.pyYes
OpenAIModelopenai.pyYes

Model and BaseModelConfig are exported eagerly. Source: strands-py/src/strands/models/__init__.py.

TypeScript Provider Catalog

The TS SDK mirrors the same model-provider philosophy. The Bedrock provider, for example, imports @aws-sdk/client-bedrock-runtime and reuses shared streaming types such as CitationsDelta, ReasoningContentDelta, and Usage. It also re-exports the common BaseModelConfig and StreamOptions from a single source of truth. Source: strands-ts/src/models/bedrock.ts, strands-ts/src/models/model.ts.

Streaming Event Vocabulary

The TS SDK defines a stream event vocabulary that the Python WASM package mirrors through its generated bindings. Key event shapes include:

TypePurpose
ToolUseInputDeltaIncremental tool input being generated.
ReasoningContentDeltaIncremental reasoning/thinking content.
CitationsDeltaCitations attached to generated content.
UsageInput, output, total, and cache token counts.

Source: strands-ts/src/models/streaming.ts.

Provider Implementation Patterns

Each provider implements the same loop, with provider-specific request formatting and error handling. The OpenAI provider formats an OpenAI-compatible chat streaming request, the OpenAI Responses provider reuses the native input_tokens.count endpoint when use_native_token_count is enabled, and the Mistral provider supports both streaming and non-streaming code paths. Source: strands-py/src/strands/models/openai.py, strands-py/src/strands/models/openai_responses.py, strands-py/src/strands/models/mistral.py.

Documentation Site

The site/ package is the user-facing documentation hub. It is built with Astro 6 and Starlight 0.38, uses TypeDoc 0.28 for TypeScript reference generation, and uses pydoc-markdown for the Python reference. The package script surface shows how the docs are tied to both SDKs:

ScriptEffect
buildastro build
build:allsdk:clone + sdk:generate + build
sdk:cloneClones both SDK repositories locally.
sdk:generate:pyRuns pydoc-markdown (via uv or pip).
sdk:generate:tsRuns TypeDoc on the TypeScript SDK.
sdk:syncsdk:clone + sdk:generate + npm install.
routes:updateUpdates the known-routes index used by the site.
typecheck / test / formatStandard maintenance scripts.

Source: site/package.json.

Governance and Design Process

Two governance documents shape the monorepo's evolution.

Design Proposals (`designs/`)

A design document is required for new major features affecting multiple parts of the SDK, breaking changes to existing APIs, architectural changes requiring design discussion, large contributions, and features that introduce new concepts. Bug fixes, small improvements, documentation updates, and new extensions in a contributor's own repository are explicitly excluded. The submission flow is:

  1. Check the roadmap.
  2. Create a branch.
  3. Add designs/NNNN-feature-name.md using the provided template.
  4. Submit a pull request.
  5. Iterate on feedback.
  6. Get approval and merge.
  7. Reference the design from the implementation PR.

The template captures Status, Date, Issue, Context, Decision, Developer Experience, Alternatives Considered, Consequences, and Willingness to Implement. At the time of the source files reviewed, "No designs have been accepted yet." Source: designs/README.md.

Team Doctrine (`team/`)

The team/ directory contains the long-lived principles that apply to all SDK work:

DocumentPurpose
TENETS.mdCore principles guiding SDK design.
DECISIONS.mdRecord of design and API decisions with rationale.
API_BAR_RAISING.mdProcess for reviewing and approving API changes.
AGENT_GUIDELINES.mdConventions for AI agents operating on the repos.

When a contribution results in a new decision that could guide future work, the contribution should add it to DECISIONS.md. Source: team/README.md.

End-to-End Developer Workflow

The first-time developer experience flows through the monorepo's npm run dev -- bootstrap command, which is intentionally exhaustive so that "if this command doesn't enable development out of the box, file an issue." Source: strands-wasm/README.md.

graph TD
    A[Clone repository] --> B[npm install]
    B --> C[npm run dev -- bootstrap]
    C --> D[Toolchains installed]
    C --> E[strandly linked to PATH]
    C --> F[Type bindings generated]
    C --> G[All layers built]
    C --> H[strands-py-wasm installed]
    C --> I[All tests run]
    D --> J[Ready to develop]
    E --> J
    F --> J
    G --> J
    H --> J
    I --> J

Source: strands-wasm/README.md.

Prerequisites are intentionally minimal: Node.js 20+ and Python 3.10+. Source: strands-wasm/README.md.

Configuration and Customization Points

The monorepo is configurable in several places, each owned by a different package.

LayerConfiguration mechanismSource
TypeScript model providersBaseModelConfig (modelId, maxTokens, temperature, topP, contextWindowLimit). contextWindowLimit is auto-resolved from a built-in lookup table when not explicitly set, and re-resolved when modelId changes via updateConfig().strands-ts/src/models/model.ts
Python provider selectionLazy import via __getattr__ so unused providers do not impose dependency costs.strands-py/src/strands/models/__init__.py
WASM Python public surfacetypes.py drops stream-only primitives (Datetime, Duration, Error, InputStream, OutputStream, Pollable) and adds curated union types (ModelInput, ConversationManagerInput, VendedToolInput, VendedPluginInput).strands-py-wasm/src/strands/types.py
OpenAI Responses token countinguse_native_token_count in provider config toggles between native input_tokens.count and fallback estimation.strands-py/src/strands/models/openai_responses.py
Mistral tool choicetool_choice is accepted but currently ignored for that provider (with a runtime warning).strands-py/src/strands/models/mistral.py
Documentation sitesite/package.json scripts (sdk:clone, sdk:generate:py, sdk:generate:ts, routes:update) drive which SDKs are referenced and how.site/package.json

Common Failure Modes and Pitfalls

These are the failure modes that can be observed from the source files alone; they are not invented, only described from evidence in the code.

  • Optional provider dependencies. The Python models/__init__.py lazy-loads every provider except BedrockModel. If a user instantiates, e.g., AnthropicModel without that provider's package installed, the lazy import will fail at first use. Source: strands-py/src/strands/models/__init__.py.
  • Native token counting fallback. The OpenAI Responses provider attempts a native count when use_native_token_count is true, but on any exception it logs a debug message and falls back to estimation. Callers must not assume native counts are always returned. Source: strands-py/src/strands/models/openai_responses.py.
  • Ignored tool_choice. The Mistral provider accepts tool_choice for interface consistency but explicitly does not honor it. Relying on it for Mistral will silently misbehave. Source: strands-py/src/strands/models/mistral.py.
  • Auto-populated contextWindowLimit. The TS base config notes that explicitly set contextWindowLimit is preserved when modelId changes, while auto-populated values are re-resolved. Code that mutates the model ID dynamically should be aware of this. Source: strands-ts/src/models/model.ts.
  • Design gating. New major features require an accepted design document. A pull request that adds cross-cutting functionality without a corresponding accepted design is likely to be sent back to the proposal stage. Source: designs/README.md.
  • Bootstrap dependency. The bootstrap script is the single source of truth for first-time setup. If it does not yield a working developer environment, the project's own documentation asks contributors to file an issue rather than improvise. Source: strands-wasm/README.md.

Community-Reported Gaps and Roadmap Signals

Several community requests are worth calling out here because they directly map to monorepo decisions:

  • TypeScript/Node SDK (#156) — Already addressed by strands-ts, though users continue to discuss frontend, backend, and IaC (CDK) TypeScript workflows.
  • Go SDK (#616) and Java SDK (#240) — Both are open requests. Neither has a corresponding package in the monorepo today; both would require new top-level directories analogous to strands-py and strands-ts.
  • Agent Skills (#1181) — The generated strands-py-wasm symbols already include SkillSource, and the VendedPluginInput union includes AgentSkills, indicating the WASM-bridged SDK has begun to expose a skills surface.
  • AG-UI Protocol (#140) — Community proposal to map Strands events to the AG-UI protocol. The streaming event vocabulary in strands-ts/src/models/streaming.ts is the natural integration point.
  • Latest release signal — "Python WASM v0.0.1 / Initial release of strands-agents-wasm" indicates the WASM bridge is the most recent forward step in the monorepo.

Source: community_context provided in the query; cross-references via strands-py-wasm/src/strands/types.py and strands-py-wasm/src/strands/_generated/__init__.py.

See Also

Source: https://github.com/strands-agents/harness-sdk / Human Manual

Agent Loop, Tools & Hooks

Related topics: Monorepo Architecture & SDKs Overview, Model Providers & Multi-Agent Patterns

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Monorepo Architecture & SDKs Overview, Model Providers & Multi-Agent Patterns

Agent Loop, Tools & Hooks

Overview

The Agent Loop, Tools & Hooks is the core execution model that makes Strands Agents a model-driven SDK for building and running AI agents. Rather than prescribing a rigid graph or state machine, Strands keeps the agent loop lightweight, hands the model control over tool selection, and exposes lifecycle hooks so developers can observe, customize, and integrate around each turn of the loop.

Strands Agents is delivered as a monorepo containing multiple SDKs that all converge on the same conceptual model:

PackagePathPurpose
Python SDKstrands-py/Agent loop, model providers, tools (PyPI: strands-agents)
TypeScript SDKstrands-ts/Agent loop, model providers, tools (npm: @strands/agents)
WebAssembly bindingsstrands-wasm/ + strands-py-wasm/Run the TypeScript agent from Python via WASM
Developer CLIstrandly/Local builds, codegen, workspace tooling
Documentation sitesite/Astro/Starlight site at strandsagents.com
Design proposalsdesigns/RFC-style documents for significant changes
Team docsteam/Tenets, decisions, API review process

Source: README.md

The high-level tagline — "simple agent loop that just works and is fully customizable" — is the design intent behind this subsystem. Source: strands-py/README.md

Source: https://github.com/strands-agents/harness-sdk / Human Manual

Model Providers & Multi-Agent Patterns

Related topics: Agent Loop, Tools & Hooks, Plugins, Bidirectional Streaming & WASM Interop

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Provider Package Layout

Continue reading this section for the full explanation and source context.

Section Provider Inventory

Continue reading this section for the full explanation and source context.

Section Common Configuration Surface

Continue reading this section for the full explanation and source context.

Related topics: Agent Loop, Tools & Hooks, Plugins, Bidirectional Streaming & WASM Interop

Model Providers & Multi-Agent Patterns

Overview

Strands Agents is a model-driven SDK for building and running AI agents. Its two most consequential architectural commitments are: (1) a model-agnostic provider layer that lets the same agent loop drive Bedrock, Anthropic, OpenAI, Gemini, Mistral, Writer, LiteLLM, LlamaAPI, LlamaCpp, Ollama, and SageMaker, and (2) a multi-agent orchestration layer that composes those agents into Graph and Swarm topologies. This page documents both layers, the streaming event contract that ties them together, and the multi-language surface (Python, TypeScript, and the WASM bridge) that exposes them.

The provider layer is declared in strands-py/src/strands/models/__init__.py as a package of "an abstract base Model class along with concrete implementations for specific providers," and it uses lazy import via __getattr__ so optional provider SDKs are only loaded when actually requested. The TypeScript counterpart is declared in strands-ts/src/models/model.ts through the BaseModelConfig interface and the StreamOptions shape, ensuring provider parity across languages.

The multi-agent capabilities (Graph and Swarm) are advertised as "Advanced Capabilities" in the top-level README and as "Multi-Agent Orchestration" in the TypeScript README, and are exposed across the Python, TypeScript, and WASM boundaries through the type set in strands-py-wasm/src/strands/_generated/__init__.py (e.g. SwarmConfig).

The Model-Provider Layer

Provider Package Layout

strands-py/src/strands/models/__init__.py lists the model module's public surface and implements lazy loading for every non-default provider:

# strands-py/src/strands/models/__init__.py
from . import bedrock, model
from .bedrock import BedrockModel
from .model import BaseModelConfig, CacheConfig, CacheToolsConfig, Model

__all__ = [
    "bedrock",
    "model",
    "BaseModelConfig",
    "BedrockModel",
    "CacheConfig",
    "CacheToolsConfig",
    "Model",
]

def __getattr__(name: str) -> Any:
    if name == "AnthropicModel":
        from .anthropic import AnthropicModel
        return AnthropicModel
    # ... GeminiModel, LiteLLMModel, LlamaAPIModel, LlamaCppModel,
    #     MistralModel, OllamaModel, OpenAIModel, ... lazily loaded

Source: strands-py/src/strands/models/__init__.py

This pattern is important operationally: a project that only needs Bedrock never imports the Anthropic, Gemini, or Mistral SDKs, keeping cold-start times and dependency graphs lean. Each provider module follows a uniform contract (format_request, format_chunk, stream, _handle_non_streaming_response) so the agent loop can be provider-blind.

Provider Inventory

The table below summarizes the providers shipped in the Python SDK, the module that implements them, and notable configuration behaviors visible in the source.

ProviderModuleStream ToggleTool ChoiceNotable Behavior
Amazon Bedrockstrands-py/src/strands/models/bedrock.pyconfig["stream"] (default True)HonoredDefault provider, requires model_id in us-west-2 per strands-py/README.md
Anthropicstrands-py/src/strands/models/anthropic.pyHonoredHonoredDirect Anthropic API
OpenAI (Chat Completions)strands-py/src/strands/models/openai.pyHonoredHonored_format_system_messages and _format_regular_messages produce OpenAI-compatible arrays
OpenAI (Responses)strands-py/src/strands/models/openai_responses.pyHonoredHonoredSeparate module for the new Responses API
Geministrands-py/src/strands/models/gemini.pyHonoredHonoredGoogle GenAI
Mistralstrands-py/src/strands/models/mistral.pyconfig.get("stream", True)Ignored with warn_on_tool_choice_not_supportedRaises ModelThrottledException on rate limits
Writerstrands-py/src/strands/models/writer.pyAlways streaming in _streamIgnored with warningRenames model_idmodel; raises KeyError if not set; tools key omitted when empty
LiteLLMstrands-py/src/strands/models/litellm.pyHonoredHonoredRoutes through LiteLLM to 100+ providers
LlamaAPIstrands-py/src/strands/models/llamaapi.pyHonoredHonoredHosted Llama API
LlamaCppstrands-py/src/strands/models/llamacpp.pyHonoredHonoredLocal in-process inference
Ollamastrands-py/src/strands/models/ollama.pyHonoredHonoredLocal Ollama daemon
SageMakerstrands-py/src/strands/models/sagemaker.pyHonoredHonoredSelf-hosted SageMaker endpoints

Source: strands-py/src/strands/models/mistral.py, strands-py/src/strands/models/writer.py, strands-py/src/strands/models/openai.py

Common Configuration Surface

strands-py/src/strands/models/model.py defines BaseModelConfig, which every provider extends. The TypeScript equivalent lives in strands-ts/src/models/model.ts as the BaseModelConfig interface:

// strands-ts/src/models/model.ts
export interface BaseModelConfig {
  modelId?: string
  maxTokens?: number
  temperature?: number
  topP?: number
  contextWindowLimit?: number
}

Source: strands-ts/src/models/model.ts

contextWindowLimit has special semantics in the TypeScript layer: when not provided, it is resolved from a built-in lookup table keyed by modelId, and is re-resolved automatically after updateConfig({ modelId }) if the value was initially auto-populated. This auto-resolution behavior is implemented to keep cache- and truncation-related code free of provider-specific branching.

Streaming Event Contract

Every provider funnels into the same chunk vocabulary. strands-ts/src/models/streaming.ts documents the wire-level types that both the Python and TypeScript layers must emit:

Chunk TypePurpose
messageStartBegins an assistant turn; sets role: "assistant"
contentBlockStartOpens a content block (text or tool use)
contentBlockDeltaIncremental text or tool input
contentBlockStopCloses a content block
messageStopEnds an assistant turn
toolUseStart / toolUseInputDelta / toolUseStopTool-use lifecycle
reasoningContentDeltaReasoning / thinking tokens (text, signature, redacted)
citationsDeltaCitations linking generated content to source locations
usageInput/output/cache token accounting

Source: strands-ts/src/models/streaming.ts

The Python providers emit matching chunk types via format_chunk. For example, the Mistral provider emits {"chunk_type": "message_start"} and then translates streamed choices into content_block_delta events, accumulating text in accumulated_text and tool calls in a dict[str, list[Any]] keyed by tool id. Source: strands-py/src/strands/models/mistral.py

The Writer provider follows the same shape: format_chunk({"chunk_type": "message_start"}) then format_chunk({"chunk_type": "content_block_start", "data_type": "text"}) followed by per-token content_block_delta events for choice.delta.content and tool-call deltas for choice.delta.tool_calls. Source: strands-py/src/strands/models/writer.py

Provider Streaming Flow

graph TD
    A[Agent Loop] --> B[Model.stream]
    B --> C[format_request]
    C --> D{stream flag}
    D -->|True| E[Provider stream API]
    D -->|False| F[Non-streaming API + _handle_non_streaming_response]
    E --> G[format_chunk per event]
    F --> G
    G --> H[Standardized StreamEvent]
    H --> I[Agent consumes via async iterator]
    I --> J[Tool dispatch, if toolUse present]

Source: strands-py/src/strands/models/mistral.py, strands-py/src/strands/models/writer.py

Provider Quirks and Failure Modes

Two cross-provider quirks are worth flagging because they trip up new users:

  1. tool_choice is silently ignored on some providers. Mistral and Writer accept the parameter for interface consistency but pass it through warn_on_tool_choice_not_supported(tool_choice) and discard the value. Source: strands-py/src/strands/models/mistral.py, strands-py/src/strands/models/writer.py
  1. Throttling is normalized to ModelThrottledException. Both Mistral and Writer translate provider-specific rate-limit errors (mistralai.RateLimitError, writerai.RateLimitError) into a single SDK exception so retry/circuit-breaker code in the agent loop can be provider-agnostic. Source: strands-py/src/strands/models/mistral.py, strands-py/src/strands/models/writer.py
  1. Empty tools lists are dropped. Writer raises a KeyError if model_id is not set, and explicitly omits the tools key from the request when tool_specs is empty, because the Writer API rejects empty tools arrays. Source: strands-py/src/strands/models/writer.py

TypeScript Provider Parity

The TypeScript SDK follows the same model-agnostic philosophy. The default BedrockModel is the canonical first-class provider, with OpenAI listed as supported and an extension point for custom providers (advertised in strands-ts/README.md):

import { Agent, BedrockModel } from '@strands-agents/sdk'

const agent = new Agent({
  model: new BedrockModel({ region: 'us-east-1' }),
  tools: [notebook],
})

Source: strands-ts/README.md, strands-ts/src/vended-tools/notebook/README.md

The TypeScript BaseModelConfig includes an explicit contextWindowLimit field whose default behavior (auto-resolved from a lookup table, re-resolved on modelId change unless explicitly set) is documented in the JSDoc and designed to let conversation managers pick a strategy without per-provider branching. Source: strands-ts/src/models/model.ts

Multi-Agent Patterns

Pattern Catalog

The Strands SDK ships two multi-agent orchestration patterns, both surfaced across Python, TypeScript, and the WASM surface:

PatternBest ForSurface Name
GraphExplicit, deterministic routing between agents with typed edgesExposed via Python, TypeScript, and strands-py-wasm
SwarmAutonomous, emergent delegation between peer agentsExposed as SwarmConfig in the WASM type set

Source: strands-py/README.md, strands-ts/README.md, strands-py-wasm/src/strands/_generated/__init__.py

The SwarmConfig symbol appears in the WASM public types generated for the Python↔TypeScript bridge, indicating that Swarm is treated as a first-class orchestration primitive that must round-trip through the WIT contract. Source: strands-py-wasm/src/strands/_generated/__init__.py

How the Multi-Agent Loop Reuses the Provider Layer

Every agent in a Graph or Swarm is itself a Strands Agent, so it can target any provider in the table above. This means a single multi-agent system can mix providers — for example, a routing agent on Bedrock, a research agent on OpenAI, and a code-generation agent on a local LlamaCpp instance — without any change to the orchestration code. The provider-agnosticism of the Model base class is what makes that composition possible. Source: strands-py/src/strands/models/__init__.py

graph TD
    User[User Request] --> Router{Router Agent}
    Router -->|research| Research[Research Agent<br/>OpenAI]
    Router -->|code| Code[Code Agent<br/>LlamaCpp local]
    Router -->|summarize| Summary[Summary Agent<br/>Bedrock]
    Research --> Synth[Synthesizer Agent<br/>Bedrock]
    Code --> Synth
    Summary --> Synth
    Synth --> User

The diagram is a representative Graph topology; concrete edge conditions are authored by the application, not the SDK. Source: strands-py/README.md, strands-ts/README.md

Tool and Plugin Reuse in Multi-Agent Setups

Multi-agent setups benefit from the same plugin/tool system as single agents. Vended tools (BashTool, FileEditorTool, HttpRequestTool, NotebookTool) and vended plugins (AgentSkills, ContextOffloader) are re-exported by the WASM surface via type unions in strands-py-wasm/src/strands/types.py:

VendedToolInput = VendedTool | BashTool | FileEditorTool | HttpRequestTool | NotebookTool
VendedPluginInput = VendedPlugin | AgentSkills | ContextOffloader

Source: strands-py-wasm/src/strands/types.py

A community request, [FEATURE] Add support for skills (#1181), asks for first-class Agent Skills support to load relevant knowledge files into context per task. The AgentSkills plugin already exists in the WASM type surface, so the request maps onto plugin wiring rather than a new primitive. Source: strands-py-wasm/src/strands/types.py

Streaming and Conversation Management

Both single-agent and multi-agent invocations share the same streaming event contract documented in strands-ts/src/models/streaming.ts. Three event categories matter most for multi-agent systems:

  1. Reasoning deltasreasoningContentDelta carries incremental text, signature, and redacted-reasoning bytes. This is the type multi-agent routers surface to expose an agent's intermediate deliberation to the parent.
  2. Tool-use deltastoolUseInputDelta streams partial JSON for tool inputs, which is critical when an agent invokes a long-running tool that another agent should be able to observe.
  3. Usage deltasUsage reports inputTokens, outputTokens, totalTokens, plus cache-related metrics, enabling fair cost accounting when one parent agent orchestrates many children.

Source: strands-ts/src/models/streaming.ts

On the Python side, conversation managers are exposed as the union SlidingWindowConversationManager | SummarizingConversationManager, and the model-agnostic input is ModelConfig | BedrockModel | AnthropicModel | OpenaiModel | GoogleModel | CustomModel. These unions make the orchestration surface fully provider-agnostic. Source: strands-py-wasm/src/strands/types.py

The WASM Bridge and Cross-Language Providers

The Python WASM build (strands-py-wasm) is a WebAssembly packaging of the TypeScript SDK. The contract is defined by wit/agent.wit and the type set in strands-py-wasm/src/strands/_generated/__init__.py:

  • Exports (TypeScript implements, Python calls): the api interface, including agent construction, streaming, and conversation management. All model provider HTTP calls — Bedrock, Anthropic, OpenAI, Gemini — happen inside the WASM guest.
  • Imports (Python implements, TypeScript calls back into): tool-provider for executing Python-defined tools, and host-log for routing log entries to Python's logging framework.

Source: strands-wasm/README.md

This means that when running strands-py-wasm, the model-provider HTTP calls are made by the TypeScript code compiled into strands-agent.wasm, and Python only sees streamed events through the api export. For a multi-agent Python application that imports the WASM package, every child agent's provider is effectively a TypeScript-backed provider, but the Python orchestration code is unaware of that boundary. Source: strands-wasm/README.md

The latest release of strands-agents-wasm is v0.0.1 (initial release), per the community context.

Community-Driven Direction

Several community issues are directly relevant to the provider and multi-agent story:

  • #156 Add TypeScript/JavaScript/NodeJS SDK — Resolved by the existence of the strands-ts package and the strands-py-wasm bridge, both of which expose the same provider and multi-agent surfaces.
  • #616 Go SDK — Not yet on the roadmap. The WASM bridge demonstrates that the provider contract is portable enough to retarget, so a future Go SDK is plausible but unannounced.
  • #240 Java SDK — Same status as Go; no announced work, but the type set in strands-py-wasm/src/strands/_generated/__init__.py is a candidate seed for cross-language codegen.
  • #1181 Agent Skills — The AgentSkills plugin already appears in the WASM type surface; further work is integration rather than core infrastructure.
  • #140 AG-UI protocol — A proposal to map Strands stream events to the AG-UI protocol. The standardized event vocabulary in strands-ts/src/models/streaming.ts (and mirrored by Python format_chunk) is the natural mapping source.

Source: strands-py-wasm/src/strands/_generated/__init__.py, strands-ts/src/models/streaming.ts

Design and Contribution Workflow

Significant changes to the provider or multi-agent layers are expected to follow the design process described in designs/README.md. The repository uses an RFC-style template with Status, Context, Decision, Developer Experience, Alternatives Considered, Consequences, and Willingness to Implement sections. As of the most recent README snapshot, no designs have been accepted yet, so all multi-agent and provider work is currently shaped in code rather than in merged design documents. Source: designs/README.md

The team/ directory houses internal guidance: TENETS.md (core SDK principles), DECISIONS.md (rationale records), API_BAR_RAISING.md (the API review process), and AGENT_GUIDELINES.md (conventions for AI agents operating on the repo). Source: team/README.md

See Also

Source: https://github.com/strands-agents/harness-sdk / Human Manual

Plugins, Bidirectional Streaming & WASM Interop

Related topics: Monorepo Architecture & SDKs Overview, Model Providers & Multi-Agent Patterns

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Monorepo Architecture & SDKs Overview, Model Providers & Multi-Agent Patterns

Plugins, Bidirectional Streaming & WASM Interop

The Strands Agents SDK exposes three closely related extensibility surfaces:

  1. A vended plugin system (Skills, Context Offloader, Steering) that wraps reusable agent behaviors into a single lifecycle API.
  2. A bidirectional streaming (bidi) subsystem under strands.experimental.bidi for realtime, multimodal model sessions.
  3. A WebAssembly (WASM) interop layer (strands-wasm, strands-py-wasm, strands-ts) that compiles the TypeScript runtime into a WASM component embedded inside the Python host.

This page describes the public shape of those subsystems, how they fit together, and how the WIT contract defines the boundary between the WASM guest and the Python host.

Source: https://github.com/strands-agents/harness-sdk / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

high Security or permission risk requires verification

Developers may expose sensitive permissions or credentials: [BUG] CacheConfig(strategy="auto") does not detect Claude models when using ARN-based inference profiles

high Security or permission risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Identity risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 30 structured pitfall item(s), including 3 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

1. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/strands-agents/harness-sdk/issues/2748

2. Security or permission risk: Security or permission risk requires verification

  • Severity: high
  • Finding: Developers should check this security_permissions risk before relying on the project: [BUG] CacheConfig(strategy="auto") does not detect Claude models when using ARN-based inference profiles
  • User impact: Developers may expose sensitive permissions or credentials: [BUG] CacheConfig(strategy="auto") does not detect Claude models when using ARN-based inference profiles
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: [BUG] CacheConfig(strategy="auto") does not detect Claude models when using ARN-based inference profiles. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_issue | https://github.com/strands-agents/harness-sdk/issues/2601

3. Security or permission risk: Security or permission risk requires verification

  • Severity: high
  • Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/strands-agents/harness-sdk/issues/482

4. Identity risk: Identity risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a identity risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: identity.distribution | https://github.com/strands-agents/harness-sdk

5. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Developers should check this installation risk before relying on the project: [BUG] Gemini rejects tool results with multiple same-format images: duplicate displayName in function_response.parts (400 INVALID_ARGUMENT)
  • User impact: Developers may fail before the first successful local run: [BUG] Gemini rejects tool results with multiple same-format images: duplicate displayName in function_response.parts (400 INVALID_ARGUMENT)
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: [BUG] Gemini rejects tool results with multiple same-format images: duplicate displayName in function_response.parts (400 INVALID_ARGUMENT). Context: Observed when using node, docker, macos, linux
  • Evidence: failure_mode_cluster:github_issue | https://github.com/strands-agents/harness-sdk/issues/2748

6. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Developers should check this installation risk before relying on the project: [BUG] OpenAIModel tool message content sent as array instead of string breaks OpenAI-compatible endpoints (e.g., Kimi K2.5)
  • User impact: Developers may fail before the first successful local run: [BUG] OpenAIModel tool message content sent as array instead of string breaks OpenAI-compatible endpoints (e.g., Kimi K2.5)
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: [BUG] OpenAIModel tool message content sent as array instead of string breaks OpenAI-compatible endpoints (e.g., Kimi K2.5). Context: Observed when using python, macos
  • Evidence: failure_mode_cluster:github_issue | https://github.com/strands-agents/harness-sdk/issues/1696

7. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Developers should check this installation risk before relying on the project: python/v1.41.0
  • User impact: Upgrade or migration may change expected behavior: python/v1.41.0
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: python/v1.41.0. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_release | https://github.com/strands-agents/harness-sdk/releases/tag/python/v1.41.0

8. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Developers should check this installation risk before relying on the project: v1.41.0
  • User impact: Upgrade or migration may change expected behavior: v1.41.0
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: v1.41.0. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_release | https://github.com/strands-agents/harness-sdk/releases/tag/v1.41.0

9. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/strands-agents/harness-sdk/issues/1696

10. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/strands-agents/harness-sdk/issues/2614

11. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/strands-agents/harness-sdk/issues/2421

12. Configuration risk: Configuration risk requires verification

  • Severity: medium
  • Finding: Developers should check this configuration risk before relying on the project: [FEATURE] Support Managed Bedrock Knowledge Bases for Memory Manager
  • User impact: Developers may misconfigure credentials, environment, or host setup: [FEATURE] Support Managed Bedrock Knowledge Bases for Memory Manager
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: [FEATURE] Support Managed Bedrock Knowledge Bases for Memory Manager. Context: Source discussion did not expose a precise runtime context.
  • Evidence: failure_mode_cluster:github_issue | https://github.com/strands-agents/harness-sdk/issues/2880

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using harness-sdk with real data or production workflows.

  • Python middleware: add interrupt source field to distinguish middleware- - github / github_issue
  • [[BUG] Gemini rejects tool results with multiple same-format images: dupl](https://github.com/strands-agents/harness-sdk/issues/2748) - github / github_issue
  • [[FEATURE] Support Managed Bedrock Knowledge Bases for Memory Manager](https://github.com/strands-agents/harness-sdk/issues/2880) - github / github_issue
  • [[FEATURE] Support for multiple MCP servers (and loading from config file](https://github.com/strands-agents/harness-sdk/issues/482) - github / github_issue
  • [[BUG] CacheConfig(strategy="auto") does not detect Claude models when us](https://github.com/strands-agents/harness-sdk/issues/2601) - github / github_issue
  • [[FEATURE] Support audio input for standard Agent (Specially using Bedroc](https://github.com/strands-agents/harness-sdk/issues/2614) - github / github_issue
  • [[WASM] Python SDK - Gaps and Limitations](https://github.com/strands-agents/harness-sdk/issues/2421) - github / github_issue
  • [[WASM] MCP tools](https://github.com/strands-agents/harness-sdk/issues/2456) - github / github_issue
  • [[BUG] OpenAIModel tool message content sent as array instead of string b](https://github.com/strands-agents/harness-sdk/issues/1696) - github / github_issue
  • typescript/v1.6.0 - github / github_release
  • python/v1.44.0 - github / github_release
  • typescript/v1.5.0 - github / github_release

Source: Project Pack community evidence and pitfall evidence