Skip to content

OpenAI 兼容 provider 下 Computer Use 截图返回空——消息转换器丢弃 tool_result 图片块 #1277

Description

@yangxiangyou

摘要

使用 OpenAI 兼容的 provider 时,Computer Use 截图(mcp__computer-use__screenshotzoom)返回,而基于文本的工具(如 cursor_position)正常工作。截图本身已正确捕获(生成真实的 JPEG),但在到达上游模型前被悄悄剥掉了。

根因

sidecar 的 Anthropic → OpenAI 消息转换器丢弃了 tool_result 里的图片块。

转换器由 apiFormat 选择:

if (_.apiFormat === "openai_chat") return await II3($, A, _.apiKey, H, w, J);
else return await mI3($, A, _.apiKey, H, w, J, j);
  • openai_chatII3/v1/chat/completions),通过 $w3/Ow3 构建消息。tool_result 分支只保留文本:
else if (_.type === "tool_result") {
  let $ = typeof _.content === "string"
    ? _.content
    : Array.isArray(_.content)
      ? _.content.filter((H) => H.type === "text").map((H) => H.text).join(`\n`)
      : "";
  K.push({ role: "tool", tool_call_id: _.tool_use_id, content: $ });
}
  • openai_responsesmI3,其 tool_result 转换器 Qa4 也只保留 type === "text"
function Qa4(q) {
  if (typeof q === "string") return q;
  if (!Array.isArray(q)) return "";
  return q.map((K) => {
    if (K && typeof K === "object" && "type" in K) {
      if (K.type === "text" && typeof K.text === "string") return K.text;
    }
    return "";
  }).filter(Boolean).join(`\n`);
}

此外,对 baseUrlopencode.aideepseek 的 provider,UW5(baseUrl)===true 会强制 imageContentMode="text_only",连用户消息里的图片也会被替换成占位符(zw3)——所以丢的不只是 tool_result 图片:

function UW5(q) {
  return /(^|[./-])deepseek([./-]|$)/i.test(q) || /(^|[./-])opencode\.ai([:/]|$)/i.test(q);
}
function uI3(q) { return UW5(q); } // → imageContentMode = "text_only"

证据

  1. 截图工具确实返回真实图片。 Anthropic 格式的请求里包含:
{
  "type": "tool_result",
  "tool_use_id": "call_00_q7th5rjrFvmNGEVkwTt15015",
  "content": [
    { "type": "image", "source": { "type": "base64", "media_type": "image/jpeg", "data": "/9j/4AAQSkZJ..." } }
  ]
}
  1. 请求被路由到 OpenAI-chat 路径。{ format: "openai_chat", baseUrl: "https://opencode.ai/zen/go/" } 这样的 provider,出站 URL 是 https://opencode.ai/zen/go/v1/chat/completions

  2. 隔离复现 $w3 确认了该行为:

  • 输入 tool_result[text, image] → 输出 { role: "tool", tool_call_id: "...", content: "Screenshot taken" }(图片消失)。
  • 输入 user 消息为 [text, image] → 输出保留 { type: "image_url", image_url: { url: "data:image/jpeg;base64,..." } }

所以图片在 user 消息里被保留(vision 模式),但在两种转换器路径的 tool_result 里都被丢弃。

影响

  • 任何 OpenAI 兼容 provider(chat 或 responses 格式)都会静默丢弃作为 tool result 返回的图片。
  • Computer Use 的 screenshot / zoom 一直为空——模型只看到一个纯文本的 tool result。

建议的修复

  • $w3/Ow3(以及 Qa4)里,保留 tool_result 内的 image 内容块,例如在 tool 内容数组里输出为 OpenAI 的 { type: "image_url", image_url: { url: "data:..." } },而不是只过滤 text
  • 重新审视支持 vision 流式输出的 provider 上 UW5/uI3text_only 门控。

Activity

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

    bugSomething isn't working

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions