dsh-router-core 0.4.7 → 0.4.8

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 (53) hide show
  1. package/README.md +9 -69
  2. package/cordis.patch.yml +2 -7
  3. package/docs/ext.md +3 -17
  4. package/lib/client-registry.js +50 -565
  5. package/lib/client.js +50 -565
  6. package/lib/ext-prompt/index.js +20 -15
  7. package/lib/index.js +0 -419
  8. package/lib/types/ext/contract.d.ts +1 -1
  9. package/lib/types/ext-prompt/content.d.ts +11 -0
  10. package/lib/types/ext-prompt/index.d.ts +7 -9
  11. package/lib/types/ext-prompt/mount.d.ts +2 -2
  12. package/lib/types/ext-prompt/plugin.d.ts +3 -5
  13. package/lib/types/suppliers/registry.d.ts +0 -1
  14. package/package.json +1 -10
  15. package/src/client/ExtDetail.tsx +1 -13
  16. package/src/client/group-controls.test.ts +1 -1
  17. package/src/client/group-controls.ts +1 -1
  18. package/src/client/index.tsx +0 -17
  19. package/src/client/router-components.test.ts +1 -1
  20. package/src/client/router.css +3 -354
  21. package/src/ext/contract.ts +1 -1
  22. package/src/ext-prompt/content.ts +17 -12
  23. package/src/ext-prompt/ext-prompt.test.ts +3 -3
  24. package/src/ext-prompt/index.ts +7 -9
  25. package/src/ext-prompt/mount.ts +2 -2
  26. package/src/ext-prompt/plugin.ts +3 -5
  27. package/src/router/index.ts +2 -3
  28. package/src/router/models-cache.test.ts +5 -6
  29. package/src/router/supplier-switch.test.ts +1 -1
  30. package/src/suppliers/registry.ts +0 -71
  31. package/lib/contract-D4BWZ7Xe.js +0 -13
  32. package/lib/ext-test/index.js +0 -36
  33. package/lib/ext-test/locale/en.json +0 -6
  34. package/lib/ext-test/locale/zh.json +0 -6
  35. package/lib/ext-test/package.json +0 -5
  36. package/lib/types/ext-test/index.d.ts +0 -21
  37. package/lib/types/ext-test/plugin.d.ts +0 -23
  38. package/lib/types/suppliers/probe.d.ts +0 -160
  39. package/src/client/ExtTestPanel.tsx +0 -392
  40. package/src/client/comp-button-scope.test.ts +0 -58
  41. package/src/client/comp-panel-layout.test.ts +0 -58
  42. package/src/client/ext-panels.test.ts +0 -44
  43. package/src/client/ext-panels.ts +0 -49
  44. package/src/client/model-choice.test.ts +0 -41
  45. package/src/client/model-choice.ts +0 -37
  46. package/src/ext-test/ext-test.test.ts +0 -60
  47. package/src/ext-test/index.ts +0 -35
  48. package/src/ext-test/locale/en.json +0 -6
  49. package/src/ext-test/locale/zh.json +0 -6
  50. package/src/ext-test/plugin.ts +0 -34
  51. package/src/ext-test/row.json +0 -5
  52. package/src/suppliers/probe.test.ts +0 -266
  53. package/src/suppliers/probe.ts +0 -475
package/README.md CHANGED
@@ -119,7 +119,7 @@ team 测试就是多个会话交错发请求。dsh-router 原生适配这个场
119
119
  第二处入口是**设置 → 插件 → dsh-router-core 的详情页**,那里分两层:
120
120
 
121
121
  - 宿主的原生**「包含的组件」**列 core 自己 patch 里声明的**行**:core 本体、三个
122
- 内置供应商、插件自检这个内置扩展。每行一个宿主管的开关,关一行 = loader 不
122
+ 内置供应商、分层提示词这个内置扩展。每行一个宿主管的开关,关一行 = loader 不
123
123
  import 它 = 它压根没注册。
124
124
  - 原生列表**下面**是本插件自绘的**「路由组件」**一节,列**外部供应商插件**与
125
125
  **扩展插件**,两组都带开关。
@@ -291,55 +291,6 @@ Anthropic 的工具调用(非流式 `tool_use` 与流式 `content_block_start` +
291
291
  把它开回来。开关 UI 在**设置 → 插件 → dsh-router-core 详情页**下面的「路由组件」一节
292
292
  (「供应商」组 + 「扩展」组)。
293
293
 
294
- ## 插件自检(内置扩展 `dsh-router-ext-test`)
295
-
296
- 随核心分发的内置扩展,提供两块自检面板。它**不挂任何监听、不改写任何命令** ——
297
- 与 RTK 那类扩展的区别只在于它只提供面板。
298
-
299
- 1. **连接测试**:选**供应商 / 模型 / 连接**,跑一次真实的访问测试。
300
- 2. **契约体检**:选一个**外部供应商插件**,逐个契约成员报告「实现了吗 / 实跑通了吗 /
301
- 为什么没跑」。
302
-
303
- 它与三个内置供应商走同一套管道:是 `cordis.patch.yml` 里的一个**行**(子路径模块
304
- `dsh-router-core/ext-test`),因此在插件页原生「包含的组件」里占一行、开关由宿主管,
305
- 且**默认关闭**。行关闭时 loader 根本不 import 这个模块,扩展就不在 `router.ext` 表里 ——
306
- 「打开那一行才出现这张卡片」是天然的,不需要额外的状态位。
307
-
308
- 面板入口**只有一处**:设置 → 路由 → 扩展 → 点开「插件自检」。插件页那一行不挂详情页,
309
- 它只负责开关(理由见 [扩展插件](#扩展插件routerext) 一节)。
310
-
311
- 测试走核心已有的 `POST /suppliers/:id/models/test`,与面板「供应商」详情里的「测试」
312
- 按钮**同一条真实路径**(账号遍历 + chatOnce)。区别只在可以**钉死连接**:留空则由账号池
313
- 任选可用号(与那个按钮同义);指定连接则只测它、**失败不回退到别的号** —— 否则
314
- 「测这个连接」测出来的是另一个号的结果,诊断就成了假话。
315
-
316
- 面板的模型下拉**只列可用模型**:那个端点给的是全部模型(含用户在供应商详情里停用的),
317
- 把停用的也列出来,用户会挑一个自己明明关掉的模型去测。列表为空时还区分「一个模型都
318
- 没有」(该去拉取)与「全被停用」(该去开启)—— 共用一句「没有模型」会把用户往错的方向指。
319
-
320
- ### 契约体检:报告,不是代替你操作
321
-
322
- `POST /router/api/suppliers/:id/probe` 逐个成员给状态:`ok`(实现了且实跑通)/
323
- `fail`(必填成员缺失,或实跑抛错)/ `absent`(可选成员没实现)/ `skipped`(实现了但**故意
324
- 不跑**)。
325
-
326
- **有副作用的一律不自动执行**,只标出它实现了并说明为什么:
327
-
328
- | 成员 | 为什么不给自动跑 |
329
- | --- | --- |
330
- | `dispose` | 调用它就是把这个供应商卸载掉 |
331
- | `addApiKey` / `removeLink` | 写/删凭证 |
332
- | `generateLoginUrl` | 可能直接触发设备码 / OAuth 登录流 |
333
- | `completeLogin` | 需要一个真实回调 URL,空调没有意义 |
334
- | `checkinNow` | 替这个连接真的去签到 |
335
- | `chatOnce` | 会真发一次请求(消耗额度)——用上面的「跑一次访问测试」单独测 |
336
-
337
- 体检是给眼睛看的,不是给手用的:要触发上面这些,去供应商详情里点对应的按钮。
338
-
339
- 清单与契约**必须一起长**:`src/suppliers/probe.ts` 的成员表有一条判据直接解析
340
- `contract.ts` 源码里的 `SupplierModule` 成员名并断言全覆盖(编译期抓不到这种「两份
341
- 清单」),所以契约新增成员而体检漏检会当场红。
342
-
343
294
  ## 扩展插件(`router.ext`)
344
295
 
345
296
  > 完整契约、注册方式、自检与降级约定见 [`docs/ext.md`](docs/ext.md)。
@@ -372,17 +323,6 @@ Anthropic 的工具调用(非流式 `tool_use` 与流式 `content_block_start` +
372
323
  (`PATCH /router/api/ext`)。开启时会**自检**:`getState().ready === false` 的拒绝开启
373
324
  (API 409),那一面的开关禁用并显示原因。
374
325
 
375
- ### 扩展可以自带详情面板
376
-
377
- 扩展详情页原本是一张写死的只读页(名字、id、状态、一段说明),扩展自己想放的交互
378
- (要选的模型、要跑的测试、要看的诊断)没地方放。客户端因此有一张按**扩展 id** 索引的
379
- 面板注册表(`src/client/ext-panels.ts` 的 `registerExtPanel`):登记了就用你的组件渲染
380
- 整个内容区,没登记才落回通用只读页。`插件自检` 就是这么用的。
381
-
382
- ⚠️ 这张注册表目前只在 dsh-router 自己的 client bundle 内,**外部插件包还引不到** ——
383
- `dsh-router-core/client` 是整个入口闭包、不导出它。要让外部插件也能自带面板需要加一个
384
- 真正的导出路径,详见 [`docs/ext.md`](docs/ext.md)。
385
-
386
326
  ### 内置扩展不在自绘节里重复列
387
327
 
388
328
  随核心分发的扩展(`source: 'builtin'`)已经是插件页原生「包含的组件」里的一行、自带
@@ -405,16 +345,17 @@ Anthropic 的工具调用(非流式 `tool_use` 与流式 `content_block_start` +
405
345
 
406
346
  ### 两层,各管一件事
407
347
 
408
- **第一层:准则(内置 13 条)**
348
+ **第一层:准则(内置 12 条)**
409
349
 
410
- 插件自带一套协作准则(`[准则 v5]`),按语义拆成 13 条,**每条独立开关、独立可改**:
350
+ 插件自带一套协作准则(`[准则 v5]`),按语义拆成 12 条,**每条独立开关、独立可改**:
411
351
 
412
352
  | 分类 | 管什么 |
413
353
  | --- | --- |
414
354
  | 身份气质 / 视野 / 懒人梯子 | 怎么定位自己、动手前看什么、找最省的解法 |
415
- | 领地 / 全局收口 / 可判定 | 工作边界、收尾复查、什么叫"做完了" |
355
+ | 领地 / 全局收口 | 工作边界、收尾复查 |
356
+ | 文档 | 只写权威内容(结论/约束/怎么用),不写流水账 |
416
357
  | 修根因 / 取舍 / 底线 | 改共享函数而不是补单点、砍边角与升级路径、不可逆禁令 |
417
- | 结构 / 绝不偷懒 / 交付 | 先结构后代码、校验与安全、交付口径 |
358
+ | 结构 / 交付 | 先结构后代码、交付口径 |
418
359
  | 执行顺序 | 一次任务的固定流程 |
419
360
 
420
361
  **还能自己加条目**:面板上「新增」写一条自己的准则,与内置的并列、同样能开关。
@@ -460,7 +401,7 @@ Anthropic 的工具调用(非流式 `tool_use` 与流式 `content_block_start` +
460
401
 
461
402
  ### 两条纪律
462
403
 
463
- - **自己那段永不进段落清单**。准则已经有总开关 + 14 条分类开关,再列一条段开关
404
+ - **自己那段永不进段落清单**。准则已经有总开关 + 逐条分类开关,再列一条段开关
464
405
  就是同一件事的两个开关,状态必然漂移;过滤时它也恒放行。
465
406
  - **落盘只存关闭项**(`data.sections[name] = false`),开回来就删键。宿主段随
466
407
  版本增删,存全表就得每次升级对账;只记"用户主动关了谁"让新段自然落回默认。
@@ -479,14 +420,13 @@ Anthropic 的工具调用(非流式 `tool_use` 与流式 `content_block_start` +
479
420
  │ │ ├─ StatsTab 概览:用量看板(周期按钮组 + 汇总卡 + 折线趋势 + Top 榜 + 最近请求)
480
421
  │ │ ├─ SupplierDetail 供应商详情:链接池 + 加链接 + 可用模型 + 模型测试
481
422
  │ │ ├─ CombosTab / EndpointTab
482
- │ │ └─ ExtTab → ExtDetail 扩展列表(只列已启用)与详情(优先渲染扩展自带的面板)
423
+ │ │ └─ ExtTab → ExtDetail 扩展列表(只列已启用)与详情(子开关 + 未就绪原因)
483
424
  │ └─ LastHitDock 「路由」徽章(composer.dock 座位;按会话显示最近命中)
484
425
  ├─ 设置 → 插件(官方 plugins.detail.section 座位)
485
426
  │ ├─ (原生「包含的组件」) core patch 里声明的行:core 本体 + 内置供应商 + 内置扩展
486
427
  │ │ 宿主管的开关,关一行 = loader 不 import 它
487
428
  │ └─ RouterComponentsSection dsh-router-core 详情页自绘的「路由组件」一节
488
429
  │ (外部供应商 + 扩展,两组都带开关)
489
- │ └─ ExtTestPanel 插件自检扩展的详情面板(按 ext id 登记到 ext-panels.ts)
490
430
  └─ fetch /router/api/* (同源,无 CORS)
491
431
  └─ host 半(src/index.ts)
492
432
  ├─ /v1/models + /v1/chat/completions (OpenAI 兼容, KeysStore 鉴权)
@@ -509,7 +449,7 @@ Anthropic 的工具调用(非流式 `tool_use` 与流式 `content_block_start` +
509
449
  └─ 外部插件供应商(经 router.suppliers service 注册)
510
450
  ↑ 内置三个是 core 自己 patch 里的**行**(子路径模块),与外部插件同一条通道
511
451
  └─ 扩展表 router.ext(core provide 空表,谁都能往里 append)
512
- ├─ 内置:插件自检(行 dsh-router-core/ext-test,默认关闭)
452
+ ├─ 内置:分层提示词(行 dsh-router-core/ext-prompt,默认关闭)
513
453
  └─ 外部:dsh-router-ext-rtk 等独立 bundle 经同一个 service 注册
514
454
  ```
515
455
 
package/cordis.patch.yml CHANGED
@@ -30,13 +30,8 @@
30
30
  name: 'dsh-router-core/suppliers/openrouter'
31
31
  - id: dsh-router-nvidia
32
32
  name: 'dsh-router-core/suppliers/nvidia'
33
- # 连接自检扩展。**默认关闭**:行关闭时 loader 根本不 import 它,扩展就不在
34
- # `router.ext` 表里 —— 所以「打开才出现这张卡片」是天然的,不需要额外状态位。
35
- - id: dsh-router-ext-test
36
- name: 'dsh-router-core/ext-test'
37
- disabled: true
38
- # 分层提示词扩展。**默认关闭**(与 ext-test 同款):行关闭时 loader 根本不
39
- # import 它,扩展就不在 `router.ext` 表里 —— 「打开才出现这张卡片」是天然的。
33
+ # 分层提示词扩展。**默认关闭**:行关闭时 loader 根本不 import 它,扩展就不在
34
+ # `router.ext` 表里 —— 「打开才出现这张卡片」是天然的。
40
35
  #
41
36
  # ⚠️ 这里来回改过一次(2026-09-29):先改成默认开启(理由是"准则是基础设施"),
42
37
  # 随后又改回默认关闭 —— **决定权在用户**。判据见 ext-prompt.test.ts 的
package/docs/ext.md CHANGED
@@ -12,20 +12,6 @@ bash 命令。装好后出现在「设置 → 路由 → 扩展」,**开关不
12
12
  数据目录是 `<profile>/data/`,**不跟进程 cwd 跑**——从任何目录启动 `dsh web`
13
13
  读到的都是同一份配置(见 `src/data-dir.ts`)。
14
14
 
15
- ## 扩展详情页可以自带内容
16
-
17
- 扩展详情页默认是一张**写死的只读页**(名字、id、状态、一段说明)。扩展若想在详情里放
18
- 自己的交互(要选的模型、要跑的测试、要看的诊断),可以按**扩展 id** 登记一个面板组件
19
- (`src/client/ext-panels.ts` 的 `registerExtPanel`):登记后 `ExtDetail` 用你的组件渲染
20
- 整个内容区,没登记才落回那张通用只读页。组件**不收 props** —— 面板的渲染点只有详情页
21
- 一处。核心自带的 `插件自检` 就是这么做的。
22
-
23
- ⚠️ **目前这张注册表在 dsh-router 自己的 client bundle 内部,外部插件包还引不到它**:
24
- `dsh-router-core/client` 是整个 client 入口(一个注册座位的 CJS 闭包),并不导出
25
- `registerExtPanel`。要让外部插件也能自带面板,需要给它加一个真正的导出路径
26
- (如 `./client/panels`)。这是已知的升级路径,不是现在就能用的写法 —— 照着现有 exports
27
- 去 `import { registerExtPanel } from 'dsh-router-core/client'` 会拿到 undefined。
28
-
29
15
  参考实现:[dsh-router-ext-rtk](https://github.com/CARVIN94/dsh-router-ext-rtk)
30
16
  (把命令改写成 `rtk <cmd>` 压缩输出)。
31
17
 
@@ -68,9 +54,9 @@ export function createPromptExt(deps): RouterExt {
68
54
  (隐藏会让用户以为它们不存在),重新打开总开关就恢复原样。
69
55
  3. **`control.id` 是持久化键**,改名会让用户已保存的选择丢失 —— 同 `ExtId`。
70
56
 
71
- ⚠️ **不适用于外部插件包(暂时)**:与下面的 `registerExtPanel` 一样,
72
- `controls` 的读写经 `dsh-router-core/client` 才能到达外部 bundle,而该入口不导出
73
- 这些能力。要让外部扩展用上,需要给它加一条真正的导出路径。这是已知的升级路径。
57
+ ⚠️ **不适用于外部插件包(暂时)**:`controls` 的读写经 `dsh-router-core/client`
58
+ 才能到达外部 bundle,而该入口不导出这些能力。要让外部扩展用上,需要给它加一条
59
+ 真正的导出路径。这是已知的升级路径。
74
60
 
75
61
  ## 分工:管理归核心,执行归插件
76
62