Repository navigation
fix(responses): /v1/responses never sent captcha tokens — every start-plan request failed with 3007 - #38
Merged
TriDefender merged 2 commits intoAug 31, 2026
Conversation
`/v1/responses` never touched the captcha layer. It passed `undefined`
where handler.ts passes captcha headers:
buildUpstreamHeaderPairs(..., opts.config.plan, undefined, undefined)
buildUpstreamRequest(..., opts.config.plan, undefined, undefined)
On start-plan the upstream gates every call behind an Aliyun captcha
token, so every /v1/responses request came back as
HTTP 400 {"error":{"type":"upstream_error",
"message":"{\"code\":3007,\"msg\":\"captcha verify failed\"}"}}
while /v1/messages and /v1/chat/completions worked, since handler.ts mints
a token for them. The failure is plan-specific and route-specific, which
made it look like a captcha-solver problem rather than a missing call site.
- Mint a pooled token before the upstream POST when plan is start-plan,
mirroring handler.ts (same lazy captcha import so coding-plan processes
never load the solver).
- Retry once on an explicit challenge, detected both ways handler.ts does:
the captcha response header and the in-body `{"code":3007}` variant on
HTTP 400. The challenged token is already spent, so the retry carries a
freshly pooled one.
- Extract the send into `dispatch(pairs)` so the first attempt and the
retry share one routing/signing path.
- Add a `captcha` option alongside the existing fetchImpl/endpointRouting/
clientSigning test seams, so tests exercise the paths without network.
Tests: token attached on start-plan, retry on in-body 3007, retry on
header challenge, exactly one retry (no loop) with the upstream error
surfaced afterwards, and coding-plan untouched.
Owner
|
LGTM |
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.
问题
/v1/responses完全没有接入验证码层。它在handler.ts传验证码头的位置传了undefined:对比
handler.ts:159-172,那里会先getCaptchaToken()再注入x-aliyun-captcha-verify-param/-region。start-plan 下上游对每一个调用都做验证码校验,所以
/v1/responses必然失败:而同一进程、同一凭证下
/v1/messages和/v1/chat/completions完全正常 —— 因为handler.ts给它们铸了令牌。这个组合(只在 start-plan、只在这一条路由)很容易被误判成求解器故障或指纹问题:本地求解成功、令牌校验通过、其他路由都好,唯独这条 400。实际上是少了调用点。
grep -c captcha src/proxy/responses-handler.ts修复前为0。改动
严格对齐
handler.ts的既有模式,不引入新抽象:plan === "start-plan"时取一枚池中令牌注入请求头,沿用同样的惰性import("./captcha.js"),coding-plan 进程仍然不会加载 happy-dom 求解器。handler.ts一致 —— 验证码响应头,以及 HTTP 400 + body 内{"code":3007}这个变体。被挑战的令牌已被消耗,所以重试必须带新令牌。dispatch(pairs):首发与重试共用同一条 endpoint-routing + client-signing 链路,避免把那段逻辑抄第二遍。captcha?注入口:与文件里已有的fetchImpl/endpointRouting/clientSigning测试注入口并列,让测试无需联网即可覆盖这些路径。验证
bun test:708 pass / 0 fail;bun x tsc --noEmit干净。{"code":3007}触发重试,且重试携带的是新令牌(token-1→token-2)upstream_error(防止无限循环)undefined,其中 3 个测试立即失败。