
这一小时四仓都没有新版本:上一期那条会让整站冻住的死锁有了第一张还没合并的补丁,OpenAI→Claude 翻译每块重读整份请求被 pprof 量到 56% CPU,sub2api 上有人交了两类计费漏洞的库表证据。
#6744)等来了第一张修复补丁;一起新报障把「OpenAI→Claude 翻译每块重读整份请求」的 CPU 开销量到了 pprof 上;sub2api 上有人交了一份带库表数字的两类计费漏洞报告。usage_logs 里 actual_cost = 0 且 tokens 大于 0 的行,按模型分组数一遍。gjson.parseSquash 的占比。请求体几百 KB 时,首 token 会被这一行拖慢。#6748 是上一期那条死锁的第一张修复补丁,创建于 23:04:17,落在本文窗口的末尾10。它对着 dev 开,4 个文件、+166/−18、1 提交,mergeable 是 clean,两条评论都来自仓库机器人。Manager.mu 在外面、插件在里层被调用;保存插件配置时 Host.mu 在外面、RegisterExecutor 在里层被调用。两个方向撞上,就是 ABBA。PluginSchedulerWantsAcrossPriorities:先在 m.mu.RLock() 下把 m.pluginScheduler 取出来,放了锁再调插件的 SchedulerWantsAcrossPriorities。原来那个带 Locked 后缀、握着锁调插件的函数被整个删掉;availableAuthsForSelector 多了一个 schedulerAcross bool 参数,由 pickNextLegacy 与 pickNextMixedLegacy 在取锁之前算好11。
CLIProxyAPI v8.0.33 的 internal/pluginhost/adapters_executors.go 第 176–198 行:第 186 行注册执行器、第 193 行注销执行器,第 195 行才 h.mu.Unlock()。补丁把这一行提到两个循环之前。12registrations、staleProviders、nextModelClients 三个局部变量;ownsExecutor 只做类型断言与指针比较,不碰共享 map;模型注册本来就在锁外。这一处改得干净。go test -race ./... 2290 项全过,gofmt 与 go build 都跑过,改动借了 AI 助手、由他本人复核。这几条是作者自述,本刊没有独立复跑10。PluginSchedulerWantsAcrossPriorities 才会走进插件的代码。没有这类插件的部署,两处改动都碰不到它。#6744 也还开着13。今晚能做的只有规避:高峰时段别触发插件能力重载,或者临时停用带调度器的插件。想彻底解决,就得自己把这一笔打到源码上编译,或者等它并进 dev、再等下一个版本。#6746 报的是:Claude 格式的客户端走 OpenAI 兼容上游时,ConvertOpenAIResponseToClaude 对每一个流式分块都执行一次 gjson.GetBytes(originalRequestRawJSON, "stream")14。ToolNameMap 是每流只算一次的15。
CLIProxyAPI v8.0.33 的 internal/translator/openai/claude/openai_claude_response.go 第 136–152 行:第 143 行每次调用都从原始请求里取 stream,第 144 到 147 行据此分派。补丁要做的事,就是把这次取值挪成每流一次。15stream 这个键通常放在 JSON 末尾。gjson 要读到它,就得扫过整份 body,分块越多扫得越多。gjson.parseSquash 的 flat 占比分别是 56.5% 与 77.5%,进程 CPU 约 190%,当时只有几个会话在流式输出14。stream 放在最后一个键,每块从 104–110 微秒降到 5–6 微秒。#6747:给 per-stream 参数加两个字段,streamResolved 与 streamRequested,第一块解析一次、之后复用;语义保持不变,缺 stream 或 stream: false 走非流式16。internal/translator/,仓库的 translator-path-guard 会把它拦下,按 AGENTS.md 要先开 issue,所以这张 PR 交给维护者裁量16。它短期内不会随版本发出来。gjson.parseSquash 的占比;给请求瘦身(少挂 tools、截短历史)能直接压低每块的代价;或者把 Claude 格式的客户端直接指向原生 Anthropic 上游,绕开这层翻译。#8202 也是这个窗口里开出的,22:59 创建,作者贴了库表数字与容器日志,声明 B 型已在本地复现,并按负责任披露的方式只给路径、不给脚本17。request admitted without reservation (fail-open, throttled log),然后放行18。定价查不到时,底层返回的是 pricing not found19。isUsagePricingUnavailableError 命中就打 warn 一句 openai_usage.pricing_missing_record_zero_cost,然后把 cost 换成一个零成本的结构体20。
sub2api v0.2.17 的 backend/internal/service/openai_gateway_usage.go 第 250–272 行:第 257 行只对「定价不可用」放行,别的错误照旧返回;第 268 行打 warn,第 269 行把成本换成零成本结构体。20qwen3-235b-a22b-instruct 3769 条、deepseek-ai/DeepSeek-V3.2 388 条零成本记录,这两组数字来自他的实例,本刊没有独立复现17。usage_logs 里 actual_cost = 0 且 tokens 大于 0 的行。第二,日志里搜 pricing_missing_record_zero_cost 与 inflight reservation cannot price model 两个 key。第三,把用到的模型价补齐:pricing.override_file 是覆盖文件、优先级最高,pricing.fallback_file 只补目录里缺的模型,两个都按内容哈希在下一次检查时自动重载21。ErrAPIKeyNotFound 在那两处被显式放过,注释写的是「Key 已不存在时跳过其自身的额度/限速计数,其余结算项不受影响」22。
sub2api v0.2.17 的 backend/internal/repository/usage_billing_repo.go 第 186–206 行:第 186 行先落下新的余额,第 190 行的注释说明 key 不存在时只跳过 key 自身的计数,第 193 与 200 行把 ErrAPIKeyNotFound 排除在失败之外。22balance >= $1 更新,没命中时去掉这个条件再更新一次,返回 sufficient = false,调用方把它记成 BalanceOverdrafted23。这解释了报告人看到的余额变成负数。usageLog.ActualCost 置 0,再 best-effort 落一条用量日志,然后把错误交回调用方;调用方只把它打成 openai.record_usage_failed2425。这条路径在库里留下的是一行 0 成本的记录。latest 镜像,本刊核的是 v0.2.17 标签,两者可能不是同一份代码。要做自查,就把他那 763 条 API_KEY_NOT_FOUND 的时间窗取出来,对一遍同一时段 usage_logs 里的实际 cost:有行但钱是 0,和整行都没有,是两种不同的漏法,处置也不一样。#8200 在 22:21 开出,15 个文件、+523/−5、1 提交、mergeable unstable,对着 main26。/v1/messages 上只带一个 web_search_20250305 工具的纯搜索轮次,改由一个能原生跑搜索的账号执行。账号打上 extra.web_search_capable 标记即可入选;全局配了 managed_account_id 时,那个账号优先。请求按原生 Anthropic 协议透传,web_search_tool_result 结构原样保留;用量按 server_tool_use(name=web_search) 计次,走既有的每次价格字段。c558d3203e 让 Gemini 清洗器先展开本地 $ref 再删定义容器,并且保住 default、example、examples、const、enum 里的字面量,关掉 #6732;那三处清洗问题本刊在 10 月 18 日午间那期登过27。#6744 会不会被这张补丁关掉、维护者会不会要作者改方向;#6746 里报障人提到的「其他 translator 也在每块读请求」有没有第二处同样的放大;#8202 的 B 型能不能被维护方复现出来;#8200 合入后搜索计次与主池额度怎么分摊;#6732、#6733 两笔随哪一版发出。github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
patch-diff.githubusercontent.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
status.openai.com
status.openai.com
status.anthropic.com
status.cloud.google.com
codex-reset.com
community.openai.com
reddit.com
reddit.com
reddit.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.