Repository navigation
fix(antigravity):思考签名在 Anthropic 入口缺失导致工具续接 400 —— 新增服务端签名缓存 - #298
Open
loney123456 wants to merge 1 commit into
Open
loney123456 wants to merge 1 commit into
loney123456 wants to merge 1 commit into
Conversation
问题:Claude Code 走 /v1/messages(Anthropic Messages),其 tool_use 块没有 extra_content 字段,响应侧挂在 extra_content.google.thought_signature 上的 签名回不来。抓真实报文可确认:上游响应里带了 thoughtSignature,而出站请求的 functionCall part 一个都没有,上游每轮工具续接返回 400。 方案:新增 thought_signature_cache(call id → signature)。上游响应里带签名的 functionCall 按它的 id 存一份,下一轮出站时按同一个 id 取回,不依赖客户端行为。 优先级:客户端显式回带 > 服务端缓存。 选 call id 作键:上游响应的 functionCall 自带 id 且与签名同 part;同一条历史在 连续两轮请求里 id 完全一致、无空值。容量上限 4096 条 FIFO 淘汰;未命中时行为 与改动前一致(省略签名),所以是尽力而为的优化,不是正确性前提。 已知限制:缓存只在进程存活期内有效,网关重启后那一轮退化为改动前行为(见模块头)。 验证:新增 4 个单测;cargo test --release 589 passed / 0 failed。 端到端同一二进制下,缓存命中 200 / 未命中 400(对照组排除了上游碰巧放行的可能)。 Claude Code Desktop 经 cc-switch 接入后多轮工具调用全部正常。 参考 aimod-cc#237(同一句报错,那条是 OpenAI chat 路径的聚合器丢 extra_content)、aimod-cc#253。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
Claude Code 走 Anthropic Messages(
/v1/messages)接入 antigravity 时,每轮工具续接都被上游 400 拒:根因
thoughtSignature的往返依赖客户端回带:这条链只在 OpenAI chat 协议上成立。 Anthropic Messages 的
tool_use块没有extra_content字段,签名根本没有承载位置 —— 于是:extra_content上的签名,Claude Code 看不见;call_signature只能在那三条 pointer 上找,全都取不到;functionCallpart 缺thoughtSignature,上游 400。抓真实报文可以确认:上游响应里确实带了签名(
functionCallpart 上的thoughtSignature,且该 part 自带
id),但出站请求里的 functionCall part 一个都没有。方案
新增
thought_signature_cache:服务端自持的call id → thoughtSignature映射,让签名不再依赖客户端回带。
antigravity_stream::tool_call_frames):拿到带签名的functionCall时,按它的
id存一份;antigravity_outbound::call_signature):客户端三条路径都没带时,按
id取回。优先级 客户端显式回带 > 服务端缓存(前者是客户端自己的会话态,更准)。选 call id 作键是因为实测两点:上游响应的
functionCall自带id且与签名在同一个 part;同一条历史在连续两轮请求里的 id 完全一致、无空值。所以不需要按出现顺序做位置匹配。
容量上限 4096 条、FIFO 淘汰;缓存未命中时行为与改动前完全一致(省略签名),
所以它是尽力而为的优化,不是正确性前提。
已知限制
缓存只在进程存活期内有效 —— 网关重启后历史会话的签名丢失,那一轮退化成改动前的行为。
要跨重启就得落库,这里刻意不做:签名是短时效的会话态数据,为它加表和迁移不划算。
(该限制已写在模块头。)
验证
单元测试:新增 4 个(往返、空输入忽略、空白裁剪、同 id 覆盖不涨 order)。
全量测试:
cargo test --release→ 585 passed / 0 failed。端到端(同一二进制,唯一变量是缓存命中与否):
thoughtSignature对照组排除了「上游碰巧放行」的可能 —— 200 确实来自签名回填。
真实客户端:Claude Code Desktop(
ua=claude-cli/2.1.295)经 cc-switch 接入后,多轮工具调用(含连续两轮
Bash)全部正常,不再出现 400。范围
改动 4 个文件:新增
thought_signature_cache.rs(142 行),改
antigravity_stream.rs(+9)、antigravity_outbound.rs(+16)、mod.rs(+1)。对既有行为无影响:客户端回带签名时优先用客户端的值,缓存只在取不到时才生效。
参考:#237(同一句上游报错,但那条是 OpenAI chat 路径的聚合器丢
extra_content)、#253。🤖 本条回复由 AI Agent 生成
Generated by an AI agent.