Files
deepseek-harness/packages/subagent/tool-subagent-control
Dudu-0223 9e5ae0d12e fix: address codex review round 3
- Strict steer additionally requires an OPEN STEP: between steps the
  loop may be awaiting its continuation/turn-stop checkpoints, where
  pending steering was already folded and a terminal stop discards a
  later arrival. A message accepted during an open step is drained and
  recorded at that step's settlement before any terminal decision, so
  the acknowledged-then-discarded window is closed. New keyless test
  holds agent/turn-stop open and pins the rejection.
- tool-subagent-control README: distinguish synchronous not-delivered
  errors from started-Task failures (unknown/foreign/descriptor-less
  ids settle the started Task as failed), and drop the claim that the
  completion notice carries the child's response.
2026-08-02 04:34:15 +08:00
..
2026-08-02 04:34:15 +08:00

@deepseek-ai/dsh-tool-subagent-control

The globally named send_message tool: a thin adapter over ctx.subagentControl.sendMessage(). Provider-bound @deepseek-ai/dsh-tool-subagent instances register distinct delegation tools per transport; this separately loaded package registers the one shared control tool, so multiple delegation tools never register duplicate global controls.

The tool performs no lifecycle routing. The control service decides between live delivery to the running activation's existing Task and a fresh Task that cold-resumes the durable child; the tool renders which route was taken and the relevant Task id. A control-service throw becomes an errored tool result stating the message was not delivered.

Model Experience

Tool schema

What the model sees

The generated send_message schema: subagent_id and message, with delivery-or-continue semantics and the task_output collection path described.

Token effect

Fixed schema cost per parent request.

KV Cache effect

Prefix-stable; the schema does not change at runtime.

Delivery result

What the model sees

message delivered to running task <taskId> when the message joined the running activation, or message started task <taskId> continuing subagent <subagent_id> when it started a cold-resume activation. Synchronous routing failures — an ownership conflict, a lost steering race, no live-delivery capability — are errored results whose message states the message was not delivered. An absent activation always reports started: lookup runs inside that Task, so an unknown, foreign, or descriptor-less child surfaces as the started Task settling failed (read through task_output), not as an errored send_message result.

Token effect

One short acknowledgement per call; the child's response enters parent history only when collected through task_output (the completion notice is a status line, never the response).

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

  • A delivered message has no independent result — its effect is reflected in the current Task's eventual result; only a started follow-up owns a fresh Task result.
  • Delivery can lose timing races — a message racing task settlement, cancellation, or cleanup fails explicitly rather than falling through to cold resume; the model retries after the task settles.