Files
deepseek-harness/packages/tasks/tool-tasks/README.md
Yichen Jiang 9956528495 Merge remote-tracking branch 'origin/master' into codex/rfc-subagent-background-tasks
# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/bash.md
#	docs/event-producer-consumer.md
#	docs/rfc/implemented/feature/2026-07-06-sandbox.md
#	docs/rfc/proposed/architecture/2026-06-20-generic-long-running-tool-runtime.md
#	examples/AGENTS.md
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/permission-switching/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/system-prompt.golden.md
#	examples/coding-agent/cordis.yml
#	examples/sandbox-acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/sandbox-acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/sandbox-acp-agent/tests/snapshots/mode-switching/session.jsonl
#	packages/bash/bash-local/README.md
#	packages/bash/bash-local/src/index.ts
#	packages/bash/bash-local/tests/executor.spec.ts
#	packages/bash/bash-sandbox/README.md
#	packages/bash/bash-sandbox/src/index.ts
#	packages/bash/bash/README.md
#	packages/bash/bash/src/index.ts
#	packages/bash/bash/src/types.ts
#	packages/bash/tool-bash/README.md
#	packages/bash/tool-bash/src/index.ts
#	packages/bash/tool-bash/tests/tools.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-core/README.md
#	packages/core/agent-core/src/index.ts
#	packages/subagent/subagent/README.md
#	packages/subagent/tool-subagent/README.md
#	packages/subagent/tool-subagent/src/index.ts
#	packages/ui/acp-agent/README.md
#	packages/ui/acp/README.md
#	packages/ui/stdio-agent/README.md
#	packages/util/brand/src/index.ts
#	scripts/doc-budgets.manifest.json
2026-07-14 18:05:46 +08:00

4.3 KiB

@deepseek-ai/dsh-tool-tasks

The model-facing background task control surface over ctx.tasks: three kind-agnostic tools, the completion-notice injection, and the prompt section that teaches the background habit. Loading this plugin calls ctx.tasks.attachSurface('tool-tasks'), which is what arms producers' ctx.tasks.start().

Tools

  • task_output(task_id, wait?, timeout_ms?) — non-blocking read by default (stream kinds: the consuming delta since the previous read; final kinds: the final answer once terminal); every response ends with a [status: …] line (generic status + producer detail, e.g. [status: completed, exit code: 0]). wait: true blocks until settlement, bounded by waitTimeoutMs/maxWaitTimeoutMs config; a timed-out wait returns [status: running] and leaves the task alive.
  • task_list() — the caller's tasks, <id> [<kind>] <status> — <label> per line.
  • task_kill(task_id, reason?) — requests cancellation and returns immediately; the logged reason is forwarded to the producer. An already-terminal task is described via a non-consuming snapshot (never eats a pending delta).

ACP render intent: all three are generic cards (read/read/execute) — a task read is not a terminal.

Completion notices

On onTaskDone, injects background task <id> (<kind>: <label>) finished [status: …]. Read its output with task_output. into the owning agent's session (agent.inject() — durable context for the next request, not a wake-up). Suppressed when the snapshot is reported (the model already killed it, or a read/wait returned the end) — never a redundant "finished". The disposed-owner race is contained; a missing agent registry drops the notice.

Config

key default meaning
waitTimeoutMs 30000 wait duration when task_output sets wait without timeout_ms
maxWaitTimeoutMs 600000 hard cap; larger model-supplied timeout_ms values are clamped

A config whose default exceeds the cap fails loud at load.

Model Experience

System prompt

What the model sees: Every request in this plugin's registration scope contains the background-task guidance below. Agent-scoped tool filtering can hide the control schemas without removing this independently registered section.

Token effect: Small fixed input cost per request while the plugin is active.

Background-task guidance

Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.

Tool schemas

What the model sees: The model sees the generated task_output, task_list, and task_kill schemas while this control surface is visible.

Token effect: Fixed schema cost on each request where the tools are visible.

Task results and notices

What the model sees: Reads return a producer-owned output delta or (no new output), followed by [status: <status>] with optional producer detail. Listing returns (no background tasks) or one <id> [<kind>] <status> — <label> line per visible task. Kill returns requested cancellation of task <id> or task <id> had already finished [status: ...]. An unreported owned completion injects exactly background task <id> (<kind>: <label>) finished [status: ...]. Read its output with task_output.

Token effect: Results and completion notices are retained in the parent session until compaction; stream reads consume their cursor and do not repeat prior output.

Known Limitations and Deferred Work

  • Completion notices do not wake idle agents — they become durable context for the next request; callers needing an immediate result must use task_output.
  • Stream reads are single-consumer — this control surface exposes the task runtime's one consuming cursor rather than independent observers.
  • Unowned tasks have no session fence — deployments exposing background starts outside an agent must provide their own caller policy or avoid ownerless tasks.