Skip to content

fix(desktop): one-shot Responses 请求体不再发送空 tools 下的 tool_choice - #2689

Closed
TravisCao wants to merge 2 commits into
makecindy:mainfrom
TravisCao:fix/oneshot-responses-tool-choice
Closed

fix(desktop): one-shot Responses 请求体不再发送空 tools 下的 tool_choice#2689
TravisCao wants to merge 2 commits into
makecindy:mainfrom
TravisCao:fix/oneshot-responses-tool-choice

Conversation

@TravisCao

@TravisCao TravisCao commented Aug 13, 2026

Copy link
Copy Markdown

这次改了什么

摘要

fix #2684。one-shot Responses 请求体(requestProviderHttpText,wire responses)删除硬编码的 tool_choice: 'auto'。one-shot 请求从不声明 tools,而 api.x.ai 对「空 tools + tool_choice」返回 HTTP 400 invalid-argument("A tool_choice was set on the request but no tools were specified"),导致 xAI 会话的 Auto-review 评审 100% 失败、3 次重试耗尽后弹 AUTO_REVIEW_UNAVAILABLE,所有需评审动作退回手动确认。

  • anthropic-responses-bridge/translate-request.ts 的既有约定对齐:bridge 只在有 function tools 时才下发 tool_choice / parallel_tool_calls(主对话因此不受影响);one-shot 自拼 body 漏掉了这条约定。
  • 保留 tools: []parallel_tool_calls: false:两上游实测均接受,最小化对现网 openai 分支请求形状的扰动。
  • 新增回归测试:xAI 分支 body 断言不含 tool_choice

变更类型

  • fix 缺陷修复
  • feat 新功能
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

UI 变化

不涉及。

  • 引用的设计规范:不涉及

怎么验证的

自动验证

pnpm --filter desktop exec vitest run src/main/utility-model/__tests__/oneShotCandidates.test.ts
结果:47 passed (47),含新增回归断言

NODE_OPTIONS=--max-old-space-size=6144 pnpm --filter desktop run --if-present typecheck
结果:通过(0 错误)

手工验证

用本人订阅凭证对两个真实上游做了字段级隔离重放(2026-08-13,macOS arm64):

api.x.ai/v1/responses(grok-4.6,SuperGrok OAuth):

请求体 结果
现网 one-shot 完整 body HTTP 400("A tool_choice was set on the request but no tools were specified")
tools:[] 单独 HTTP 200
tools:[] + parallel_tool_calls:false HTTP 200
tools:[] + tool_choice:"auto" HTTP 400(同上)
移除 tool_choice 后的完整 body HTTP 200

chatgpt.com/backend-api/codex/responses(gpt-5.6-sol,ChatGPT OAuth):移除 tool_choice 后的 body HTTP 200,openai 分支不受影响。

未执行的验证

  • 未跑 desktop 全量单测:改动面为单文件单字段,目标测试文件与 typecheck 已覆盖;如需要我可以补跑。
  • 未做打包后的应用内端到端 Auto-review 触发:上游行为已由手工重放按字段钉死,请求体形状由测试断言到字段级。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:

影响与回滚

  • 影响范围:所有走 wire responses 的 one-shot 请求体少发一个 tool_choice 字段——内置 openai(实测不受影响)、内置 xai(修复对象)、声明 responses 协议的自定义供应商(标准 Responses 语义下该字段在空 tools 时本就非法,移除只会降低被拒风险);主对话 bridge 路径字节不变。
  • 回滚 / 降级方式:revert 本 commit,回到 xAI 评审恒 400 的原状;无状态、无数据迁移。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO)
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

api.x.ai 对「tools 为空 + tool_choice」直接 400(invalid-argument:
"A tool_choice was set on the request but no tools were specified"),
导致 xAI 会话的 Auto-review 评审 100% 失败,3 次重试后弹
AUTO_REVIEW_UNAVAILABLE,全部动作退回手动确认。

one-shot 请求从不声明 tools,删除硬编码的 tool_choice:'auto' 即可;
与 anthropic-responses-bridge translate-request 的既有约定对齐
(bridge 只在有 function tools 时才下发 tool_choice)。

两个上游端点均已实测(2026-08-13):
- api.x.ai/v1/responses(grok-4.6):原 body 400,去掉 tool_choice 后 200
- chatgpt.com/backend-api/codex/responses(gpt-5.6-sol):去掉后仍 200

fix makecindy#2684

Signed-off-by: Travis Cao <edwardjordan172@gmail.com>
@TravisCao
TravisCao requested a review from a team as a code owner August 13, 2026 16:06
@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown

Greptile Summary

修复 desktop one-shot Responses 请求在没有工具时仍发送 tool_choice: "auto"、导致 xAI 拒绝请求的问题。

  • 从非 minimal Responses 请求体中移除 tool_choice
  • 保留现有 tools: []parallel_tool_calls: false、流式响应和存储配置
  • 新增 xAI 回归断言,确保请求体不再包含 tool_choice

Confidence Score: 5/5

该 PR 看起来可以安全合并,未发现由本次字段移除引入的可达故障。

无工具时省略 tool_choice 与仓库现有 Responses bridge 的行为一致;xAI 和 Codex 路径均支持新的请求体形状,新增测试也覆盖了此次修复的关键回归条件。

Important Files Changed

Filename Overview
apps/desktop/src/main/utility-model/oneShotCandidates.ts 无工具的 one-shot Responses 请求不再发送不兼容的 tool_choice,并与现有 bridge 约定保持一致。
apps/desktop/src/main/utility-model/tests/oneShotCandidates.test.ts xAI 回归测试现在明确验证序列化请求体不含 tool_choice

Reviews (1): Last reviewed commit: "fix(desktop): one-shot Responses 请求体不再发送..." | Re-trigger Greptile

@TravisCao

Copy link
Copy Markdown
Author

首次向本仓库提交,verify / Windows unit tests 等 workflow 还在等 maintainer 批准才会跑(Checks 里那条 “3 workflows awaiting approval”)。

Greptile 已给 5/5,无 inline 意见。请有权限的同事批准这批 workflow;CI 过后再走 CODEOWNERS review。

@MagicLizi MagicLizi added status:ci-running CI 还在跑(review-pr 自动维护,仅展示) status:ci-failed CI 失败(review-pr 自动维护,仅展示) and removed status:ci-running CI 还在跑(review-pr 自动维护,仅展示) labels Aug 14, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

@TravisCao 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

@MagicLizi MagicLizi added status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) and removed status:ci-failed CI 失败(review-pr 自动维护,仅展示) labels Aug 16, 2026
…es-tool-choice

Signed-off-by: Travis Cao <edwardjordan172@gmail.com>
@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown

No reviewable files after applying ignore patterns.

@TravisCao

Copy link
Copy Markdown
Author

@TravisCao 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

@MagicLizi 已经 merge 了~

@MagicLizi MagicLizi removed the status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) label Aug 17, 2026

@MagicLizi MagicLizi 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.

当前 head 的净 diff 为空(0 files / +0 / −0):merge 冲突解决时该文件冲突区全部采纳了 main 侧版本,本 PR 自身的改动已被完全覆盖;而声称的修复已由 #2799(commit 1f11bed)以更强的方式(整体移除 tools: [] / tool_choice / parallel_tool_calls 块)合入 main,关联 issue #2684 也已关闭。

  • P1 apps/desktop/src/main/utility-model/oneShotCandidates.ts — PR 描述与验证章节声称的改动对当前 head 均不存在,合并只会留下一个「已修复 #2684」的无操作合并与误导性记录(development-workflow.md「PR 描述必须与 diff 一致、验证必须如实」)。
    建议:直接关闭本 PR(标注 superseded by #2799);或 rebase 后确认是否仍有独立于 #2799 的净变更再重新请求审查。

@TravisCao

Copy link
Copy Markdown
Author

Closing: net diff is empty after conflict resolution; the fix already landed in #2799.

@TravisCao TravisCao closed this Aug 17, 2026
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: xAI 会话 Auto-review 100% 失败——one-shot Responses 请求体在空 tools 下发送 tool_choice,api.x.ai 返回 400

2 participants