DSH / PLUGIN / ORCHESTRATION

dsh-subagent-claude-code

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

Included in DSHPluginsWorkflow & orchestrationBuilt-in sourceConfigurable
Runtime anatomy
HOSTCLIENTUITOOLDATAFLOW

Overview

dsh-subagent-claude-code

This package registers the fixed claude-code subagent provider. Each accepted run invokes the official Claude Agent SDK in the delegating Session's workspace, resolves the native claude executable through the shared subprocess service, submits one self-contained text task, and returns only the final answer through the shared dsh-subagent result 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 stateabsentIncluded in DSH

README / EN

Package documentation

@deepseek-ai/dsh-subagent-claude-code

English | 中文

This package registers the fixed claude-code subagent provider. Each accepted run invokes the official Claude Agent SDK in the delegating Session's workspace, resolves the native claude executable through the shared subprocess service, submits one self-contained text task, and returns only the final answer through the shared dsh-subagent result contract.

Start and ownership

start(request) accepts only a non-empty sequence of text blocks and derives the child cwd from the parent Session. It creates one private AbortController, calls the official SDK query(), and publishes the run only after the SDK's spawnClaudeCodeProcess hook has supplied a live CLI handle owned by dsh-subprocess. A failure or cancellation before publication closes the query, terminates any acquired process tree, waits for it to exit, and rejects start().

The SDK receives the exact concatenated text task. The provider iterates the complete SDK message stream and accepts only a result message with subtype: "success", is_error: false, and a nonblank result, followed by normal iterator completion. Every SDK error subtype, an error-marked success, a missing answer, iterator failure, protocol failure, or process failure maps to error; the provider produces neither max-tokens nor refusal.

Local cancellation wins the result race and maps to aborted. dispose() is idempotent: it aborts the run, asks the SDK query to close, invokes the shared process-tree termination escalation, and waits for whole-tree exit. SDK graceful close expresses protocol intent; the subprocess handle remains the authority for process quiescence. Result failure and independent teardown failure remain separate.

Native settings and interaction

The provider deliberately omits the SDK settingSources option. The official SDK therefore reads the host's normal user, project, and local Claude settings relative to the parent Session cwd, including native account state and product configuration. The provider neither copies nor filters those files and does not create or modify login state.

Each query sets persistSession: false and disables AskUserQuestion. It supplies no canUseTool, elicitation, or dialog callback, so unattended interactions fail through the SDK instead of waiting for a user interface this provider does not own.

Capabilities and context

The provider advertises no optional start-time capabilities and reports inheritsParentContext: false. Claude Code receives the standalone text task and the parent Session cwd, but not the parent conversation, persona, tool filter, depth policy, or structured-output contract. Every run has an independent SDK query, cancellation controller, CLI process, and non-persisted product session.

Configuration

Key Default Meaning
env {} Explicit SDK/CLI environment layered over the shared credential-scrubbed parent environment.
disposeGraceMs 3000 Positive finite grace in milliseconds, no greater than MAX_TIMER_DELAY_MS, between the shared process-tree owner's termination tiers; disposal then waits for whole-tree exit.

Production resolves claude from the subprocess execution world's credential-scrubbed PATH, with explicit env entries applied, and passes the resulting path to the SDK as pathToClaudeCodeExecutable. On Windows, a resolved .cmd or .bat path is carried as a quoted, per-spawn environment value that cmd.exe /v:off expands once, so valid path metacharacters remain data. The pinned SDK's fixed flags then occupy cmd's command tail and contain no cmd metacharacters; they are not ordinary Windows argv. Native settings and authentication remain authoritative. The plugin does not install another CLI, select a model, create a product home, log in, or probe an account. Credential-shaped ambient variables are removed before the explicit env overlay is applied, so an API key or token intended for the child must be supplied there. Non-credential endpoint variables such as ANTHROPIC_BASE_URL, along with ordinary ambient values such as PATH and HOME, remain inherited unless overridden.

Shipped profiles load this provider once on the host and start no Claude process until a tool call. Full Agent Presets carry the tool row below with disabled: true; copy a preset and remove that field to expose subagent_claude_code only to agents composed from the copy. A custom host composition can still use both rows directly.

- id: subagent-claude-code
  name: '@deepseek-ai/dsh-subagent-claude-code'
  config:
    env:
      ANTHROPIC_API_KEY: !!js process.env.ANTHROPIC_API_KEY

- id: tool-subagent-claude-code
  name: '@deepseek-ai/dsh-tool-subagent'
  disabled: true
  config:
    provider: claude-code
    toolName: subagent_claude_code
    enableRunInBackground: false
    maxDepth: provider-managed

Product compatibility and evidence

The runtime dependency is pinned to @anthropic-ai/claude-agent-sdk@0.3.220. Production runs the native claude installation. The keyless real-product test uses the SDK-distributed Claude Code 2.1.220 CLI as a deterministic fixture, routed through the same native executable-resolution and Windows batch-shim path; it does not claim compatibility with every independently installed version. Loader composition proves that both product packages coexist without starting either product.

The project owner's identity-scoped distribution authorization covers the official SDK and the official CLI/platform payloads declared by each SDK version. THIRD_PARTY_NOTICES.md discloses the current optional payload closure without classifying its declared terms as permissive; unrelated non-permissive runtime dependencies continue to fail the notices gate.

Model Experience

Child request

What the model sees

The Claude Code child receives the standalone text task as one fresh SDK query. Its workspace is the parent Session cwd, while its model, system instructions, tools, permissions, and authentication come from the host's native Claude settings and product installation.

Token effect

The child pays for an independent Claude Code context and query. Child tokens do not enter the parent's context.

KV Cache effect

Independent of the parent request cache. Reuse depends only on Claude Code's own model, instructions, tools, native settings, and fresh query.

Parent tool result, indirectly

What the model sees

Through dsh-tool-subagent, the parent sees only the strict final Claude Code answer or the consumer's exact error for a non-completed result. Claude Code reasoning, tool activity, intermediate messages, stderr, workspace diffs, usage, and product ids are not copied into the parent Session.

Token effect

Parent input grows only by the final answer or error retained in the tool result. This provider adds no parent tool schema by itself.

KV Cache effect

Append-only: the new tool result follows the reusable parent request prefix.

Known Limitations and Deferred Work

  • One fresh query and process per run — there is no continuation, resume, pooling, progress stream, or product-session persistence.
  • Host settings are intentionally authoritative — project and user settings can change model, tools, and behavior; the provider does not provide a filtered or hermetic production mode.
  • Product installation and account state remain native — a missing or incompatible claude, configuration error, or authentication failure is surfaced as a startup or run error; the plugin provides no installer or login flow.
  • The SDK platform CLI remains in the install closure — production ignores it in favor of the host claude, but the current SDK optional dependency is still installed and supplies the keyless compatibility fixture. Removing that payload belongs to the separate product installation-closure follow-up.
  • No human interaction pathAskUserQuestion is disabled and other interactive callbacks are absent, so tasks requiring new approval or input fail instead of suspending.
  • Final text only — reasoning, intermediate messages, tool traffic, usage, stderr, and workspace diffs remain product-local.
  • No optional shared capabilities — output schemas, child personas, tool filtering, and harness depth enforcement are rejected by the shared service for this provider.
  • No wall-clock timeout or side-effect rollback — the caller cancels long work, and files or external systems changed before cancellation are not restored.

LIMITATIONS

Known limitations

- **One fresh query and process per run** — there is no continuation, resume, pooling, progress stream, or product-session persistence. - **Host settings are intentionally authoritative** — project and user settings can change model, tools, and behavior; the provider does not provide a filtered or hermetic production mode. - **Product installation and account state remain native** — a missing or incompatible `claude`, configuration error, or authentication failure is surfaced as a startup or run error; the plugin provides no installer or login flow. - **The SDK platform CLI remains in the install closure** — production ignores it in favor of the host `claude`, but the current SDK optional dependency is still installed and supplies the keyless compatibility fixture. Removing that payload belongs to the separate product installation-closure follow-up. - **No human interaction path** — `AskUserQuestion` is disabled and other interactive callbacks are absent, so tasks requiring new approval or input fail instead of suspending. - **Final text only** — reasoning, intermediate messages, tool traffic, usage, stderr, and workspace diffs remain product-local. - **No optional shared capabilities** — output schemas, child personas, tool filtering, and harness depth enforcement are rejected by the shared service for this provider. - **No wall-clock timeout or side-effect rollback** — the caller cancels long work, and files or external systems changed before cancellation are not restored.