YixiangTang/dsh-tool-subagent-batch ↗★ 0
dsh-tool-subagent-batch
Rolling-window batch orchestration for DeepSeek Harness subagents with synchronous and asynchronous modes, user-owned concurrency, and per-task acceptance reports.
安裝
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:YixiangTang/dsh-tool-subagent-batch說明文件
閱讀完整 README ↗Configuration
| Field | Default | Meaning |
|---|---|---|
provider | spawn | Subagent provider name on ctx.subagents. |
toolName | subagent_batch | Model-facing batch tool name. |
statusToolName | subagent_batch_status | Model-facing status tool for async batches. |
mode | sync | Default mode: sync or async. |
concurrency | auto | User-owned window: an integer 1..maxConcurrency, or auto. |
maxConcurrency | 8 | Ceiling for auto, the environment, and (when enabled) the model. |
allowModelConcurrency | false | false hides the model parameter; "lower" lets the model only shrink the window; true lets it choose up to maxConcurrency. |
maxTasks | 32 | Largest queue one call may carry. |
outputCharsPerTask | 12000 | Characters of each child answer retained in the report. |
maxAsyncBatches | 8 | Concurrent async batches allowed per parent session. |
retainedBatches | 16 | Finished batches kept for later status reads. |
maxDepth | Host setting | Absolute delegation-depth cap; omit to use subagent.maxDepth (default 1). |
Unknown fields are rejected at mount, so a typo fails loudly instead of being silently ignored.
Usage
Sync mode
Ask the main agent for a batch, for example:
I have six independent modules to review. Use
subagent_batchin sync mode, at most three at a time, and report each result.
{
"tasks": [
{ "description": "Review auth module", "prompt": "Review src/auth for ... Report findings only." },
{ "description": "Review billing module", "prompt": "Review src/billing for ..." },
{ "description": "Review search module", "prompt": "Review src/search for ..." }
],
"mode": "sync",
"fail_fast": false
}
With concurrency: 3 the three children start immediately. With concurrency: 2, the third starts as soon as either of the first two settles. The call returns the complete report.
Async mode
Start the same six reviews in async mode, then let me know when they are done.
The model starts the batch:
{
"tasks": [
{ "description": "Review auth module", "prompt": "Review src/auth for ..." },
{ "description": "Review billing module", "prompt": "Review src/billing for ..." }
],
"mode": "async"
}
The immediate result is a running snapshot:
{
"batchId": "batch-1f0c...",
"mode": "async",
"status": "running",
"total": 2,
"completed": 0,
"failed": 0,
"cancelled": 0,
"skipped": 0,
"pending": 1,
"running": 1,
"concurrency": 3,
"concurrencySource": "config",
"startedAt": "2026-10-30T09:41:00.000Z",
"durationMs": 12,
"results": [
{ "index": 1, "description": "Review auth module", "status": "running", "childId": "session-...", "output": "", "outputTruncated": false, "durationMs": 12 },
{ "index": 2, "description": "Review billing module", "status": "pending", "output": "", "outputTruncated": false, "durationMs": 0 }
]
}
Later, collect it:
{
"batchId": "batch-1f0c...",
"wait": true,
"timeout_ms": 120000
}
subagent_batch_status accepts:
| Field | Meaning |
|---|---|
batchId | Required. The id returned by the async start. |
wait | Wait until the batch settles or the timeout expires. |
timeout_ms | Wait bound, 1000..600000, default 60000. |
cancel | Cancel the batch and wait for its children to stop. |
Only the session that started the batch can read or cancel it. Without wait, the call returns a snapshot immediately; poll it to show progress.
Result
{
"batchId": "batch-1f0c...",
"mode": "sync",
"status": "completed",
"total": 3,
"completed": 2,
"failed": 1,
"cancelled": 0,
"skipped": 0,
"pending": 0,
"running": 0,
"concurrency": 3,
"concurrencySource": "config",
"startedAt": "2026-10-30T09:41:00.000Z",
"finishedAt": "2026-10-30T09:41:48.000Z",
"durationMs": 48210,
"results": [
{
"index": 1,
"description": "Review auth module",
"status": "completed",
"childId": "session-...",
"stopReason": "completed",
"output": "Found two issues: ...",
"outputTruncated": false,
"durationMs": 22100
},
{
"index": 2,
"description": "Review billing module",
"status": "failed",
"childId": "session-...",
"stopReason": "error",
"output": "",
"outputTruncated": false,
"durationMs": 900,
"error": "child stopped with reason \"error\"",
"diagnostic": "..."
}
]
}
childId is a durable session id. In deployments that mount @deepseek-ai/dsh-tool-subagent-control, the main agent can use send_message to continue a child, for example to ask for a corrected answer, without rerunning the whole batch.
Statuses
Batch status:
| Status | Meaning |
|---|---|
running | The pool has not settled; some tasks may be pending or running. |
completed | Every task settled (individually completed, failed, or skipped). |
cancelled | The batch was cancelled before every task settled. |
Task status:
| Status | Meaning |
|---|---|
pending | Queued, not admitted yet. |
running | A child is executing this task. |
completed | Child stopped with stopReason: "completed". |
failed | Start rejection, child error, or non-completed stop reason. |
cancelled | Child stopped because the batch was cancelled. |
skipped | Never started, because fail_fast fired or the batch was cancelled. |