@crewhaus/tool-task 0.2.0 → 0.2.2

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.
Files changed (2) hide show
  1. package/dist/index.js +39 -3
  2. package/package.json +9 -9
package/dist/index.js CHANGED
@@ -14,9 +14,19 @@
14
14
  * becomes `instructions`.
15
15
  * 3. Built-in `general-purpose` fallback.
16
16
  *
17
- * Concurrency: marked `concurrencySafe: true` because parallel sub-agents
18
- * are independent — each gets its own IsolatedContext. T7 in
19
- * sub-agent-spawner exercises 10-way parallelism end-to-end.
17
+ * Concurrency: a Task dispatch runs in parallel with its siblings ONLY
18
+ * when the specific sub-agent it spawns is itself entirely read-only —
19
+ * that per-call decision can't be a static flag, so Task stays statically
20
+ * `readOnly: false` (never eligible by flags) and supplies a
21
+ * `concurrencyClassifier` that opts a call back in iff the resolved
22
+ * sub-agent's whole effective tool catalog is read-only + concurrency-safe
23
+ * + non-destructive. Each eligible spawn gets its own IsolatedContext
24
+ * (fresh crypto-random sessionId/runId, own event log), and the parent's
25
+ * append-only log serialises writes at the syscall, so concurrent spawns
26
+ * don't collide. A child that can write/edit/bash, spawn its own Task, or
27
+ * touch module-level tool state (TodoWrite, Remember) is excluded and
28
+ * serialises. The runtime bounds how many run at once (see
29
+ * `runChatLoop({ maxConcurrentTools })`, default 4).
20
30
  *
21
31
  * The bridge is opaque from `tool-catalog`'s perspective; we cast inside
22
32
  * `execute` so ordinary tools (which never touch `ctx.bridge`) keep their
@@ -193,6 +203,32 @@ export function createTaskTool(opts = {}) {
193
203
  concurrencySafe: true,
194
204
  readOnly: false,
195
205
  destructive: false,
206
+ // Per-call parallel eligibility (see the module header). A dispatch is
207
+ // parallel-safe iff the resolved sub-agent's ENTIRE effective tool set
208
+ // is read-only + concurrency-safe + non-destructive. Fail-closed: an
209
+ // unresolvable/unsafe `subagent_type`, a malformed input, or an
210
+ // inherit-the-whole-catalog child (which would include write/bash/Task)
211
+ // all return false and route the call serial. `catalog` is the parent
212
+ // tool set, from which `buildChildCatalog` derives the child's tools.
213
+ concurrencyClassifier: (input, catalog) => {
214
+ const parsed = taskInputSchema.safeParse(input);
215
+ if (!parsed.success)
216
+ return false;
217
+ let def;
218
+ try {
219
+ def = resolveSubAgentDefinition(parsed.data.subagent_type, opts);
220
+ }
221
+ catch {
222
+ return false;
223
+ }
224
+ const childTools = buildChildCatalog(catalog, def);
225
+ // An empty child catalog is not provably safe (it means "inherit
226
+ // nothing" or an unresolved filter) — require an explicit, non-empty,
227
+ // uniformly-read-only tool set.
228
+ if (childTools.length === 0)
229
+ return false;
230
+ return childTools.every((t) => t.concurrencySafe && t.readOnly && !t.destructive);
231
+ },
196
232
  execute: async (input, ctx) => {
197
233
  const bridge = ctx?.bridge;
198
234
  if (bridge === undefined || bridge.spawnSubAgent === undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewhaus/tool-task",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Task(description, prompt, subagent_type?) tool — spawns a sub-agent and returns its final message (Section 13)",
6
6
  "main": "dist/index.js",
@@ -15,18 +15,18 @@
15
15
  "test": "bun test src"
16
16
  },
17
17
  "dependencies": {
18
- "@crewhaus/agent-context-isolation": "0.2.0",
19
- "@crewhaus/errors": "0.2.0",
20
- "@crewhaus/sub-agent-permission-inheritance": "0.2.0",
21
- "@crewhaus/tool-builder": "0.2.0",
22
- "@crewhaus/tool-catalog": "0.2.0",
18
+ "@crewhaus/agent-context-isolation": "0.2.2",
19
+ "@crewhaus/errors": "0.2.2",
20
+ "@crewhaus/sub-agent-permission-inheritance": "0.2.2",
21
+ "@crewhaus/tool-builder": "0.2.2",
22
+ "@crewhaus/tool-catalog": "0.2.2",
23
23
  "yaml": "^2.6.0",
24
24
  "zod": "^3.23.8"
25
25
  },
26
26
  "devDependencies": {
27
- "@crewhaus/event-log": "0.2.0",
28
- "@crewhaus/permission-engine": "0.2.0",
29
- "@crewhaus/run-context": "0.2.0"
27
+ "@crewhaus/event-log": "0.2.2",
28
+ "@crewhaus/permission-engine": "0.2.2",
29
+ "@crewhaus/run-context": "0.2.2"
30
30
  },
31
31
  "license": "Apache-2.0",
32
32
  "author": {