Skip to content

Releases: wjf1/commandcode-proxy

v4.22.4: 直连 IPv4 优先与代理探针双模自愈

Choose a tag to compare

@github-actions github-actions released this 01 Oct 02:03

新增与修复

  • 直连 IPv4 优先与代理连通性自愈(Auto-fallback),彻底解决换设备或未开代理时的连接稳定:
    解决在未开启代理软件、或切换到无代理终端时,直连海外 Cloudflare 上游依然稳定高可用。
    • IPv4 优先解析策略:全局注入 dns.setDefaultResultOrder('ipv4first')(可通过 COMMANDCODE_DNS_ORDER 自定义),彻底避开国内运营商恶劣的 IPv6 握手黑洞与 10 秒超时(UND_ERR_CONNECT_TIMEOUT);
    • 代理探针与双模自愈:proxy-agent 启动时自动执行 TCP 快速探针;若本地代理未开启或切换至无代理环境,自动平滑回退为 IPv4 优先直连模式,绝不阻塞任何模型调用;
    • 测试覆盖:新增代理探测与 Auto-fallback 降级单元测试,全量 48 个套件、626 个测试用例 100% 通过。

v4.22.3: 出站 HTTP/HTTPS 代理集成与网络超时修复

Choose a tag to compare

@github-actions github-actions released this 30 Sep 18:05

新增与修复

  • 出站网络代理(HTTP/HTTPS Proxy)集成,解决海外上游连接超时与 fetch failed:
    直连海外上游 https://api.commandcode.ai 时,因国内网络对 Cloudflare CDN 节点的丢包、高延迟及 IPv6 首选握手失败,导致后台额度同步、健康探活及部分模型调用频繁抛出 fetch failed(UND_ERR_CONNECT_TIMEOUT)。
    • 网络层治理:新增 src/utils/proxy-agent.ts,基于 undici 的 ProxyAgent 与 setGlobalDispatcher,将全局出站 fetch 流量路由至本机科学上网客户端(默认 http://127.0.0.1:7897);
    • 配置与安全隔离:
      • 支持 config.json(upstream.proxy)与环境变量(HTTPS_PROXY / HTTP_PROXY / ALL_PROXY);
      • 强制加固 NO_PROXY,确保本地回环地址(localhost,127.0.0.1,::1)直连,保证本地测试与 Fastify 服务不受代理影响;
      • 代理配置仅作为传输层跳板,现有针对业务目标 URL 的 SSRF 与域名白名单安全校验保持严格生效;
    • 部署与启动链适配:在 start.cmd 与 .env 中固化出站代理支持;
    • 测试与验证:新增 tests/proxy-agent.test.ts 单元测试,全量 48 个套件、621 个测试用例 100% 通过。

v4.22.2: 兼容 fake-ip DNS 解析,防止上游主机被误拦截 (BLOCKED_HOST)

Choose a tag to compare

@github-actions github-actions released this 30 Sep 17:00

修复

  • fake-ip 环境下上游被误拦(BLOCKED_HOST):本机 clash 系代理开启 fake-ip 模式(TUN/DNS 劫持)时,
    api.commandcode.ai 会被解析为 198.18.x.x 假 IP,DNS rebinding guard 将其判为保留地址直接拒绝,
    请求毫秒级失败(2026-09-30 23:40~23:47 批量复现)。修复分两层:
    • 部署侧:start.cmd 注入 COMMANDCODE_UPSTREAM_ALLOWED_HOSTS=api.commandcode.ai,
      将该域名加入 DNS 校验白名单(仅豁免此域,SSRF/rebinding 防护对其它域名不变);
    • 网关侧(本机 Clash Verge 配置,不入库):dns.fake-ip-filter 加入 +.commandcode.ai,
      令该域名走真实 IP 解析。
      影响面:API 行为零变化;watchdog.ps1 同步注入环境变量(被 .gitignore 忽略,需本机部署手动同步)。
      已知环境遗留:本机项目根的历史 ~/.env(2026-09-04 凭据文件)使 admin-key-mask 一项隔离断言失败,与本次变更无关。

v4.22.1: 管理面 Origin Scheme 校验收紧与安全加固 (ORIGIN_SCHEME_CHECK)

Choose a tag to compare

@github-actions github-actions released this 25 Sep 06:37

安全

  • Wave 4:管理面 Origin scheme 校验收紧(ORIGIN_SCHEME_CHECK)——原安全策略的最后一项。
    管理面写操作此前只比对 Origin 的 host,scheme 不受限:同 host 的混合内容场景
    (如 https 页面驱动 http 管理接口)可以通过校验。现在默认要求 Origin scheme 与
    请求协议一致(dashboard 与 prompts 两处管理面 hook 均已接入)。
    影响面:绑定 127.0.0.1 直连的本地用户(http→http)完全不受影响;反代 TLS 终止
    (https 页面 → http 后端)的部署会收到 403,设 ORIGIN_SCHEME_CHECK=off 显式回退。
    不传请求协议的旧调用形态保持旧语义(零破坏)。新增 4 项测试(含端到端 403)。

说明

  • 本版收口后,原开发计划全部项目均处于「已落地」或「有记录的取消/条件触发」终态。

v4.22.0: 上游 Pipeline 编排化与仪表盘运营可视化

Choose a tag to compare

@github-actions github-actions released this 25 Sep 00:27

优化提升计划收尾:架构 D(upstream Pipeline)完成 + 仪表盘运营能力可视化。
零配置升级承诺:API 行为与错误语义零变化(导出面 14 符号逐一比对一致);
前端为纯增量两张只读卡片,默认渲染不变。

架构

  • D. upstream Pipeline 编排化:sendToCC 325 行深嵌套 → 181 行编排层 +
    pipeline/ 5 个阶段模块(timeouts 超时装配 / request 受控请求含 SSRF 重定向防护 /
    response-error 分类与退避 / stream 流包装与首事件探测 / errors 共享基础件),
    upstream.ts 730 → 393 行。阶段间显式参数传递、无共享可变闭包;SSRF 注释逐行随迁;
    日志顺序与文案逐字保留。导出面 14 符号一致,调用方零改动。
    明确保留在编排层:并发槽位管理、onRetry 换号回调、重试循环控制流(强行提取会引入风险)。
  • 既有测试矩阵(挂钟上限/首事件探测/重试换号/SSRF 重定向/流错误)拆分前后零回归。

仪表盘

  • 新增 GET /api/features 只读端点:健康检查/Webhook/Prompt 版本/限流/模型访问/审计
    六类能力的运行时开关状态与参数(WEBHOOK_URL 不回显,专测锁死)。
  • 概览页新增「通道健康」与「运行开关」两张只读卡片:探活结果/延迟/连续失败/可用率、
    各开关徽标与参数;随概览页既有 30s 轮询刷新,不新增定时器;全 esc() 转义。

明确不做(计划终态)

  • E. 路由去重(chat.ts/messages.ts 60% 重复 → RouteMiddleware):按架构师建议
    取消——风险最高、成本翻倍,且 4.21.0 的限流/审计插桩刚在两路由落地,大改会把
    插桩与既有覆盖搅动,回归风险陡增;重复的维护代价由 607 项测试矩阵兜底可控。
  • Prompt A/B、语义缓存、MCP Gateway、Docker/K8s、最低成本路由:与本地单 exe 定位
    冲突,砍掉(4.20.0 分析结论维持)。

测试

  • 全量 606/607 通过(+features 5 项);唯一失败为既有环境性用例(本机生产 .env)。
  • tsc --noEmit、eslint 零错误。

v4.21.1: 仪表盘版本徽标显示真实版本号 (v4 → v4.21.1)

Choose a tag to compare

@github-actions github-actions released this 24 Sep 23:41

修复

  • 仪表盘头部版本徽标显示真实版本号:此前硬编码为 v4,现从 /api/status 的
    version 字段驱动(fetchStatus 既有轮询顺带更新,无新增请求);接口不可达时
    保持占位 v4 不谎报。<title> 同步去掉过时的 v4 字样。

v4.21.0: 仪表盘全新 UI、账户生命周期管理与凭据安全加固

Choose a tag to compare

@github-actions github-actions released this 24 Sep 17:42

优化提升计划第 0 期(界面)+ 第 1 期 + 第 2 期,6 条任务线并行开发后合并。
零配置升级承诺:仪表盘默认渲染与 4.20.0 完全一致;除审计日志(minimal,仅元数据)与
健康检查(纯旁路日志)默认开启外,其余新功能全部默认关闭,API 行为不变。

可视化界面(Phase 0–2,21 人日计划的全量前置三期)

  • Phase 0(零感知):语义色板 CSS 变量收口(暗色默认视觉逐一对齐不变)、统一空状态与骨架屏、
    窄屏宽表横向滚动降级。
  • Phase 1(受益):概览页补「今日请求/成本」「活跃账号」卡片;账号卡片登录方式与 5h 额度徽标;
    概览页快捷刷新。
  • Phase 2(增强):用量表默认折叠的筛选栏 + 列头排序 + 行下钻详情;模型家族徽章;
    日志 level/模型/错误码结构化高亮。全部动态内容走 esc() 转义,新增 20 项 spa 测试(65 项前端测试全绿)。

架构(Phase 1 + Phase 2 存储/adapter 部分)

  • config.ts 859 → 547 行:OAuth/浏览器登录拆出 auth-browser.ts,SSRF 守卫拆出
    security-guard.ts(均 re-export 保持调用方零改动);types 按域拆 5 文件(index.ts 聚合 re-export)。
  • usage-store 后端接口化(UsageStorageBackend,默认 jsonl,文件格式逐字节不变,为 SQLite 预留)。
  • adapter.ts 964 行单类 → 组装式 5 模块(reasoning / request-translate / stream-encode /
    anthropic-response / usage-extract),92 个 SSE 快照逐字节钉住行为零变化;
    快照注入固定模型缓存保证跨环境可复现。
  • 明确不做(本轮):upstream Pipeline 编排(D)与路由去重(E)——按架构师建议后置,
    需配合绞杀者灰度单独一轮。

新功能(默认关闭 / 仅旁路)

  • 通道健康检查(默认 5 分钟探活,仅日志告警,绝不拦截请求):HEALTH_CHECK_INTERVAL_MS(0 关闭)。
  • Webhook 告警(默认关):WEBHOOK_URL + WEBHOOK_COST_USD / WEBHOOK_ERROR_RATE 阈值,
    每日每事件一次去重,fire-and-forget 不重试。
  • Prompt 版本管理(默认关):PROMPT_VERSIONS=on 启用 /api/prompts/*——保存自动快照、
    按时间戳回滚(回滚前当前内容同样先快照,历史不丢);目录穿越白名单防护。
  • 速率限制(默认关):RATE_LIMIT_RPM / RATE_LIMIT_TPM,60s 滑动窗口,超限 429 +
    Retry-After;错误码复用既有 RATE_LIMIT(429),零追加公共契约。
  • 模型访问控制(默认关):MODEL_ALLOWLIST / MODEL_BLOCKLIST,拒绝 403。
  • 审计日志(默认 on,minimal):只记 ts/route/model/tokens/status/duration 元数据,
    绝不记录消息正文;AUDIT_LOG=off 关闭。

修复

  • 删除 adapter 拆分暴露的死函数 anthropicImageToWire(拆分前即无调用的 private 方法)。

测试

  • 全量 601/602 通过(+188:spa 20、adapter 快照 92、健康检查 12、webhook 18、prompt 11、
    限速 13、模型控制 13、审计 10 等新测试);唯一失败为既有环境性用例(本机存在生产 .env)。
  • tsc --noEmit、eslint 零错误;6 分支合并零冲突(按文件域并行隔离)。

v4.20.0: DNS 重绑定防御、安全审计日志与模型访问控制

Choose a tag to compare

@github-actions github-actions released this 24 Sep 16:32

优化提升计划第 0 期(安全止血 Wave 2–3)。三个新开关全部安全默认:默认 on/conservative,
不改配置的用户升级后 API 行为不变(零配置升级承诺),每个开关都可显式回退。

安全

  • 日志密钥脱敏(Wave 2):LOG_REDACTION=on(默认)对进入环形缓冲 / proxy.log / 仪表盘
    日志页的每条日志按密钥形态打码——Authorization: Bearer/Basic、api-key / x-api-key
    键值(含 JSON 引号形态)、裸 sk- 令牌、query 中的 token/key 参数统一替换为
    [REDACTED];off 显式回退。脱敏在控制字符清洗之后执行,用 � 拆分关键字的
    日志注入无法绕过。新增 tests/log-redaction.test.ts(10 项)。
  • SSRF 重定向阻断(Wave 3):修复真实绕过点——此前唯一的数据面 fetch 未设
    redirect,Node 默认 follow,被攻击者控制的上游可用 302 把带凭据的请求引向
    169.254.169.254 等内网/元数据地址,完全绕过对初始 URL 的白名单校验(回归测试先行
    证实:mock 上游 302 → 元数据地址,旧代码真被跟过去直到空闲超时)。现在所有上游请求
    一律 redirect: 'manual'(数据面 POST + 3 个 GET 出口),默认 conservative 不跟随;
    UPSTREAM_REDIRECT=follow 显式放行后逐跳复检:私网/回环/保留地址永不跟随且不受
    allowlist 影响
    ,同 host 跳转保留 POST 与请求体,跨 host 跳转剥离 Authorization,
    链条最多 5 跳。新增 tests/upstream-redirect.test.ts(6 项,真实 mock 上游 + fetch mock)。
  • DNS rebinding 防护(Wave 3):DNS_REBINDING_GUARD=on(默认)在每个上游请求出口
    做"请求前解析 + 校验"——URL 字面校验只能看 hostname,攻击者域名可先解析公网通过校验、
    实际建连时再解析进内网;现在解析结果含私网/保留地址即拒绝(fail-closed),off 显式
    回退。IP 字面量 / localhost / allowlist 命中主机跳过解析校验(无 rebinding 可能或已
    显式信任)。已知残余:lookup 与建连间存在 TOCTOU 窗口,彻底封闭需固定解析结果建连
    (自定义 undici Agent),按计划做"请求前校验"档位。新增 tests/dns-rebinding.test.ts(8 项)。
  • 说明:计划 Wave 1(safeEqual 侧信道修复、usage-history 原子写)在 4.18.x–4.19.x
    已先行落地,本版无对应改动。

兼容性

  • 三个开关默认值即安全默认:LOG_REDACTION=on 只影响日志显示不影响 API;重定向默认
    不跟随——依赖上游 302 跳转的自建镜像用户需显式设 UPSTREAM_REDIRECT=follow;
    DNS_REBINDING_GUARD=on 对 allowlist 命中的自建网关域名不生效(运维显式信任即放行)。

测试

  • 新增 24 项测试(10 + 6 + 8),全量 413 项通过(Windows 本机 412 + 1 项既有环境性失败:
    admin-key-mask 的 .env 隔离用例在本机存在生产 .env 时必然触发,CI 干净环境全绿);
    tsc --noEmit、eslint 无错误。

v4.19.1: 修复 exe 加载期崩溃、Node 18 支持结束与换用 @yao-pkg/pkg

Choose a tag to compare

@github-actions github-actions released this 23 Sep 16:47

修复

  • engines 从 >=18.17 抬到 >=20,Node 18 支持结束。4.19.0 新增的 smoke-node18 作业首跑就红了:TypeError: diagnostics.tracingChannel is not a function——fastify 5 用到的 diagnostics_channel.tracingChannel 是 Node 20 才有的 API。
    这不是新引入的缺陷,而是"声明的支持面下限从来没人执行过":主矩阵跑在 20/22 上,engines 只是声明、npm 默认不拦,所以自 dependabot 把 fastify 从 4.29.1 升到 5.12.3 起,Node 18 就已经起不来了,直到这个作业出现才被发现。该作业本身是对的,不要为了让它变绿而放宽它。
  • 打包后的 exe 此前在加载期就崩,根本起不来(src/utils/version.ts)。CJS 打包下 import.meta.url 是空字符串,new URL('../../package.json', '') 抛 ERR_INVALID_URL——而抛出点在"为坏候选兜底"的那个 try 之外(它在数组字面量求值时发生,不是读取文件时),于是模块加载失败、进程在起监听之前就死了。改为单独包住这一句、让它降级到下面的兜底路径。
    实测:修复前 exe 退出码 1、无监听;修复后 exe 正常启动(banner 报 4.19.1、/health 200、netstat 确认端口归属 commandcode-proxy-v4.exe)。

构建

  • 打包器 pkg → @yao-pkg/pkg(6.x),目标 node18-win-x64 → node22-win-x64。原来那条链是被 vercel/pkg 的天花板钉住的:pkg 已停止维护、最高只支持 node18,engines >=18.17 与 --target node18-win-x64 都是它的产物,不是独立的产品决策。换到维护中的 fork 后 exe 内嵌 node22,"零依赖 exe"这项能力不变(静态资源另有问题,见文末「已知问题」)。
    注意:打包需要 Node ≥22 来运行 @yao-pkg/pkg 自身(其预编译二进制由 @yao-pkg/pkg-fetch 提供,覆盖 node22/24/26)。

CI

  • smoke-node18 → smoke-node20,改为验证 engines 的下限本身。选下限而不是 22:能起在 20 上就蕴含能起在 22 上,一个作业同时覆盖"声明的下限是真的"和"pkg 内嵌的 node22 跑得起来"。

安全

  • npm audit 清零(此前 2 高危 + 1 中危)。曾评估"把 fastify 回退到 4.x 以保住 Node 18"这条路线:技术上可行(^4.29.1 下 typecheck/lint/build 0 错误、389 项全绿、零代码改动),但 4.29.1 是 4.x 终点、不会再有安全补丁,npm audit 会常驻 fastify 与 find-my-way 两个 high(唯一修复是升到 fastify@5.12.5 这个 semver-major),故不采用——不值得为一个已 EOL 的运行时长期背一组修不掉的公告。顺带把 vercel/pkg 那条 no fix 的 moderate 也一并去掉了。

测试

  • 全量 389 项通过,tsc --noEmit、eslint . 无错误。
  • 交付运行时冒烟在真实 Node 20.20.2 上实测通过(跑的是 node dist/index.js,即 CI 里那个作业的形态):/health 返回 {"status":"ok","version":"4.19.1"},/ 返回 99,986 字节、含 <title> 的仪表盘 HTML。

已知问题

  • 打包后的 exe 仍不能提供仪表盘:exe 起得来、/health 与 /v1/* 正常,但 GET / 返回 500 Dashboard assets missing: public/index.html not found.。
    根因是静态资源的落点与代码读取的路径不一致,且本次没能定位到正确落点,故不写成"已修复"。实测数据:exe 内 __dirname = C:\snapshot\dist,而 C:\snapshot\public\index.html 不存在(构建日志里连 Cannot stat 警告都没有——它既不报缺,也没落在预期位置)。
    临时办法:把仓库的 public/ 目录放在 exe 同级再运行(那是代码的第一候选路径)。定位 pkg 的资源落点需要单独一轮,届时再决定是修正 assets 路径还是改成构建期内嵌。

    这条与本次改动无关,是既存缺陷:修复前 exe 连启动都到不了,所以从未暴露过。

v4.19.0: 架构审查批次 B — 修复工具调用吞丢与凭据掩码收口

Choose a tag to compare

@github-actions github-actions released this 23 Sep 15:37

架构审查(批次 B)修复。取次版本号而非修订号:含四处行为变更(下方标 ⚠️)与一处内部契约变更(saveConfigFile 的返回值),不是单纯补丁。

修复

  • 流式 finish_reason 不再压过已经流出的工具调用(adapter.ts)。上游明确回 stop 时,此前会把 finish_reason 定成 stop 并盖掉 tool-calls,而客户端按它判断回合是否结束——整批 tool_calls 被丢弃、agent 静默卡住。现在只有在没有任何工具调用流出时才回 stop。
  • Anthropic 路由的 tool_use 分片合并(messages.ts)。此前每个 tool-call-delta 各发一轮 start/delta/stop,N 个分片变成 N 个同 id 的块;现在合并为一块。
  • OpenAI 非流式工具调用按 id 合并(chat.ts)。此前用 set 覆盖,同一调用的后续分片直接丢失;固定回落的 call_1 改为唯一 id。
  • 流交还后的空闲超时按真实分类落库(upstream.ts)。此前一律记 PROVIDER_PROTOCOL_ERROR,README 承诺的 STREAM_IDLE_TIMEOUT 一直没有兑现。
  • /api/auth/manual-login 不再明文回传 apiKey(dashboard.ts)。同文件的 accounts / browser-login / aggregate 三个出口早已掩码,这是唯一漏网的一个;四处重复的掩码表达式收口为 toSafeAccount() / maskApiKey(),新增端点不会再漏。
  • 删掉最后一个账号时同步清除 .env 凭据与进程内兜底 Key(config.ts)。getActiveApiKey() 在账号表为空时会回落到环境变量,此前被删除的账号仍会继续烧额度。.env 也不再固化 apiBase / ccVersion 的公网默认值。
  • 配置落盘失败不再假成功(config.ts + dashboard.ts)。⚠️ saveConfigFile 改为返回是否落盘,setActiveAccount / setRotationMode / logoutAccount 传播失败,loginNewAccount 落盘失败时抛错,三个仪表盘端点改回 500——配置目录不可写从"假成功"变成显式失败,前端已同步适配。
  • 流式路径上游不给 usage 时用编码器估算兜底 outputTokens(chat.ts)。实测 205 条真实请求中 0 条带输出量,成本此前被系统性低估。
  • input_tokens 估算不再把 config 元数据与图片 base64 当提示词(messages.ts + upstream.ts);count_tokens 计入数组形态 tool_result、图片与 tools schema——此前 1200 字符的工具输出只报 1。
  • project 归属不再恒为空(request-context.ts)。systemTextOf 此前不认 OpenAI 的 messages[role=system|developer],导致 /v1/chat/completions 全部记录 project: null。
  • 崩溃预算退出前 flush 排队的用量写入(index.ts)。此前直接 process.exit,把已经排队的用量丢掉。
  • 面板的删除/开关失败不再静默(public/index.html)。18 处裸 fetch 收敛为一个 apiJson() 封装,此前只有 2 处检查 res.ok,后端改返回 500 时 UI 会 TypeError,表现为"点了删除没反应";fetchStatus 不再整体吞异常,代理挂掉时显式显示"无法连接代理"而非 Port :undefined。
  • 额度卡片渲染前统一重置(public/index.html),此前切换账号会留着上一个账号的数字;日志页只在原本贴底时跟随滚动,不再每 5s 强制跳底。

新增

  • DETERMINISTIC_REQUEST_SHAPE 否决表(upstream.ts)。请求形态类错误不再重试——实测此前会打满 3 次、多花约 1.5s 退避;瞬时故障的重试保护保持不变,未做策略反转。
  • /api/usage/history 支持 ?limit=,导出 CSV 取全量并在截断时如实说明(此前恒 200 条却提示"已导出 N 条")。
  • auto-quota 轮换与额度采样的装配条件移入 tick 并读新鲜配置(index.ts),面板上开启后无需重启代理即生效。
  • ⚠️ 引擎开关只认严格布尔(dashboard.ts),"false" / 0 此前会被当成"继续运行"。
  • 无障碍基线(public/index.html):48 个图标补 aria-hidden、24 个 th 补 scope、tablist/tab/tabpanel 配 aria-selected 与方向键、三个弹窗补 role="dialog" / aria-modal / 焦点圈定与归还、live region、label for、纯图标按钮补 aria-label。

性能

  • dayKey 按 timeZone 缓存 Intl.DateTimeFormat(usage-store.ts):3 万条带时区记录 1776ms → 140ms。此前逐条构造 formatter,会阻塞事件循环约 2 秒。
  • logger 每行时间戳不再用 toLocaleTimeString,同属逐次构造 formatter 的写法。
  • 原子写的临时文件名加 pid(config.ts + usage-store.ts),避免多实例互踩。

构建

  • CI 主矩阵 Node 20 → 22:vitest@5 要求 ≥22.12,此前是把测试 Runner 跑在它自己声明的支持面之下。
  • 新增 smoke-node18 作业:只装生产依赖 + 下载 dist 产物,用 Node 18.17 起真实进程断言 /health 与仪表盘 HTML,覆盖 pkg 交付的运行时。
  • 覆盖率步骤加 --coverage.thresholds.statements=65。已验证该开关真会拦:阈值 99 时 exit=1,65 时 exit=0。
  • eslint.config.js 把仓库根三个 .mjs 工具纳入 lint(此前被根级 *.mjs 忽略,与配置自己写明的原则矛盾),立刻抓出 bench-models.mjs 一个"取了不用"的变量;该工具的起始额度用量改为真的打印出来(它会实际烧额度)。

测试

  • 新增 10 个回归防线文件:tool-call-fragments、config-account-lifecycle、usage-surfacing、dashboard-browser-login-mask、token-estimation、tool-image-and-params、spa-api-json、spa-a11y、spa-search-functions、spa-html-integrity,并扩充 attribution、upstream-probe。
  • 全量 389 项通过(原 316 + 73),tsc --noEmit、eslint . 无错误。所有"修复"类改动都先在未改动的 HEAD 上跑出红、改后变绿才提交结论。

已知未做

  • cache_control 透传、tool_result 内图片的 wire 形状、stop / response_format 下发:需要真实 Key 且套餐覆盖 Anthropic 系模型才能验证效果。上游对未知字段是静默忽略(已实测),但"不报错"不等于"生效"——不要当已支持特性宣传。
  • 流式背压(write() 返回值被忽略、不 pause 上游)与 getUsageStats 整体记忆化:建议配压测单独一轮。
  • 配置落在 process.cwd()(换目录启动会像"账号全丢"):需迁移策略。