Skip to content

Releases: strands-agents/sdk-python

v1.33.0

24 Mar 17:55
0a723bc

Choose a tag to compare

Pins litellm<=1.82.6 to supply chain attack - S​upply Chain Attack in litellm 1.82.8 on PyPI

What's Changed

  • fix: summarization conversation manager sometimes returns empty response by @Unshure in #1947
  • fix: remove agent from swarm test to get more consistency out of it by @Unshure in #1946
  • fix: CRITICAL: Hard pin litellm<=1.82.6 to mitigate supply chain attack by @udaymehta in #1961

New Contributors

Full Changelog: v1.32.0...v1.33.0

v1.32.0

20 Mar 14:02
38c1ab6

Choose a tag to compare

What's Changed

  • fix(event-loop): ensure all cycle metrics include end time and duration by @stephentreacy in #1903
  • fix: pin upper bound for mistralai dependency by @mkmeral in #1935
  • fix: override end_turn stop reason when streaming response contains toolUse blocks by @atian8179 in #1827

New Contributors

Full Changelog: v1.31.0...v1.32.0

v1.31.0

19 Mar 14:07
1643a62

Choose a tag to compare

What's Changed

  • feat: pass A2A request context metadata as invocation state by @mkmeral in #1854
  • fix: s3session manager bug by @mehtarac in #1915
  • fix(graph): only evaluate outbound edges from completed nodes by @giulio-leone in #1846
  • fix(openai): always use string content for tool messages by @giulio-leone in #1878
  • feat: widen openai dependency to support 2.x for litellm compatibility by @BV-Venky in #1793
  • fix: typeError when serializing multimodal prompts with binary content in Graph/Swarm session persistence by @JackYPCOnline in #1870
  • fix: lowercase the python language in code snippet by @zastrowm in #1929
  • fix: openai repsonses api error handling by @Unshure in #1931

New Contributors

Full Changelog: v1.30.0...v1.31.0

v1.30.0

11 Mar 18:34
2da3f7c

Choose a tag to compare

What's Changed

  • feat: add "anthropic" cache strategy to bypass model ID check by @kevmyung in #1808
  • feat: serialize tool results as JSON when possible by @clareliguori in #1752
  • fix: summary manager using structured output by @pgrayy in #1805
  • feat(mcp): expose server instructions from InitializeResult on MCPClient by @ShotaroKataoka in #1814
  • fix: added LANGFUSE_BASE_URL check for additinoal attribute by @poshinchen in #1826
  • feat(session): add dirty flag to skip unnecessary agent state persistence by @Unshure in #1803
  • feat: add public tool_spec setter by @mkmeral in #1822
  • feat: add CancellationToken for graceful agent execution cancellation by @jgoyani1 in #1772
  • feat(session): optimize session manager initialization by @Unshure in #1829
  • fix(mistral): report usage metrics in streaming mode by @jackatorcflo in #1697
  • fix(openai_responses): use output_text for assistant messages in multi-turn conversations by @giulio-leone in #1851
  • feat(hooks): add resume flag to AfterInvocationEvent by @mkmeral in #1767
  • fix: place cache point on last user message instead of assistant by @kevmyung in #1821
  • feat(skills): add agent skills as a plugin by @mkmeral in #1755
  • feat(steering): move steering from experimental to production by @dbschmigelski in #1853
  • fix: break circular references so Agent cleanup doesn't hang with MCPClient by @dbschmigelski in #1830
  • fix: Set is_new_session = False at the end of each initialize* method by @mehtarac in #1859

New Contributors

Full Changelog: v1.29.0...v1.30.0

v1.29.0

04 Mar 21:13
31f1e64

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.28.0...v1.29.0

v1.28.0

25 Feb 19:32
37938da

Choose a tag to compare

What's Changed

  • fix: update region for agentcore in our new account by @afarntrog in #1715
  • fix: remove test that fails for python 3.14 by @Unshure in #1717
  • feat(hooks): support union types and list of types for add_hook by @Unshure in #1719
  • feat: make pyaudio an optional dependency by lazy loading by @mehtarac in #1731
  • feat(hooks): add Plugin Protocol for agent extensibility by @Unshure in #1733
  • feat: add plugins parameter to Agent by @Unshure in #1734
  • refactor(plugins): convert Plugin from Protocol to ABC by @Unshure in #1741
  • feat(steering): migrate SteeringHandler from HookProvider to Plugin by @Unshure in #1738
  • chore: switch to Sonnet 4.6 for Anthropic provider integ tests by @clareliguori in #1754
  • fix: rename init_plugin to init_agent by @Unshure in #1765

Full Changelog: v1.27.0...v1.28.0

v1.27.0

19 Feb 17:10
0a31848

Choose a tag to compare

What's Changed

  • feat: Propagate exceptions to AfterToolCallEvent for decorated tools (#1565) by @charles-dyfis-net in #1566
  • feat(workflows): add conventional commit workflow in PR by @mkmeral in #1645
  • fix: the A2AAgent returns empty AgentResult content by @afarntrog in #1675
  • auto run review workflow on maintainer PR by @mehtarac in #1673
  • fix: correct output reference for approval-env in integration test by @afarntrog in #1685
  • fix: update approval env var for strands agent workflows by @Unshure in #1701
  • fix: update allowed roles to include maintainer by @afarntrog in #1704
  • fix: propagate reasoningSignature on Gemini tool use by @afarntrog in #1703
  • ci: bump actions/github-script from 7 to 8 by @dependabot[bot] in #1699
  • ci: bump amannn/action-semantic-pull-request from 5 to 6 by @dependabot[bot] in #1684
  • fix: handle OpenAI model responses with tool calls and no other assistant content by @clareliguori in #1562
  • fix: Update finalize condition for workflow execution by @Unshure in #1708
  • fix: upgrade mcp minimum dependency to 1.23.0 for Tasks support by @clareliguori in #1674
  • feat(agent): add concurrent_invocation_mode parameter by @zastrowm in #1707
  • test: coverage for python 3.14 by @awsarron in #1178
  • feat(agent): add add_hook convenience method for hook callback registration by @Unshure in #1706

Full Changelog: v1.26.0...v1.27.0

v1.26.0

11 Feb 19:49
a43e936

Choose a tag to compare

What's Changed

  • ci: bump aws-actions/configure-aws-credentials from 5 to 6 by @dependabot[bot] in #1632
  • docs: add guidance on using Protocol instead of Callable for extensible interfaces by @dbschmigelski in #1637
  • feat(mcp): Implement basic support for Tasks by @LucaButBoring in #1475
  • fix(multiagent): set empty text part data in parts for Artifact by @punkyoon in #1643
  • fix(summarizing_conversation_manager): use model stream to generate summary by @mkmeral in #1653
  • fix(bedrock): add 'prompt is too long' to context window overflow mes… by @eladb3 in #1663
  • fix: fix mcp tests by @afarntrog in #1664

New Contributors

Full Changelog: v1.25.0...v1.26.0

v1.25.0

05 Feb 19:48
4f1a8b3

Choose a tag to compare

Major Features

A2AAgent: First-Class Client for Remote A2A Agents - PR#1441

The new A2AAgent class makes it simple to connect to and invoke remote agents that implement the Agent-to-Agent (A2A) protocol. A2AAgent implements the AgentBase protocol, so it can be called synchronously, asynchronously, or used in streaming mode just like a local Agent. It automatically discovers the remote agent's card to populate its name and description, and manages HTTP client lifecycle for you.

from strands.agent.a2a_agent import A2AAgent

# Connect to a remote A2A agent
a2a_agent = A2AAgent(endpoint="http://localhost:9000")

# Invoke it like any other agent
result = a2a_agent("Show me 10 ^ 6")
print(result.message)

# Or stream events asynchronously
async for event in a2a_agent.stream_async("Summarize this report"):
    if event.get("type") == "a2a_stream":
        print(f"A2A event: {event['event']}")
    elif "result" in event:
        print(f"Final: {event['result'].message}")

A2AAgent Support in Graph Workflows - PR#1615

Graph nodes now accept any AgentBase implementation as an executor, not just the concrete Agent class. This means A2AAgent instances and other custom AgentBase implementations can participate in graph-based multi-agent workflows alongside local agents. The Agent class also now explicitly extends AgentBase for compile-time protocol verification.

from strands import Agent
from strands.agent.a2a_agent import A2AAgent
from strands.multiagent.graph import GraphBuilder

local_agent = Agent(name="summarizer", system_prompt="Summarize input concisely.")
remote_agent = A2AAgent(endpoint="http://remote-agent:9000")

builder = GraphBuilder()
builder.add_node(remote_agent, "research")
builder.add_node(local_agent, "summarize")
builder.add_edge("research", "summarize")
graph = builder.build()

result = graph("Analyze recent AI trends")

Interrupt Support for MultiAgent Graph Nodes - PR#1606

Interrupts now propagate correctly through nested multi-agent graph nodes. When an agent inside a nested Graph, Swarm, or any custom MultiAgentBase node raises an interrupt, the outer graph pauses execution and surfaces the interrupt to the caller. After the caller provides a response, the outer graph resumes execution from where it left off. This builds on the interrupt support for single-agent graph nodes added in v1.24.0.

from strands import Agent, tool
from strands.interrupt import Interrupt
from strands.multiagent import GraphBuilder, Status
from strands.types.tools import ToolContext

@tool(context=True)
def approval_tool(tool_context: ToolContext) -> str:
    return tool_context.interrupt("approval", reason="Needs human approval")

agent = Agent(name="reviewer", tools=[approval_tool])

inner_graph = GraphBuilder()
inner_graph.add_node(agent, "reviewer")
outer_graph = GraphBuilder()
outer_graph.add_node(inner_graph.build(), "review_pipeline")

graph = outer_graph.build()
result = graph("Review this document")

while result.status == Status.INTERRUPTED:
    responses = [
        {"interruptResponse": {"interruptId": i.id, "response": "Approved"}}
        for i in result.interrupts
    ]
    result = graph(responses)

S3 Location Support for Documents, Images, and Videos - PR#1572

Media content types now support S3 locations as a source, allowing you to reference documents, images, and videos stored in Amazon S3 directly without base64 encoding. The new S3Location type includes a required uri field and an optional bucketOwner field for cross-account access. On Bedrock, S3 locations are passed through to the API natively.

from strands import Agent

agent = Agent()

response = agent([{
    "role": "user",
    "content": [
        {"text": "Summarize this document:"},
        {
            "document": {
                "format": "pdf",
                "name": "report",
                "source": {
                    "location": {
                        "type": "s3",
                        "uri": "s3://my-bucket/documents/report.pdf",
                        "bucketOwner": "123456789012"  # optional, for cross-account
                    }
                }
            }
        }
    ]
}])

Configurable Structured Output Prompt - PR#1627

The prompt message the agent uses to request structured output formatting is now configurable via the structured_output_prompt parameter. Previously, the hardcoded message "You must format the previous response as structured output." could trigger Bedrock Guardrails prompt-attack filters. You can now customize this message at the agent level or per invocation to work around guardrail rules or to better suit your use case.

from strands import Agent
from pydantic import BaseModel

class UserInfo(BaseModel):
    name: str
    age: int

# Custom prompt avoids triggering Bedrock Guardrails prompt attack filter
agent = Agent(
    structured_output_model=UserInfo,
    structured_output_prompt="Please use the output tool now."
)

# Or override per invocation
result = agent(
    "Extract user info from: John is 30 years old",
    structured_output_prompt="Format the response using the output tool."
)

Major Bug Fixes

  • Nullable Semantics Preserved for Required Union[T, None] Tool Parameters - PR#1584
    When a @tool parameter was typed as T | None without a default value, the schema cleaning logic was stripping null from the anyOf array, making the field required with no way to express null. This caused LLMs to fall back to passing "null" as a string. The anyOf simplification is now skipped for fields in the required array, preserving proper nullable semantics.

  • LedgerProvider Now Handles Parallel Tool Calls Correctly - PR#1559
    When agents proposed multiple tool calls in a single model response, the ledger provider only updated the last tool in the batch (ledger['tool_calls'][-1]), leaving earlier pending tools without proper status updates. The provider now correctly tracks and updates each individual tool call.

  • Context Overflow Detection for OpenAI-Compatible Bedrock Endpoints - PR#1529
    OpenAI-compatible endpoints that wrap Bedrock models (e.g., Databricks Model Serving) return Bedrock-style error messages like "Input is too long for requested model" as APIError instead of BadRequestError with code context_length_exceeded. These errors are now detected and converted to ContextWindowOverflowException, allowing conversation managers like SummarizingConversationManager to trigger properly.

  • retry_strategy=None Now Disables Retries - PR#1630
    Passing retry_strategy=None to the Agent constructor previously applied the default retry strategy instead of disabling retries. Now None explicitly disables all SDK retries (equivalent to ModelRetryStrategy(max_attempts=1)), while omitting the parameter entirely still applies the default strategy. Note: This is a minor breaking change in behavior for code that explicitly passed None.

  • A2A Server Agent Card URL Updated on Host/Port Override - PR#1626
    When overriding host and port in A2AServer.serve(), the agent card at /.well-known/agent-card.json still returned the original URL from constructor defaults, causing A2A clients to connect to the wrong address. The server now updates the agent card URL to match the overridden host/port, unless an explicit http_url was provided in the constructor.


Minor Changes

  • Increase pytest timeout to 45 seconds - PR#1586
  • Publish integ test results to CloudWatch - PR#1587
  • Clone main metrics upload script for integ tests - PR#1600
  • Skip S3 location for non-Bedrock model providers - PR#1602
  • Add conditional execution for finalize step - PR#1605
  • Fix various test warnings - PR#1613
  • Fix Bedrock file warnings - PR#1603
  • Increase test timeout - PR#1623
  • Fix OpenAI test - PR#1624
  • Remove broken MCP transport timeout test - PR#1635
  • Bump actions/setup-python from 4 to 6 - PR#1548
  • Bump aws-actions/configure-aws-credentials from 4 to 5 - PR#1547
  • Bump actions/download-artifact from 4 to 7 - PR#1609
  • Bump actions/upload-artifact from 4 to 6 - PR#1608

New Contributors

Read more

v1.24.0

29 Jan 01:23
4e4534e

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.23.0...v1.24.0