mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
fix(opencodezen): UA 升到 1.19.4 并补回 x-opencode-session-id
- 上游按客户端指纹判定免费层资格:CLI 1.18.29(4 个 x-opencode-* 头) 稳定 429;CLI 1.19.4(5 个头,含 session-id)200 且任务真实完成。 - 适配器的 UA 与头集合必须**同步**升级:只改 UA 声称的版本、不发对应头, 指纹反而更不一致,实测重新落回 429。 - 头形状按官方 CLI 抓包校正;`x-opencode-session-id` 与 `x-opencode-session` 同值,此前被误删。 - live 测试新增 `gatewayBinary()`:优先 `MODELROUTER_BIN`,其次 `/usr/local/bin/modelrouter`,回退改名前的 `/usr/local/bin/llmsproxy`。 注:本提交是改名/插件整改之外的独立修复,先于 v3.0.0 收口。
This commit is contained in:
@ -59,7 +59,7 @@ adapter.hidden = true
|
||||
-- ⚠️ 参考实现 dsh-our-free-model 的门禁桩(bash + read,但无真实 properties)
|
||||
-- 恰好卡在第 3 条上 —— 即它「伪装需跟进上游更新」的真实原因。
|
||||
adapter.headers = {
|
||||
["User-Agent"] = "opencode/1.19.0 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14",
|
||||
["User-Agent"] = "opencode/1.19.4 ai-sdk/provider-utils/4.0.23 runtime/bun/1.4.4",
|
||||
}
|
||||
|
||||
-- rand_id:按官方的 48-bit 公式生成 12 位 hex 段 + 14 位 base62 随机段。
|
||||
@ -176,17 +176,39 @@ end
|
||||
function adapter.build_headers(meta)
|
||||
local ms = now_ms(meta)
|
||||
local bucket = session_bucket_ms(meta)
|
||||
-- 免费层要求两个头都在且值相同(对齐官方 CLI;缺任一个则 403)。
|
||||
-- 会话亲和键(可能为空)混入 tail:同一分钟桶内不同会话得到不同会号,
|
||||
-- 同一会话跨分钟仍共享指纹 ⇒ 前缀缓存按会话命中而非按分钟命中。
|
||||
-- ★ 本函数的头集合以**官方 CLI 抓包**为准(opencode 1.19.4,2026-10-24
|
||||
-- 通过本地抓包代理取得明文请求)。官方实际发这五个 x-opencode-* 头:
|
||||
--
|
||||
-- x-opencode-client: cli
|
||||
-- x-opencode-project: global
|
||||
-- x-opencode-request: msg_<12hex><14base62>
|
||||
-- x-opencode-session: ses_<12hex><14base62>
|
||||
-- x-opencode-session-id: ses_<12hex><14base62> ← 与 session 同值
|
||||
--
|
||||
-- ⚠⚠ 这里有一个**版本相关的陷阱**,用实测记录,因为它反反复复:
|
||||
-- 同一台机器、同一个 `Bearer public` 凭据、同一个模型:
|
||||
--
|
||||
-- CLI 1.18.29(只发 4 个头,无 session-id) → "Free usage limit reached"
|
||||
-- CLI 1.19.4 (发 5 个头,含 session-id) → 200,任务真实完成
|
||||
--
|
||||
-- 我一度根据 1.18.29 的抓包删掉了 `x-opencode-session-id`,并把注释
|
||||
-- 改写成「官方根本不发这个头」。**那是错的** —— 旧版客户端当时的报错
|
||||
-- 本来就是额度不足,不是头缺失;而新版上游确实要这个头。删掉它会让
|
||||
-- 1.19.x 的指纹不匹配,重新落回 429。
|
||||
--
|
||||
-- 结论:头集合必须与 **UA 里声称的版本**一致。声称 1.19.4 就必须发 5 个头。
|
||||
-- 将来升级 UA 时,必须**重新抓包**该版本的发头集合,不能沿用旧结论。
|
||||
--
|
||||
-- 会话亲和键(可空)混入 tail:同一分钟桶内不同会话得到不同会号,
|
||||
-- 同一会话跨分钟仍共享指纹 ⇒ 前缀缓存按会话命中而非按分钟命中。
|
||||
local sid = rand_id("ses_", bucket, "session", session_affinity_key(meta))
|
||||
return {
|
||||
["User-Agent"] = adapter.headers["User-Agent"],
|
||||
["x-opencode-client"] = "cli",
|
||||
-- project 固定:同网关实例共享一个工作区身份(非门禁必需,但官方也发)
|
||||
-- project 固定:同网关实例共享一个工作区身份(官方也发同样值)
|
||||
["x-opencode-project"] = "global",
|
||||
["x-opencode-session"] = sid,
|
||||
-- ★ 两个都要:上游对免费池同时校验 x-opencode-session 与这个头。
|
||||
-- ★ 1.19.4 实测**必须**并发这一份(与 session 同值)。见上面的版本陷阱。
|
||||
["x-opencode-session-id"] = sid,
|
||||
-- request id 每请求唯一(不参与缓存键),用当前时间而非桶,避免同桶内重复
|
||||
["x-opencode-request"] = rand_id("msg_", ms, "request"),
|
||||
|
||||
Reference in New Issue
Block a user