Skip to content

agent: verify chatd handling of content tool result outputs (toModelOutput) #404

Closed

Description

@ThomasK33

@coder/ai-sdk-agent forwards a content tool result output to chatd unchanged. Nobody has checked what chatd does with it.

Where

  • packages/agent/src/model/prompt.ts toolResultOutputToChatd: case "content" returns output.value (an array of text / file items, file data as { type: "data", data }).
  • The resume path then submits that array as the client tool result output.

Who hits it

  • AI SDK v7 users whose client tools set toModelOutput (AI SDK core emits content outputs).
  • @coder/ai-sdk-effect users of CoderAgentModel whose effect/ai tools set toModelOutput (effect >= 4.0.7). Since chore: bump effect to 4.0.7 #403, the effect bridge maps effect/ai modelOutput onto the same content output.

What to check

  1. Run one live turn with a client tool whose result is a content output with a text part and a small PNG file part.
  2. See whether chatd gives the model the image, or serializes the array as JSON text (base64 inside the text).
  3. If chatd cannot take images in tool results, map file items to text placeholders (as effect's Prompt.toolModelOutputToText does for OpenAI-compatible APIs) or upload them, and document the limit.

Found by the advisor pass on #403. CoderLanguageModel (Gateway) is not affected: the AI SDK providers handle content outputs natively.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

Activity

  1. ThomasK33 commented on Oct 29, 2026

    @ThomasK33
    MemberAuthor

    Result: chatd does not show the image to the model. It stores the content array as opaque JSON and gives it to the model as text, with the PNG as base64 characters.

    Source (coder/coder 8d643af, the commit dogfood runs):

    1. codersdk.ToolResult has only tool_call_id, output (json.RawMessage), and is_error (codersdk/chats.go:871-876). A client cannot mark a result as media.
    2. chatd stores the result with Result: r.Output and no IsMedia (coderd/x/chatd/chatstate/transitions.go:1247-1253).
    3. chatd sends string(part.Result) to the LLM as a text tool result (coderd/x/chatd/chatprompt/chatprompt.go:1379-1385, 1464-1472). Only internal IsMedia results (computer-use screenshots) become media (chatprompt.go:1414-1430).

    Live probe on dogfood (sonnet, client tool returns a text part and a 4x4 solid red PNG, both chats archived):

    • Before: the stored result was the raw array with the base64 PNG. The model answered RECEIVED: TEXT, COLOR: UNKNOWN.
    • With fix(agent): flatten content tool outputs to text for chatd #405: the stored result is "Swatch label: PROBE-404-LABEL\n[image/png swatch.png omitted]". The model answered RECEIVED: NOTE, COLOR: UNKNOWN.

    #405 flattens content outputs to text in @coder/ai-sdk-agent and documents the limit. Images in client tool results need a chatd change (an is_media-style field on ToolResult).


    Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions