@argszero/cordis-plugin-subagent-wait 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 argszero
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # cordis-plugin-subagent-wait
2
+
3
+ `wait_for_agent` for the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`).
4
+
5
+ A thin orchestration helper for **continuable background subagents**: it blocks — under a bounded timeout —
6
+ until a specific continuable child is **terminal**, instead of forcing the parent to re-derive completion by
7
+ polling `list_agents` (whose `idle` status collapses "between turns" and "waiting on its own children").
8
+
9
+ ## Why
10
+
11
+ `list_agents` reports a child's status as `running | idle | ready`. But `idle` is ambiguous:
12
+
13
+ - an `idle` child may simply be between turns;
14
+ - **an `idle` child may be blocked-waiting on its own grandchildren** — and is *not* terminal.
15
+
16
+ So a parent that polls `list_agents` and treats `status !== 'running'` as "done" can hang on a child that is
17
+ actually waiting on its own descendants. `status === 'ready'` (only in storage) is also **not** a terminal
18
+ result to collect — it means "resumable, not finished."
19
+
20
+ `wait_for_agent` solves this by keying on the **settlement signal**, not a status read: the harness's
21
+ continuation manager publishes a `subagent-settled` notice (a typed message source, `form: notice`, carrying
22
+ the child's `senderSessionId`) into the **parent agent's inbox** exactly when the child settles and is
23
+ disposed. This plugin binds to that signal (via the `agent/inbox/inserted` event) and falls back to a bounded
24
+ registry/status read, so a blocked-waiting child is never mistaken for terminal.
25
+
26
+ ## Install
27
+
28
+ ```sh
29
+ npm install @argszero/cordis-plugin-subagent-wait
30
+ ```
31
+
32
+ Mount the plugin into your `dsh` profile (it registers the `wait_for_agent` tool):
33
+
34
+ ```yaml
35
+ # cordis.yml
36
+ plugins:
37
+ "@argszero/cordis-plugin-subagent-wait": {}
38
+ ```
39
+
40
+ > Requires the subagent continuation runtime (`@deepseek-ai/dsh-subagent` is a peer dependency). The tool
41
+ > is a thin model-facing adapter over `ctx.subagents` and the live Agent registry.
42
+
43
+ > **Version pin.** The `@deepseek-ai/dsh-*` `latest` dist-tag is frozen at an old `0.0.1-rc.1`; the current
44
+ > harness line is published under `next` (`0.1.2-rc.1`). This plugin's peer range (`>=0.1.0`) resolves to
45
+ > `next` and **excludes** the stale `latest`. If you install by tag, prefer:
46
+ >
47
+ > ```sh
48
+ > npm install @argszero/cordis-plugin-subagent-wait @deepseek-ai/dsh-tools@next @deepseek-ai/dsh-subagent@next
49
+ > ```
50
+
51
+ ## Usage
52
+
53
+ After starting a **continuable** background subagent, call `wait_for_agent` to block until it settles:
54
+
55
+ ```
56
+ wait_for_agent agent_id="<child session id>" timeout_ms=30000
57
+ ```
58
+
59
+ Returns:
60
+
61
+ ```json
62
+ { "settled": true, "status": "settled", "agent_id": "<child session id>" }
63
+ ```
64
+
65
+ When the timeout lapses (and the child is still alive), `settled` is `false` and `status` reflects the
66
+ observed runtime status (`running` / `idle` / `ready`). A `false` result means "the child may still be
67
+ running" — not "the child failed."
68
+
69
+ ### Parameters
70
+
71
+ | param | type | default | description |
72
+ |-------|------|---------|-------------|
73
+ | `agent_id` | `string` | — (required) | The durable session id of your direct continuable child. |
74
+ | `timeout_ms` | `number` | `30000` | Max milliseconds to block. Capped at `300000`. |
75
+
76
+ ## Exported helper
77
+
78
+ The same logic is available as a parent-side helper for other plugins:
79
+
80
+ ```ts
81
+ import { waitForAgent } from '@argszero/cordis-plugin-subagent-wait'
82
+ import type { Context } from '@deepseek-ai/cordis'
83
+
84
+ const { settled, status } = await waitForAgent(ctx, parentAgent, childId, {
85
+ signal, // caller cancellation
86
+ timeoutMs: 30_000, // bounded wait (default 30s)
87
+ })
88
+ // settled: true → the child disposed (terminal)
89
+ // status: 'idle' → timeout, child alive but between turns (NOT terminal)
90
+ ```
91
+
92
+ ## Design notes
93
+
94
+ - **Keyed on settlement, not status.** The wait binds to the `subagent-settled` notice carrying the child id,
95
+ and re-checks registry terminality (disposal) as a fallback. An `idle` child waiting on its own
96
+ grandchildren never satisfies the wait.
97
+ - **Timeout is mandatory.** A model-facing tool must never be left awaiting a child that never settles, so
98
+ the wait is always bounded.
99
+ - **Cooperative cancellation.** The wait observes the tool's `signal` and resolves promptly on abort.
100
+ - **Composes public surface only.** It widens no core interface: it consumes `agent/inbox/inserted` (a
101
+ registered typed event), `ctx.subagents.listChildren()`, and the live Agent registry. The core
102
+ `wait_for_agent` primitive, if upstream adopts one, stays a separate harness concern.
103
+
104
+ ## License
105
+
106
+ MIT
package/lib/index.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * A thin orchestration helper for continuable background subagents: a
3
+ * `wait_for_agent` model-facing tool (and a parent-side `waitForAgent`
4
+ * helper) that blocks — under a bounded timeout — until a specific
5
+ * continuable child is terminal, instead of forcing the parent to re-derive
6
+ * completion by polling `list_agents` (whose `idle` status collapses
7
+ * "between turns" and "waiting on its own children").
8
+ *
9
+ * The wait is keyed on the *settlement signal*, not a status read: the
10
+ * continuation manager publishes a `subagent-settled` notice
11
+ * (`SubagentSettledMessageSource`, `form: notice`) carrying the child's
12
+ * `senderSessionId` into the parent agent's inbox exactly when the child
13
+ * settles. `wait_for_agent` binds to that typed source kind (and falls back to
14
+ * a bounded registry/status read), so an `idle` child that is merely
15
+ * blocked-waiting on its own grandchildren is never mistaken for terminal.
16
+ *
17
+ * This composes *existing public surface* — the `agent/inbox/inserted` event,
18
+ * `ctx.subagents.listChildren()`, and the live Agent registry — and widens no
19
+ * core interface. It is the orchestration-layer package the community invited
20
+ * (see the subagent continuation discussion); the core `wait_for_agent`
21
+ * primitive, if any, stays a separate harness concern.
22
+ *
23
+ * @module @argszero/cordis-plugin-subagent-wait
24
+ */
25
+ import type { Context } from '@deepseek-ai/cordis';
26
+ import type { Agent } from '@deepseek-ai/dsh-agent';
27
+ import type { SessionId } from '@deepseek-ai/dsh-session';
28
+ export declare const name = "tool-subagent-wait";
29
+ export declare const inject: string[];
30
+ /** Default maximum milliseconds the wait may block before returning the current status. */
31
+ export declare const DEFAULT_TIMEOUT_MS = 30000;
32
+ /** Per-call cap so a single tool invocation cannot block a step indefinitely. */
33
+ export declare const MAX_TIMEOUT_MS = 300000;
34
+ /** Observed terminal/status shape returned by {@link waitForAgent}. */
35
+ export type WaitStatus = 'settled' | 'running' | 'idle' | 'ready';
36
+ /** One result: whether the child became terminal, plus its observed status. */
37
+ export interface WaitResult {
38
+ readonly settled: boolean;
39
+ readonly status: WaitStatus;
40
+ }
41
+ /**
42
+ * Block until `childId` reaches agent terminality, or `timeoutMs` elapses, or
43
+ * `signal` aborts. Returns the terminal/observed status so the caller can
44
+ * distinguish "settled" from "still running at timeout."
45
+ *
46
+ * @param ctx - context carrying the live Agent registry and the parent's
47
+ * scope for `agent/inbox/inserted` subscription.
48
+ * @param parent - the exact calling agent whose inbox carries the
49
+ * `subagent-settled` notice.
50
+ * @param childId - the durable child session id to wait on.
51
+ * @param options - `signal` for cancellation and `timeoutMs` bound.
52
+ */
53
+ export declare function waitForAgent(ctx: Context, parent: Agent, childId: SessionId, options?: {
54
+ signal?: AbortSignal;
55
+ timeoutMs?: number;
56
+ }): Promise<WaitResult>;
57
+ /**
58
+ * Register the `wait_for_agent` tool.
59
+ * @param ctx - context carrying the tool registry, subagent service, and live Agent registry.
60
+ */
61
+ export declare function apply(ctx: Context): void;
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGtE,eAAO,MAAM,IAAI,uBAAuB,CAAA;AACxC,eAAO,MAAM,MAAM,UAAmC,CAAA;AAEtD,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB,QAAS,CAAA;AAExC,iFAAiF;AACjF,eAAO,MAAM,cAAc,SAAU,CAAA;AAErC,uEAAuE;AACvE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjE,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAC5B;AAcD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,KAAK,EACb,OAAO,EAAE,SAAS,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACzD,OAAO,CAAC,UAAU,CAAC,CA+DrB;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAqDxC"}
package/lib/index.js ADDED
@@ -0,0 +1,175 @@
1
+ /**
2
+ * A thin orchestration helper for continuable background subagents: a
3
+ * `wait_for_agent` model-facing tool (and a parent-side `waitForAgent`
4
+ * helper) that blocks — under a bounded timeout — until a specific
5
+ * continuable child is terminal, instead of forcing the parent to re-derive
6
+ * completion by polling `list_agents` (whose `idle` status collapses
7
+ * "between turns" and "waiting on its own children").
8
+ *
9
+ * The wait is keyed on the *settlement signal*, not a status read: the
10
+ * continuation manager publishes a `subagent-settled` notice
11
+ * (`SubagentSettledMessageSource`, `form: notice`) carrying the child's
12
+ * `senderSessionId` into the parent agent's inbox exactly when the child
13
+ * settles. `wait_for_agent` binds to that typed source kind (and falls back to
14
+ * a bounded registry/status read), so an `idle` child that is merely
15
+ * blocked-waiting on its own grandchildren is never mistaken for terminal.
16
+ *
17
+ * This composes *existing public surface* — the `agent/inbox/inserted` event,
18
+ * `ctx.subagents.listChildren()`, and the live Agent registry — and widens no
19
+ * core interface. It is the orchestration-layer package the community invited
20
+ * (see the subagent continuation discussion); the core `wait_for_agent`
21
+ * primitive, if any, stays a separate harness concern.
22
+ *
23
+ * @module @argszero/cordis-plugin-subagent-wait
24
+ */
25
+ import { brandString } from '@deepseek-ai/dsh-brand';
26
+ import { defineTool } from '@deepseek-ai/dsh-tools';
27
+ export const name = 'tool-subagent-wait';
28
+ export const inject = ['tools', 'subagents', 'agents'];
29
+ /** Default maximum milliseconds the wait may block before returning the current status. */
30
+ export const DEFAULT_TIMEOUT_MS = 30_000;
31
+ /** Per-call cap so a single tool invocation cannot block a step indefinitely. */
32
+ export const MAX_TIMEOUT_MS = 300_000;
33
+ /** Whether one child is terminal according to the live Agent registry. */
34
+ function isAgentTerminal(agents, id) {
35
+ return agents.get(id) === undefined;
36
+ }
37
+ /** Whether an inserted inbox message is the settlement notice for `childId`. */
38
+ function isSettlementFor(message, childId) {
39
+ const source = message.source;
40
+ return source.kind === 'subagent-settled'
41
+ && source.senderSessionId === childId;
42
+ }
43
+ /**
44
+ * Block until `childId` reaches agent terminality, or `timeoutMs` elapses, or
45
+ * `signal` aborts. Returns the terminal/observed status so the caller can
46
+ * distinguish "settled" from "still running at timeout."
47
+ *
48
+ * @param ctx - context carrying the live Agent registry and the parent's
49
+ * scope for `agent/inbox/inserted` subscription.
50
+ * @param parent - the exact calling agent whose inbox carries the
51
+ * `subagent-settled` notice.
52
+ * @param childId - the durable child session id to wait on.
53
+ * @param options - `signal` for cancellation and `timeoutMs` bound.
54
+ */
55
+ export async function waitForAgent(ctx, parent, childId, options = {}) {
56
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
57
+ // A terminal child is one the registry no longer holds. This is the
58
+ // settlement-by-disposal path: the continuation manager disposes the
59
+ // AgentHandle when a continuable child settles, so its absence IS terminal.
60
+ if (isAgentTerminal(ctx.agents, childId)) {
61
+ return { settled: true, status: 'settled' };
62
+ }
63
+ const signal = options.signal;
64
+ return new Promise((resolve) => {
65
+ let done = false;
66
+ let disposeInbox;
67
+ let removeAbort;
68
+ let timer;
69
+ const finish = (settled, status) => {
70
+ if (done)
71
+ return;
72
+ done = true;
73
+ if (timer !== undefined)
74
+ clearTimeout(timer);
75
+ if (disposeInbox !== undefined)
76
+ disposeInbox();
77
+ if (removeAbort !== undefined) {
78
+ signal?.removeEventListener('abort', onAbort);
79
+ removeAbort = undefined;
80
+ }
81
+ resolve({ settled, status });
82
+ };
83
+ const onInserted = (payload) => {
84
+ // Scope-filtered dispatch delivers only this agent's messages, but the
85
+ // listener is registered on the shared ctx — filter by the exact parent.
86
+ if (payload.agent !== parent)
87
+ return;
88
+ if (!isSettlementFor(payload.message, childId))
89
+ return;
90
+ finish(true, 'settled');
91
+ };
92
+ const onAbort = () => finish(false, 'running');
93
+ // A settlement notice establishes terminality, but the notice may have
94
+ // already been claimed from the inbox before we subscribed. Close that
95
+ // window by re-checking registry terminality after subscribing.
96
+ disposeInbox = ctx.on('agent/inbox/inserted', onInserted);
97
+ if (signal !== undefined) {
98
+ signal.addEventListener('abort', onAbort, { once: true });
99
+ removeAbort = () => signal.removeEventListener('abort', onAbort);
100
+ }
101
+ timer = setTimeout(() => {
102
+ // Timeout: re-read the live registry. If the child disposed during the
103
+ // wait boundary, report settled; otherwise report the observed status.
104
+ const agent = ctx.agents.get(childId);
105
+ const observed = agent === undefined
106
+ ? 'settled'
107
+ : agent.status === 'running' ? 'running' : 'idle';
108
+ finish(agent === undefined, observed);
109
+ }, timeoutMs);
110
+ // Unref so the timer does not keep the process alive on a long idle wait.
111
+ timer.unref();
112
+ // Post-subscription re-check: the child may have settled between the
113
+ // initial status read and our listener registration.
114
+ if (isAgentTerminal(ctx.agents, childId))
115
+ finish(true, 'settled');
116
+ });
117
+ }
118
+ /**
119
+ * Register the `wait_for_agent` tool.
120
+ * @param ctx - context carrying the tool registry, subagent service, and live Agent registry.
121
+ */
122
+ export function apply(ctx) {
123
+ ctx.tools.register(defineTool({
124
+ name: 'wait_for_agent',
125
+ description: 'Block until a direct continuable background subagent reaches terminality (settles and is disposed), '
126
+ + 'or until a bounded timeout elapses. Use this instead of repeatedly calling `list_agents` and '
127
+ + 'interpreting `idle`: an `idle` child may simply be waiting on its own children, and is NOT terminal. '
128
+ + 'This call keys on the settlement signal (the `subagent-settled` notice the manager sends to your '
129
+ + 'inbox when the child finishes), so it is correct even when the child is blocked-waiting on '
130
+ + 'grandchildren. Returns `true` when the child settled, `false` when the timeout lapsed (the child may '
131
+ + 'still be running). A timeout is mandatory so a model is never left awaiting a child that never settles.',
132
+ parameters: {
133
+ agent_id: {
134
+ type: 'string',
135
+ required: true,
136
+ description: 'The agent id of your direct continuable child to wait on.',
137
+ },
138
+ timeout_ms: {
139
+ type: 'number',
140
+ description: 'Maximum milliseconds to block before returning the current status. '
141
+ + `Defaults to ${DEFAULT_TIMEOUT_MS} (${DEFAULT_TIMEOUT_MS / 1000}s), capped at ${MAX_TIMEOUT_MS / 1000}s.`,
142
+ },
143
+ },
144
+ output: {
145
+ schema: {
146
+ type: 'object',
147
+ additionalProperties: false,
148
+ properties: {
149
+ settled: { type: 'boolean', required: true },
150
+ status: { type: 'string', required: true, enum: ['settled', 'running', 'idle', 'ready'] },
151
+ agent_id: { type: 'string', required: true },
152
+ },
153
+ },
154
+ render: (args, value) => [{
155
+ type: 'text',
156
+ text: value.settled
157
+ ? `agent ${args.agent_id} settled`
158
+ : `agent ${args.agent_id} is ${value.status} after waiting (timeout)`,
159
+ }],
160
+ },
161
+ async execute(args, exec) {
162
+ const parent = exec.agent;
163
+ if (!parent) {
164
+ throw new Error('wait_for_agent requires a calling agent (exec.agent was undefined)');
165
+ }
166
+ const timeoutMs = args.timeout_ms === undefined ? DEFAULT_TIMEOUT_MS : Math.min(args.timeout_ms, MAX_TIMEOUT_MS);
167
+ const result = await waitForAgent(ctx, parent, brandString(args.agent_id), {
168
+ signal: exec.signal,
169
+ timeoutMs,
170
+ });
171
+ return { settled: result.settled, status: result.status, agent_id: args.agent_id };
172
+ },
173
+ }));
174
+ }
175
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@argszero/cordis-plugin-subagent-wait",
3
+ "description": "wait_for_agent for the dsh harness: block until a continuable background subagent settles (via the subagent-settled notice) instead of polling list_agents and misreading idle.",
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/index.d.ts",
11
+ "default": "./lib/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "lib",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "peerDependencies": {
20
+ "@deepseek-ai/cordis": ">=4.0.0 <5",
21
+ "@deepseek-ai/dsh-tools": ">=0.1.0",
22
+ "@deepseek-ai/dsh-subagent": ">=0.1.0",
23
+ "@deepseek-ai/dsh-agent": ">=0.1.0",
24
+ "@deepseek-ai/dsh-session": ">=0.1.0",
25
+ "@deepseek-ai/dsh-brand": ">=0.1.0"
26
+ },
27
+ "peerDependenciesMeta": {
28
+ "@deepseek-ai/dsh-agents": {
29
+ "optional": true
30
+ }
31
+ },
32
+ "scripts": {
33
+ "build": "tsc -p .",
34
+ "prepack": "tsc -p .",
35
+ "test": "node test/logic.test.mjs"
36
+ },
37
+ "engines": {
38
+ "node": "^22.19 || >=24"
39
+ },
40
+ "keywords": [
41
+ "deepseek",
42
+ "dsh",
43
+ "cordis",
44
+ "plugin",
45
+ "subagent",
46
+ "wait",
47
+ "orchestration",
48
+ "continuable"
49
+ ],
50
+ "license": "MIT",
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/argszero/cordis-plugin-subagent-wait.git"
57
+ },
58
+ "devDependencies": {
59
+ "@deepseek-ai/cordis": ">=4.0.0 <5",
60
+ "@deepseek-ai/dsh-tools": ">=0.1.0",
61
+ "@deepseek-ai/dsh-subagent": ">=0.1.0",
62
+ "@deepseek-ai/dsh-agent": ">=0.1.0",
63
+ "@deepseek-ai/dsh-session": ">=0.1.0",
64
+ "@deepseek-ai/dsh-brand": ">=0.1.0",
65
+ "typescript": "^7.0.2"
66
+ },
67
+ "dependencies": {
68
+ "@types/node": "^22.20.1"
69
+ }
70
+ }