@eddyskywalker/dsh-chatgpt-subscription 0.26.1 → 0.27.0

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 (83) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +57 -0
  3. package/lib/client.js +2176 -116
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +2112 -93
  6. package/lib/types/client/index.d.ts +2 -0
  7. package/lib/types/client/index.d.ts.map +1 -1
  8. package/lib/types/client/progress-updates/contracts.d.ts +125 -0
  9. package/lib/types/client/progress-updates/contracts.d.ts.map +1 -0
  10. package/lib/types/client/progress-updates/guide-artwork.d.ts +28 -0
  11. package/lib/types/client/progress-updates/guide-artwork.d.ts.map +1 -0
  12. package/lib/types/client/progress-updates/host-source.d.ts +128 -0
  13. package/lib/types/client/progress-updates/host-source.d.ts.map +1 -0
  14. package/lib/types/client/progress-updates/index.d.ts +91 -0
  15. package/lib/types/client/progress-updates/index.d.ts.map +1 -0
  16. package/lib/types/client/progress-updates/locales.d.ts +127 -0
  17. package/lib/types/client/progress-updates/locales.d.ts.map +1 -0
  18. package/lib/types/client/progress-updates/markdown-lite.d.ts +60 -0
  19. package/lib/types/client/progress-updates/markdown-lite.d.ts.map +1 -0
  20. package/lib/types/client/progress-updates/progress-row.d.ts +87 -0
  21. package/lib/types/client/progress-updates/progress-row.d.ts.map +1 -0
  22. package/lib/types/client/progress-updates/settings-binding.d.ts +71 -0
  23. package/lib/types/client/progress-updates/settings-binding.d.ts.map +1 -0
  24. package/lib/types/client/progress-updates/settings-section.d.ts +57 -0
  25. package/lib/types/client/progress-updates/settings-section.d.ts.map +1 -0
  26. package/lib/types/client/progress-updates/styles.d.ts +34 -0
  27. package/lib/types/client/progress-updates/styles.d.ts.map +1 -0
  28. package/lib/types/client/progress-updates/tool-name.d.ts +14 -0
  29. package/lib/types/client/progress-updates/tool-name.d.ts.map +1 -0
  30. package/lib/types/client/progress-updates/updates-panel.d.ts +113 -0
  31. package/lib/types/client/progress-updates/updates-panel.d.ts.map +1 -0
  32. package/lib/types/client/step-code/locales.d.ts +2 -2
  33. package/lib/types/client/workbuddy/WorkBuddySection.d.ts.map +1 -1
  34. package/lib/types/client/workbuddy/locales.d.ts +108 -0
  35. package/lib/types/client/workbuddy/locales.d.ts.map +1 -1
  36. package/lib/types/client/workbuddy/styles.d.ts.map +1 -1
  37. package/lib/types/client/workbuddy/useWorkBuddySection.d.ts +9 -1
  38. package/lib/types/client/workbuddy/useWorkBuddySection.d.ts.map +1 -1
  39. package/lib/types/host/progress-updates/index.d.ts +90 -0
  40. package/lib/types/host/progress-updates/index.d.ts.map +1 -0
  41. package/lib/types/host/progress-updates/nudge.d.ts +91 -0
  42. package/lib/types/host/progress-updates/nudge.d.ts.map +1 -0
  43. package/lib/types/host/progress-updates/prompt.d.ts +34 -0
  44. package/lib/types/host/progress-updates/prompt.d.ts.map +1 -0
  45. package/lib/types/host/progress-updates/routes.d.ts +39 -0
  46. package/lib/types/host/progress-updates/routes.d.ts.map +1 -0
  47. package/lib/types/host/progress-updates/store.d.ts +74 -0
  48. package/lib/types/host/progress-updates/store.d.ts.map +1 -0
  49. package/lib/types/host/progress-updates/tool.d.ts +42 -0
  50. package/lib/types/host/progress-updates/tool.d.ts.map +1 -0
  51. package/lib/types/host/reasoning-collapse-guard/index.d.ts +5 -0
  52. package/lib/types/host/reasoning-collapse-guard/index.d.ts.map +1 -1
  53. package/lib/types/host/web-provider-reconciler.d.ts +34 -0
  54. package/lib/types/host/web-provider-reconciler.d.ts.map +1 -0
  55. package/lib/types/host/workbuddy/account-pool.d.ts +32 -1
  56. package/lib/types/host/workbuddy/account-pool.d.ts.map +1 -1
  57. package/lib/types/host/workbuddy/adapter.d.ts +32 -0
  58. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  59. package/lib/types/host/workbuddy/atrest.d.ts +98 -0
  60. package/lib/types/host/workbuddy/atrest.d.ts.map +1 -0
  61. package/lib/types/host/workbuddy/checkin.d.ts +16 -0
  62. package/lib/types/host/workbuddy/checkin.d.ts.map +1 -1
  63. package/lib/types/host/workbuddy/client.d.ts +9 -0
  64. package/lib/types/host/workbuddy/client.d.ts.map +1 -1
  65. package/lib/types/host/workbuddy/dsml.d.ts +55 -0
  66. package/lib/types/host/workbuddy/dsml.d.ts.map +1 -0
  67. package/lib/types/host/workbuddy/guardrails.d.ts +111 -0
  68. package/lib/types/host/workbuddy/guardrails.d.ts.map +1 -0
  69. package/lib/types/host/workbuddy/mapper.d.ts +11 -0
  70. package/lib/types/host/workbuddy/mapper.d.ts.map +1 -1
  71. package/lib/types/host/workbuddy/model-catalog.d.ts +8 -1
  72. package/lib/types/host/workbuddy/model-catalog.d.ts.map +1 -1
  73. package/lib/types/host/workbuddy/outbound-identity.d.ts +66 -0
  74. package/lib/types/host/workbuddy/outbound-identity.d.ts.map +1 -0
  75. package/lib/types/host/workbuddy/routes.d.ts +8 -1
  76. package/lib/types/host/workbuddy/routes.d.ts.map +1 -1
  77. package/lib/types/host/workbuddy/token-store.d.ts +93 -0
  78. package/lib/types/host/workbuddy/token-store.d.ts.map +1 -1
  79. package/lib/types/index.d.ts +63 -5
  80. package/lib/types/index.d.ts.map +1 -1
  81. package/lib/types/shared/workbuddy-contracts.d.ts +54 -2
  82. package/lib/types/shared/workbuddy-contracts.d.ts.map +1 -1
  83. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.27.0 - 2026-10-18
6
+ - **【进展更新】agent 在多步任务中主动汇报,对话流里一行一条,右侧栏可回看**
7
+ - **是什么**:新增 in-tree 子模块 `src/host/progress-updates/` + `src/client/progress-updates/`,复刻 Kimi Code 的「进展更新」。agent 通过一个**不结束回合**的工具 `progress_update(title?, message)` 主动汇报,对话流里渲染成一行(状态点 + 标题 + 状态词,正文点开看),右侧栏有一个总览面板。
8
+ - **宿主侧**:工具注册始终进行(工具清单不能在会话中途变化),开关关闭时 `execute` 返回 `{displayed:false}` 而不是抛错;系统提示词用 `systemPrompt.section({ text: () => enabled ? … : '' })` 的**函数形式**,所以设置改了立刻生效、不需要新开会话;`tools/post-execute` 上做 8 轮催促——**按会话维度计数**(subagent 沿 `header.parentSession` 归并到顶层祖先,整棵委派树共用一个计数器,修正了「主 agent 与子 agent 各记一份、谁都没到阈值」的既有瑕疵)、**按模型步去重**(读 `sessionProjections` 的 `turnBoundary.lastStepStartSeq`,一次并行发多个工具只算一轮),达到阈值注入一条 `additionalContexts` 提醒。
9
+ - **可选服务一律走 `ctx.get()`**:`tools` / `systemPrompt` / `webServer` / `sessions` / `sessionProjections` 全部在**调用时**读取,缺任何一个只退化成更弱的实现(不注册工具 / 无提示词 / 无路由 / 按工具结果计数),**不抛错、不降级整个插件**。`inject` 数组没有新增任何一项。
10
+ - **取数通道**:`GET /api/dsh-progress-updates/updates?session=<id>` → `{ updates: ProgressUpdate[] }`,带 `cache-control: no-store`,loopback 信任栅栏(socket + Host 头 + `sec-fetch-site`)。浏览器半边是独立运行时,拿不到宿主进程的任何对象,所以只能走同源 HTTP —— 轮询客户端在 `src/client/progress-updates/host-source.ts`,无订阅者时不发任何请求。
11
+ - **设置**:并入本插件已有的 `Config`,两个字段 `progressUpdates`(默认 false)与 `progressUpdatesNudgeThreshold`(默认 8,1–50),都是 `volatile()`,改完即时生效。设置页是**独立一格**(`settings.section`,id `progress-updates`,order 150),不与订阅服务那格(`subscription-hub`,45)合并。
12
+ - **右侧栏入口**:`sidebarRightTabs.register` 声明页面型页签,并带一个 `guide` 条目与自绘的 36×36 彩色标记——页签类型只是声明,**guide 条目才是用户看得见、点得到的入口**。
13
+ - **正文渲染**:`markdown-lite.tsx`(零依赖)渲染段落、无序/有序列表、行内代码、粗体与最多三级标题;段落、列表、行内标记都是真实元素,不经 `dangerouslySetInnerHTML`,因此没有注入面。平台 `MarkdownText` 是第一选择但被排除(见提交信息:它的 lib 顶层静态 import `.module.css`,Node 的 ESM 加载器先于任何 vite 插件与 alias 生效)。
14
+ - **验证**:`npm run typecheck` 0 错误;全量 **3985 passed | 7 skipped**;`npm run build` 通过。四条回归守卫各自做过变异测试(不插值 / 展开改回单选 / 正文改回纯文本 / 去掉 guide 条目,各自都会让对应用例变红)。
15
+
16
+ - **[推理塌缩守卫] 熔断器默认关闭:功能与实现全部保留,只把「默认接电」改成「部署显式接电」**
17
+ - **现状**:本线的「熔断器」即推理塌缩守卫(`src/host/reasoning-collapse-guard/index.ts`),它订阅 `llm/stream` 瀑布,在「n-gram 重复度」与「语义复现」双信号连续命中时切断本轮流并排一条续跑。该守卫已无需在生产轮次里生效。
18
+ - **改法(只动接线,不动实现)**:`src/index.ts` 的 `reasoningCollapseGuard` 配置默认值由 `{}` 改为 `false`(`Config` 与 `apply()` 的注释同步改写)。默认配置下 `if (pluginConfig.reasoningCollapseGuard !== false)` 直接跳过,守卫的 `ctx.effect` 注册、`llm/stream` 订阅、per-turn 熔断簿记与续跑排队**全部不装配**,运行时零开销、零副作用。
19
+ - **保留下来的**:`installReasoningCollapseGuard` 导出、全部调参与 fail-loud 校验(`resolveOptions`、`threshold`/`semantic*`/`maxBreaksPerTurn` 等)、`test/reasoning-collapse-guard.test.ts`(80 例)与 `test/reasoning-collapse-guard-registry.test.ts`(注册表读取边界)**一律未动**;部署要重新启用只需在插件配置里写 `"reasoningCollapseGuard": {}`(用出厂默认)或写入调参对象,`false` 保持关闭。
20
+ - **新增回归**:`test/circuit-breaker-default.test.ts`(3 例)钉住两半——`Config({}).reasoningCollapseGuard === false`、写入对象/ `false` 仍被原样接受、`installReasoningCollapseGuard` 仍可导入且无事件总线时返回 `undefined` 而不抛错。
21
+ - **验证**:`npm run typecheck` 0 错误;全量 **233 passed | 1 skipped(234 文件)、3821 passed | 7 skipped、0 failed**;**承重已双向检查**——把默认值临时改回 `{}`,新用例立即 1 failed,恢复后全绿。
22
+ - **升级提示**:默认安装的 Host 升级后不再有任何塌缩熔断与随之的续跑;此前依赖「死循环自动刹车」的部署需在插件配置里显式写回 `"reasoningCollapseGuard": {}`。运行中的 Host 需重启(或重载该插件条目)才会加载新 bundle。
23
+ - **文档(“将来需要时再开”的落点)**:README 新增独立章节 **「推理塌缩守卫(熔断,默认关闭)」**——两个信号各测什么、双信号连续命中才切断且只排一条续跑、关闭后哪四样东西不再发生(不注册 `llm/stream` 订阅 / 不建每回合熔断簿记 / 不排续跑 / 零运行时开销)、以及**将来重新开启的具体做法**(`cordis.patch.yml` 里写 `reasoningCollapseGuard: {}` 或调参对象,取值表:缺省=`false` 关闭、`{}`=出厂默认开启、对象=调参、`false`=显式关闭),并记下守卫与 `noAnswerResume` 在 `llm/stream` 外层的共用边界(重新开守卫前需复查);「子代理模型授权」的配置项表下补一条指向该章节的说明;守卫源码头部与 §Config 注释同步标注默认关闭。
24
+
25
+ - **[Web 抓取] 选择退回 DSH 自带 provider 后再无触发点自愈:整条抓取线路静默失效(本机实证)**
26
+ - **现象**:本机 `web_fetch` 对任何域名都报 `URL hostname "…" resolves to a non-public IP address`(`WEB_BLOCKED_URL`),而设置页显示搜索来源已是「ChatGPT(代理隧道)」、自定义代理 `http://127.0.0.1:7890` 可用。
27
+ - **本机实证**:`GET /api/dsh-chatgpt-subscription/status` 读到 `preferences.searchProvider = "codex"`、`activeProxy = "http://127.0.0.1:7890"`,而 `switcher = { state: "applied", configuredSearchProvider: "deepseek-official", configuredFetchProvider: "http" }` —— `web` 条目仍是 DSH 默认值。报错文案同时指认服务方:对 IP 字面量 `127.0.0.1` 得到的是内置 provider 的措辞(`resolves to a non-public IP address`,见 `web-fetch-http/src/network.ts`),本插件对字面量用的是 `is not a public IP address`(`fetch-address-policy.ts`)。
28
+ - **根因(两处,都是「没人再问一次」)**:① `applyWebProviders` 可能在 `preferences.hydrate()` 落盘之前就跑完,此时读到的默认值(`dsh` + 无代理)算出的目标恰好等于 `web` 条目自带默认值,`applySelection` 的 `configured && applied` 提前返回、写 `state='applied'`,一个字节都没写,之后同样没有事件再触发;② 即使选择写进去了,它只存在于 loader 条目的运行期 config,后续一次组合把该 config 改回默认值时,同样没有任何事件通知本插件。
29
+ - **改法**:`applyWebProviders` 先 `await preferences.hydrate()` 再读 `preferences.status()`(不再采信调用方传入的旧快照);新增 `src/host/web-provider-reconciler.ts`,每 30s 做一次干对账——无漂移时 `select()` 直接返回、不重启任何条目,有漂移才把选择写回,并在插件 disposer 里停表。
30
+ - **验证**:`npm run typecheck` 0 错误;`npm run build` 通过;全量 **232 passed | 1 skipped(233 文件)、3818 passed | 7 skipped、0 failed**(基线 3813,新增 5 例:对账定时器 4 例 + 条目 config 被外部改写后自愈 1 例)。**运行时双向验证**:修复前 `web_fetch` 全部被拒;用插件接口把搜索来源切到 `dsh` 再切回 `codex` 触发一次真实应用后,`configuredFetchProvider` 变为 `codex-subscription`,`example.com` / npm registry / `deepseek.com/harness` 均 200,`web_search` 正常返回来源。
31
+ - **升级提示**:运行中的 Host 需重启(或重载该插件条目)才会加载新 bundle;重启前若仍被拒抓,可在设置页把「搜索来源」切到 DSH 默认再切回 ChatGPT 手动触发一次。
32
+
5
33
  ## 0.26.1 - 2026-10-17
6
34
  - **[WorkBuddy] 一次上游 401 把整个号池写成「需要重新登录」且永不恢复:线路跑着跑着忽然全部国区账号要重登**
7
35
  - **现象**:运行中的一轮突然失败,报 `WorkBuddy(CodeBuddy 订阅) rejected the stored credential (401). Sign in again with the CodeBuddy desktop client.`;随后设置卡片里**每一个**国区账号都显示「需要重新登录」,只有重新登录(重新加号)才能恢复。
package/README.md CHANGED
@@ -12,6 +12,7 @@
12
12
  - [环境要求](#环境要求)
13
13
  - [安装](#安装)
14
14
  - [使用](#使用)
15
+ - [推理塌缩守卫(熔断,默认关闭)](#推理塌缩守卫熔断默认关闭)
15
16
  - [Command Code 线路](#command-code-线路)
16
17
  - [WorkBuddy 线路](#workbuddy-线路)
17
18
  - [Claude(订阅)线路](#claude订阅线路)
@@ -547,6 +548,8 @@ DSH 设置页的「Subagent」卡片会把勾选的模型写成会话级的允
547
548
  | `subagentModelInheritTools` | `['subagent_fork', 'spawn_teammate']` | 按设计继承调用者路由的委派工具(校验实际继承到的路由);设 `[]` 关闭 |
548
549
  | `subagentModelScope` | `session` | `session` 只约束记录了允许列表的会话;`preference` 额外用当前设置卡列表约束未记录的会话 |
549
550
 
551
+ > 同一份插件行 `config` 里还有推理塌缩守卫的开关 `reasoningCollapseGuard`——**默认 `false`(关闭)**,功能保留、将来需要时按[推理塌缩守卫(熔断,默认关闭)](#推理塌缩守卫熔断默认关闭)一节显式打开。
552
+
550
553
  改动只在设置卡片里保存过的勾选生效:设置改动只影响之后新建的会话(DSH 的会话快照语义),已运行的会话继续使用它自己记录的那份列表。
551
554
 
552
555
  > 升级提示:从 0.3.2 起,带有允许列表的会话里**任何**未写明 `provider` + `model` 的委派都会被拒绝(此前只有写明且不在列表内的路由会被拒绝)。这是有意的行为变更——它消除了「子代理悄悄继承主代理模型」的漏洞;把 `subagentModelAuthorization` 设为 `false` 可回到 DSH 原始行为。
@@ -564,6 +567,60 @@ DSH 设置页的「Subagent」卡片会把勾选的模型写成会话级的允
564
567
 
565
568
  **区域**:默认使用中国大陆主机(`auth.kimi.com` / `api.kimi.com`)。国际账号可设置 `DSH_KIMI_CODE_OAUTH_HOST=https://auth.kimi.ai` 与 `DSH_KIMI_CODE_BASE_URL=https://api.kimi.ai/coding` 后重新登录;环境变量同时会钉住区域,设置页会显示当前解析到的主机。
566
569
 
570
+ ## 推理塌缩守卫(熔断,默认关闭)
571
+
572
+ 本线的“熔断器”就是**推理塌缩守卫**(`src/host/reasoning-collapse-guard/index.ts`)。一个长推理流可能退化成复读——反复绕过同一小撮短语、既不调工具也不收尾,一直到输出上限把这一轮截断(曾经有一次会话就这样烧掉 128,000 输出 token 并返回空答案)。守卫订阅 `llm/stream` 瀑布,对**尾部推理窗口**同时算两个信号:
573
+
574
+ - **字面重复度**:n-gram 唯一性,健康推理接近 0,退化流接近 1;
575
+ - **语义复现度**:每条句子有多强地重复了 `semanticLag` 句之前已经说过的内容——用来抓“换着词说同一件事”,这类流的字面分只有 0.48,永远碰不到 0.85 的阈值。
576
+
577
+ 两个信号必须在**同一个窗口同时越线**,并且连续 `semanticConfirmations` 个窗口都如此,守卫才会切断本轮流;切掉之后它只做一件事:在 Agent 空闲时 steer 一条续跑,让这一轮在新的步骤上跑完。单个信号或单个异常窗口只记日志、放行——**误杀一段健康回答的代价比放过一次失控更大**。
578
+
579
+ **现状:默认关闭。** 这个熔断在生产轮次里已经没有需要,所以本线不再默认接电;功能、实现与全部测试都原样保留,等将来需要时再打开。
580
+
581
+ | 现象 | 关闭后 |
582
+ |---|---|
583
+ | `llm/stream` 订阅 | 不注册(守卫连 `ctx.effect` 都不装) |
584
+ | 每回合的熔断簿记 | 不建立 |
585
+ | 切断后那条续跑 | 不排队 |
586
+ | 运行时开销 | 零:默认配置下这段代码根本不会进入执行路径 |
587
+
588
+ ### 将来需要时怎么打开
589
+
590
+ 守卫的开关是插件行 `config` 里的 `reasoningCollapseGuard`,写在 profile 的 `cordis.patch.yml`(与「抓取模式与上限」同一位置,**重载插件或重启 DSH 后生效**):
591
+
592
+ ```yaml
593
+ - id: dsh-chatgpt-subscription
594
+ config:
595
+ reasoningCollapseGuard: {} # 空对象 = 用出厂默认值把熔断接回来
596
+ ```
597
+
598
+ 想调参就在这个对象里写字段;省略的字段取出厂默认值:
599
+
600
+ ```yaml
601
+ - id: dsh-chatgpt-subscription
602
+ config:
603
+ reasoningCollapseGuard:
604
+ threshold: 0.85 # 字面重复度阈值(默认 0.85)
605
+ windowChars: 4096 # 每次参与评分的尾部推理字符数(默认 4096)
606
+ maxBreaksPerTurn: 3 # 单回合最多切断几次(默认 3)
607
+ cooldownMs: 30000 # 两次切断的最小间隔毫秒(默认 30000)
608
+ semanticThreshold: 0.35 # 语义复现度阈值(默认 0.35)
609
+ semanticConfirmations: 3 # 双信号需连续命中的窗口数(默认 3)
610
+ includeModels: [gpt-6.1-sol] # 只看这些模型;空数组 = 看全部(默认 [])
611
+ ```
612
+
613
+ | 取值 | 含义 |
614
+ |---|---|
615
+ | 不写(缺省) | **关闭**——2026-10 起的出厂默认 |
616
+ | `{}` | 打开,全部取出厂默认值 |
617
+ | 对象(含调参) | 打开,按对象覆盖默认值;数字由守卫自己的 fail-loud 校验,非法值会让插件加载失败而不是被静默忽略 |
618
+ | `false` | 显式关闭(与缺省等价,写出来更自明) |
619
+
620
+ > **将来重新开启前先验证一件事**:守卫与续跑队列共用 `llm/stream` 的**外层**位置,开启后它在切断时不会给出 finish chunk,因此 `noAnswerResume`(无答案续跑,默认仍开启)在那种被放弃的流上不结算、也不消耗预算——这条约束在 0.26.0 的续跑预算修复里已经落实并有回归用例(`test/no-answer-resume.test.ts`)。若将来改了守卫的切断方式,需要同时复查这条边界。
621
+
622
+ **升级提示**:默认安装的 Host 升级后不再有任何塌缩熔断与随之的续跑;依赖“死循环自动刹车”的部署按上面的 YAML 显式写回即可。新增回归用例 `test/circuit-breaker-default.test.ts` 钉住了“默认必须关闭”和“打开后仍可用”两半。
623
+
567
624
  ## Command Code 线路
568
625
 
569
626
  插件注册 `command-code` Provider,对接 Command Code 的两套接口: