dsh-subagent-profile 0.1.0 → 0.3.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/README.md +46 -3
- package/README.zh.md +45 -2
- package/cordis.patch.yml +2 -2
- package/index.mjs +161 -1200
- package/lib/client.js +780 -505
- package/lib/core/catalog.mjs +83 -0
- package/lib/core/cost-guard.mjs +108 -0
- package/lib/core/delegation.mjs +61 -0
- package/lib/core/dispatch-tool.mjs +371 -0
- package/lib/core/http-routes.mjs +328 -0
- package/lib/core/intersection.mjs +27 -0
- package/lib/core/presets-sync.mjs +136 -0
- package/lib/core/profile-provider.mjs +241 -0
- package/lib/core/profiles-store.mjs +226 -0
- package/lib/core/pure.mjs +336 -0
- package/lib/core/shims.mjs +215 -0
- package/lib/core/whitelist.mjs +22 -0
- package/package.json +14 -6
- package/presets/orchestrator/agent.cordis.yml +7 -9
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- Hero -->
|
|
4
4
|
<div align="center">
|
|
5
|
-
<b style="font-size: 1.15em;"
|
|
5
|
+
<b style="font-size: 1.15em;">Subagent dispatch, profiled — the right agent for the right task (preset / model / reasoning effort)</b><br /><br />
|
|
6
6
|
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" />
|
|
7
|
-
<img alt="Version:
|
|
8
|
-
<img alt="
|
|
7
|
+
<img alt="Version: v0.3.0" src="https://img.shields.io/badge/Version-v0.3.0-blue.svg" />
|
|
8
|
+
<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" />
|
|
9
10
|
</div>
|
|
10
11
|
|
|
11
12
|
<div align="center">English · <a href="README.zh.md">中文</a></div>
|
|
@@ -90,6 +91,48 @@ Delegation never lets a subagent gain more power than you already have — this
|
|
|
90
91
|
|
|
91
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".
|
|
92
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.
|
|
95
|
+
|
|
96
|
+
## Repository structure
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
dsh-subagent-profile/
|
|
100
|
+
├── index.mjs # host side: the plugin itself (dispatch tool, profile provider, service, HTTP routes)
|
|
101
|
+
├── lib/
|
|
102
|
+
│ ├── client.js # browser side: settings page + dispatch tool-call card
|
|
103
|
+
│ └── core/ # host-side modules (lightweight layering)
|
|
104
|
+
│ ├── pure.mjs # dependency-free pure functions (sanitize / prune / guard math — unit-tested)
|
|
105
|
+
│ ├── 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
|
|
108
|
+
├── presets/orchestrator/ # bundled "orchestrator" agent preset (self-installed, synced on every startup)
|
|
109
|
+
├── cordis.patch.yml # bundle patch: inserts the plugin row into the host composition
|
|
110
|
+
├── .gitea/workflows/ci.yml # bare-CI (Gitea Actions; needs an Act runner on the server)
|
|
111
|
+
├── package.json # metadata, files whitelist, exports (test / test:bare / preflight scripts)
|
|
112
|
+
├── scripts/
|
|
113
|
+
│ ├── release.mjs # release helper (version bump / tag checks)
|
|
114
|
+
│ └── preflight.mjs # preflight: preset-tree reconciliation + README badge == version (zero-dep)
|
|
115
|
+
├── docs/
|
|
116
|
+
│ └── screenshots/ # README screenshots
|
|
117
|
+
├── test/ # host-side tests (node:test, zero extra deps; 101 cases = 26 bare + 75 junction)
|
|
118
|
+
│ ├── README.md / README.zh.md # test directory guide (EN/ZH) — two-tier split explained
|
|
119
|
+
│ ├── harness/ctx.mjs # fake Cordis ctx + ~/.dsh isolation
|
|
120
|
+
│ ├── 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)
|
|
122
|
+
├── README.md / README.zh.md # this document (EN/ZH)
|
|
123
|
+
└── LICENSE
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Contributing
|
|
127
|
+
|
|
128
|
+
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
|
+
|
|
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
|
+
If this plugin has been useful to you, please give it a ⭐ on GitHub — it helps others find it.
|
|
93
136
|
|
|
94
137
|
## Credits
|
|
95
138
|
|
package/README.zh.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
<div align="center">
|
|
5
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:
|
|
8
|
-
<img alt="
|
|
7
|
+
<img alt="Version: v0.3.0" src="https://img.shields.io/badge/Version-v0.3.0-blue.svg" />
|
|
8
|
+
<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" />
|
|
9
10
|
</div>
|
|
10
11
|
|
|
11
12
|
<div align="center"><a href="README.md">English</a> · 中文</div>
|
|
@@ -90,6 +91,48 @@ dispatch(
|
|
|
90
91
|
|
|
91
92
|
- **后台**一次性派发需要加载 `@deepseek-ai/dsh-jobs` 与 `@deepseek-ai/dsh-tool-jobs`,否则报「background jobs unavailable」。
|
|
92
93
|
- **可续跑**模式走 DSH 标准组合路径,因此 `preset` 换用与 `reasoningEffort` 会被忽略(继承父预设、使用默认推理强度)。
|
|
94
|
+
- **可续跑**工具门为插件侧缓解:子 Agent 的 `allow` 预加工为闭集 —— 父工具集 − `run_code` − `deny`,再与 `allow` 取交集。**假设:** 可续跑继承父预设 ⇒ 子工具集 ≈ 父工具集。**失效条件:** 任何导致子工具集与父工具集不一致的宿主行为变化(非仅换用预设——例如未来允许换用预设、组合不同工具集等),父集都可能含子集没有的工具,`tools.restrict` 会抛「未知工具」→ 本缓解自动降级为 fail-loud(保守安全);待上游提供 provider 守卫接缝后替换为真交集。
|
|
95
|
+
|
|
96
|
+
## 目录结构
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
dsh-subagent-profile/
|
|
100
|
+
├── index.mjs # 宿主侧:插件本体(dispatch 工具、profile provider、服务、HTTP 路由)
|
|
101
|
+
├── lib/
|
|
102
|
+
│ ├── client.js # 浏览器侧:设置页 + dispatch 工具调用卡片
|
|
103
|
+
│ └── 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)
|
|
112
|
+
├── scripts/
|
|
113
|
+
│ ├── release.mjs # 发布脚本(版本 bump / tag 校验)
|
|
114
|
+
│ └── preflight.mjs # preflight:preset 树对账 + README 徽章 == version(零依赖)
|
|
115
|
+
├── docs/
|
|
116
|
+
│ └── 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 # 本文档(中英双语)
|
|
123
|
+
└── LICENSE
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 贡献
|
|
127
|
+
|
|
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` 一致。非零退出即漂移,发布前修复后重跑。
|
|
134
|
+
|
|
135
|
+
如果这个插件帮到了你,欢迎在 GitHub 上点个 ⭐,让更多人看到它。
|
|
93
136
|
|
|
94
137
|
## 致谢
|
|
95
138
|
|
package/cordis.patch.yml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# dsh-subagent-profile bundle patch: inserts the dual-face plugin row into the
|
|
2
|
-
# profile roster. The node
|
|
2
|
+
# profile roster. The node side (exports ".") runs in the host process — it
|
|
3
3
|
# registers the dispatch tool, the profile provider, the subagent-profiles
|
|
4
4
|
# service, and the /subagent-profiles/* loopback HTTP routes; the `dsh.client`
|
|
5
|
-
# declaration in package.json makes the browser
|
|
5
|
+
# declaration in package.json makes the browser side (exports "./client", served
|
|
6
6
|
# at /plugins/<id>/client.js) load in the web GUI as the settings page and the
|
|
7
7
|
# dispatch tool-call card.
|
|
8
8
|
- insert:
|