dsh-subagent-hub 0.0.0-stage → 0.10.2
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 +21 -0
- package/README.md +110 -2
- package/cordis.patch.yml +17 -0
- package/lib/catalog.js +54 -0
- package/lib/client.js +1799 -0
- package/lib/definitions.js +25 -0
- package/lib/guard.js +131 -0
- package/lib/index.js +454 -0
- package/lib/official-settings.js +105 -0
- package/lib/presets.js +50 -0
- package/lib/prompt.js +105 -0
- package/lib/router.js +74 -0
- package/locale/en.json +1 -0
- package/locale/zh.json +1 -0
- package/package.json +61 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ccsert
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,111 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/ccsert/dsh-subagent-hub/v0.10.2/docs/assets/hero.webp" alt="Subagent Hub — Named roles. Clear routes. Visible models." width="100%">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/ccsert/dsh-subagent-hub/releases/tag/v0.10.2"><img src="https://img.shields.io/badge/version-0.10.2-66c8ab" alt="Version 0.10.2"></a>
|
|
7
|
+
<a href="https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
|
|
8
|
+
<a href="https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/install.md"><img src="https://img.shields.io/badge/DSH_Desktop-0.12.1-7087ad" alt="Tested with DSH Desktop 0.12.1"></a>
|
|
9
|
+
<a href="https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/CONTRIBUTING.md"><img src="https://img.shields.io/badge/verified-102_unit_%2B_31_runtime-66c8ab" alt="102 unit tests and 31 runtime assertions verified"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center"><a href="https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/README.md">简体中文</a> · <b>English</b></p>
|
|
13
|
+
|
|
14
|
+
# Subagent Hub
|
|
15
|
+
|
|
16
|
+
**Roles, model selection context, and route boundaries for official DeepSeek Harness subagents.** Give the main agent useful reviewer, tester, or research roles; manage allowed models in Settings; inspect the most recent model request from a child conversation.
|
|
17
|
+
|
|
18
|
+
Uses official `subagent` / `subagent_fork` dispatch, Agent Presets, and conversation UI. Keep your existing main-agent preset.
|
|
19
|
+
|
|
20
|
+
[Install](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/install.md) · [Download a release](https://github.com/ccsert/dsh-subagent-hub/releases/latest) · [Configuration example](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/examples/subagent-hub.yml) · [Changelog](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/CHANGELOG.md) · [Contribute](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/CONTRIBUTING.md)
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
| Feature | Behavior |
|
|
25
|
+
|---|---|
|
|
26
|
+
| **Named roles** | Register official `hub-agent-<id>` presets and dispatch with `agent_preset` |
|
|
27
|
+
| **Model selection catalog** | Provide configured routes, capabilities, purposes, and role instructions to the main agent |
|
|
28
|
+
| **Route guard** | Check the global child routes before subagent, fork, and Team creation; named roles can narrow that range further |
|
|
29
|
+
| **Per-session concurrency** | Limit child agents in each parent session, alongside DSH's global capacity |
|
|
30
|
+
| **Native settings form** | Edit models, roles, tags, and management options in **Settings → Subagent Hub** |
|
|
31
|
+
| **Request model visibility** | Read the latest provider/model from the child header; expand for full IDs and recorded reasoning effort |
|
|
32
|
+
|
|
33
|
+
## Screenshots
|
|
34
|
+
|
|
35
|
+
**Models and named agents**
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
**The latest child request**
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
These are the actual plugin components rendered with demo data. They contain no user profile, private conversation, or credentials. See [screenshot provenance](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/screenshots.md) for full-size and narrow views. The Hero was generated with [dsh-image-gen](https://github.com/shanliuling/dsh-image-gen).
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
Tested with **DSH Desktop 0.12.1 / `@deepseek-ai/dsh` 0.2.1-rc.2**. Configure a working model provider in DSH first.
|
|
48
|
+
|
|
49
|
+
1. Download `dsh-subagent-hub-0.10.2.tgz` from [Releases](https://github.com/ccsert/dsh-subagent-hub/releases/latest).
|
|
50
|
+
2. Install it from the target profile directory:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm add /absolute/path/to/dsh-subagent-hub-0.10.2.tgz
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
3. **Append** `"dsh-subagent-hub"` to `dsh.profile.bundles` in that profile's package manifest. Preserve existing bundles and restart DSH to load the plugin code.
|
|
57
|
+
4. Open **Settings → Subagent Hub**, select models already available in your DSH, and add a role. Enable **Manage the official delegation settings** if you want Hub to synchronize the official allowlists. Save, then start a new conversation.
|
|
58
|
+
|
|
59
|
+
Git checkout installation, profile locations, upgrades, and removal are covered in the [installation guide](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/install.md). The package is published as [dsh-subagent-hub](https://www.npmjs.com/package/dsh-subagent-hub); fixed GitHub release archives are also available. The Team/inheritance guard requires 0.10.2 or newer.
|
|
60
|
+
|
|
61
|
+
## Minimal configuration
|
|
62
|
+
|
|
63
|
+
The settings form and profile patch edit the same configuration. The provider/model below must already be available in your DSH:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
- id: subagent-hub
|
|
67
|
+
config:
|
|
68
|
+
maxConcurrent: 4
|
|
69
|
+
manageOfficialSettings: true
|
|
70
|
+
routes:
|
|
71
|
+
- id: flash
|
|
72
|
+
provider: deepseek-official
|
|
73
|
+
model: deepseek-flash
|
|
74
|
+
tags: [fast, cheap]
|
|
75
|
+
agents:
|
|
76
|
+
- id: reviewer
|
|
77
|
+
description: Reviews changes and reports concrete findings
|
|
78
|
+
instructions: Read the diff, report actionable findings, and do not edit files.
|
|
79
|
+
routes: [flash]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Try: **“Use reviewer to review the current changes. Report concrete findings without editing files.”**
|
|
83
|
+
|
|
84
|
+
The main agent selects a role based on the task and catalog. When the official tool exposes the parameter, `agent_preset: hub-agent-reviewer` selects this role. The route guard checks the delegation before dispatch.
|
|
85
|
+
|
|
86
|
+
## Behavior to keep in mind
|
|
87
|
+
|
|
88
|
+
- **Team context selects history.** In the supported runtime, fresh and fork both inherit the Lead model and have no model-selection input. For a specific child model, use a `subagent` tool whose actual schema exposes model selection. See [Team model routing](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/team-model-routing.md).
|
|
89
|
+
- **Global routes also guard inheritance.** A nonempty `routes` list bounds all three creation tools; out-of-list or unconfirmed models are refused. An empty list retains native inheritance. Existing members and later request rewrites are outside this creation check.
|
|
90
|
+
- **Tags guide decisions.** Tags such as `fast`, `reasoning`, or `free` are maintained by you. Use a role's `routes` for a hard route boundary. Tags do not verify pricing or implement automatic fallback.
|
|
91
|
+
- **The guard runs before dispatch.** Model rewrites performed by other plugins during a later child request are outside this guard. Check those plugins when combining route policies.
|
|
92
|
+
- **Fork follows official capabilities.** The target fork provider does not support an independent `agent_preset`; named roles use `subagent`.
|
|
93
|
+
- **Managed settings are opt-in.** `manageOfficialSettings` defaults to `false`. Enabling it synchronizes official allowlists. Disabling it stops syncing and retains settings already written.
|
|
94
|
+
- **Existing conversations keep their tool schema.** Saved configuration is live; use a new conversation for newly added roles or tool parameters. Plugin code upgrades require a DSH restart.
|
|
95
|
+
- **The model badge shows request history.** `lastUsed` identifies the latest request; a different `next` selection is shown separately. A ready empty history says “No request yet”; unavailable data says “Unconfirmed.” A request record does not establish success or billing, and forked history may include inherited requests.
|
|
96
|
+
|
|
97
|
+
## Development (repository checkout)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm ci
|
|
101
|
+
npm run test:unit # no model account required
|
|
102
|
+
npm run docs:check # local documentation links, assets, and metadata
|
|
103
|
+
bash test.sh # real DSH integration in a temporary DSH_HOME
|
|
104
|
+
npm run pack:check # inspect the distributable archive
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This release is verified by **87 unit tests and 23 real-runtime assertions**. Integration uses scripted model streams and makes no external model calls. CI runs unit, documentation, and package checks. See the [settings acceptance record](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/ui-acceptance.md) and [model badge acceptance record](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/model-badge-acceptance.md) for scope and limitations. [Team routing verification](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/team-model-routing.md) covers the new creation checks.
|
|
108
|
+
|
|
109
|
+
Issues and PRs are welcome. Read [CONTRIBUTING](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/CONTRIBUTING.md), the [design notes](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/design.md), and the [release guide](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/docs/releasing.md). The previous v0.3.0 architecture remains available at its tag.
|
|
110
|
+
|
|
111
|
+
[MIT License](https://github.com/ccsert/dsh-subagent-hub/blob/v0.10.2/LICENSE) · Maintained by [ccsert](https://github.com/ccsert)
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# dsh-subagent-hub: one Host row plus one browser config card. It reads `routes` and `agents`
|
|
2
|
+
# (both live-editable from that card on the official Plugins page), registers each agent as an
|
|
3
|
+
# Agent Preset, and adds a system-prompt catalog plus a route guard to the official delegation
|
|
4
|
+
# tools. It does not replace them.
|
|
5
|
+
#
|
|
6
|
+
# - id: subagent-hub
|
|
7
|
+
# config:
|
|
8
|
+
# routes: # exact child models; also the official allowedModels list
|
|
9
|
+
# - { id: flash, provider: <provider>, model: <model>, tags: [fast], note: <label> }
|
|
10
|
+
# - { id: pro, provider: <provider>, model: <model>, tags: [reasoning] }
|
|
11
|
+
# agents: # each becomes preset `hub-agent-<id>`
|
|
12
|
+
# - { id: reviewer, description: Reviews diffs, instructions: '...', routes: [pro] }
|
|
13
|
+
# maxConcurrent: 4 # children running at once per session; 0 = unlimited
|
|
14
|
+
# manageOfficialSettings: false # true == this plugin writes the official allowlists
|
|
15
|
+
- insert:
|
|
16
|
+
- id: subagent-hub
|
|
17
|
+
name: dsh-subagent-hub
|
package/lib/catalog.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Resolve the plugin configuration into the runtime catalog: indexed routes, named agents with
|
|
2
|
+
// stable official preset ids, and the problems that made a row unusable. Pure and testable;
|
|
3
|
+
// the Host service only registers what this returns.
|
|
4
|
+
|
|
5
|
+
import { normalizeDefinition } from './definitions.js'
|
|
6
|
+
import { indexRoutes, knownTags } from './router.js'
|
|
7
|
+
|
|
8
|
+
/** Prefix of every Agent Preset this plugin registers. Also the marker used to own allowlist entries. */
|
|
9
|
+
export const AGENT_PRESET_PREFIX = 'hub-agent-'
|
|
10
|
+
|
|
11
|
+
/** Stable official preset id of one named agent. No fingerprint: the id is written into the profile. */
|
|
12
|
+
export function presetIdOf(agentId) {
|
|
13
|
+
return `${AGENT_PRESET_PREFIX}${agentId}`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {{ routes: Array<Record<string, unknown>>, agents: Array<Record<string, unknown>> }} config
|
|
18
|
+
* @returns {{
|
|
19
|
+
* routes: Map<string, any>,
|
|
20
|
+
* agents: any[],
|
|
21
|
+
* byPreset: Map<string, any>,
|
|
22
|
+
* tags: string[],
|
|
23
|
+
* problems: string[],
|
|
24
|
+
* }}
|
|
25
|
+
*/
|
|
26
|
+
export function buildCatalog(config) {
|
|
27
|
+
const { routes, problems: routeProblems } = indexRoutes(config.routes ?? [])
|
|
28
|
+
const problems = [...routeProblems.map(problem => `routes: ${problem}`)]
|
|
29
|
+
const agents = []
|
|
30
|
+
const byPreset = new Map()
|
|
31
|
+
for (const [index, raw] of (config.agents ?? []).entries()) {
|
|
32
|
+
let agent
|
|
33
|
+
try {
|
|
34
|
+
agent = normalizeDefinition(raw, `agents[${index}]`)
|
|
35
|
+
} catch (error) {
|
|
36
|
+
problems.push(String(error?.message ?? error))
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
const missing = (agent.routes ?? []).filter(id => !routes.has(id))
|
|
40
|
+
if (missing.length > 0) {
|
|
41
|
+
problems.push(`agent "${agent.id}" names unknown route${missing.length > 1 ? 's' : ''}: ${missing.join(', ')}`)
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
const presetId = presetIdOf(agent.id)
|
|
45
|
+
if (byPreset.has(presetId)) {
|
|
46
|
+
problems.push(`duplicate agent id "${agent.id}"`)
|
|
47
|
+
continue
|
|
48
|
+
}
|
|
49
|
+
const entry = { ...agent, presetId }
|
|
50
|
+
agents.push(entry)
|
|
51
|
+
byPreset.set(presetId, entry)
|
|
52
|
+
}
|
|
53
|
+
return { routes, agents, byPreset, tags: knownTags(routes), problems }
|
|
54
|
+
}
|