Skip to content

dsh-subagent-conductor

Verified

dsh-subagent-conductor · v0.2.8 · MIT · Web UI

EN: Settings and default-route layer for official DeepSeek Harness subagents: session/role/global model routing with a composer selector. ZH: 面向 DeepSeek Harness Web 官方子代理的设置与默认路由层:会话/角色/全局模型路由与输入框选择器。

Install

dsh plugin add dsh-subagent-conductor

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Readme

dsh-subagent-conductor

English

Portable settings transport — the plugin now resolves its settings scope on both the settingsScope (≤ 0.1.5) and configForms (≥ 0.1.7-rc.1) hosts, so the composer selector and Settings card keep working across the rename.

Lifecycle-safe subagent routing settings for DeepSeek Harness Web: per-root-session provider/model/reasoning-effort selection in the composer, role templates with a visual editor, and a global default route. It does not patch DSH, does not replace or wrap the stock subagent / subagent_fork tools, and does not register its own delegation tool.

中文

面向 DeepSeek Harness Web 官方子代理工具(subagent / subagent_fork)的设置与默认路由层:输入框根会话选择、角色模板与全局默认路由。不修改 DSH、不替换官方工具、不注册自有委派工具、不使用私有 marker。

How it works

Delegation and explicit model selection belong to the official tools. Conductor only provides layers that run before the official choice at every subagent request boundary:

root-session composer selection
> default role route
> global Settings default
> official tool selection (explicit tool arguments / tool-instance defaults)
> native DSH inheritance

Provider, model, and reasoning effort resolve independently through those layers. The final provider/model pair is validated as one exact route through llm.resolveModelInfo; a conductor reasoning effort is applied only when that exact model publishes it in reasoning.efforts. When every conductor layer is empty the request is left exactly as the official flow produced it, so pure official/inherit delegation never changes. Invalid configured routes degrade with a Host warning and keep the official/inherited request intact — stock delegation never breaks.

The official layer is read from the child's creation-time AgentOptions snapshot (provider / model / reasoningEffort). That snapshot already contains explicit model-facing tool arguments, tool-instance config defaults, or the parent route copied at creation, so the listener needs no private marker and has no cold-resume special case: the same deterministic precedence applies to fresh, nested, and cold-resumed children.

Composer selector

The selector renders on the left of the main model seat (conversation.input.right). It picks one provider/model (and optionally a reasoning effort) per root session: root and child views resolve the same key through the official session-summary lineage (origin / parentId) and fail closed instead of writing a child-only key. It labels the effective source of each value (default role / root-session / global default / official-or-native) and writes through the revision-aware official Settings API.

Settings card

The card registers on both settings seats, because DSH moved it: on ≤ 0.1.5 it is a card under Settings → Plugins (settings.plugin.item), and on 0.1.7-rc.2 — which removed that slot — it is the configuration page of the subagent-conductor bundle row in the 插件 panel (the first sidebar panel icon) (plugins.row.config, keyed <package name>#<row id>). On 0.1.7-rc.2 the same card is also a first-class page one click deep in 设置 (settings.section, id yotk-subagent-conductor, order 62), so it stays reachable from the settings list as well as from its bundle row, and on that page and on the row's configuration page it starts expanded instead of collapsed (the Plugins-list card on ≤ 0.1.5 keeps its collapsed default). Both seats manage:

  • global default route (provider/model pair plus optional effort),
  • the default role (applied only when no root-session selection exists),
  • visual role CRUD (id, display name, description, provider/model pair, effort), with JSON import/export as an advanced bulk-edit and backup path.

@deepseek-ai/schemastery is a private dependencies entry whose floor must be ≥ 3.18.4 (^3.18.4): the profile hoists an older line (3.18.2) that satisfies a lower floor, and an entry whose Config exposes no volatile field is dropped from SettingsForms.describe() — the card then renders nothing with no error.

Roles are route presets with display metadata. They do not carry persona or tool filters: those are start-time fields owned by the official tool rows, and conductor does not claim a runtime channel for them in v0.2.

Migration from 0.1.x

v0.1's private AgentOptions marker, the subagent_direct delegation tool, and the runtime persona/toolFilter/transport/maxDepth/background controls are removed: the official tool rows own delegation, persona/toolFilter config, depth and background policy now. Existing subagent-conductor namespace values are normalized on read — dropped v1 keys are ignored and never resurrected. Behavior change is deliberate: routing precedence is now session > default role > global default > official choice (v0.1 put an explicit role marker above the session selection).

On DSH ≥ 0.1.7 a v0.1 section needs one manual step. That release removed the settings document: on the first launch the host renames settings.yaml to settings.yaml.imported and imports each section into its entry's Config, one section at a time. Because a v0.1 section still carries keys v0.2 dropped (subagentProvider, backgroundMode, maxDepth, enableRunInBackground), and the import refuses any path the entry's Config does not declare, the whole section is rejected — including defaultRoute and every sessionSelections entry, so the plugin starts from defaults (the composer selector reads inherit). The host only logs a warning; this plugin additionally reports it once per launch, naming the file and the offending keys. To carry the values over, put the part you want to keep on the subagent-conductor row of the profile patch:

- id: subagent-conductor
  config:
    defaultRoute:
      provider: <provider>
      model: <model>
      reasoningEffort: <effort>
    sessionSelections:
      <session-id>: { provider: <provider>, model: <model> }

Only keys this version's Config declares are accepted; subagentProvider, backgroundMode, maxDepth and enableRunInBackground cannot be represented any more and are ignored by design.

Install

dsh plugin --profile web add dsh-subagent-conductor

Restart the existing DSH Web process afterwards: the Host scans the browser plugin roster at startup, so the composer selector and the Settings card appear only after that restart. Then open the Subagent Conductor settings — on ≤ 0.1.5 Settings → Plugins → Subagent Conductor, on 0.1.7-rc.2 the subagent-conductor row's configuration page in the 插件 panel (the first sidebar panel icon) — to manage the global default route and the default role.

Local development, from this package directory:

dsh plugin --profile web add .

Either form records the package in the profile's dsh.profile.bundles, which is what mounts the Host request listener and serves the client bundle.

Development

From this directory run:

npm test
npm run check
npm pack --dry-run

See docs/design.md for the v0.2 contract. HANDOFF.md records the superseded v0.1 review and is kept for history.

Acknowledgements

Design research reviewed the MIT-licensed projects dsh-subagent-model-picker and dsh-plugin-subagent-director. This package keeps its own settings/lifecycle contract and does not copy their delegation implementation.

License

MIT