DSH / PLUGIN / TOOLS

dsh-tool-subagent

v0.1.0-rc.5deepseek-ai / deepseek-harness47f943859b

Included in DSHPluginsModel tools & skillsBuilt-in sourceConfigurable
Runtime anatomy
HOSTCLIENTUITOOLDATAFLOW

Overview

dsh-tool-subagent

The model-facing delegation tool over one configured ctx.subagents provider. Changing the provider changes transport without changing the execution contract.
BUILT-IN / ATOMIC
Already shipped with DSH — no separate install

This is an atomic module already shipped with Harness, not a standalone profile layer.

Capabilities

What it contributes

HostCordis loadableConfigurable
Client / UIHost only0 contributions
Model tools0None declared
Profile stateenabledbase, headless, preset:code, preset:cordis, preset:standard, web

README / EN

Package documentation

@deepseek-ai/dsh-tool-subagent

English | 中文

The model-facing delegation tool over one configured ctx.subagents provider. Changing the provider changes transport without changing the execution contract.

Provider selection and lifecycle

Each plugin instance binds one provider to one toolName; the model receives no provider selector. Load another distinctly named instance to expose another transport. The tool registers only while its provider exists, avoiding sibling load-order and provider-reload dependencies. Its description follows provider.inheritsParentContext: fresh children require standalone prompts, while forked children already see completed parent turns.

A foreground call passes the execution signal through startup and execution, awaits run.result, and always awaits run.dispose() before returning. Only completed returns the canonical { kind: 'foreground', runId, output: JsonValue[] }, rendered as the same final text; abort, refusal, token limit, and other failures become errored tool results whose message appends the child's preserved partial text (the SubagentResult.output selection) after the stop-reason headline, so a truncated answer is never reported as success yet never silently lost. If result collection and disposal both reject, the errored result preserves both diagnostics.

backgroundMode selects both the background route and the omitted run_in_background default. one-shot waits in the foreground by default; an explicit true registers a plain parent-owned Task and returns canonical { kind: 'background', jobId }, rendered as started background subagent job <id>, even when the provider supports continuable children. Generic task tools own its later status, collection, cancellation, and notices. continuable runs in the background when the argument is omitted or true; an explicit false waits for the result in the foreground. Its background route requires a provider with the prepareContinuable capability, calls ctx.subagents.startContinuable(), and returns { kind: 'continuable', subagentId }, rendered as started subagent <childId>. The route resolves at inbox acceptance: the child owns its own turns from there, so this call neither waits for nor collects a result. The child's transcript by that id remains the source of its detailed output, and the optional global send_message tool sends it more work. The continuation service delivers one settlement notice whenever the child's Activation ends, containing its outcome and any final assistant message independently of report. Starting continuable work does not require send_message to be loaded. See the background subagent Agent Note, the continuable subagents Agent Note, and the background-first delegation Agent Note.

toolFilter changes the child's global tool layer but is not a parent-derived authority ceiling. See the agent-scope security non-goal.

Config

Key Meaning
provider (required) Provider name (spawn, fork, acp, ...).
toolName Model-facing name, default subagent; distinct for every loaded instance.
enableRunInBackground Exposes background mode, default true; disabling also rejects forced background calls.
backgroundMode Background lifecycle policy, default one-shot. one-shot defaults calls to foreground; continuable defaults them to background, requires the provider's prepareContinuable capability, and returns a durable child id without requiring the follow-up tool.
agentOptions Provider-specific child provider, model, and positive maxTokens; the in-process provider treats explicit values as overrides of inherited parent options.
persona Per-child persona; requires provider persona capability.
toolFilter Per-child global-tool restriction; requires toolFilter capability.
maxDepth Absolute delegation-depth cap, default 3 (0 forbids delegation); a numeric cap requires the depthLimit capability and fails the mount without it. 'provider-managed' sends no cap for an out-of-process provider whose budget belongs to the child harness. The tool stays visible at the cap; each attempted start checks the calling agent's current depth and returns an errored tool result when rejected.

Concurrency

Foreground and background calls are concurrency-safe: sibling delegations in one assistant message overlap under the loop's rolling pool (maxParallelToolCalls), and results still commit in model order. Children work in their own sessions and a run never mutates the parent session; the one-shot background form's one parent-owned write — registering a Task — is a synchronous, commutative insertion that tolerates concurrent dispatch, so overlapping background calls acquire their job ids in dispatch-race order. Coordinating sibling workspace effects belongs to the model, exactly as it already does for background and continuable children. See the parallel subagent Agent Note and the parallel tool-call Agent Note.

Model Experience

Tool schema

What the model sees

The generated default subagent schema under this instance's configured name while its provider exists. Provider context inheritance changes the tool and prompt descriptions. Enabled background mode adds run_in_background: continuable mode documents its true default, runtime settlement notice, and explicit foreground override, while one-shot mode documents its false default and the job id collected with job_output or stopped with job_kill. While the tool is visible in an assembly's scope, a tool:<toolName> system-prompt section tells the model to start independent continuable delegations together, keep working while they run, and choose foreground only when its next action depends on the result; a tool restriction removes both its schema and this guidance.

Token effect

Fixed schema cost per parent request; each provider instance adds one schema, and each continuable instance adds one short system-prompt section.

KV Cache effect

Prefix-stable while provider instances, names, descriptions, and schemas are unchanged. Provider registration lifecycle may invalidate parent reuse from the first changed tool definition.

Foreground result

What the model sees

The call retains the description and prompt. Success contains only the child's final text; other outcomes become Error: <message>. Intermediate child steps stay out of the parent.

Token effect

The prompt and result remain in parent history until compaction; child working context remains in the child.

KV Cache effect

Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.

Background result

What the model sees

Start returns exactly started subagent <childId> in configured continuable mode, or started background subagent job <id> in configured one-shot mode. In one-shot mode the generic task surface provides later status, final output, cancellation responses, and notices. In continuable mode this tool returns no result of its own; the child's settlement reaches the parent as a service-owned notice, an independently loaded send_message tool delivers follow-ups, and the child's transcript by its id is the source of its detailed output.

Token effect

The acknowledgement is retained; a one-shot final output enters parent history only when collected or injected, while a continuable child's output never returns through this tool — its settlement notice arrives independently of any tool result.

KV Cache effect

Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.

Known Limitations and Deferred Work

  • Background runs expose no result through this tool — a one-shot task's final output is collected through the generic task surface, and a continuable child's output stays in its own session, read by its subagent id. The settlement notice states how that child ended and carries any final assistant message, but it is not this call's return value and cannot be awaited here.
  • Duplicate names across waiting one-shot instances are detected late (TODO(subagent-dup-toolname)) — continuable instances reserve their prompt-section name during plugin application, but preventing provider-registration rollback for waiting one-shot instances requires a registry of intended names.
  • Child policy is fixed per instance — another model, persona, tool filter, or depth cap requires another distinctly named tool.

LIMITATIONS

Known limitations

- **Background runs expose no result through this tool** — a one-shot task's final output is collected through the generic task surface, and a continuable child's output stays in its own session, read by its subagent id. The settlement notice states how that child ended and carries any final assistant message, but it is not this call's return value and cannot be awaited here. - **Duplicate names across waiting one-shot instances are detected late** (`TODO(subagent-dup-toolname)`) — continuable instances reserve their prompt-section name during plugin application, but preventing provider-registration rollback for waiting one-shot instances requires a registry of intended names. - **Child policy is fixed per instance** — another model, persona, tool filter, or depth cap requires another distinctly named tool.