dsh-advisor-group 0.1.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.
- package/LICENSE +15 -0
- package/README.md +100 -0
- package/README.zh.md +100 -0
- package/cordis.patch.yml +10 -0
- package/lib/client.js +1444 -0
- package/lib/index.d.mts +165 -0
- package/lib/index.mjs +2650 -0
- package/package.json +86 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Apache License 2.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-advisor-group contributors
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# dsh-advisor-group
|
|
2
|
+
|
|
3
|
+
> A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH) plugin that lets the main model consult **multiple expert advisor models** in a retro chat-group card — for professional, long-tail world-knowledge, high-risk, or uncertain questions.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/topics/dsh-plugin)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ✨ Features
|
|
10
|
+
|
|
11
|
+
- **Auto-deepen consultation pipeline** — one `ask_advisors` call runs up to `maxRounds` rounds automatically: each round is a *driver deep-question → advisor A → advisor B (sees A) → advisor C (sees A+B) → …* sequential relay, closed by a driver-generated synthesis conclusion.
|
|
12
|
+
- **Three ways to activate** — `@顾问群` mention (force-start), same question repeated 3 times without resolution, or main-model self-assessed confidence below the threshold.
|
|
13
|
+
- **Real streaming** — advisors stream thinking chain + Markdown body via the DSH `ctx.llm` channel, with a direct-http fallback (OpenAI / Anthropic / Gemini compatible protocols) and incremental 200ms throttling.
|
|
14
|
+
- **SSE replay with resync** — `/advisor-group/stream` serves `eventId`/`bootId` framed frames, a 500-frame / 5-minute ring buffer, and `event: resync` on restart or gap.
|
|
15
|
+
- **Retro CRT chat cards** — green/amber/blue CRT themes, scanlines, LIVE/DONE headers, auto-expanded thinking panel with auto-scroll; advisor Markdown rendered with a link-protocol whitelist (headings, lists, code, quotes, links, tables).
|
|
16
|
+
- **Provider presets (11 platforms · 26 presets)** — DeepSeek, Moonshot Kimi, Kimi Code, Aliyun Bailian, Zhipu AI, OpenAI, Claude, Gemini, SiliconFlow, AIHubMix, OpenRouter (OpenAI/Anthropic-compatible variants included).
|
|
17
|
+
- **Security-minded by design** — API keys use official `SecretField` semantics (never returned to the browser; `apiKeysByProvider` key history is server-side only), SSRF-guarded diagnostics (https-only / loopback, no IP literals, no redirects), per-boot token auth on `/advisor-group/*` routes, and an atomic 50 consultations/day quota persisted across restarts.
|
|
18
|
+
- **Runtime toggle** — `toggle_advisor_group` enables/disables the plugin and persists the flag to settings.
|
|
19
|
+
|
|
20
|
+
## ✅ Compatibility
|
|
21
|
+
|
|
22
|
+
| Surface | Status |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Harness | DeepSeek Harness `0.1.2-rc.1` |
|
|
25
|
+
| Node | `^22.19.0 \|\| >=24.0.0` |
|
|
26
|
+
| Platforms | DSH Web (client bundle) + headless host logic |
|
|
27
|
+
|
|
28
|
+
## 📦 Installation
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
# 1. Install the plugin (one package, everything included)
|
|
32
|
+
dsh plugin --profile web add dsh-advisor-group
|
|
33
|
+
|
|
34
|
+
# 2. Restart DSH web
|
|
35
|
+
npx @deepseek-ai/dsh web
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> **From source (development)**
|
|
39
|
+
> ```sh
|
|
40
|
+
> npm install --legacy-peer-deps --no-audit --no-fund
|
|
41
|
+
> npm run build
|
|
42
|
+
> dsh plugin --profile web add ./dsh-advisor-group-0.1.0.tgz # after npm pack
|
|
43
|
+
> ```
|
|
44
|
+
|
|
45
|
+
## 🚀 Quick start
|
|
46
|
+
|
|
47
|
+
1. Restart DSH web and hard-refresh the browser (`Ctrl+Shift+R`).
|
|
48
|
+
2. Go to **Settings → Plugins → Advisor Group**: configure your advisors (provider route + model; use *获取模型列表* to pull the authoritative model list) and tune `maxRounds`, thresholds, and the UI theme.
|
|
49
|
+
3. Just start a conversation:
|
|
50
|
+
- type `@顾问群` in your question to force a consultation, or
|
|
51
|
+
- ask a professional/uncertain question — the plugin escalates automatically when appropriate.
|
|
52
|
+
|
|
53
|
+
`ask_advisors` tools available to the model: `ask_advisors`, `toggle_advisor_group`.
|
|
54
|
+
|
|
55
|
+
## ⚙️ Configuration
|
|
56
|
+
|
|
57
|
+
| Key | Type | Default | Description |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| `enabled` | boolean | `true` | Enable advisor group |
|
|
60
|
+
| `discussion.maxRounds` | number | `2` | Total rounds of the auto-deepen pipeline (each round = driver question + all advisors in relay) |
|
|
61
|
+
| `discussion.maxAdvisorsPerCall` | number | `3` | Max advisors per call (1–10) |
|
|
62
|
+
| `discussion.autoDeepen` | boolean | `true` | Run the auto-deepen pipeline (driver follow-ups + final synthesis) |
|
|
63
|
+
| `discussion.driverModel` | object | – | Fallback driver model `{provider, model}` when the session header cannot be read |
|
|
64
|
+
| `discussion.advisorTimeoutMs` | number | `120000` | Per-advisor call timeout (ms, 1000–600000), applied to both channels |
|
|
65
|
+
| `trigger.requireClassifier` | boolean | `true` | Run the pre-classifier before starting |
|
|
66
|
+
| `trigger.allowWebFallback` | boolean | `true` | Allow classifier to recommend web search |
|
|
67
|
+
| `trigger.confidenceThreshold` | number | `0.6` | Escalate when main-model confidence is below this |
|
|
68
|
+
| `ui.theme` | string | `retro-green` | Chat card theme (`retro-green` / `retro-amber` / `retro-blue`) |
|
|
69
|
+
| `ui.showTimestamps` | boolean | `true` | Show timestamps |
|
|
70
|
+
| `ui.autoExpand` | boolean | `true` | Auto-expand card |
|
|
71
|
+
| `advisors` | array | `[]` | Advisor list (provider/model/baseURL/apiKey/apiKeyEnv/protocol…, keys are `role('secret')`) |
|
|
72
|
+
|
|
73
|
+
> `discussion.parallel` and `discussion.stopOnConsensus` are deprecated leftovers kept only for stored-config compatibility.
|
|
74
|
+
|
|
75
|
+
## 🔒 Security & privacy
|
|
76
|
+
|
|
77
|
+
- Direct API keys can be stored in the DSH `settings.yaml` (marked secret, never returned to the browser by `describe`); prefer `apiKeyEnv` (env-var mode) if you don't want keys on disk.
|
|
78
|
+
- `/advisor-group/*` routes use a per-boot shared token for local single-user use — **not** multi-user auth. Add a reverse-proxy auth layer before LAN exposure.
|
|
79
|
+
- Diagnostics endpoints resolve the real key server-side and validate the target URL against an https-only / loopback SSRF guard; DNS-rebinding protection is a documented out-of-scope limitation.
|
|
80
|
+
- Daily quota (50 new consultations) is persisted to `$DSH_HOME/storages/advisor-group/daily-guard.json` (UTC day key), so restarts don't reset it.
|
|
81
|
+
- Classifier shadow mode appends one observation sample per non-forced classification (read-only `/advisor-group/shadow`), used for threshold tuning only — never influences behavior.
|
|
82
|
+
|
|
83
|
+
## ⚠️ Known limitations
|
|
84
|
+
|
|
85
|
+
- Disconnecting the SSE stream does not cancel in-flight advisor calls (per-advisor timeout `discussion.advisorTimeoutMs` is the fallback); refreshing keeps the consultation completing in the background.
|
|
86
|
+
- The lightweight Markdown renderer does not support nested lists, inline HTML, or complex tables.
|
|
87
|
+
- Preset default model lists are best-effort approximations — `ask_advisors` refuses to start (with a precise reason) while any advisor has an empty model; use *获取模型列表* for the authoritative list.
|
|
88
|
+
|
|
89
|
+
## 🛠️ Development
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
npm install --legacy-peer-deps --no-audit --no-fund
|
|
93
|
+
npm run typecheck
|
|
94
|
+
npm test # 64 tests, incl. provider streaming contracts against a local fake LLM server
|
|
95
|
+
npm run build # tsdown; client bundle must NOT be built with minify: true
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 📄 License
|
|
99
|
+
|
|
100
|
+
[Apache License 2.0](LICENSE) © 2026 dsh-advisor-group contributors.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# dsh-advisor-group
|
|
2
|
+
|
|
3
|
+
> [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)插件:主模型在遇到**专业、长尾世界知识、高风险或不确定**的问题时,召集多位**专家顾问模型**,在复古 CRT 聊天组卡片中真流式对话。
|
|
4
|
+
|
|
5
|
+
[](https://github.com/topics/dsh-plugin)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ✨ 功能特性
|
|
10
|
+
|
|
11
|
+
- **自动深挖咨询流水线**:一次 `ask_advisors` 自动跑满 `maxRounds` 轮——每轮 = *驱动模型深挖追问 → 顾问 A → 顾问 B(看到 A)→ 顾问 C(看到 A+B)→ …* 顺序接力,最后驱动模型产出**综合结论**。
|
|
12
|
+
- **三种触发方式**:`@顾问群` 提及(强制启动)、同一问题重复 3 次未解决、主模型自评置信度低于阈值。
|
|
13
|
+
- **真流式双通道**:顾问思维链 + Markdown 正文经 DSH `ctx.llm` 实时流式返回(增量 200ms 节流),并提供 direct-http 兜底(OpenAI / Anthropic / Gemini 兼容协议)。
|
|
14
|
+
- **SSE 回放 + 断连恢复**:`/advisor-group/stream` 按 `eventId`/`bootId` 帧推送,每会话 500 条 / 5 分钟环形缓冲,重启或缺口发 `event: resync`。
|
|
15
|
+
- **复古 CRT 聊天组卡片**:绿/琥珀/蓝三主题、扫描线、LIVE/DONE 标题、💭 思考面板默认展开自动滚底;顾问正文走轻量 Markdown 渲染(链接协议白名单,支持标题/列表/代码/引用/链接/表格)。
|
|
16
|
+
- **供应商预设(11 平台 · 26 预设)**:DeepSeek、月之暗面 Kimi、Kimi Code、阿里云百炼、智谱 AI、OpenAI、Claude、Gemini、硅基流动、AIHubMix、OpenRouter(含 OpenAI / Anthropic 兼容变体)。
|
|
17
|
+
- **注重安全**:API Key 采用官方 `SecretField` 语义(浏览器永不回显;`apiKeysByProvider` 供应商密钥档案仅存服务端);诊断端点 SSRF 加固(仅 https/loopback、拒绝 IP 字面量与重定向);`/advisor-group/*` 路由启动期 token 鉴权;每日新咨询 50 次**原子配额**,持久化跨重启。
|
|
18
|
+
- **运行时开关**:`toggle_advisor_group` 启停插件并持久化到设置。
|
|
19
|
+
|
|
20
|
+
## ✅ 兼容性
|
|
21
|
+
|
|
22
|
+
| 项目 | 状态 |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Harness | DeepSeek Harness `0.1.2-rc.1` |
|
|
25
|
+
| Node | `^22.19.0 \|\| >=24.0.0` |
|
|
26
|
+
| 平台 | DSH Web(客户端 bundle)+ headless 宿主逻辑 |
|
|
27
|
+
|
|
28
|
+
## 📦 安装
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
# 1. 安装插件(一个包全都有)
|
|
32
|
+
dsh plugin --profile web add dsh-advisor-group
|
|
33
|
+
|
|
34
|
+
# 2. 重启 dsh web
|
|
35
|
+
npx @deepseek-ai/dsh web
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> **从源码开发安装**
|
|
39
|
+
> ```sh
|
|
40
|
+
> npm install --legacy-peer-deps --no-audit --no-fund
|
|
41
|
+
> npm run build
|
|
42
|
+
> dsh plugin --profile web add ./dsh-advisor-group-0.1.0.tgz # 先 npm pack
|
|
43
|
+
> ```
|
|
44
|
+
|
|
45
|
+
## 🚀 快速开始
|
|
46
|
+
|
|
47
|
+
1. 重启 dsh web 并硬刷新浏览器(`Ctrl+Shift+R`)。
|
|
48
|
+
2. 打开 **设置 → 插件 → 顾问群**:配置顾问(提供商路由 + 模型,用「获取模型列表」拉取权威清单),按需调整 `maxRounds`、阈值与 UI 主题。
|
|
49
|
+
3. 直接开聊:
|
|
50
|
+
- 提问时带 `@顾问群` 强制发起咨询,或
|
|
51
|
+
- 直接提专业/不确定的问题——插件会按需自动升级。
|
|
52
|
+
|
|
53
|
+
模型可用工具:`ask_advisors`、`toggle_advisor_group`。
|
|
54
|
+
|
|
55
|
+
## ⚙️ 配置项
|
|
56
|
+
|
|
57
|
+
| 键 | 类型 | 默认 | 说明 |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| `enabled` | boolean | `true` | 启用顾问群 |
|
|
60
|
+
| `discussion.maxRounds` | number | `2` | 自动深挖流水线总轮数(每轮 = 驱动追问 + 全体顾问接力) |
|
|
61
|
+
| `discussion.maxAdvisorsPerCall` | number | `3` | 单次咨询最大顾问数(1–10) |
|
|
62
|
+
| `discussion.autoDeepen` | boolean | `true` | 启用自动深挖流水线(驱动追问 + 综合结论) |
|
|
63
|
+
| `discussion.driverModel` | object | – | 兜底驱动模型 `{provider, model}`(会话头信息不可读时) |
|
|
64
|
+
| `discussion.advisorTimeoutMs` | number | `120000` | 单顾问调用超时(毫秒,1000–600000),双通道均生效 |
|
|
65
|
+
| `trigger.requireClassifier` | boolean | `true` | 发起前先跑前置分类器 |
|
|
66
|
+
| `trigger.allowWebFallback` | boolean | `true` | 分类器建议联网搜索时返回该提示 |
|
|
67
|
+
| `trigger.confidenceThreshold` | number | `0.6` | 主模型置信度低于该值时升级 |
|
|
68
|
+
| `ui.theme` | string | `retro-green` | 卡片主题(retro-green / retro-amber / retro-blue) |
|
|
69
|
+
| `ui.showTimestamps` | boolean | `true` | 显示时间戳 |
|
|
70
|
+
| `ui.autoExpand` | boolean | `true` | 自动展开卡片 |
|
|
71
|
+
| `advisors` | array | `[]` | 顾问列表(provider/model/baseURL/apiKey/apiKeyEnv/protocol…,key 均标 `role('secret')`) |
|
|
72
|
+
|
|
73
|
+
> `discussion.parallel` 与 `discussion.stopOnConsensus` 为弃用遗留项,仅保留以兼容已存配置。
|
|
74
|
+
|
|
75
|
+
## 🔒 安全与隐私
|
|
76
|
+
|
|
77
|
+
- 直连 API Key 可存于 DSH `settings.yaml`(标 secret,官方 `describe` 绝不回传浏览器);不想落盘请用 `apiKeyEnv` 环境变量模式。
|
|
78
|
+
- `/advisor-group/*` 路由为**单机共享 token**(本地单用户使用),不是多用户鉴权;暴露局域网必须外层加反代鉴权。
|
|
79
|
+
- 诊断端点服务端按存档 key 解析真实值再打供应商,并对目标 URL 做 https-only/loopback SSRF 校验;DNS rebinding 记为文档化已知边界。
|
|
80
|
+
- 每日配额(新咨询 50 次)持久化在 `$DSH_HOME/storages/advisor-group/daily-guard.json`(UTC 日切),重启不再归零。
|
|
81
|
+
- 分类器影子模式:每次非强制分类追加一条观测样本(只读 `/advisor-group/shadow`),仅用于阈值调优,绝不干预行为。
|
|
82
|
+
|
|
83
|
+
## ⚠️ 已知限制
|
|
84
|
+
|
|
85
|
+
- SSE 断连**不取消在途顾问调用**(以 `discussion.advisorTimeoutMs` 超时兜底);刷新后咨询后台完成,durable 卡片重建完整内容。
|
|
86
|
+
- 轻量 Markdown 渲染器不支持嵌套列表 / 内联 HTML / 复杂表格。
|
|
87
|
+
- 预设默认模型清单为近似值——任一顾问模型为空时 `ask_advisors` 快速失败(附原因);用「获取模型列表」拉取权威清单。
|
|
88
|
+
|
|
89
|
+
## 🛠️ 开发
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
npm install --legacy-peer-deps --no-audit --no-fund
|
|
93
|
+
npm run typecheck
|
|
94
|
+
npm test # 64 单测(含本地假 LLM 服务器上的供应商流式契约)
|
|
95
|
+
npm run build # tsdown;客户端 bundle 禁用 minify: true
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 📄 许可证
|
|
99
|
+
|
|
100
|
+
[Apache License 2.0](LICENSE) © 2026 dsh-advisor-group contributors.
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# dsh-advisor-group bundle layer: register the scaffolded plugin as a bundle row.
|
|
2
|
+
# This file is the `dsh.bundle.patch` layer (see package.json#dsh.bundle.patch).
|
|
3
|
+
# Layer semantics: a YAML array of row verbs; `insert` adds plugin rows to the
|
|
4
|
+
# composed config. A row's `id` must be unique within the layer stack; `name`
|
|
5
|
+
# resolves the plugin module through the installed package (package.json#main).
|
|
6
|
+
- insert:
|
|
7
|
+
# `id`: stable row identifier used by later layers to override this row.
|
|
8
|
+
- id: dsh-advisor-group
|
|
9
|
+
# `name`: the module the loader imports; resolves to this package entry.
|
|
10
|
+
name: dsh-advisor-group
|