Skip to content

Releases: fish2lab/DSCodex

DSCodex v1.4.0 — Lighter History

Choose a tag to compare

@fish2lab fish2lab released this 04 Oct 06:35

DSCodex v1.4.0 — Lighter History

一段看过很多截图的会话,请求体会越过 DeepSeek 网关约 47 MB 的上限,之后每一轮都只收到 HTML 413 Request Entity Too Large。这一版在请求超过 44 MB 时把老图改小,会话不再卡死;另修好了一类工具调用重放失败。

Highlights

  • 🖼️ 超限旧图自动缩小,不再 413 卡死。 出站请求超过 44 MB 时,最新 4 张原样保留,更老的图转成有损 WebP(长边 1024、质量 75);缩完仍放不下,才把最老的图换成一条写明序号、类型、大小的 input_text 记录。作者实测一段 44 张图的会话:图片 47.92 → 10.1 MB,整个请求 50.67 → 12.88 MB,44 张全在。转码结果按内容哈希缓存在 ~/.codex/dscodex/image-cache/。编码器(sharp)是找到就用,不是依赖:包仍只声明 ws,没装编码器时退回文字记录。想要缩图,运行 npm install --prefix ~/.codex/dscodex/encoders sharp。五个旋钮(max_upstream_bytes、keep_recent_images、image_max_side、webp_quality、webp_encoder_dir)写进 ~/.codex/dscodex/config.json,max_upstream_bytes: 0 关闭。感谢 @Yilmhi(#28)。
  • 🔧 tool_search 与函数调用混在同一轮时不再被 DeepSeek 拒绝。 同一个 reasoning 回合里同时有 function_call 和 tool_search_call 时,重放顺序现在会被正确修复,不再因此卡住会话。感谢 @LukasAI(#26)。
  • 🧪 CI 增加语法检查,仓库增加 PR 模板。 对 src/*.mjs 与 scripts/*.mjs 逐个 node --check;.github/PULL_REQUEST_TEMPLATE.md 列出提交前的核对项(来自 #27 的建议)。

升级

git pull --ff-only
npm install
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor

验收

  • 版本号在 package.json、package-lock.json、src/constants.mjs、CITATION.cff 对齐 1.4.0。
  • 本机测试:155 项,148 通过,0 失败,7 项 Windows 专属测试在 macOS 上跳过。
  • PR #28 在 macOS、Windows、Ubuntu 三平台 CI 通过。

未验收

  • 缩图的真实会话效果采用 PR 作者的实测数字,发布机未复现。
  • smoke:picker 与 smoke:state 依赖真实安装的 Codex,不在 CI 中运行,本次未跑。

DSCodex v1.3.0 — Live Model List

Choose a tag to compare

@fish2lab fish2lab released this 23 Sep 05:46

DSCodex v1.3.0 — Live Model List

v1.2.2 及更早版本安装后,Codex 的模型选择器停在安装那一刻:OpenAI 之后上线的 GPT 模型不出现,已经下架的模型也一直留着。这一版改成实时读取 ChatGPT 的模型列表,并修好了 Codex 重写配置后卸载删不干净的问题。

Highlights

  • 🔄 模型选择器跟着 ChatGPT 实时更新。 旧版在 config.toml 里写入 model_catalog_json,Codex 对这个键只在启动时读一次,之后再也不去 ChatGPT 刷新。本机实测:旧快照停在 2026-09-10,其中 GPT-6 只有已下架的 gpt-6-astra;而上游对桌面端 0.155 下发的是新的 gpt-6-luna。现在 DSCodex 只写 openai_base_url,Codex 按自己的刷新规则(5 分钟 TTL,加上每次响应带回的 ETag)经路由器请求 /models。路由器带着客户端原有的 OAuth 请求头和 client_version 转发给 ChatGPT,插入 🐳 DeepSeek Flash 后返回,并保留上游 etag。上游不同版本号返回的列表不同,路由器照原样透传。
  • 🛟 ChatGPT 连不上时不丢 DeepSeek。 每次成功拉到的列表写进 ~/.codex/dscodex-models.json。遇到网络错误或 5xx 时返回这份列表;遇到 401 这类 4xx 时原样透传,让 Codex 自己刷新登录。
  • 🧹 卸载不再依赖标记注释。 Codex 桌面端重写 config.toml 时会丢掉 # DSCodex managed 注释,旧版 uninstall 因此认不出自己的行:命令报成功,配置里却留下指向已关闭端口的 openai_base_url 和已删除文件的 model_catalog_json,Codex 随之连不上。现在按值认领:带 43 位令牌的回环 openai_base_url,以及指向 dscodex-models.json 的 model_catalog_json,只可能是 DSCodex 写的。start 会把它们补回标记并原位重写,uninstall 会把它们删掉。用户自己写的 openai_base_url 和目录路径不受影响。
  • ⬆️ 自动迁移。 升级后第一次 start 会删掉旧的 model_catalog_json,令牌和端口保持不变,不需要重新 install。

升级

git pull --ff-only
npm install
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor

随后完全退出(⌘Q)并重开 ChatGPT 桌面端。选择器会在 Codex 下一次刷新时换成 ChatGPT 当前的模型列表。

验收

  • 版本号在 package.json、src/constants.mjs、CITATION.cff、node src/cli.mjs --version 四处对齐 1.3.0。
  • 本机测试:138 项,132 通过,0 失败,6 项 Windows 原生测试在 macOS 上跳过。git diff --check 干净。
  • 端到端(隔离的 CODEX_HOME,真实 ChatGPT 登录,真实 chatgpt.com):
    • 按实际用户机器的状态构造旧配置(model_catalog_json 存在、标记注释丢失),start 后该键被删、标记补回、令牌沿用。doctor 其余五项 ok,catalog_present 在 Codex 第一次经路由器拉取列表后转为 ok(这个隔离目录之前没有备用列表)。
    • codex debug models 经路由器返回的列表与直连上游逐项一致,另加 DeepSeek Flash:桌面端 0.155.0 看到 gpt-6-luna,CLI 0.154.0 看不到(上游按版本下发)。npm run smoke:picker 通过。
    • 真实请求:gpt-6-luna 回复正确;deepseek/deepseek-flash 工具循环通过(WS 握手 426 后两次 HTTP 200)。
    • 测试中碰到一次 chatgpt.com fetch failed,路由器返回上一份 7 个模型的列表,Codex 未受影响。
    • stop + uninstall 后 config.toml 只剩用户自己的行。

未验收

  • npm run smoke:state 需要真实 ~/.codex 下已安装的 DSCodex,发布机当时处于卸载状态,未运行。
  • Windows 实机(桌面端 + 自启动)未在发布机上跑过,仅有 CI 覆盖。

DSCodex v1.2.2 — Spawn and Switch

Choose a tag to compare

@fish2lab fish2lab released this 20 Sep 09:38

DSCodex v1.2.2 — Spawn and Switch

三条社区报告一起落地:DeepSeek 上 spawn 子 agent 必炸、同一任务 DeepSeek → GPT 切换在 v1.2.1 上再次 400、DeepSeek 任务首轮要等 10–15 秒的 WebSocket 重连。感谢 @Yilmhi(#24)、@danielkuang666(#25)、@zhuzw1990(#23)。

Highlights

  • 🤖 DeepSeek 上可以 spawn 子 agent 了(#24)。 Codex 把交给子 agent 的任务放在 agent_message 里,内容块类型是 encrypted_content(实际是明文)。DeepSeek 的内容枚举只认 input_text / output_text / input_image / input_file,整个请求 422;改成 assistant 角色重放后又因为缺 reasoning_text 400。现在路由器把这类块改写成 input_text、把 agent_message 以 user 角色重放,并剥掉 internal_chat_message_metadata_passthrough。任何 DeepSeek 不认识的内容块都按同一规则处理:有文字的保留文字,没有的丢弃。
  • 🔁 DeepSeek → GPT 切换再次修好(#23)。 DeepSeek 现在给 reasoning item 填一个 38 字符的 UUID 占位 encrypted_content,v1.2.0 的「encrypted_content 为空才算外来」判据因此失效。新判据不再看该字段是否为空:带 reasoning_text 内容的 reasoning 一律剥掉(官方 GPT reasoning 从不带 content),encrypted_content 非空且不是 ChatGPT 密文(base64 gAAAAA 开头)的也剥掉;compaction 同理。HTTP 与 WebSocket 两条路一致。
  • ⚡ DeepSeek 的 WS 握手直接 426(#25)。 ChatGPT 登录的桌面端在握手时带 x-codex-routing-hint: model=<slug>;tier=<tier>。识别为 DeepSeek 就在握手阶段回 HTTP 426,客户端走零重试的 HTTP 回退,不再吃 5 次退避重连;本机实测首轮从 10–15 秒降到约 1.4 秒。没有该头的客户端保持原来的首帧 close 1008 路径。
  • 🎙 Voice 说明更新。 桌面端 26.908 起语音由客户端自己直连 chatgpt.com/wham/realtime/calls,不经过 openai_base_url,路由器无事可做;PR #21 据此关闭。

升级

git pull --ff-only
npm install
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor

随后完全退出(⌘Q)并重开 ChatGPT 桌面端,再新建一个任务。已有任务保留旧模型状态。

验收

  • 版本号在 package.json、src/constants.mjs、CITATION.cff、node src/cli.mjs --version 四处对齐 1.2.2。
  • 本机测试:131 项,0 失败;Windows 原生项在 macOS 上跳过。git diff --check 干净。
  • 活探针:codex -m deepseek/deepseek-flash … exec 工具循环通过;server.log 显示 deepseek websocket upgrade rejected with 426 … (hint model=deepseek/deepseek-flash) 后 1.4 秒内 HTTP 200。
  • #24 作者对真实 DeepSeek 端点做过 400 → 200 与子 agent 端到端验证(含子 agent 调工具、子 agent 再 spawn)。

未验收

  • GPT 模型的子 agent仍在客户端侧失败(Encrypted function output content could not be decrypted or decoded),属上游问题:https://github.com/openai/codex/issues/33267。
  • Windows 实机(桌面端 + 自启动)未在发布机上跑过,仅有 CI 覆盖。

DSCodex v1.2.1 — Keep the Wire

Choose a tag to compare

@fish2lab fish2lab released this 12 Sep 09:59

DSCodex v1.2.1 — Keep the Wire

ChatGPT 桌面端 26.908 起,官方 GPT 模型会先连 ws://127.0.0.1:10110/<token>/v1/responses。DSCodex 原先对所有 upgrade 回 426,路由器一停官方模型就 Reconnecting 1/5…5/5。本版本把这条线接到 chatgpt.com,DeepSeek 仍走 HTTP Responses。

Highlights

  • 🔌 官方 GPT 走回 Responses WebSocket。 授权过的 /v1/responses upgrade 透传到 wss://chatgpt.com/backend-api/codex/responses,OAuth 头与 query 原样转发。桌面端 warmup 在 accept 时就向上游握手,首个 turn 不再多付一次 TLS。--use-env-proxy 下 wss 走 HTTPS_PROXY 的 CONNECT,loopback 仍直连。
  • 🐳 DeepSeek 仍是原生 HTTP Responses。 Flash 的 catalog 保持 prefer_websockets = false。若桌面端还是先打 WS,看到 DeepSeek model(含嵌套 envelope)就 close 1008,客户端回 POST api.deepseek.com/responses。DeepSeek 请求不会进 OpenAI 的 WebSocket。
  • 🧹 同一条 WS 上的后续 turn 也会剥外来 reasoning_text。 不只第一条 response.create。DeepSeek 中途切到这条连接同样 1008。
  • 🛡 关停与畸形请求。 闲置透传 WS 不再让 server.close() 挂死,dscodex stop / autostart 交接能结束。畸形 upgrade 请求行回 400 而不是把路由器打死。上游空 close 帧(1005)会映射成合法 close,客户端不再悬挂。

升级

git pull --ff-only
npm install
node src/cli.mjs sync
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor
node src/cli.mjs autostart enable   # 建议:避免路由器停掉后官方模型再次 5/5

随后完全退出(⌘Q)并重开 ChatGPT 桌面端,再新建一个任务。已有任务保留旧模型状态。

验收

  • 版本号在 package.json、src/constants.mjs、CITATION.cff、node src/cli.mjs --version 四处对齐 1.2.1。
  • 本机测试:0 失败;Windows 原生项在 macOS 上跳过。git diff --check 干净。
  • 活探针:带 token 的 /v1/responses WebSocket handshake 为 open;无 token 仍为 426;畸形请求行后 /health 仍 200。
  • DeepSeek HTTP 路径本次未改:目标仍是 https://api.deepseek.com/responses。

未验收

  • Voice / Realtime(PR #21)仍未合并。
  • Windows 实机(桌面端 + 自启动)未在发布机上跑过,仅有 CI 覆盖。
  • 桌面端是否每个 turn 按当前模型选传输:若按 session 锁 WS,DeepSeek 任务会先吃一次 1008 再回 HTTP。上线后看 server.log 里 deepseek websocket rejected 是否在正常 DeepSeek 使用时出现。

DSCodex v1.2.0 — From the New World

Choose a tag to compare

@fish2lab fish2lab released this 10 Sep 17:22

DSCodex v1.2.0 — From the New World

DeepSeek 从 V4 到 V4.1 是一次完整换代,本版本随之把模型菜单收成一条 🐳 DeepSeek Flash,并把图片、跨 provider 历史和路由恢复三处长期边界一并收口。

Highlights

  • 🐳 DeepSeek V4.1 Flash。 菜单只剩 🐳 DeepSeek Flash,API 名 deepseek-flash:原生视觉、1M 上下文、最高 384K 输出。旧的 deepseek-v4-flash / deepseek-v4-pro / deepseek-v4-flash-vision-exp 名称继续路由到 Flash,恢复旧任务不需要改模型设置,用户保存的 model 行不动。官方将于 **2026-09-14 12:00(北京时间)**起把 V4 Pro 请求转到 Flash 并按 Flash 计费。
  • 🖼 原生识图。 input_image 直接转发给 DeepSeek,包括工具返回的图片;路由器里的 GPT 代读路径和 DSCODEX_VISION_MODEL 一并移除。
  • 🧹 同一任务从 DeepSeek 切回 GPT 不再持续 400。 转发 GPT 前剥掉外来明文 reasoning_text,保留 GPT 原生加密 reasoning;无法解密的 DSCodex 压缩项丢弃,其余请求保持原始字节。关闭 #17。
  • 🛡 自启动交接与 supervisor 恢复。 合并 Windows 自启动修复(#19)。注册未完成前不替换健康的手动 router;handoff 或 rollback 失败时仍尝试恢复原 router,不再出现杀掉健康实例后无人接手的空窗。

思考强度:为什么仍然只有 High / Max

模型卡写了 1–100 的连续 Juice,但托管 Responses API 只收字符串档位 none / minimal / low / medium / high / xhigh / max。实测整数 1 / 25 / 50 / 75 / 100、字符串 "50" 和 ultra 全部 HTTP 400。底层对照是 low = 50、high = 75、max = 100,官方把 Codex 六档收成三档:minimal / low → 50,medium / high / xhigh → 75,max / ultra → 100。展开成六档滑块,其中三档指向同一个 Juice,没有分辨率。目录因此维持两档:

Codex 滑块 发给 DeepSeek 模型 Juice
High high 75
Max(默认) max 100

路由器把 low / medium / high 折成 high,其余(含 xhigh、max、ultra)折成 max。

升级

git pull --ff-only
node src/cli.mjs sync
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor

随后完全退出(⌘Q)并重开 ChatGPT 桌面端,再新建一个任务。已有任务保留旧模型状态。

验收

  • 版本号在 package.json、src/constants.mjs、node src/cli.mjs --version 三处对齐 1.2.0。
  • 113 项测试:107 通过、0 失败、6 项 Windows 原生跳过(macOS,Node 26.8.1);git diff --check 干净。
  • 隔离环境真实 Codex 闭环:Flash Max 恰好执行一次 shell 命令;原生识图请求在路由器出站边界确认含 input_image,且未发出任何 GPT 识图请求。
  • 新增 macOS / Windows / Linux 的 Node 24 CI 矩阵。

未验收

  • Voice / Realtime(PR #21):multipart Live 请求绕过解压体积上限,且其全局 custom-provider 改动缺少真实客户端验收,本版本未合并。
  • Windows 实机(桌面端 + 自启动)未在发布机上跑过,仅有 CI 覆盖。

DSCodex v1.1.0 — Router 稳定性、GPT 压缩与元数据隔离

Choose a tag to compare

@fish2lab fish2lab released this 13 Aug 08:11

Highlights

  • 修复 router 随机退出后桌面端永久重连 — WebSocket upgrade 探测收到客户端 ECONNRESET 时,不再触发未处理的 socket error 并结束整个 router 进程。
  • 恢复 GPT remote compaction v2 — GPT 直通路径现在保留 Responses-Lite、residency、FedRAMP、memgen 与版本请求头,/compact 能正确返回 Codex 期望的压缩结果。
  • 隔离 DeepSeek 请求元数据 — DeepSeek upstream 只继承通用 user-agent;ChatGPT account、session/thread、attestation、Codex installation/turn metadata 与 OAuth 信息不会跨 provider 转发。DeepSeek 鉴权仍由 router 独立设置。

安装 / 升级

git pull --ff-only
node src/cli.mjs sync
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor

随后完全退出(⌘Q)并重新启动 ChatGPT 桌面端,再新建一个任务。

Notes

  • 版本号在 package.json、src/constants.mjs、node src/cli.mjs --version 三处对齐 1.1.0。
  • 81/81 测试通过,git diff --check 干净。
  • 本版本关闭 #15、#16,并合并 router crash 修复 #14。
  • 已知问题:#17 仍开放。同一任务从 DeepSeek 切回 GPT 时,历史中的 DeepSeek 明文 reasoning_text 可能导致 GPT 请求持续返回 400;本版本未声称修复该跨 provider 历史兼容问题。

DSCodex v1.0.0 — DeepSeek V4 Pro 与思考强度记忆修复

Choose a tag to compare

@fish2lab fish2lab released this 12 Aug 16:25

Highlights

  • 🐳 DeepSeek V4 Pro 进入原生模型菜单 — 与 V4 Flash 并列,目录、路由分流、GPT 识图、上下文压缩、CLI 与 smoke 检查全链路支持双模型;桌面端菜单可选 🐳 V4 Flash / 🐳 V4 Pro,CLI 用 codex -m deepseek/deepseek-v4-pro -c 'model_reasoning_effort="max"'。
  • 🧠 修复思考强度按 provider 记忆 — 桌面端在 GPT 与 DeepSeek 间切换时,自动恢复各自家族的 thinking effort(以及 GPT 专属速度)。修复了 app-server bridge 重启后,状态文件里的 activeProvider 与 config.toml 当前模型不一致导致的档位误采纳:bridge 现在启动时以 config.toml 为准校正,跨 provider 切换真正恢复本族槽位,而不是把另一族带过来的档位写进错误的槽位。新增回归测试覆盖“bridge 关闭期间切换模型后重启”的场景。
  • 🔧 DeepSeek 工具循环重放修复(继承 v0.7.0) — 工具输出按 call_id 紧贴其调用重排、每轮只重放一个工具调用、reasoning 不跨 turn 边界泄漏;已卡死的会话自动修复。
  • 📄 README 压缩 — 中英文 README 收敛为快速开始 + 架构 + 兼容性速查;细粒度约束移入 AGENTS.md(新增第 14–15 条:平台差异与非路由客户端功能)。

安装 / 升级

git pull --ff-only
node src/cli.mjs sync
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor
node src/cli.mjs bridge enable   # 可选:启用桌面端模型菜单的档位记忆

随后完全退出(⌘Q)并重新启动 ChatGPT 桌面端,再新建一个任务。

Notes

  • 版本号在 package.json、src/constants.mjs、node src/cli.mjs --version 三处对齐 1.0.0;78/78 测试通过,git diff --check 干净。
  • app-server bridge 仍为 opt-in 且仅 macOS:它会把 App 的 app-server 连接降级为 stdio,可能影响 Computer Use;bridge disable 可随时回退。思考强度记忆依赖该 bridge,未启用时模型切换照常工作,但档位跟随下拉框全局值。
  • model-selections.json 的 reconcile 修复沿用 version 1,旧状态文件可直接加载,无需迁移。
  • DeepSeek V4 Flash 与 Pro 均为纯文本模型;图片输入由 GPT 经 chatgpt.com 转译为文字后注入,不会原样发给 DeepSeek。

v0.7.0

Choose a tag to compare

@fish2lab fish2lab released this 06 Aug 06:19
9cb4861

What changed

Fix: DeepSeek Responses tool-loop replay compatibility

Two failure modes fixed:

  1. Interleaved items inside a call/output pair — Codex can insert PostToolUse hook context between a function_call and its output, which DeepSeek rejects. The router now pulls the output up to sit directly after its call before forwarding.

  2. Multiple tool calls behind a single reasoning item — DeepSeek rejects the replayed turn with a misleading "reasoning_text must be passed back" error. The catalog now advertises supports_parallel_tool_calls = false and the router forces parallel_tool_calls: false on every DeepSeek-bound body. Already-wedged sessions are repaired by duplicating reasoning per extra call, scoped to the correct turn boundary.

Covers function_call, custom_tool_call (freeform apply_patch), and local_shell_call.

Docs

  • README compressed from ~150 lines to ~80 for human readability; granular details moved to AGENTS.md.
  • AGENTS.md records invariants 13–15 (replay constraints, platform differences, non-routed features).

Files changed

src/proxy.mjs | src/catalog.mjs | test/proxy.test.mjs | AGENTS.md | README.md | README.en.md | package.json

DSCodex v0.6.0 — DeepSeek 上下文压缩(remote compaction v2)

Choose a tag to compare

@fish2lab fish2lab released this 05 Aug 11:31

亮点

  • DeepSeek 上下文压缩:路由侧实现 Codex remote compaction v2(#7)。DeepSeek 会话的自动/手动 /compact 不再报 expected exactly one compaction output item(修复 #6)。交接摘要由 V4 Flash 生成,AES-256-GCM 加密封装为恰好一个 compaction 输出项,后续请求在路由内解密还原,明文不落会话 JSONL。

安全性

  • 回环端口要求客户端鉴权:install 生成 256 位路由 token 并写入管理的 openai_base_url,无 token 的请求一律拒绝
  • Windows 上 DeepSeek API key 改用 DPAPI 加密存储
  • 加固路由生命周期与代理处理:pid-state 文件、认证关闭端点、压缩/解压请求体大小上限
  • 转发代理 re-exec 信号

修复

  • 无法解密的 compaction 项(如切换 provider 前由 GPT 封套的)直接丢弃,不再原样转发给 DeepSeek
  • app-server bridge 改为 opt-in,Computer Use 恢复可用(#8)
  • Windows 自启动 VBS 的 PowerShell 路径统一使用反斜杠

测试 72/72 通过。

DSCodex v0.5.1 — 修复 Windows 非 ASCII 用户目录自启动

Choose a tag to compare

@fish2lab fish2lab released this 02 Aug 09:40

Highlights

  • 修复 Windows 非 ASCII 用户目录下的登录自启动 — wscript.exe 会按系统 ANSI 代码页读取 .vbs;旧版把含中文等非 ASCII 用户名的完整日志路径以 UTF-8 字面量写入脚本,路径乱码后 cmd 无法打开 server.log,路由器因而无法启动。0.5.1 将用户主目录下的日志路径改写为 %USERPROFILE%\...,交给 cmd 在运行时展开;用户主目录之外的自定义日志路径保持原样。新增测试同时保证这类 VBS 输出不再包含非 ASCII 用户名。
  • DeepSeek 图片输入由 GPT 视觉转译 — V4 Flash 保留图片模态声明,使粘贴图片和 view_image 结果能够通过 Codex 桌面端的前置检查。路由器会把发往 DeepSeek 的 input_image 转成由 chatgpt.com GPT 生成的文字描述,复用请求携带的 OAuth header,不需要额外 API Key;同一请求并发处理,并按图片 sha256 在路由器进程内缓存。默认视觉模型为 gpt-5.6-sol,可用 DSCODEX_VISION_MODEL 覆盖。
  • provider 间的推理档位与速度状态彻底隔离 — OpenAI 与 DeepSeek 分别保存 reasoning effort,只有 OpenAI 保存 service tier。跨窗口、fork、bridge 重启和恢复旧任务时均按 provider 恢复状态;staleEffort 阻止仅写入模型时把另一 provider 遗留的 model_reasoning_effort 带入新会话。每任务 provider 记忆持久化在 model-selections.json,上限为最近 500 个任务。
  • 减少 GPT 模型的伪断线 — 路由器 keep-alive timeout 现在长于 Codex 客户端约 90 秒的连接池空闲期,避免客户端复用已被 Node 默认 5 秒超时关闭的 loopback 连接,从而减少 stream disconnected before completion: error sending request。客户端断开时会中止上游请求,截断的上游流会写入 server.log。
  • 跨平台登录自启动 — node src/cli.mjs autostart enable 可注册 macOS launchd、Linux systemd user service 或 Windows Task Scheduler(配合隐藏窗口的 wscript shim)。崩溃会自动拉起,手动 stop 后保持停止;serve 统一持有 pid 文件,uninstall 会移除自启动项。生成的配置与脚本不会写入 DeepSeek API Key。

安装 / 升级

git pull --ff-only
node src/cli.mjs sync
node src/cli.mjs stop && node src/cli.mjs start
node src/cli.mjs doctor
node src/cli.mjs autostart enable   # 可选;Windows 旧自启动用户需重新执行

随后完全退出(⌘Q)并重新启动 ChatGPT 桌面端,再新建一个任务。

Notes

  • 已启用自启动的 Windows 用户升级后必须重新运行 node src/cli.mjs autostart enable,以重生成使用 %USERPROFILE% 的 autostart-run.vbs。成功标准是 Task Scheduler 的 Last Result 为 0,并且 node src/cli.mjs doctor 五项均为 ok。
  • DeepSeek V4 Flash 本身仍是纯文本模型;图片不会原样发送给 DeepSeek。若请求没有 authorization header,路由器不会执行 GPT 视觉转译,而是保持请求体不变;视觉描述失败时会写入明确的占位文本,并在 ~/.codex/dscodex/server.log 记录 vision describe failed。
  • GPT 视觉路径目前由 fake backend 单元测试覆盖;仍建议用真实截图执行一次 view_image,验证当前 ChatGPT 后端接受所选视觉模型。
  • 图片描述缓存仅存在于当前路由器进程内;若 app-server 重新编码图片导致 data URL 改变,该图片会再次生成描述。
  • model-selections.json 增加的每任务 provider 记忆与 staleEffort 仍沿用 version 1,旧状态文件可直接加载。