@eddyskywalker/dsh-chatgpt-subscription 0.10.15 → 0.10.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/README.md +8 -4
  3. package/lib/client.js +641 -121
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +2029 -299
  6. package/lib/types/client/ProviderHubSection.d.ts.map +1 -1
  7. package/lib/types/client/command-code/CommandCodeSection.d.ts.map +1 -1
  8. package/lib/types/client/index.d.ts +1 -0
  9. package/lib/types/client/index.d.ts.map +1 -1
  10. package/lib/types/client/locales.d.ts +4 -4
  11. package/lib/types/client/ollama/OllamaSection.d.ts +25 -0
  12. package/lib/types/client/ollama/OllamaSection.d.ts.map +1 -0
  13. package/lib/types/client/ollama/api.d.ts +36 -0
  14. package/lib/types/client/ollama/api.d.ts.map +1 -0
  15. package/lib/types/client/ollama/locales.d.ts +413 -0
  16. package/lib/types/client/ollama/locales.d.ts.map +1 -0
  17. package/lib/types/host/antigravity/adapter.d.ts.map +1 -1
  18. package/lib/types/host/claude/adapter.d.ts +3 -5
  19. package/lib/types/host/claude/adapter.d.ts.map +1 -1
  20. package/lib/types/host/claude/model-catalog.d.ts +30 -16
  21. package/lib/types/host/claude/model-catalog.d.ts.map +1 -1
  22. package/lib/types/host/command-code/adapter.d.ts.map +1 -1
  23. package/lib/types/host/command-code/mapper.d.ts.map +1 -1
  24. package/lib/types/host/command-code/model-catalog.d.ts +19 -2
  25. package/lib/types/host/command-code/model-catalog.d.ts.map +1 -1
  26. package/lib/types/host/command-code/types.d.ts +29 -1
  27. package/lib/types/host/command-code/types.d.ts.map +1 -1
  28. package/lib/types/host/common/output-reservation.d.ts +11 -0
  29. package/lib/types/host/common/output-reservation.d.ts.map +1 -0
  30. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  31. package/lib/types/host/kimi-code/model-catalog.d.ts +1 -1
  32. package/lib/types/host/kimi-code/model-catalog.d.ts.map +1 -1
  33. package/lib/types/host/minimax-code/adapter.d.ts +2 -3
  34. package/lib/types/host/minimax-code/adapter.d.ts.map +1 -1
  35. package/lib/types/host/model-catalog.d.ts.map +1 -1
  36. package/lib/types/host/ollama/account-pool.d.ts +65 -0
  37. package/lib/types/host/ollama/account-pool.d.ts.map +1 -0
  38. package/lib/types/host/ollama/adapter.d.ts +47 -0
  39. package/lib/types/host/ollama/adapter.d.ts.map +1 -0
  40. package/lib/types/host/ollama/client.d.ts +101 -0
  41. package/lib/types/host/ollama/client.d.ts.map +1 -0
  42. package/lib/types/host/ollama/mapper.d.ts +44 -0
  43. package/lib/types/host/ollama/mapper.d.ts.map +1 -0
  44. package/lib/types/host/ollama/routes.d.ts +22 -0
  45. package/lib/types/host/ollama/routes.d.ts.map +1 -0
  46. package/lib/types/host/ollama/token-store.d.ts +73 -0
  47. package/lib/types/host/ollama/token-store.d.ts.map +1 -0
  48. package/lib/types/host/ollama/types.d.ts +115 -0
  49. package/lib/types/host/ollama/types.d.ts.map +1 -0
  50. package/lib/types/host/responses-mapper.d.ts +0 -2
  51. package/lib/types/host/responses-mapper.d.ts.map +1 -1
  52. package/lib/types/host/search-provider-switcher.d.ts +12 -0
  53. package/lib/types/host/search-provider-switcher.d.ts.map +1 -1
  54. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  55. package/lib/types/index.d.ts.map +1 -1
  56. package/lib/types/shared/command-code-contracts.d.ts +10 -4
  57. package/lib/types/shared/command-code-contracts.d.ts.map +1 -1
  58. package/lib/types/shared/model-catalog.d.ts +58 -1
  59. package/lib/types/shared/model-catalog.d.ts.map +1 -1
  60. package/lib/types/shared/ollama-contracts.d.ts +36 -0
  61. package/lib/types/shared/ollama-contracts.d.ts.map +1 -0
  62. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,40 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - **修复输出上限被当作固定预留,导致自动压缩失效**(#30 / #31);仅修改本插件,不要求修改 DSH。
6
+ - Kimi / MiniMax 不再上报动态预算为 `defaultMaxTokens`;仍在发送阶段按原公式计算并夹取线上 cap,显式请求上限(含摘要请求)仍优先,不引入固定 32K/64K 截断。
7
+ - 其余六条线路按 DSH 默认压缩策略检查固定预留:安全的默认值保持原样,不安全的省略。覆盖实时目录与窗口覆盖;Command Code 的 Kimi-K2.6 / Grok 4.5 / Grok 4.6、WorkBuddy 的 deepseek-v3-2-volc 默认配置受益。Claude、Antigravity、Codex 内置默认配置未发现同类失败,仍增加小窗口保护;Ollama 检查实时窗口。
8
+ - Claude / WorkBuddy 发送阶段保留实时目录 cap,Antigravity 保留模型 cap,Codex 仍不发送输出上限字段;设置卡中的输出能力值不改成零。
9
+ - 边界:显式过大的 maxTokens、自定义压缩策略、即使零预留也无法容纳 headroom/保留尾部的小窗口不在此保证内。WorkBuddy 的 default(56K)仍需部署方降低 compaction headroom/摘要预算或切换足够大窗口的模型;不会伪造窗口容量。升级后需重启插件/host,让新请求重新解析模型默认值,旧版会话若把旧默认持久化为显式值需清除该覆盖。
10
+ - 验证:新增 202 条回归用例,强制源码/测试类型检查、构建及全量测试通过;公共预算函数与真实 DSH 压缩解析器的 144 组边界结果一致。保留原 Kimi 复现文件;旧版 clean-room 与真实订阅账号端到端尚未复验。详细结果见兼容记录 `.dsh/skills/dsh-harness-upgrade/references/output-reservation.md`。
11
+
12
+ - **修复 Codex 线路「跟随官方」名不副实:两个读取参数默认值与官方客户端不一致,其中一项持续多花额度**(用户报告:近期更新后额度消耗变快)。
13
+ - **取证**:以订阅目录 `GET /backend-api/codex/models` 为准,并与本机官方 Codex CLI 的权威产物逐字核对——随包的 `codex-rs/models-manager/models.json`、账号级 cache(`~/.codex/models_cache.json`),以及官方真实会话的 rollout。三处一致:**每个模型都声明 `default_reasoning_summary: "none"`、`default_verbosity: "low"`、`support_verbosity: true`**。官方 `client.rs` 的 `build_responses_request` 也正是这么发的:`default_reasoning_summary != None` 才带 `summary`,`default_verbosity` 每轮都参与 `create_text_param_for_request`。
14
+ - **缺口一(省钱)**:`responses-mapper.ts` 在未配置时发 `{ summary: 'auto' }`,而官方默认是 `none`。**推理摘要是计费生成**——模型要先把思考写成摘要,这部分计入输出。一个从未打开该设置的用户,因此每轮都在花官方客户端从不花的那一块。现在:未配置或选「无」一律**省略 `summary` 字段**(与官方 `skip_serializing_if = "Option::is_none"` 同形);显式选择 `auto`/`concise`/`detailed` 仍照发。
15
+ - 顺带修掉一个真实浪费:此前选「无」会发 `summary: 'none'`,那是让后端**先生成再丢弃**——官方表达「不要摘要」的方式是根本不发该字段。
16
+ - **缺口二(体验,方向相反)**:未配置时本插件**整个不发 `text`**,而官方每轮发 `default_verbosity`(`low`)。省略该字段时服务端套用**隐含的 `medium`**,所以一个从未打开该设置的用户拿到的是比官方客户端更啰嗦的回答——这解释了为何「按默认」反而不简洁。现在未配置时按目录发 `low`。
17
+ - **不凭沉默放宽**:新增 `codexCatalogEntryById()`,与 `resolveCodexCatalogEntry()` 分开——后者对未知模型回落到默认条目,那是「给一个合理下限」的正确做法,但**无法区分「该模型声明支持」与「没人说过」**。`text` 只对显式声明 `supportsOutputVerbosity` 的模型发送,未知模型照旧省略,不会强加一个可能被拒收的字段。
18
+ - **测试**:新增 `test/codex-official-defaults.test.ts` 5 条,把官方目录的事实钉住——默认省略摘要、显式选择仍然发送、默认发 `low` 详细程度、GPT-6 全家族都声明了详细程度支持(新增模型漏声明会失败)、未知模型不得凭空得到该字段。已实测**承重**:把 `summary: 'auto'` 改回去,第一条立即以 `expected { effort: 'high', summary: 'auto' } to deeply equal { effort: 'high' }` 失败。既有 `responses-mapper` 13 处断言按官方契约更新(其中 4 处正是编码旧默认值的)。
19
+ - **未在真实订阅账号上做端到端额度对比**:结论来自官方目录/源码/rollout 的逐字核对与本地报文断言,未测量真实会话前后额度曲线。
20
+ - **修复 Command Code 线路新模型没有思考等级(用户报告:`deepseek/deepseek-v4.1-flash-fast` 只有模型名,选不了思考程度)**。
21
+ - **根因**:能力表(`src/host/command-code/model-catalog.ts`)是**手工转抄**官方 CLI 注册表的一份快照,而官方注册表已经扩到 **92 条**、实时 `/provider/v1/models` 也在服务这些 id,本文件的转抄却停在 **74 条**。适配器对表里没有的 id 不是「不知道」而是走保守回落——**纯文本 + 空思考等级**,于是这些真实模型同时**丢掉图片输入**、并让 `resolveModel` 返回的 `reasoning` 整个缺失,模型选择器因此不再渲染 Effort 行。
22
+ - **不是这一个模型的问题**:同一根因造成 **16 个**正在被服务的 id 一起缺档,包括 `gpt-6-sol` / `gpt-6-luna` / `gpt-6.1-sol`、`claude-sonnet-5-5`、`claude-opus-5-5`、`xai/grok-4.7`、`z-ai/glm-5.3-flashx`、`xiaomi/mimo-v2.6-*`、`Qwen/Qwen3.8-Omni-Flash`、`stepfun/Step-5-Preview`、`stealth/space-bunny-alpha`、`inclusionai/ling-3.1-flash:free`、`meituan/LongCat-2.0`;用户报的 `deepseek/deepseek-v4.1-flash-fast` 只是其中一个。另外 4 条已有模型(`deepseek-v4-pro`、`deepseek-v4-flash`、`deepseek-v4-flash-vision-exp`、`deepseek-v4.1-flash`)的等级也少报了一档。
23
+ - **修法**:按官方 CLI 的注册表**重抄整张表**(92 条含 7 条 CLI 隐藏、但本插件不隐藏的免费位;实际服务 85 条,与实时目录逐一核对,context window 完全一致),并**补上此前遗漏的两档**:`z-ai/glm-5.3-flash`、`z-ai/glm-5.3-flashx`、`Qwen/Qwen3.8-27B` 等注册表明写的 `maxTokens` 现在如实落到表里;模型的 `name` 也按 CLI 注册表逐条校正(`gpt-6-astra` 等)。
24
+ - **`off` 不再原样透传**:注册表把「不思考」这一档命名为 `off`,DSH 的词汇是 `none`(Kimi / Claude 线路早就这么写)。现在 `reasoningEffortsFor()` 在**读**的时候把 `off` 翻成 `none`,表本身保持对来源的忠实转抄;新增 `wireReasoningEffort()` 在两个请求构建器里把 `none` **从报文中彻底删掉**——这条线路表达「不思考」的方式是**不发该字段**(官方 CLI 的 `thinkingHook` 对 `off` 正是直接 return),而不是发一个上游不认识的字面量。为此 `COMMAND_CODE_REASONING_EFFORTS` 增加 `none`,设置卡的默认等级下拉多一项「Off」。
25
+ - **顺手堵住一个会让用户 400 的缺口**:设置卡只提供**一条**全线路默认等级,而不同模型的可用档位不同(如 `gpt-5.4-mini` 没有 `xhigh`)。此前这个默认值被无条件写进每一轮请求,**为 A 模型选的档用在 B 模型上会被上游拒收**。现在 `adapter.stream()` 检查当前模型公布的档位,不在其中就退回模型自身默认,而不是把无效值发出去。
26
+ - **测试**:`command-code-routes` 新增「覆盖实时目录的模型」(锁住这次遗漏的 11 个 id,再出现同样漏抄会在这里失败)与「`none` 绝不上线」(`none`/`off`/`null`/`''` 全部不产生字段,`low`/`max` 照常发送);`command-code-adapter` 新增 fast 变体与 GPT-6 兄弟型号的等级断言;`command-code-mapper` 新增「关闭思考时两种协议都不得出现 reasoning 字段」。已核对**承重**:把 `wireReasoningEffort` 的 `none` 分支拿掉后,mapper 用例立即失败。
27
+ - **验证**:`tsc -b --force` 与 test tsconfig 均 0 错误;全量 **1929 passed** / 7 skipped,**0 失败**;`npm run build` 干净,并在**构建产物** `lib/index.js` 上直接跑 `resolveModel('deepseek/deepseek-v4.1-flash-fast')`,确认从「无 `reasoning` 字段」变为 `['none','low','high','max']`。
28
+ - **未在真实订阅账号上端到端复验**:等级表来自官方 CLI 注册表与实时目录的静态核对,未用真实凭据实际发过一轮 `reasoning_effort: 'none'` 请求确认上游接受「省略该字段」这一写法(官方 CLI 如此发送,是当前最强的行为依据)。
29
+
30
+ - **修复 Codex 订阅线路对话每轮 400:上游拒收 `max_output_tokens`**([issue #29](https://github.com/Aa728848/dsh-chatgpt-subscription/issues/29),实测账号 `plus`、模型 `gpt-6-sol` / `gpt-6.1-sol`)。
31
+ - **根因**:`responses-mapper.ts` 的 `buildResponsesPayload()` 在调用方未指定 `maxTokens` 时也会补上 `codexModelMaxTokens(model)`,因此**每一轮对话报文都带 `max_output_tokens`**;而订阅版 Responses 端点对部分账号/模型直接以 `400 {"detail":"Unsupported parameter: max_output_tokens"}` 拒收。这与 [#28](https://github.com/Aa728848/dsh-chatgpt-subscription/issues/28) 的 `/alpha/search` 是**两个不同端点上的同一个错误结论**:当时认定「只有搜索端点拒收该字段,对话端点合法地发送它」,报告者的对照实验推翻了它——只删掉这个字段、账号/模型/代理都不动,对话即恢复。
32
+ - **不是配置问题**:错误文案 `Codex request failed (400): …` 由 `responses-client.ts` 的 `responseError()` 产出(搜索侧是 `Codex subscription search failed (400).`),错误码 `PROVIDER_ERROR`,指向对话链路;报告者在 0.10.15 的打包产物里定位到两个发送点,删除对话侧的那两行并重启 host 后 400 消失。
33
+ - **官方客户端本来就不发这个字段**:Codex CLI 的 `codex-rs/codex-api/src/common.rs` 中 `ResponsesApiRequest` **没有** `max_output_tokens` 字段,`codex-rs/core/src/client.rs` 构建请求时也不赋值;[openai/codex#31181](https://github.com/openai/codex/issues/31181) 记录了同一条 400(自定义 baseURL 走 Responses 时 `@ai-sdk/openai` 会无条件发出该字段)。也就是说,发它是本插件自行加出来的、与 wire 契约不同步的一行。
34
+ - **修法**:`buildResponsesPayload()` **不再写入该字段**(连同 `ResponsesPayload` 上的类型声明一起删除),`codexModelMaxTokens()` 保留但改为「仅进程内使用」并加注释说明。不再用「按模型上限封顶」的方式重引入——被拒收的正是这个请求本身。
35
+ - **保留了什么**:适配器仍上报 `defaultMaxTokens`(`host/model-catalog.ts`),DSH 用它做**本地**输出预留、供 `compaction-basic` 把完成部分计入窗口(harness 的 `reservedCompletionTokens`);这个数字不出进程。截断仍可上报:后端以 `response.incomplete` 收尾,`parseResponsesStream` 映射为 `max-tokens` 结束原因。代价是调用方的 `maxTokens` 不再传给上游,长度由服务端默认值决定——与官方 CLI 行为一致。
36
+ - **测试**:`test/codex-output-cap.test.ts` 重写为**报文契约**用例(沿用 #28 在搜索侧确立的做法:断言整包而不是单个字段的缺席)——「未指定 `maxTokens` 时不发」「显式指定 4096 时也不发」,并保留一条正向断言锁住 `model` / `stream` / `store` / `include` / `input` 仍在,使「删字段」不能靠清空 body 满足。已验证该用例是**承重**的:把 `payload.max_output_tokens = 128_000` 加回后立即以 `expected … to not have property "max_output_tokens"` 失败。
37
+ - **验证**:强制类型检查(`npx tsc -b --force`)与 test tsconfig 均 0 错误;全量 **1923 passed** / 7 skipped,**0 失败**;`npm run build` 干净,产物 `lib/index.js` 中该字段只剩注释;`npm pack --dry-run` 正常。
38
+ - **未在报告者账号上端到端复验**:结论来自报告者的对照实验与本机的报文断言,未用真实订阅凭据发过一轮。
5
39
  - **修复 Codex 线路模型选择器为空(供应商已启动、登录正常,但一个模型都不显示)**(用户报告,账号实测为 `prolite` 套餐)。
6
40
  - **根因**:接入实时目录那次提交(`d821752`,`feat(codex): follow upstream third-party wire`,v0.10.12)让 `listCodexModels` 把订阅目录当成唯一来源,再与用户的 `visibleModelIds` 求交集:`{codex-auto-review} ∩ {gpt-6-astra}` = **空集**,于是选择器一个不剩。
7
41
  - **目录并非空的,是不含 chat 模型**:实测该套餐的 `GET /backend-api/codex/models` 返回 `count=1, slugs=codex-auto-review`——只含账号的 code-review slug。目录「比内置表窄」的设计意图是对的,但它**不能保证窄的那部分与用户的选择有交集**;交集为空时,目录就把用户自己勾选的模型全部删掉了。
@@ -33,7 +67,8 @@
33
67
  - **顺带修掉一个真实的不一致**:`buildClaudeSystemBlocks` 是导出函数且自己写标记,此前固定写裸 `{ type: 'ephemeral' }`,会绕过 TTL(请求构建器事后虽会覆盖,但直接调用该函数的调用方拿到的永远是 5 分钟)。现两处写入用同一个 `cacheControlFor`,并更新了 `claude-mapper` / `claude-adapter` / `claude-routes` / `claude-token-store` 中断言旧标记形态的用例。
34
68
  - **验证**:强制类型检查(`tsc -b --force`)与 test tsconfig 均 0 错误,`npm run build`、`npm pack --dry-run`、`npm ci --dry-run` 通过,全量 **1847 passed** / 7 skipped;失败的 7 条仍是先前已确认与本插件无关的 `claude-model-catalog`(5)、`antigravity-callback-port`(1) 与一条既有用例。
35
69
  - **未在真实订阅账号上端到端验证**。Kimi 订阅端是否接受 `prompt_cache_options` / 顶层 `cache_control`(开放平台文档有,订阅端未实测)与 Claude 1 小时写入的实际命中收益,都需要在真机上确认;第一检查点是发一轮带 1 小时的请求后看 `usage.cache_creation.ephemeral_1h_input_tokens` 是否非零。
36
- - **修复 Codex 线路声明了输出上限却从不发送**。`shared/model-catalog.ts` 为 GPT-6 家族声明了 128K 输出上限,`resolveCodexModel` 也把它作为 `defaultMaxTokens` 报给 DSH,但 `responses-mapper.ts` 构建 payload 时**完全没有 `max_output_tokens`** 字段——目录里没有的模型则回落到 32K 预 GPT-6 默认。
70
+ - ~~**修复 Codex 线路声明了输出上限却从不发送**~~ — **已被 #29 的修复推翻,勿再照此实现**(本条当时的结论是「对话端点合法地发送该字段」,事实并非如此;详见 Unreleased 首条)。留档以说明这行代码的来历与它为什么看起来合理。
71
+ - 原文:`shared/model-catalog.ts` 为 GPT-6 家族声明了 128K 输出上限,`resolveCodexModel` 也把它作为 `defaultMaxTokens` 报给 DSH,但 `responses-mapper.ts` 构建 payload 时**完全没有 `max_output_tokens`** 字段——目录里没有的模型则回落到 32K 预 GPT-6 默认。
37
72
  - **为什么重要**:不带这个字段时由服务端套用自己的默认值,本线路既无法预测也无法上报——某一轮撞上上限看起来就像一次普通的短回答。这与 Claude 线把 `model_context_window_exceeded` 当成正常结束是同一类问题。Codex 走 `store:false` 且每轮全量重发,这一项尤其容易被反复触发。
38
73
  - **修法**:始终发送 `options.maxTokens ?? codexModelMaxTokens(model)`,并在调用方请求更大时用 `Math.min` 封到模型自身上限(与 antigravity mapper 同一道守卫)——超出模型能力的请求会被后端直接拒绝,因此必须向下封而不是原样透传。
39
74
  - **测试**:`test/codex-output-cap.test.ts` 6 条——「始终发送模型上限」(回归锁定)、「调用方要求更小时照发」、「超出上限必须封顶」、「只存在于实时目录的未知模型也带上限」。
package/README.md CHANGED
@@ -61,11 +61,15 @@
61
61
  - **请求带 `openai-beta: responses=experimental`**:
62
62
  - 该订阅后端在 beta 标志下提供,官方 Codex CLI 一直发送这个头;
63
63
  - 缺它时请求面不同:当前后端宽容,但这正是收紧后会变成 400/403 的那一行;
64
+ - **读取参数默认值与官方 Codex 一致**(依据订阅目录 `GET /backend-api/codex/models`,与官方随包的 `codex-rs/models-manager/models.json` 同源):
65
+ - **推理摘要默认不发**:目录里每个模型都声明 `default_reasoning_summary: none`,官方以此为准。此前本插件在未配置时发 `summary: auto`,而摘要属于**计费生成**,等于每一轮都多花一块官方从不花的额度;现在默认省略该字段,用户显式选择 `auto` / `concise` / `detailed` 时照旧发送,选「无」也改为**省略字段**而不是发 `summary: none`(后者是让后端先生成再丢弃)。
66
+ - **输出详细程度默认发目录值 `low`**:官方客户端每轮都发送模型目录里的 `default_verbosity`(当前全部为 `low`)。此前本插件在未配置时**整个不发** `text` 字段,于是服务端套用隐含的 `medium`——一个从未打开过该设置的用户,会拿到比官方客户端更啰嗦、也更贵的回答。现在未配置时按目录发 `low`,显式选择仍以用户为准。
67
+ - 目录里**没有记录**的模型不猜:仅对该表声明了 `supportsOutputVerbosity` 的模型发送 `text`,避免把一个模型可能拒收的字段强加给它;
64
68
  - **多轮续传**,避免每轮重发整个历史:
65
69
  - 每个会话发送稳定的 `prompt_cache_key`,让后端复用提示前缀;
66
70
  - 回传后端在响应头给出的 `x-codex-turn-state`,让它续接该轮;
67
71
  - 后端不再下发该头时立即停止回送——不重放过期值;
68
- - **始终发送 `max_output_tokens`**,按 `min(调用方请求, 模型上限)` 封顶(详见「模型目录」);
72
+ - **对话报文绝不发送 `max_output_tokens`**:订阅版 Responses 端点在部分账号/模型上直接以 `400 Unsupported parameter: max_output_tokens` 拒收该字段([#29](https://github.com/Aa728848/dsh-chatgpt-subscription/issues/29),实测 `gpt-6-sol` / `gpt-6.1-sol`),官方 CLI 的请求结构里也没有这个字段;输出长度由服务端默认值决定,撞上限仍以 `max-tokens` 结束原因上报(详见「模型目录」);
69
73
  - Antigravity(Gemini / Claude)线路同样接受图片输入:DSH 以 `{ type: 'image', attachment }` 下发的粘贴图片会经附件服务读出字节并按 Gemini `inlineData` 发出,读不出的图片降级为一条可见的说明文本而不是被静默丢弃。单次请求的图片 base64 负载超过 12 MiB 时,最旧的图片按上游同款占位文案替换为文本,避免整条请求被体积上限拒绝;
70
74
  - 原样转发 DSH 暴露的工具 schema;命令工具兼容 `pwsh` / `powershell`、`bash`、`sh` 与 `shell`,并按 PowerShell、Bash 或 POSIX sh 注入对应说明;
71
75
  - 429/5xx 由 DSH retry policy 接管;401 只强制刷新并重试一次,支持 `AbortSignal`;
@@ -252,7 +256,7 @@
252
256
  - 模型勾选、思考深度、上下文窗口覆盖与额度在「设置 → 订阅服务 → Claude」标签页中配置,输入框右侧另有额度胶囊(取**剩余最紧的那个窗口**)。
253
257
 
254
258
  ### 设置页
255
- - 展示账号(脱敏 email、套餐、账号 ID 后四位)、连接状态、额度与订阅增强功能开关;
259
+ - 展示账号(脱敏 email、套餐、账号 ID 后四位)、连接状态、额度与订阅增强功能开关;「输出详细程度」「推理摘要」两项的默认值即官方 Codex 客户端的取值;
256
260
  - **偏好落盘位置随 harness 生成**:
257
261
  - 有 `settings.register` 的一代(≤0.1.6)仍写进 harness 的设置文档;
258
262
  - 0.1.7 起该 API 被 `SettingsForms` 取代,偏好改由插件自己持久化到 `<dshHome>/storages/dsh-chatgpt-subscription-preferences.json`(0600、原子写;读取失败或校验不过就回落默认值);
@@ -260,7 +264,7 @@
260
264
  - 子代理的模型与思考深度沿用 DSH 自身设置:**设置 → Subagent** 卡片授权 Agent 可以为子代理挑选的模型(来自 DSH 已接入的全部 Provider,包含本插件的 Codex / Antigravity),新 Agent 的默认路由由 DSH 的 `agent-default-model` 设置提供;
261
265
  - 最大嵌套深度不在本插件设置内,由 DSH 侧决定:0.1.5 及以前是 preset 中 `tool-subagent` 行的 `maxDepth`(默认 3),0.1.6 起改由 `subagent` 服务的设置项提供(默认 1);`provider-managed` 表示把预算交给进程外提供方;
262
266
  - GPT-6 系列(6 Astra / 6 Sol / 6 Luna)默认使用 384K 有效上下文,可配置最高 872K;5.6 Sol / Terra / Luna 保持 272K,最高 1M,用于 DSH 压缩与溢出判断;其他模型保持目录声明值;
263
- - 单次输出上限按模型区分:GPT-6 系列为 128K(官方对 6 Astra / 6 Sol / 6 Luna 均标 128K),更早的模型保持 32768。调用方未显式指定时按模型上限发送;显式指定时按 `min(请求值, 模型上限)` 封顶——超出模型能力的请求会被上游直接拒绝,因此必须向下封而不是原样透传。**`max_output_tokens` 始终出现在请求中**:不发送时由上游套用自己的默认值,本插件既无法预测也无法上报,某一轮撞上上限会看起来像一次普通的短回答。
267
+ - 单次输出上限按模型区分:GPT-6 系列为 128K(官方对 6 Astra / 6 Sol / 6 Luna 均标 128K),更早的模型保持 32768。**这个数字只在本插件进程内使用,不会写进请求**:订阅版 Responses 端点会以 `400 Unsupported parameter: max_output_tokens` 拒收该参数([#29](https://github.com/Aa728848/dsh-chatgpt-subscription/issues/29)),官方 Codex CLI 的 `ResponsesApiRequest` 里同样没有这个字段。它的实际用途是作为 DSH 侧的输出预留量(`defaultMaxTokens`),供压缩判定把完成部分计入上下文窗口;请求本身交给服务端决定长度。撞上服务端上限时该轮仍以 `max-tokens` 结束原因呈现(后端以 `response.incomplete` 收尾)。
264
268
  - 可访问的进度条、窄窗口/200% 缩放布局、深浅主题与 reduced-motion。
265
269
 
266
270
  ## 模型目录
@@ -764,7 +768,7 @@ npm pack --dry-run
764
768
  | --- | --- |
765
769
  | 1455 端口占用 | 结束旧登录任务或占用该端口的进程后重试;插件卸载会关闭 listener |
766
770
  | 模型选择器里没有新发布的模型 | 该模型必须出现在 `/backend-api/codex/models` 返回的列表里(该列表是「这个账号能调什么」的权威)。若后端已发布而选择器没有,点设置页的**强制刷新目录**;仍不出现则说明当前套餐/workspace 无权调用 |
767
- | 回答在中途被截断 | 可能是撞到输出上限。插件始终发送 `max_output_tokens`(按模型上限或调用方请求的较小值),被截断会以 `max-tokens` 结束原因呈现;可用**增强功能**里的上下文覆盖或换模型调整 |
771
+ | 回答在中途被截断 | 可能是撞到服务端的输出上限。对话报文不发送 `max_output_tokens`(该参数会被上游 400 拒收,见「模型目录」),长度由服务端决定;被截断会以 `max-tokens` 结束原因呈现,可用**增强功能**里的上下文覆盖或换模型调整 |
768
772
  | 断网后首次打开设置页很慢 | 目录有本地快照兜底,重启后第一次渲染不需要网络;若仍慢说明快照不可写(home 只读),此时不影响功能 |
769
773
  | 登录后仍是 401 | 刷新 token;若刷新 token 已失效,注销并重新登录,不会循环请求 |
770
774
  | 额度显示旧数据 | 设置页会保留最后成功值;等待 15 秒节流窗口后手动刷新 |