DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Plugin Subagent Roles — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-plugin-subagent-roles

Plugin Subagent Roles

DeepSeek Harness 的文件定义子代理角色:项目角色文件(.dsh/roles)和全局角色文件(~/.dsh/roles)、紧凑的角色目录,以及真正按角色进行的工具筛选。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-plugin-subagent-roles@0.3.0
README兼容性版本

兼容性与来源证明

Plugin Subagent Roles 以 dsh-plugin-subagent-roles 发布,当前版本为 0.3.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/16

版本

0.3.0stable
2026/9/16
0.2.1stable
2026/9/13
0.2.0stable
2026/9/13
查看其余 1 个版本收起版本
0.1.0stable
2026/9/13

相关插件

正在加载相关插件…

最新版
0.3.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
192.6 kB
文件数
19
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 1
周下载
0
最近提交
2026/9/16
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 agents-orchestration 分类下经过校验的插件。

Headless@deepseek-ai/dsh-headlessdsh one-shot bundle:基于 dsh-base 的直接核心 Agent/Session 运行器,不包含 Host、HTTP 或浏览器层Experimental Agent Team Web Profile@deepseek-ai/dsh-experimental-agent-team-web-profile用于 Agent Teams Remote 和 UI 插件的实验性 Web 配置层Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序Subagent Claude Code@deepseek-ai/dsh-subagent-claude-code基于官方 Agent SDK 的一次性 Claude Code 子代理提供方

README

dsh-plugin-subagent-roles

English | 中文 | Changelog (中文)

Summary

dsh-plugin-subagent-roles defines subagent roles as files. A role is one Markdown file: YAML frontmatter carries a display name, a routing description, an optional LLM route, and a tool policy; the body is the persona the child runs with. Project roles live in <project>/.dsh/roles/, global roles in ~/.dsh/roles/, and a project role wins when the same id exists in both.

The plugin registers one delegation tool and advertises the roles found for the current workspace with a compact catalog line. When a role is delegated to, the child starts with that role's persona and only the tools its policy allows — the delegating agent never carries the persona text, and a project without role files sees no catalog at all.

Install

# from npm
dsh plugin --profile web add dsh-plugin-subagent-roles

# or a local checkout
dsh plugin --profile web add link:/path/to/dsh-plugin-subagent-roles

Restart the profile afterwards (dsh web). The package ships a bundle patch, so it inserts its single row without any composition edit. Requires Node.js 20 or newer, together with a DSH deployment that provides @deepseek-ai/dsh-tools and @deepseek-ai/dsh-subagent.

Quick start

Create a role file in the project:

---
displayName: Code Reviewer
description: Reviews a diff for correctness, security, and missing tests, and reports findings by severity.
provider: deepseek-official
model: deepseek-v4-flash
reasoningEffort: low
tools: [read, grep, glob]
---
You are a code reviewer. Read the diff before judging it, separate blocking
issues from suggestions, and cite file and line for every finding.

Then ask the agent to delegate — “have the code-reviewer role review this diff” — or call the tool directly:

subagent_role({ role: "code-reviewer", prompt: "Review the staged diff.", description: "review staged diff" })

Roles are read when the prompt is assembled and again when a delegation starts, so editing a role file takes effect without restarting DSH. examples/delegation-prompts.md has dispatch prompts in the same style (中文).

Role files

Where roles are read from

PrecedencePathNotes
1<project>/.dsh/roles/<id>.md<project> is the nearest ancestor of the session working directory that contains a project marker (.git by default); the working directory itself when no marker is found.
2~/.dsh/roles/<id>.mdShared across projects. dshHome overrides the location.

A role file may be a symlink. Files are read by name, so the id is the file stem and must be kebab-case.

File format

The frontmatter is a YAML mapping; the body is the persona.

FieldRequiredMeaning
descriptionyesOne line shown in the catalog; the delegating agent routes on it.
namenoMust equal the file id when present; a guard against renaming a file without its declaration.
displayNamenoHuman-readable name; defaults to the id.
whenToUsenoExtra routing hint appended to the catalog line.
provider, modelnoLLM route for the child. Declare both or neither; omitting them inherits the parent's route.
reasoningEffortnoEffort for the child; applies together with the route.
toolsnoAllow list shorthand, e.g. [read, grep, glob].
toolFilternoExplicit policy: { allow: [...], deny: [...] }.

tools and toolFilter are mutually exclusive. Unknown frontmatter keys are rejected rather than ignored, so a typo cannot silently widen a role's tools.

The persona body may reference the prompt variables {{cwd}}, {{model}}, and {{provider}} — exactly the three the agent loop registers; they are interpolated by the harness for the child. A deployment that registers more can list them in personaVariables; a reference to anything else is rejected when the file is read, because an unknown variable throws on every turn of the child that uses it. References are matched exactly (no spaces inside the braces), and the catalog fields — description, displayName, whenToUse — must not contain {{ at all, because catalog text passes through the same interpolation before it reaches the model.

Configuration

The row accepts these options; pass them by overriding the row by id in the profile patch:

# ~/.dsh/profiles/web/cordis.patch.yml
- id: subagent-roles
  name: dsh-plugin-subagent-roles
  config:
    catalogDescriptionMaxLength: 120
OptionDefaultMeaning
toolNamesubagent_roleModel-facing delegation tool name.
subagentProviderspawnSubagent transport provider.
backgroundModeone-shotone-shot or continuable.
enableRunInBackgroundtrueExpose run_in_background on the tool.
maxDepthunsetNumeric delegation-depth cap; unset leaves it to the provider. 0 refuses every delegation.
defaultRoleunsetRole used when a call omits role.
catalogcompactcompact renders the role catalog; off renders nothing.
catalogScopemainmain advertises roles to top-level agents; all includes subagents.
catalogDescriptionMaxLength160Per-role description cap in the catalog line.
projectRootMarkers['.git']Markers searched upward from the session working directory.
projectRootTtlMs5000How long a resolved project root is trusted before the tree is re-walked, so a git init under a live session is noticed.
dshHome$DSH_HOME or ~/.dshLocation of the global roles/ directory.
maxBodyBytes65536Persona size limit, counted in UTF-8 bytes. A file larger than this plus 64 KiB of frontmatter is refused before it is read.
personaVariables['cwd', 'model', 'provider']Prompt variables a persona may reference. Extend only for variables the deployment really registers.

Tool policy

A role's policy decides which tools its child can see and call. tools (and toolFilter.allow) is an allow list: everything not listed disappears from the child — schema and prompt guidance together — and calls to it are refused. toolFilter.deny removes named tools while keeping the rest. Entries accept the glob characters * and ?, e.g. mcp__demo__*.

Globs are expanded at delegation time against the tool names visible to the delegating agent, so a name that is not registered yet cannot fail the delegation. An unavailable literal name is dropped with a warning; onMissingTool: 'error' turns that into a refusal instead. An allow list that expands to nothing is passed through as an empty allow list, which hides every inherited tool rather than granting everything.

Two cases are handled explicitly:

  • run_code, the presentation transport for PTC deployments, is never passed to a policy: the tool registry can list it, but the core refuses to restrict by that name.
  • Tools that the delegating agent registers in its own scope are inherited by the parent but are not part of a child's scope chain. Naming one makes the core reject the child. The plugin drops those names, retries the delegation once, and warns.

Diagnostics

Enable enableListTool to register subagent_roles, which reports every role with its source, file path, bound route, persona size, the expanded policy, and its schema-character budget, plus any file that was skipped and why.

To inspect a finished delegation, read the child's session log:

node scripts/inspect-session-budget.mjs --project <project-dir>
node scripts/inspect-session-budget.mjs <session-dir> --all --grep "You are a code reviewer"

The script decodes a session log read-only and prints the system-prompt size, the tool schemas the session requested, and whether the role catalog reached that session.

Settings

The trim policy is published as a host settings namespace (subagent-roles) and paired with a card in Settings → Plugins, so a deployment can retune it without editing files. The row config is the namespace's base layer; the card writes the user layer to ~/.dsh/settings.yaml, and the change applies to the next child turn (applies: live) with no restart.

The card draws its own chrome, which the host requires of any browser half, following the host's PluginCard: a collapsible header (title, description, rotating chevron), an unsaved badge, the staged form, and Reset / Discard / Save in the footer, styled with the host's own rules and the same --dsw-alias-* tokens as the bash, agent-loop, subagent-model-selection, and web-search cards. Two deliberate deviations: the badge is hand-drawn instead of the host's Tag primitive, and the failure line uses --dsw-alias-state-error-primary (the host's own --dsw-alias-label-error is not defined in the installed theme).

Editing follows the host's card conventions: every control renders staged text, nothing is written before Save (the settings scope fences the write with the revision the draft read), Discard drops the drafts, and a reset only STAGES the composed default — the write it performs is a clear, so the field re-inherits the deployment config instead of pinning today's default as an override. A field whose staged text still equals the resolved value is not written at all, so editing one field never pins the other. Editing a field cancels a reset staged for it. A clean save collapses the card; a failed save stays open with the drafts intact and the header's unsaved badge visible.

All copy follows the Language setting: the card registers its own locale dictionaries (zh / en, identical keys) and declares locale: <namespace> on the registration, so the renderer binds t for it. With no locale service it falls back to its own binding, then to the English dictionary — never to hard-coded bilingual labels.

The card edits the same keys the row config takes. Two pairing rules come from the host, not from this plugin: the Plugins tab dispatches one slot key per served namespace and renders only the cards registered under those keys, which is why the plugin ships a browser half (lib/client.js, declared through dsh.client and exports["./client"]); and a card whose namespace the deployment does not serve is never dispatched. A deployment that mounts a second row under a renamed tool gets the namespace subagent-roles-<tool> — that one has no card (the browser half binds the default key), so tune it in settings.yaml directly.

A deployment without a settings provider keeps the row config as the sole authority; a namespace that refuses to register (an invalid stored section, a duplicate from another row) is logged and degrades to the row config rather than costing the trim.

How it works

  • Catalog. One prompt section, rendered per assembly, lists the roles of the assembling agent's workspace: a framing line plus - <id> (<displayName>): <description> per role. It renders empty — and costs nothing — when a project has no roles, when the catalog is switched off, when the agent is a subagent, or when the delegation tool is not visible to that agent.
  • Delegation. subagent_role resolves the role against the delegating agent's working directory, then starts a child through ctx.subagents with the role's persona, route, and tool filter. The model-facing wording follows the transport provider: a fork provider already seeds the child with this conversation's completed turns, so the tool says to build on them instead of demanding a fully self-contained prompt. The route is preflighted through llm.resolveCallConfig() before the child exists, so a typo in a role's model or reasoningEffort is reported to the delegating agent rather than thrown from inside child creation.
  • Multiple rows. The catalog section and the diagnostic tool are named after the row (<toolName>:catalog, listToolName), so a profile can mount a second row for another transport provider (toolName: subagent_role_fork) without either registration colliding.
  • Child prompt trim. Core registers most tool-guidance sections as plain text — only dsh-tool-fs, dsh-tool-fs-search, dsh-tool-web, and dsh-file-reference-local evaluate the scope — so a child keeps paying for guidance whose tool the role's policy hid from it, plus the Web GUI, harness-checkout, and deliverable instructions it can never act on. One host-plane system-prompt/assemble listener drops exactly that dead text: tool:<name> guidance for a registered tool the child cannot see, group guidance (tool:jobs, tool:goal) when every tool its own text names is invisible, and — in full mode, the default — the named prompt parts. The rule-derived part needs no maintenance; the named part is per-row overridable because whether a child should still see the harness-checkout or deliverable line is a deployment judgement, not a fact. One list covers both arrays on purpose: the installed core registers context:file-reference as a SECTION despite its name, which a contexts-only list silently let through. Measured on a real delegation: a role child's prompt went from 5,765 to 1,904 characters (−67%) while the parent's stayed byte-identical.
  • Inheritance. A child joins its parent's agent preset, so it keeps the parent's prompt and tools except where the role's policy removes them. The role persona shadows the deployment persona prefix for that child only.

Limitations

  • Tools registered into a child's own scope are not affected by a role's tool policy; the core applies restrictions to inherited tools only. The delegation runtime and some tool plugins register per agent, so a child can end up with a small number of tools beyond its allow list.
  • Hiding a tool removes its schema and any scope-aware prompt guidance. Prompt sections with static text stay in the child's prompt — which is what childPromptTrim removes, and why tools mode needs no maintenance while full mode matches section names that a future core release may rename (a renamed section stops being trimmed; nothing breaks).
  • A role persona replaces the deployment persona prefix for the child. The persona suffix, such as the working-directory line, is kept.
  • respectModelSelection prefers the policy a Session captured (the same durable projection the official delegation tool writes) and falls back to the live subagent-model-selection setting, which is what seeds a fresh Session. A change therefore applies to Sessions that have not captured a policy yet.
  • The plugin contributes one card (Settings → Plugins → Plugin configuration) and no Settings navigation group of its own. A card is the host convention for plugin configuration; a dedicated section like the plugin market's exists because that plugin owns a whole browsing page.
  • childPromptTrim: 'off' in the row config unmounts the Settings card with the trim: no namespace is registered, so the Plugins tab has no key to dispatch (deliberate — an operator's off is a kill switch the UI must not be able to flip back). To stop trimming while keeping it configurable, set the CARD's mode to off, or use tools in the row config.
  • The Settings card covers the default row's namespace (subagent-roles). A second row renamed through toolName owns a different namespace and therefore shows no card.
  • childPromptTrim applies to EVERY subagent assembly the host plane observes, not only to children this plugin started: the runtime records no role marker on a child, so subagent and counterpart rows benefit too. Tools registered in an agent's own scope (subagent, list_agents) are absent from the registry's global view, so their guidance is never trimmed — a child that really can call one keeps its instructions.
  • The delegation tool declares no timeoutMs unless you set one; an unbounded foreground delegation can outlive the conversation that started it. Bound long runs with timeoutMs, maxDepth, or the dispatch prompt.
  • Discovery caches are bounded (512 entries), so a very large number of distinct projects in one host process re-stats files more often than it otherwise would. Results are unaffected.

Development

npm test                                      # unit tests (node --test)
npm run lint                                  # node --check over lib/, scripts/, test/
node --test --experimental-test-coverage      # per-file coverage

The runtime lives in lib/: roles.js (discovery and parsing), catalog.js (catalog text), policy.js (tool policies), route.js (LLM route), tool.js (delegation and diagnostic tools), config.js (row options), and index.js (plugin wiring).

CI runs npm run lint and npm test on Node.js 20, 22, and 24.

Releasing

  1. Add a ## [<version>] entry to CHANGELOG.md (written in Chinese). The publish workflow refuses to ship a version the changelog does not document.
  2. npm version <patch|minor|major> commits the bump and creates the tag; push the commit and the tag.
  3. .github/workflows/publish.yml then runs the tests, checks that the tag matches package.json, checks the changelog entry, and publishes through npm trusted publishing (OIDC) with a provenance attestation, so no long-lived token is stored in the repository.

Register publish.yml as a trusted publisher on the package's npm settings page before the first automated release.

License

MIT

respectModelSelectiontrueHonor the official subagent-model-selection allow list: a Session's captured policy first, otherwise the live setting.
onMissingTooldropUnavailable tool names: drop warns and continues, error refuses the delegation.
timeoutMsunsetTool-call deadline for one foreground delegation. Unset leaves it unbounded.
enableListToolfalseRegister the diagnostic tool.
listToolNamesubagent_rolesName of the diagnostic tool, so a second row can coexist with the first.
childPromptTrimfullTrim a SUBAGENT's prompt: full drops tool guidance the child cannot use PLUS the named prompt parts, tools keeps the named parts, off disables the listener. A top-level agent's prompt is never touched.
childPromptTrimNames['harness:source', 'app:web-surface', 'ui:deliverable-file-references', 'context:file-reference']Prompt parts full mode drops, matched against sections AND contexts. Empty the list to keep them all.
  • The diagnostic script needs Node.js 22.15 or newer for multi-frame zstd decoding; the plugin itself runs on Node.js 20.