Skip to content

fix(integrations): carry ToolMessage.error onto the tool-result flag in four more adapters - #2317

Merged
BenTaylorDev merged 1 commit into
ag-ui-protocol:mainfrom
TheSeydiCharyyev:fix/2306-adapters-tool-error-status
Aug 10, 2026
Merged

fix(integrations): carry ToolMessage.error onto the tool-result flag in four more adapters#2317
BenTaylorDev merged 1 commit into
ag-ui-protocol:mainfrom
TheSeydiCharyyev:fix/2306-adapters-tool-error-status

Conversation

@TheSeydiCharyyev

Copy link
Copy Markdown
Contributor

Fixes #2306.

Problem

The one-line omission fixed for LangGraph in #2263 is present in several other first-party adapters: AG-UI's ToolMessage.error is not read when an incoming tool result is converted into the target framework's tool-result shape, so a client-reported tool failure is handed to the model as a success.

Fix

Per the standard agreed on #2306: set the framework's error flag from bool(error). Flag only — the text is not folded into content, because every target here has a dedicated flag (that carve-out only applies to transports with no flag, e.g. claude-managed-agents).

Adapter Site Change
langchain/typescript messages.ts status: message.error ? "error" : "success" (verbatim #2263)
aws-strands/python agent.py _build_strands_history Bedrock toolResult status was pinned to "success" → derive from error
vercel-ai-sdk/typescript index.ts isError: !!message.error
mastra/typescript utils.ts isError: !!message.error

AI SDK version

Both vercel-ai-sdk and mastra resolve AI SDK v4, whose ToolResultPart already carries isError — no version gate needed. mastra builds the v4 CoreMessage type (the as CoreMessage cast at utils.ts:212 is what currently hides the missing field from tsc), so its behavior is pinned with a test rather than relying on a type read.

Bonus: aws-strands snapshot echo

_build_snapshot_messages is an AG-UI → AG-UI rebuild of the client's own messages (it seeds MessagesSnapshotEvent). It dropped the client's own error and encrypted_value on the echo. Both are now copied through. This one has no framework mapping and no invent-the-text question — it is a plain field copy.

Scope

Flag only, one PR for all four adapters plus the snapshot fix, matching the group decision on #2306. The docs/concepts/tools.mdx example is being handled separately.

Tests

A test is added next to each adapter's conversion tests, matching #2263's shape.

  • mastra: full package suite green, 304 tests (2 existing tool-result assertions updated for the always-present isError).
  • langchain/typescript: new messages.test.ts, 13 tests green.
  • vercel-ai-sdk/typescript: new messages.test.ts, 8 tests green.
  • aws-strands/python: new test_tool_error_status.py, pytest tests/ green — 180 passed, 2 skipped.

…in four more adapters

The same one-line omission fixed for LangGraph in ag-ui-protocol#2263 is present in several other first-party adapters: AG-UI's ToolMessage.error is not read when an incoming tool result is converted into the target framework's tool-result shape, so a client-reported tool failure is handed to the model as a success.

Per the standard agreed on ag-ui-protocol#2306, set the framework's error flag from bool(error) (flag only; text is not folded because every target here has a dedicated flag): langchain/typescript ToolMessage status (verbatim ag-ui-protocol#2263); aws-strands/python Bedrock toolResult status (was pinned to success); vercel-ai-sdk/typescript AI SDK v4 tool-result isError; mastra/typescript AI SDK v4 tool-result isError.

Both vercel-ai-sdk and mastra resolve AI SDK v4, whose ToolResultPart already carries isError; no version gate is needed.

Also fix aws-strands _build_snapshot_messages, an AG-UI to AG-UI rebuild of the client's own messages: it dropped the client's error and encrypted_value on the snapshot echo. Copy both through.

A test is added next to each adapter's conversion tests.

Fixes ag-ui-protocol#2306
@TheSeydiCharyyev
TheSeydiCharyyev requested a review from a team as a code owner August 5, 2026 06:25
@github-actions

Copy link
Copy Markdown
Contributor

Python Preview Packages

Version 0.0.0.dev1785911101 published to TestPyPI.

Warning: These packages are built from contributor code that may not yet have been vetted for correctness or security. Install at your own risk and do not use in production.

Install with uv

Add the TestPyPI index to your pyproject.toml:

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
explicit = true

Then install the packages you need:

# Core SDK
uv add 'ag-ui-protocol==0.0.0.dev1785911101' --index testpypi

# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==0.0.0.dev1785911101' --index testpypi
uv add 'ag-ui-crewai==0.0.0.dev1785911101' --index testpypi
# NOTE: ag-ui-agent-spec depends on pyagentspec (git-only, not on PyPI).
# You will need to install pyagentspec separately from its git repo.
uv add 'ag-ui-agent-spec==0.0.0.dev1785911101' --index testpypi
uv add 'ag_ui_adk==0.0.0.dev1785911101' --index testpypi
uv add 'ag_ui_strands==0.0.0.dev1785911101' --index testpypi

Install with pip

pip install \
  --index-url https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  ag-ui-protocol==0.0.0.dev1785911101

Use --extra-index-url https://pypi.org/simple/ so pip can resolve
transitive dependencies (pydantic, fastapi, etc.) from real PyPI.


Commit: a31af59

@pkg-pr-new

pkg-pr-new Bot commented Aug 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@ag-ui/a2a-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a-middleware@2317

@ag-ui/a2ui-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-middleware@2317

@ag-ui/event-throttle-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/event-throttle-middleware@2317

@ag-ui/mcp-apps-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-apps-middleware@2317

@ag-ui/mcp-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-middleware@2317

@ag-ui/a2a

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a@2317

@ag-ui/adk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/adk@2317

@ag-ui/ag2

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/ag2@2317

@ag-ui/agno

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/agno@2317

@ag-ui/aws-strands

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/aws-strands@2317

@ag-ui/claude-agent-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/claude-agent-sdk@2317

@ag-ui/claude-managed-agents

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/claude-managed-agents@2317

@ag-ui/crewai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/crewai@2317

@ag-ui/langchain

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langchain@2317

@ag-ui/langgraph

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langgraph@2317

@ag-ui/llamaindex

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/llamaindex@2317

@ag-ui/mastra

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mastra@2317

@ag-ui/pydantic-ai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/pydantic-ai@2317

@ag-ui/vercel-ai-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/vercel-ai-sdk@2317

@ag-ui/watsonx

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/watsonx@2317

@ag-ui/a2ui-toolkit

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-toolkit@2317

create-ag-ui-app

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/create-ag-ui-app@2317

@ag-ui/client

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/client@2317

@ag-ui/core

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/core@2317

@ag-ui/encoder

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/encoder@2317

@ag-ui/proto

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/proto@2317

commit: 8cf5b87

@BenTaylorDev BenTaylorDev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. CI is green across all 42 checks on 8cf5b879, and this holds up on review.

What I verified beyond reading the diff:

  • Consistent with the merged #2316 and #2263. Every site derives the flag from bool(error) / !!message.error, with no sentinel — correct, since the sentinel belongs only to the reverse direction. The five adapters now hold one rule.
  • The AI SDK version claims check out. integrations/vercel-ai-sdk/typescript resolves ai@4.3.19, whose ToolResultPart carries isError?: boolean. For mastra I went a level deeper, since that was the flagged uncertainty on #2306: @mastra/core@1.0.4 exports CoreMessage = AiCoreMessage from its bundled _types/@internal_ai-sdk-v4, and that bundled ToolResultPart does declare isError?: boolean.
  • It survives main's churn. aws-strands/.../agent.py took 7 commits since this branch's base, including #2343's parallel tool-call rework in the same area. Merged against current main in a scratch worktree: no conflict, the post-merge delta is exactly this PR's 8 files, and the aws-strands suite passes at 199 — 195 baseline plus the 4 new tests, collection checked explicitly.
  • No interaction with the reconcile work. session_reconcile.py never writes status, so nothing downstream clobbers the flag this PR stamps.
  • Completeness on the sites in scope. messages.ts:49 is the only AG-UI → LangChain tool conversion; the other toolCallId hits across the three TS adapters are outbound streaming rather than conversion. In aws-strands, client_proxy_tool.py:58 and a2ui_tool.py:640 do hardcode "success", but those are placeholder and envelope results that genuinely are always successful.

One follow-up, filed as #2361 rather than held against this PR: the aws-strands fix reaches the replay_history branch only. _build_strands_history has a single caller gated on session_manager is None (agent.py:1040), so when a session_manager_provider is configured the model reads persisted toolResult blocks created by the proxy with status: "success", and _correct_message rewrites only content. A failed frontend tool is still reported as a success on that path. That's outside what #2306 scoped, and the default configuration (replay_history_into_strands=True, no session manager) takes the branch you fixed — so this is a widening job, not a defect here.

Nice work getting all four adapters onto one rule in a single pass, and for checking the AI SDK version question rather than assuming copy-paste.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Other first-party adapters drop ToolMessage.error too (langchain TS, aws-strands, vercel-ai-sdk, mastra)

2 participants