Skip to content

fix(aikit): keep images from error tool results - #103

Merged
sanchitrk merged 5 commits into
canaryfrom
claude/awesome-dhawan-7e1cf9
Oct 26, 2026
Merged

sanchitrk merged 5 commits into
canaryfrom
claude/awesome-dhawan-7e1cf9

Conversation

@sanchitrk

@sanchitrk sanchitrk commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #102.

Error tool results dropped their image blocks for every provider. toolResultOutput returned error-text for any isError result, so the image never reached the model.

How each wire gets the images

Wire Sent as
Anthropic (anthropic, googleVertexAnthropic, Copilot messages), error results Text-only error-text with (image attached after the tool results), then a user message with Images from the error result of tool call <id> (<name>): and the images. @ai-sdk/anthropic merges both into one user message, tool_result blocks first.
Chat Completions (openai-compatible, Copilot chat, OpenAI with method: chat), every result with images Text tool result ((see attached image) when it has no text), then one user message: Attached image(s) from tool result: and the turn's images. These adapters would otherwise serialize the images as JSON text.
Google / Vertex before Gemini 3 (the adapter's own split), every result with images Text function response, then a user message with Tool result image: and the images for each result. The legacy shape would otherwise drop the function response of an image-only result.
OpenAI / Codex / xAI Responses, OpenRouter, Gemini 3 content: text, then the images in place. The AI SDK content output has no error flag, so an error result with images loses it here (Google's error key).

The wire follows the method the request resolves to, so Copilot and OpenAI method overrides are honoured. Text-only models still get (tool image omitted: model does not support images) and nothing moves.

Tests

  • test/transform.test.ts: Anthropic wire tests against the fake Anthropic server. Images move after the tool results, and error results without images are unchanged. Also checks that images stay in place for OpenAI and that text-only models get no split.
  • test/transform.test.ts: Chat Completions, Gemini 2.x/Vertex and Copilot method overrides, multiple tool rounds followed by a user message, and two failed calls in one turn on Anthropic.
  • test/e2e/image.tool.error.e2e.test.ts: a live tool call, then a failed result carrying red-circle.png; the model must describe the image. It records the request body each provider SDK sends and snapshots the part after the tool call to __artifacts__/error-tool-image.<wire>.json. Passes on Anthropic, OpenAI (Responses and Chat Completions), Codex, OpenRouter, Gemini 2.5 and Gemini 3.5.
  • test/e2e/image.tool.result.e2e.test.ts: adds OpenAI Chat Completions, Gemini 2.5 and Gemini 3.5 cases for successful image results.

vp run typecheck and the aikit unit tests pass. vp check still reports formatting issues only in the committed skill files under .agents/ and .claude/.

🤖 Generated with Claude Code

sanchitrk and others added 4 commits October 26, 2026 16:44
Tool calls now carry the input modalities of the model they answer
(`ToolCallContext.modelInput`). On a model without image input, `read`
adds a note that the image will be omitted, next to the placeholder the
transform puts in its place. A session test reads an image on a
text-only model, switches to a vision model and snapshots both requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Error tool results dropped their images for every provider. Anthropic-wire
models now get a text-only error result with a placeholder, followed by a
caption and the images after the turn's tool results. Other providers keep
the images in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The live test now records the request body each provider SDK sends and
snapshots the part after the tool call, so it catches a wire that drops
or misplaces the image. A unit case covers two failed calls in one turn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cannot carry them

Chat Completions adapters serialize a tool result's images as JSON text,
and the Google adapter's legacy shape (before Gemini 3) drops the
function response of an image-only result. On those wires a tool result
with images now goes out as text, with "(see attached image)" when it
has none, and its images follow the turn's tool results in a user
message, as Anthropic error results already did. The wire follows the
method the request resolves to, so Copilot and OpenAI method overrides
are honoured.

The live image tests now cover OpenAI over Chat Completions and Gemini
2.5, and the text-and-image prompt asks for what the model learned and
the shape's color.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from claude/linear-cod-184-ca812a to canary October 26, 2026 13:04
# Conflicts:
#	packages/harness/test/__artifacts__/tools.read.vision.json
#	packages/harness/test/tools.read.vision.test.ts
@sanchitrk
sanchitrk merged commit cfe348a into canary Oct 26, 2026
2 checks passed
@sanchitrk
sanchitrk deleted the claude/awesome-dhawan-7e1cf9 branch October 26, 2026 13:06
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.

1 participant