dsh-subagent-profile 0.3.2 → 0.3.4

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 (40) hide show
  1. package/README.md +77 -40
  2. package/README.zh.md +111 -74
  3. package/docs/screenshots/dispatch-card.png +0 -0
  4. package/docs/screenshots/settings-page1.png +0 -0
  5. package/docs/screenshots/settings-page2.png +0 -0
  6. package/index.mjs +276 -81
  7. package/lib/client.js +3218 -166
  8. package/lib/core/adoption-reminder.mjs +48 -0
  9. package/lib/core/adoption-tracker.mjs +430 -0
  10. package/lib/core/background-ledger.mjs +71 -0
  11. package/lib/core/catalog-cache.mjs +45 -7
  12. package/lib/core/catalog.mjs +6 -6
  13. package/lib/core/cost-evidence.mjs +145 -0
  14. package/lib/core/cost-guard.mjs +71 -44
  15. package/lib/core/decision-trace.mjs +413 -0
  16. package/lib/core/delegation.mjs +111 -50
  17. package/lib/core/dispatch-gates.mjs +153 -0
  18. package/lib/core/dispatch-guard.mjs +156 -0
  19. package/lib/core/dispatch-schema.mjs +103 -14
  20. package/lib/core/dispatch-tool.mjs +220 -204
  21. package/lib/core/draft-gates.mjs +45 -0
  22. package/lib/core/drafts-store.mjs +45 -0
  23. package/lib/core/escape.mjs +130 -0
  24. package/lib/core/evolution-advice.mjs +224 -0
  25. package/lib/core/evolution-ledger.mjs +300 -0
  26. package/lib/core/evolution-summary.mjs +255 -0
  27. package/lib/core/http-routes.mjs +256 -72
  28. package/lib/core/intersection.mjs +6 -9
  29. package/lib/core/presets-sync.mjs +161 -43
  30. package/lib/core/prices.mjs +46 -0
  31. package/lib/core/profile-directory.mjs +139 -0
  32. package/lib/core/profile-provider.mjs +42 -39
  33. package/lib/core/profiles-store.mjs +103 -76
  34. package/lib/core/pure.mjs +110 -66
  35. package/lib/core/reminder-store.mjs +172 -0
  36. package/lib/core/shims.mjs +67 -76
  37. package/lib/core/whitelist.mjs +23 -17
  38. package/package.json +82 -83
  39. package/presets/orchestrator/agent.cordis.yml +59 -87
  40. package/presets/orchestrator/NOTICE +0 -3
package/README.md CHANGED
@@ -2,49 +2,51 @@
2
2
 
3
3
  <!-- Hero -->
4
4
  <div align="center">
5
- <b style="font-size: 1.15em;">Subagent dispatch, profiled the right agent for the right task (preset / model / reasoning effort)</b><br /><br />
5
+ <b style="font-size: 1.15em;">子 Agent 派发插件 —— 派发可控 · 成本有数 · 决策留痕</b><br /><br />
6
6
  <img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" />
7
- <img alt="Version: v0.3.2" src="https://img.shields.io/badge/Version-v0.3.2-blue.svg" />
8
7
  <img alt="npm" src="https://img.shields.io/npm/v/dsh-subagent-profile.svg" />
9
- <img alt="DSH" src="https://img.shields.io/badge/DSH-0.1.0--rc.6%20~%200.1.1--rc.2-blue.svg" />
8
+ <img alt="DSH" src="https://img.shields.io/badge/DSH-0.1.0--rc.6%20~%200.2.0-blue.svg" />
10
9
  </div>
11
10
 
12
11
  <div align="center">English · <a href="README.zh.md">中文</a></div>
13
12
 
14
13
  For [DeepSeek Harness](https://github.com/deepseek-ai/dsh) (DSH).
15
14
 
16
- > *Thinking, Fast and Slow*: System 1 is fast and cheap, System 2 is slow and careful. The built-in `subagent` gives every subtask the same brain as its parent no way to tell them apart. `dsh-subagent-profile` lets you pick per subtask: research with a fast brain, deep work with a careful one, saved as named **profiles**.
15
+ > Dispatch subagents in DeepSeek Harness: pick model, reasoning effort, and tool scope per task; save common combos as named profiles for reuse. Built-in safety checks, cost estimation with savings analysis, and a full decision ledger.
17
16
 
18
- ## Why the built-in `subagent` isn't enough
17
+ ## Why this plugin
19
18
 
20
19
  | | Built-in `subagent` | `dsh-subagent-profile` |
21
20
  |---|---|---|
22
21
  | Per-subtask model / preset | ❌ same brain for every subtask | ✅ pick per subtask |
23
22
  | Reusable named setups | ❌ | ✅ profiles |
24
23
  | Tool-scope narrowing | ❌ | ✅ whitelist ∩ parent, `run_code` always removed |
25
- | Cost guardrails | ❌ | ✅ model / effort / tokens / depth capped |
26
- | GUI management | ❌ | ✅ settings page |
24
+ | Safety checks | ❌ | ✅ whitelist / cost / intersection / approval / budget, all recorded |
25
+ | Cost visibility | ❌ | ✅ per-dispatch estimate + savings comparison |
26
+ | Decision ledger | ❌ | ✅ full trace: request vs. effective, gates, execution, settlement |
27
+ | GUI management | ❌ | ✅ settings page + per-session ledger tab |
27
28
 
28
- ## What it solves
29
-
30
- - **Per-subtask control over the child's brain.** `dispatch` sets, per subtask: which preset (composition), which model, which reasoning effort, which tools, and the token cap. A research subtask and a coding subtask can run with completely different setups — something the plain `subagent` tool can't do (it only inherits the parent).
31
- - **Named, reusable profiles.** A profile is one bundle of preset + model + reasoning effort + tool scope + persona. Save "research" as `researcher` (reasoning off, search-only tools) and dispatch with `dispatch(profile="researcher")`; two built-ins ship (`swap-standard` = full standard coding toolkit, `researcher`), and you can add/edit/remove your own in the settings page.
32
- - **Fully observable.** Every result reports the effective profile / preset / model / reasoning effort; logs are tagged `[dsh-subagent-profile]`.
33
-
34
- ## Quick start
29
+ ## Installation
35
30
 
36
31
  ```bash
37
32
  dsh plugin --profile web add dsh-subagent-profile # published package
38
33
  dsh plugin --profile web add ./dsh-subagent-profile # from a local checkout
39
34
  ```
40
35
 
41
- Restart `dsh web`. This is a standard **bundle plugin**: it provides the `dispatch` tool, the profile provider, the `subagent-profiles` service, the `/subagent-profiles/*` loopback management routes, the settings page (「子 Agent 方案」), and the `dispatch` tool-call card in the web GUI. On startup it also **self-installs an agent preset** — **`orchestrator`** (「编排者模式」) — pick it in the new-session preset picker. The sync is idempotent and re-runs on every startup, so upgrading the plugin updates the preset.
36
+ Restart `dsh web`. This is a standard **bundle plugin**: it provides the `dispatch` tool, the profile provider, the `subagent-profiles` service, the `/subagent-profiles/*` loopback management routes, the settings page (「子 Agent 方案」), the per-session ledger tab, and the `dispatch` tool-call card in the web GUI. On startup it also **self-installs an agent preset** — **`orchestrator`** (「编排者模式」) — pick it in the new-session preset picker. The sync is idempotent and re-runs on every startup, so upgrading the plugin updates the preset.
42
37
 
43
38
  ## Usage
44
39
 
45
40
  ### 1. Configure sub-agent profiles
46
41
 
47
- Profiles are managed in the settings page — each one bundles preset + model + reasoning effort + tool scope (and optionally a persona), and can be enabled, disabled, edited, or reset individually.
42
+ Profiles are managed in the settings page — each one bundles preset + model + reasoning effort + tool scope (and optionally a persona), and can be enabled, disabled, edited, or reset individually. Two built-ins ship:
43
+
44
+ | Profile | Purpose |
45
+ |---|---|
46
+ | `swap-standard` | switch the child to the full standard coding toolkit |
47
+ | `researcher` | deep reasoning off, search-only tools |
48
+
49
+ Profiles live in `~/.dsh/subagent-profiles.json` and take effect immediately (edits are made from the settings page).
48
50
 
49
51
  ![Built-in profile list — editable, deletable, individually toggleable](docs/screenshots/settings-page1.png)
50
52
 
@@ -62,36 +64,48 @@ dispatch(
62
64
 
63
65
  ![dispatch tool-call card — every result shows what actually ran](docs/screenshots/dispatch-card.png)
64
66
 
65
- ## Profiles
67
+ ### 3. Review in the decision ledger
66
68
 
67
- Profiles live in `~/.dsh/subagent-profiles.json` and take effect immediately (edits are made from the settings page).
68
-
69
- | Profile | Purpose |
70
- |---|---|
71
- | `swap-standard` | switch the child to the full standard coding toolkit |
72
- | `researcher` | deep reasoning off, search-only tools |
69
+ Every session has a ledger tab that records each dispatch decision: what the parent saw and requested, what actually took effect (with ignored-request highlights), which tools were removed and why, how execution went (including stalls and parent interventions), and what it cost. Safety-check failures are surfaced with fix directions.
73
70
 
74
71
  ## Safety model
75
72
 
76
73
  Delegation never lets a subagent gain more power than you already have — this is the default, with no configuration:
77
74
 
78
75
  - **Tools only shrink.** A child's tool set is the intersection of the profile's tools and the parent's tools, and `run_code` is always removed.
79
- - **Approval is always "never".** A child cannot widen its own permissions; operations that need approval are rejected automatically.
76
+ - **Approval is never bypassed.** Delegation does not waive the host's approval requirements; operations that need approval are rejected automatically.
80
77
  - **Cost is capped.** Model, reasoning effort, tokens, and recursion depth are all bounded; out-of-range values fail loudly instead of silently downgrading.
78
+ - **An escape hatch, explicitly.** Non-official presets can be allowed per-preset (default off, each allowance audited).
79
+
80
+ ## Observability & notifications
81
+
82
+ - **Live status.** Background dispatches show live phase badges (start / gate / create / running / settled), driven by host job events with polling fallback.
83
+ - **Reminder center.** Urgent events (escape-hatch allowances, audit degradation, budget anomalies) raise a persistent badge; the notification center keeps every reminder with full context — parent session, child session, task summary, and outcome — plus one-click jumps to the related sessions. Normal orchestration events (e.g. a parent not adopting a child's result) are recorded in the audit ledger without interrupting you.
84
+ - **Dispatch suggestions.** Based on historical dispatch statistics, the plugin can inject read-only optimization hints for the parent agent (e.g. "this profile has a low recent success rate, consider switching") — hints only, nothing is changed automatically.
85
+ - **Subagent header badge.** Child sessions show a compact summary badge (e.g. `继承父会话 · 前台` — "inherits the parent session, foreground"); hover for the full detail (model / effort / preset / mode / origin).
81
86
 
82
87
  ## Data
83
88
 
84
89
  - `~/.dsh/subagent-profiles.json` — the profile registry (edited from the settings page).
85
90
  - `~/.dsh/subagent-profiles.state.json` — the plugin's enable/disable switch (default enabled).
91
+ - `~/.dsh/subagent-profiles.failed-traces.json` — the failure ledger (dispatch failure traces).
92
+ - `~/.dsh/subagent-evolution/` — the decision ledger and statistics:
93
+ - `dispatch.jsonl` — per-dispatch decision records (no prompt content).
94
+ - `summaries.json` — aggregated per-profile statistics (versioned, rebuilt on corruption).
95
+ - `adopted-state.json` — adoption verdict state for child results (cross-restart).
96
+ - `reminders.json` — reminder store (one reminder = one audit record).
86
97
  - `~/.dsh/.agent-presets/orchestrator/` — the self-installed `orchestrator` agent preset (synced from the bundled `presets/orchestrator/` on every startup).
87
98
 
88
- `DSH_HOME` is respected and defaults to `~/.dsh`.
99
+ `DSH_HOME` is respected and defaults to `~/.dsh`. Uninstalling the plugin removes the data files above and the self-installed `orchestrator` preset directory (other plugins' presets are left untouched); re-installing or re-launching re-syncs the preset and regenerates the data files.
89
100
 
90
101
  ## Known limitations
91
102
 
92
- - **Background** one-shot dispatch requires `@deepseek-ai/dsh-jobs` and `@deepseek-ai/dsh-tool-jobs` to be loaded; otherwise it fails with "background jobs unavailable".
93
- - **Continuable** mode goes through the DSH standard composition path, so the `preset` swap and `reasoningEffort` are ignored (the child inherits the parent preset at the default reasoning effort).
94
- - **Continuable** tool gate is a plugin-side mitigation: the child's `allow` is pre-computed as a closed set — parent tool set `run_code` − `deny`, then intersected with `allow`. **Assumption:** continuable inherits the parent preset, so the child's tool set ≈ the parent's. **Failure condition:** any host behavior change that makes the child's tool set differ from the parent's (not only preset swap — e.g. a future preset swap, composing a different tool set) means the parent set can contain tools the child does not have, so `tools.restrict` throws "unknown tool" and this mitigation automatically degrades to fail-loud (conservatively safe); it must then be replaced with a true parent ∩ child intersection once the upstream provides a provider guard seam.
103
+ - **Background dispatch** requires `@deepseek-ai/dsh-jobs` and `@deepseek-ai/dsh-tool-jobs` to be loaded; otherwise it fails with "dispatch: 后台派发不可用:缺少 jobs 服务".
104
+ - **Continuable mode** goes through the DSH standard composition path, so the `preset` swap and `reasoningEffort` are ignored (the child inherits the parent preset at the default reasoning effort).
105
+ - **Who decides the child's final tool set depends on the mode**:
106
+ - Continuable: narrowed by this plugin up front — the child's `allow` = (parent tool set − `run_code` − `deny`) ∩ `allow`. Assumption: continuable inherits the parent preset, so the child's tool set ≈ the parent's; if dsh's behavior changes so the two differ (e.g. a future preset swap composing a different tool set), tool narrowing fails with a hard error (conservatively safe — never silently granting more), to be replaced with a true parent ∩ child intersection once dsh provides an official seam.
107
+ - One-shot: decided by dsh; the plugin cannot read the final restricted result and the card reports "tools are finally granted by the system".
108
+ - **Cost figures are estimates**: computed from an average per-dispatch price (measured once per model); fine-grained per-token pricing is on the roadmap. The UI labels estimates as such and shows a note when the sample size is small.
95
109
 
96
110
  ## Repository structure
97
111
 
@@ -99,26 +113,54 @@ Delegation never lets a subagent gain more power than you already have — this
99
113
  dsh-subagent-profile/
100
114
  ├── index.mjs # host side: the plugin itself (dispatch tool, profile provider, service, HTTP routes)
101
115
  ├── lib/
102
- │ ├── client.js # browser side: settings page + dispatch tool-call card
116
+ │ ├── client.js # browser side: settings page + ledger + dispatch tool-call card
103
117
  │ └── core/ # host-side modules (lightweight layering)
104
118
  │ ├── pure.mjs # dependency-free pure functions (sanitize / prune / guard math — unit-tested)
105
119
  │ ├── shims.mjs # the single @deepseek-ai import facade (guards fail loud, helpers degrade softly)
106
- └── *.mjs # catalog / whitelist / intersection / cost-guard / delegation / profiles-store /
107
- # presets-sync / http-routes / profile-provider / dispatch-tool
120
+ ├── catalog.mjs # tool-name zh / category tables (zero-dep)
121
+ ├── catalog-cache.mjs # process-shared catalog snapshot (models / presets / tools, TTL cache)
122
+ │ ├── cost-guard.mjs # runtime capability checks (provider / model / reasoning effort)
123
+ │ ├── cost-evidence.mjs # counterfactual savings evidence (token-saving proof)
124
+ │ ├── prices.mjs # per-dispatch price table (average-based placeholder)
125
+ │ ├── decision-trace.mjs # decision trace (checks / effective / settled) + failure ledger
126
+ │ ├── delegation.mjs # background one-shot settling + child usage collection
127
+ │ ├── dispatch-gates.mjs # pre-dispatch safety checks (whitelist / cost / intersection / budget)
128
+ │ ├── dispatch-guard.mjs # concurrency + per-parent token budget guard
129
+ │ ├── dispatch-schema.mjs # dispatch tool input/output schema declarations
130
+ │ ├── dispatch-tool.mjs # dispatch tool factory (defineTool + execute + syncTool)
131
+ │ ├── draft-gates.mjs # draft profile gates (three checks)
132
+ │ ├── drafts-store.mjs # draft profile persistence
133
+ │ ├── escape.mjs # escape-hatch allow store
134
+ │ ├── evolution-ledger.mjs # decision ledger (jsonl) + governance audit
135
+ │ ├── evolution-summary.mjs # aggregate statistics (per-profile, capability/budget axes)
136
+ │ ├── evolution-advice.mjs # read-only dispatch suggestion generation
137
+ │ ├── adoption-tracker.mjs # child-result adoption verdict tracking (cross-restart)
138
+ │ ├── adoption-reminder.mjs # adoption-verdict reminder generation
139
+ │ ├── reminder-store.mjs # reminder store + audit-coupled records
140
+ │ ├── background-ledger.mjs # background job ledger (in-memory, resets on restart)
141
+ │ ├── http-routes.mjs # settings loopback HTTP routes
142
+ │ ├── intersection.mjs # tool-intersection pure core
143
+ │ ├── presets-sync.mjs # bundled preset self-install (hash-gated sync)
144
+ │ ├── profile-provider.mjs # the `profile` subagent provider
145
+ │ ├── profile-directory.mjs # read-only profile directory (for the model)
146
+ │ ├── profiles-store.mjs # profile registry store + switch persistence
147
+ │ └── whitelist.mjs # system-trust preset whitelist
108
148
  ├── presets/orchestrator/ # bundled "orchestrator" agent preset (self-installed, synced on every startup)
109
149
  ├── cordis.patch.yml # bundle patch: inserts the plugin row into the host composition
110
150
  ├── .gitea/workflows/ci.yml # bare-CI (Gitea Actions; needs an Act runner on the server)
111
151
  ├── package.json # metadata, files whitelist, exports (test / test:bare / preflight scripts)
112
152
  ├── scripts/
113
- │ ├── release.mjs # release helper (version bump / tag checks)
114
- │ └── preflight.mjs # preflight: preset-tree reconciliation + README badge == version (zero-dep)
153
+ │ ├── preflight.mjs # preflight: preset-tree reconciliation + no hardcoded version badge (zero-dep)
154
+ │ └── leak-scan.mjs # public-release gate: scans all history + worktree for sensitive patterns
115
155
  ├── docs/
116
156
  │ └── screenshots/ # README screenshots
117
- ├── test/ # host-side tests (node:test, zero extra deps; 101 cases = 26 bare + 75 junction)
157
+ ├── test/ # host-side tests (node:test, zero extra deps; 438 cases)
118
158
  │ ├── README.md / README.zh.md # test directory guide (EN/ZH) — two-tier split explained
119
159
  │ ├── harness/ctx.mjs # fake Cordis ctx + ~/.dsh isolation
120
160
  │ ├── pure / input-schema / catalog-integrity.test.mjs # bare tier (import-free, runs in bare CI)
121
- │ └── characterization / facade / gating / persist / recycle / cost-guard / continuable-guard.test.mjs # junction tier (local only)
161
+ │ └── *.test.mjs # junction tier (local only): characterization / facade / gating / persist / recycle /
162
+ │ # cost-guard / continuable-guard / decision-trace / dispatch-guard / escape-hatch /
163
+ │ # evolution-* / csrf / label-preset-sync / percall-spec / trust-label / audit-meta / …
122
164
  ├── README.md / README.zh.md # this document (EN/ZH)
123
165
  └── LICENSE
124
166
  ```
@@ -127,11 +169,6 @@ dsh-subagent-profile/
127
169
 
128
170
  Found a bug or have an idea? [Open an issue](https://github.com/muzyLink/dsh-subagent-profile/issues) or submit a pull request — all contributions are welcome.
129
171
 
130
- ### CI (bare) & preflight
131
-
132
- - **Gitea Actions** (`.gitea/workflows/ci.yml`): on `push` / `pull_request` to `v2-midterm` / `main`, runs the **bare-CI** subset — the tests that never load `@deepseek-ai` (`npm run test:bare`: pure / input-schema / catalog-integrity), `node --check` syntax checks, eslint (installed in isolation, since the bare environment cannot install the `@deepseek-ai` devDependencies), and `npm run preflight`. **Enabling Gitea Actions requires installing an Act runner on the server** (register it with the `ubuntu-latest` label); the workflow takes effect automatically once the runner is ready. Junction-dependent tests (characterization / facade / gating / persist / recycle / cost-guard / continuable-guard) run locally only — see `test/README.md` for the two-tier split and its rationale.
133
- - **Preflight** (`npm run preflight`): zero-dependency self-check — ① reconciles the bundled `presets/` tree against a fresh `$DSH_HOME/.agent-presets` derived tree (byte-identical set, both directions; never touches the real `~/.dsh`), ② asserts the README version badge (`v<version>` in the hero) matches `package.json` `version`. Non-zero exit means drift — fix and re-run before release.
134
-
135
172
  If this plugin has been useful to you, please give it a ⭐ on GitHub — it helps others find it.
136
173
 
137
174
  ## Credits
package/README.zh.md CHANGED
@@ -2,142 +2,179 @@
2
2
 
3
3
  <!-- Hero -->
4
4
  <div align="center">
5
- <b style="font-size: 1.15em;">子 Agent 派发方案化插件 —— 用对的人(预设 / 模型 / 推理强度)干对的事</b><br /><br />
5
+ <b style="font-size: 1.15em;">子 Agent 派发插件 —— 派发可控 · 成本有数 · 决策留痕</b><br /><br />
6
6
  <img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" />
7
- <img alt="Version: v0.3.2" src="https://img.shields.io/badge/Version-v0.3.2-blue.svg" />
8
7
  <img alt="npm" src="https://img.shields.io/npm/v/dsh-subagent-profile.svg" />
9
- <img alt="DSH" src="https://img.shields.io/badge/DSH-0.1.0--rc.6%20~%200.1.1--rc.2-blue.svg" />
8
+ <img alt="DSH" src="https://img.shields.io/badge/DSH-0.1.0--rc.6%20~%200.2.0-blue.svg" />
10
9
  </div>
11
10
 
12
11
  <div align="center"><a href="README.md">English</a> · 中文</div>
13
12
 
14
- [DeepSeek Harness](https://github.com/deepseek-ai/dsh)(DSH)打造。
13
+ 适用于 [DeepSeek Harness](https://github.com/deepseek-ai/dsh)(DSH)。
15
14
 
16
- > 《思考,快与慢》:系统 1 快而省,系统 2 慢而稳。内置的 `subagent` 给所有子任务同一个「大脑」,分不出快慢;`dsh-subagent-profile` 让你按任务指定——调研用快思考,攻坚用慢思考,常用搭配存成命名**方案**。
15
+ > DeepSeek Harness Agent 派发插件:按任务为子代理选模型、推理强度与工具范围,常用组合存成命名方案随时复用;内置安全检查、成本估算与节省分析、完整决策台账。
17
16
 
18
- ## 为什么内置 `subagent` 不够用
17
+ ## 为什么需要这个插件
19
18
 
20
19
  | | 内置 `subagent` | `dsh-subagent-profile` |
21
20
  |---|---|---|
22
- | 按子任务指定模型/预设 | ❌ 每个子任务同一个大脑 | ✅ 每个子任务单独指定 |
23
- | 常用组合复用 | ❌ | ✅ 命名方案(profiles) |
24
- | 收窄工具范围 | ❌ | ✅ 白名单 ∩ 父工具,`run_code` 一律移除 |
25
- | 成本护栏 | ❌ | ✅ 模型/推理强度/token/深度上限 |
26
- | GUI 管理 | ❌ | ✅ 设置页 |
21
+ | 按子任务选模型/预设 | ❌ 每个子任务同一个「大脑」 | ✅ 按任务逐个指定 |
22
+ | 可复用的命名方案 | ❌ | ✅ 方案(profile) |
23
+ | 工具范围收敛 | ❌ | ✅ 白名单 ∩ 父会话,`run_code` 恒移除 |
24
+ | 派发前安全检查 | ❌ | ✅ 白名单/成本/交集/审批/预算,全程记录 |
25
+ | 成本可见 | ❌ | ✅ 每次派发的成本估算 + 节省对照 |
26
+ | 派发决策台账 | ❌ | ✅ 请求vs生效、检查结果、执行、结算全留痕 |
27
+ | 界面管理 | ❌ | ✅ 设置页 + 会话内台账标签页 |
27
28
 
28
- ## 解决什么问题
29
-
30
- - **按子任务指定子 Agent 的「大脑」。** `dispatch` 给每个子任务单独指定:用哪个预设(composition)、哪个模型、哪种推理强度、只开哪些工具、给多少 token 上限。查资料和写代码两个子任务可以用完全不同的配置——这是内置 `subagent` 做不到的(它只能让子任务继承父 Agent 的同一套配置)。
31
- - **把常用搭配存成命名方案,按名调用。** 「方案」= 预设 + 模型 + 推理强度 + 工具范围 + 人设的一揽子配置。把「调研」存成 `researcher`(关深度推理、只留检索工具),以后 `dispatch(profile="researcher")` 即可;内置 `swap-standard`(切到 standard 全套编码工具)和 `researcher` 两个现成方案,也能在设置页自己增删改。
32
- - **每次派发都看得见实际用了什么。** 结果里标注实际生效的方案/预设/模型/推理强度,日志带 `[dsh-subagent-profile]` 标记,方便排查。
33
-
34
- ## 快速开始
29
+ ## 安装
35
30
 
36
31
  ```bash
37
32
  dsh plugin --profile web add dsh-subagent-profile # 发布包
38
- dsh plugin --profile web add ./dsh-subagent-profile # 本地检出
33
+ dsh plugin --profile web add ./dsh-subagent-profile # 本地源码
39
34
  ```
40
35
 
41
- 装完**重启 `dsh web`**。这是一个标准 **bundle 插件**,装好后自动提供:`dispatch` 派发工具、profile provider、`subagent-profiles` 服务、`/subagent-profiles/*` 本机管理接口,以及 Web 界面里的「子 Agent 方案」设置页与 `dispatch` 工具调用卡片。插件启动时还会**自动装好一个 agent 预设**——**`orchestrator`「编排者模式」**,在「新建会话」的预设选择器里选它即可。同步幂等、每次启动都执行,升级插件即更新预设。
36
+ 重启 `dsh web`。这是一个标准的 **bundle 插件**:提供 `dispatch` 工具、方案提供者、`subagent-profiles` 服务、`/subagent-profiles/*` 回环管理路由、设置页(「子 Agent 方案」)、会话内派发决策台账标签页,以及 web 界面中的 `dispatch` 工具卡片。启动时还会**自动安装一个 agent 预设**——**`orchestrator`**(「编排者模式」)——在新会话的预设选择器里选用。同步是幂等的且每次启动重跑,升级插件即更新预设。
42
37
 
43
- ## 用法
38
+ ## 使用
44
39
 
45
40
  ### 1. 配置子 Agent 方案
46
41
 
47
- 在设置页管理命名方案——每个方案打包预设 + 模型 + 推理强度 + 工具范围(可选人设),可单独启用、禁用、编辑或批量重置。
42
+ 方案在设置页管理——每个方案打包预设 + 模型 + 推理强度 + 工具范围(可选人设),可单独启用、禁用、编辑、重置。内置两个:
48
43
 
49
- ![内置方案列表:可编辑、删除、单独启用/禁用](docs/screenshots/settings-page1.png)
44
+ | 方案 | 用途 |
45
+ |---|---|
46
+ | `swap-standard` | 让子代理切换到完整标准编码工具集 |
47
+ | `researcher` | 关闭深度推理,仅搜索工具 |
50
48
 
51
- ![配置方案:设置页全貌(含新建方案表单)](docs/screenshots/settings-page2.png)
49
+ 方案数据存于 `~/.dsh/subagent-profiles.json`,设置页修改即时生效。
52
50
 
53
- ### 2. 按任务派发 —— `dispatch` 工具
51
+ ![内置方案列表——可编辑、可删除、可单独开关](docs/screenshots/settings-page1.png)
52
+
53
+ ![配置方案——完整设置页与新增方案表单](docs/screenshots/settings-page2.png)
54
+
55
+ ### 2. 按子任务派发——`dispatch` 工具
54
56
 
55
57
  ```js
56
58
  dispatch(
57
59
  profile: "researcher", // 预设 + 模型 + 推理强度 + 工具范围
58
- prompt: "调研 DSH 插件生态,列出直接竞品并对比",
60
+ prompt: "调研 DSH 插件生态并对比直接竞品",
59
61
  run_in_background: true
60
62
  )
61
63
  ```
62
64
 
63
- ![dispatch 工具调用卡片:每次派发都显示实际生效的配置](docs/screenshots/dispatch-card.png)
65
+ ![dispatch 工具卡片——每次结果都显示实际生效的配置](docs/screenshots/dispatch-card.png)
64
66
 
65
- ## 方案(Profiles)
67
+ ### 3. 在派发决策台账中复盘
66
68
 
67
- 方案保存在 `~/.dsh/subagent-profiles.json`,改完立即生效(在设置页编辑)。
68
-
69
- | 方案 | 用途 |
70
- |---|---|
71
- | `swap-standard` | 子 Agent 切换为 standard 全套编码工具 |
72
- | `researcher` | 关深度推理、只留检索工具 |
69
+ 每个会话都有「派发决策台账」标签,记录每次派发决策:父会话看到了什么、请求了什么,实际生效了什么(请求被忽略处高亮),哪些工具被移除及原因,执行过程如何(含停滞与主 Agent 干预),以及成本多少。安全检查失败时给出修复方向。
73
70
 
74
71
  ## 安全模型
75
72
 
76
- 委派绝不会让子 Agent 拿到比你更多的权限,默认生效、无需配置:
73
+ 委派永远不会让子代理获得比你更大的权限——这是默认行为,无需配置:
74
+
75
+ - **工具只减不增。** 子代理的工具集 = 方案工具 ∩ 父会话工具,且 `run_code` 恒移除。
76
+ - **审批永不豁免。** 委派不豁免宿主的审批要求;需要审批的操作自动拒绝。
77
+ - **成本有上限。** 模型、推理强度、token、递归深度全部有界;越界值大声失败而非静默降级。
78
+ - **逃生舱,显式开启。** 非官方预设可逐个放行(默认关闭,每次放行留审计)。
77
79
 
78
- - **工具只减不增。** 子 Agent 最终能用的工具,是「方案允许的工具」和「主 Agent 已有工具」的交集,且 `run_code`(运行代码)一律移除。
79
- - **审批恒为「永不」。** 子 Agent 无法扩大自己的权限,需要审批的操作会被自动拒绝。
80
- - **成本设上限。** 模型、推理强度、token、递归深度都有限制,越界直接报错、不会悄悄降级。
80
+ ## 可观测性与通知
81
81
 
82
- ## 数据
82
+ - **实时状态。** 后台派发的阶段徽标实时更新(发起/检查/创建/执行中/结算),宿主任务事件驱动,轮询兜底。
83
+ - **提醒中心。** 紧急事件(逃生舱放行、审计降级、预算异常)触发常驻红角标;通知中心里每条提醒都带完整上下文——主会话、子会话、任务摘要、结果状态——并可一键跳转对应会话。正常编排事件(如父会话未采纳某次派发结果)只记审计台账,不打断你。
84
+ - **派发优化建议。** 基于历史派发统计,插件可向主 Agent 注入只读优化提示(如「该方案近期成功率偏低,可考虑换方案」)——只提示,不自动改任何配置。
85
+ - **子会话页头徽标。** 子会话页头显示紧凑摘要标签(如 `继承父会话 · 前台`),悬停查看全部字段(模型/推理强度/预设/模式/来源)。
83
86
 
84
- - `~/.dsh/subagent-profiles.json` —— 方案注册表(由设置页编辑)。
85
- - `~/.dsh/subagent-profiles.state.json` —— 插件的启用/禁用开关(默认启用)。
86
- - `~/.dsh/.agent-presets/orchestrator/` —— 自动安装的 `orchestrator` 编排者预设(每次启动由打包的 `presets/orchestrator/` 同步)。
87
+ ## 数据文件
87
88
 
88
- 尊重 `DSH_HOME`,默认 `~/.dsh`。
89
+ - `~/.dsh/subagent-profiles.json` —— 方案注册表(设置页编辑)。
90
+ - `~/.dsh/subagent-profiles.state.json` —— 插件开关状态(默认启用)。
91
+ - `~/.dsh/subagent-profiles.failed-traces.json` —— 失败台账(派发失败轨迹)。
92
+ - `~/.dsh/subagent-evolution/` —— 派发决策台账与统计:
93
+ - `dispatch.jsonl` —— 每次派发的决策记录(不含 prompt 原文)。
94
+ - `summaries.json` —— 按方案聚合的统计(带版本号,损坏自动重建)。
95
+ - `adopted-state.json` —— 子结果采纳判定状态(跨重启)。
96
+ - `reminders.json` —— 提醒存储(一条提醒 = 一条审计记录)。
97
+ - `~/.dsh/.agent-presets/orchestrator/` —— 自动安装的 `orchestrator` 预设(每次启动从内置 `presets/orchestrator/` 同步)。
98
+
99
+ 尊重 `DSH_HOME` 环境变量(默认 `~/.dsh`)。卸载插件会移除上述数据文件与自动安装的 `orchestrator` 预设目录(其他插件的预设不动);重装或重启会重新同步预设并重建数据文件。
89
100
 
90
101
  ## 已知限制
91
102
 
92
- - **后台**一次性派发需要加载 `@deepseek-ai/dsh-jobs` 与 `@deepseek-ai/dsh-tool-jobs`,否则报「background jobs unavailable」。
93
- - **可续跑**模式走 DSH 标准组合路径,因此 `preset` 换用与 `reasoningEffort` 会被忽略(继承父预设、使用默认推理强度)。
94
- - **可续跑**工具门为插件侧缓解:子 Agent 的 `allow` 预加工为闭集 —— 父工具集 − `run_code` − `deny`,再与 `allow` 取交集。**假设:** 可续跑继承父预设 ⇒ 子工具集 ≈ 父工具集。**失效条件:** 任何导致子工具集与父工具集不一致的宿主行为变化(非仅换用预设——例如未来允许换用预设、组合不同工具集等),父集都可能含子集没有的工具,`tools.restrict` 会抛「未知工具」→ 本缓解自动降级为 fail-loud(保守安全);待上游提供 provider 守卫接缝后替换为真交集。
103
+ - **后台派发**需要 `@deepseek-ai/dsh-jobs` 与 `@deepseek-ai/dsh-tool-jobs` 已加载;否则报「dispatch: 后台派发不可用:缺少 jobs 服务」。
104
+ - **持久(continuable)模式**走 DSH 标准组合路径,`preset` 换用与 `reasoningEffort` 会被忽略(子代理继承父预设与默认推理强度)。
105
+ - **子代理的最终工具集由谁决定,取决于模式**:
106
+ - 持久(continuable)模式:由本插件预先收敛——子代理 `allow` =(父工具集 − `run_code` − `deny`)∩ `allow`。前提假设:持久模式沿用父会话预设,故子工具集与父会话基本一致;一旦 dsh 的行为变化导致两者不同(如未来支持预设换用后组合出不同工具集),工具收敛会**直接报错拒绝**(保守安全,绝不静默放行),待 dsh 官方提供相应接口后替换为真正的父 ∩ 子交集。
107
+ - 一次性模式:由 dsh 决定,插件读不到最终受限结果;卡片显示「工具由系统最终授予」。
108
+ - **成本是估算**:按每次派发的均价计算(每个模型实测一次);按 token 的精细计价在路线图中。界面明确标注「估算」,样本不足时显示说明。
95
109
 
96
- ## 目录结构
110
+ ## 仓库结构
97
111
 
98
112
  ```
99
113
  dsh-subagent-profile/
100
- ├── index.mjs # 宿主侧:插件本体(dispatch 工具、profile provider、服务、HTTP 路由)
114
+ ├── index.mjs # 宿主侧:插件本体(dispatch 工具、方案提供者、服务、HTTP 路由)
101
115
  ├── lib/
102
- │ ├── client.js # 浏览器侧:设置页 + dispatch 工具调用卡片
116
+ │ ├── client.js # 浏览器侧:设置页 + 台账 + dispatch 工具卡片
103
117
  │ └── core/ # 宿主侧模块(轻量分层)
104
- │ ├── pure.mjs # 无依赖纯函数(净化 / 剪枝 / 护栏计算——可单测)
105
- │ ├── shims.mjs # @deepseek-ai 依赖唯一入口(facade:守卫型 fail-loud、功能映射型软降级)
106
- └── *.mjs # catalog / whitelist / intersection / cost-guard / delegation / profiles-store /
107
- # presets-sync / http-routes / profile-provider / dispatch-tool
108
- ├── presets/orchestrator/ # 内置「编排者模式」agent 预设(自安装,每次启动同步)
109
- ├── cordis.patch.yml # bundle 补丁:把插件行插入宿主组成
110
- ├── .gitea/workflows/ci.yml # bare-CI(Gitea Actions;需服务器装 Act runner)
111
- ├── package.json # 元数据、files 发布白名单、exports(test / test:bare / preflight scripts)
118
+ │ ├── pure.mjs # 零依赖纯函数(清洗/剪枝/护栏数学——单测覆盖)
119
+ │ ├── shims.mjs # 唯一的 @deepseek-ai 导入门面(护栏大声失败,辅助软降级)
120
+ ├── catalog.mjs # 工具名 中文/分类表(零依赖)
121
+ ├── catalog-cache.mjs # 进程共享目录快照(模型/预设/工具,TTL 缓存)
122
+ ├── cost-guard.mjs # 运行时能力检查(提供方/模型/推理强度)
123
+ ├── cost-evidence.mjs # token 反事实对照证据
124
+ ├── prices.mjs # 每次派发单价表(当前为均价占位)
125
+ ├── decision-trace.mjs # 决策轨迹(检查/生效/结算)+ 失败台账
126
+ │ ├── delegation.mjs # 后台一次性结算 + 子用量采集
127
+ │ ├── dispatch-gates.mjs # 派发前安全检查(白名单/成本/交集/预算)
128
+ │ ├── dispatch-guard.mjs # 并发 + 每父会话 token 预算护栏
129
+ │ ├── dispatch-schema.mjs # dispatch 工具输入/输出 schema 声明
130
+ │ ├── dispatch-tool.mjs # dispatch 工具工厂(defineTool + execute + syncTool)
131
+ │ ├── draft-gates.mjs # 草稿方案三道闸
132
+ │ ├── drafts-store.mjs # 草稿方案持久化
133
+ │ ├── escape.mjs # 逃生舱放行存储
134
+ │ ├── evolution-ledger.mjs # 派发决策台账(jsonl)+ 治理审计
135
+ │ ├── evolution-summary.mjs # 聚合统计(按方案,能力/预算双轴)
136
+ │ ├── evolution-advice.mjs # 只读派发建议生成
137
+ │ ├── adoption-tracker.mjs # 子结果采纳判定跟踪(跨重启)
138
+ │ ├── adoption-reminder.mjs # 采纳判定提醒生成
139
+ │ ├── reminder-store.mjs # 提醒存储 + 审计耦合记录
140
+ │ ├── background-ledger.mjs # 后台任务台账(内存态,重启即失)
141
+ │ ├── http-routes.mjs # 设置回环 HTTP 路由
142
+ │ ├── intersection.mjs # 工具交集纯核心
143
+ │ ├── presets-sync.mjs # 内置预设自动安装(哈希门控同步)
144
+ │ ├── profile-provider.mjs # `profile` 子代理提供者
145
+ │ ├── profile-directory.mjs # 只读方案目录(供模型参考)
146
+ │ ├── profiles-store.mjs # 方案注册表存储 + 开关持久化
147
+ │ └── whitelist.mjs # system-trust 预设白名单
148
+ ├── presets/orchestrator/ # 内置「orchestrator」预设(自动安装,每次启动同步)
149
+ ├── cordis.patch.yml # bundle patch:把插件行插入宿主组合
150
+ ├── .gitea/workflows/ci.yml # bare-CI(Gitea Actions;需服务器上的 Act runner)
151
+ ├── package.json # 元数据、files 白名单、exports(test / test:bare / preflight 脚本)
112
152
  ├── scripts/
113
- │ ├── release.mjs # 发布脚本(版本 bump / tag 校验)
114
- │ └── preflight.mjs # preflight:preset 树对账 + README 徽章 == version(零依赖)
153
+ │ ├── preflight.mjs # 预检:预设树一致 + 无硬编码版本徽章(零依赖)
154
+ │ └── leak-scan.mjs # 公开发布门:扫描全历史与工作区的敏感模式
115
155
  ├── docs/
116
156
  │ └── screenshots/ # README 截图
117
- ├── test/ # 宿主侧自动化测试(node:test,零新增依赖;101 用例 = 26 bare + 75 junction)
118
- │ ├── README.md / README.zh.md # 测试目录说明(中英双语)——两档测试划分
119
- │ ├── harness/ctx.mjs # 假宿主环境(fake ctx + ~/.dsh 隔离)
120
- │ ├── pure / input-schema / catalog-integrity.test.mjs # bare 档(import-free,bare CI 可跑)
121
- │ └── characterization / facade / gating / persist / recycle / cost-guard / continuable-guard.test.mjs # junction 档(仅本机)
122
- ├── README.md / README.zh.md # 本文档(中英双语)
157
+ ├── test/ # 宿主侧测试(node:test,零额外依赖;438 用例)
158
+ │ ├── README.md / README.zh.md # 测试目录指南(中英)——两层拆分说明
159
+ │ ├── harness/ctx.mjs # Cordis ctx + ~/.dsh 隔离
160
+ │ ├── pure / input-schema / catalog-integrity.test.mjs # bare 层(免导入,bare CI 可跑)
161
+ │ └── *.test.mjs # junction 层(仅本地):characterization / facade / gating / persist / recycle /
162
+ │ # cost-guard / continuable-guard / decision-trace / dispatch-guard / escape-hatch /
163
+ │ # evolution-* / csrf / label-preset-sync / percall-spec / trust-label / audit-meta / …
164
+ ├── README.md / README.zh.md # 本文档(英/中)
123
165
  └── LICENSE
124
166
  ```
125
167
 
126
168
  ## 贡献
127
169
 
128
- 发现 Bug 或有新想法?欢迎[ Issue](https://github.com/muzyLink/dsh-subagent-profile/issues)或提交 Pull Request,任何形式的贡献都欢迎。
129
-
130
- ### CI(bare)与 preflight
131
-
132
- - **Gitea Actions**(`.gitea/workflows/ci.yml`):`push` / `pull_request` 到 `v2-midterm` / `main` 时运行 **bare-CI** 子集——从不加载 `@deepseek-ai` 的测试(`npm run test:bare`:pure / input-schema / catalog-integrity)、`node --check` 全仓库语法检查、eslint 行门(eslint 在仓库外隔离安装,因裸环境装不到 `@deepseek-ai` devDependencies)、以及 `npm run preflight`。**启用 Gitea Actions 需服务器装 Act runner**(注册时带上 `ubuntu-latest` 标签),runner 就绪后本工作流自动生效。依赖 junction 的测试(characterization / facade / gating / persist / recycle / cost-guard / continuable-guard)仅本机跑——两档测试的划分与理由见 `test/README.zh.md`。
133
- - **Preflight**(`npm run preflight`):零依赖自检——① `presets/` 与全新 `$DSH_HOME/.agent-presets` 派生树做 byte 一致集合对账(双向;绝不写真实 `~/.dsh`);② 断言 README 版本徽章(Hero 区 `v<version>`)与 `package.json` 的 `version` 一致。非零退出即漂移,发布前修复后重跑。
170
+ 发现 bug 或有想法?[提交 issue](https://github.com/muzyLink/dsh-subagent-profile/issues) PR——欢迎一切贡献。
134
171
 
135
- 如果这个插件帮到了你,欢迎在 GitHub 上点个 ⭐,让更多人看到它。
172
+ 如果这个插件对你有用,请在 GitHub 上给个 ⭐——它帮助更多人发现它。
136
173
 
137
174
  ## 致谢
138
175
 
139
- 内置的 `orchestrator` 编排者预设的构成方式参考了 [dsh-liangshen(梁神模式)](https://github.com/zhu1090093659/dsh-web-ui/tree/main/packages/dsh-liangshen)(出自 [dsh-web-ui](https://github.com/zhu1090093659/dsh-web-ui)Apache-2.0 许可)。感谢作者的出色工作。
176
+ 内置的 `orchestrator` 预设灵感来自 [dsh-web-ui](https://github.com/zhu1090093659/dsh-web-ui) [dsh-liangshen](https://github.com/zhu1090093659/dsh-web-ui/tree/main/packages/dsh-liangshen)(梁神模式),Apache-2.0 许可。感谢作者。
140
177
 
141
- ## License
178
+ ## 许可
142
179
 
143
180
  [MIT](LICENSE) — Copyright (c) 2026 muzyLink
Binary file
Binary file
Binary file