@wrongstack/core 0.6.5 → 0.6.7

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 (53) hide show
  1. package/dist/{agent-bridge-BBXK_ppx.d.ts → agent-bridge-BCVxmrOn.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-DsSm9lKN.d.ts → agent-subagent-runner-BTloSwjE.d.ts} +3 -3
  3. package/dist/{compactor-C8NhpSt5.d.ts → compactor-BUJ8550X.d.ts} +1 -1
  4. package/dist/{config-DfC6g6KV.d.ts → config-BHkYGzUT.d.ts} +1 -1
  5. package/dist/{context-DN5v-uQX.d.ts → context-C8mBUzBv.d.ts} +3 -5
  6. package/dist/coordination/index.d.ts +10 -10
  7. package/dist/coordination/index.js +62 -30
  8. package/dist/coordination/index.js.map +1 -1
  9. package/dist/defaults/index.d.ts +21 -21
  10. package/dist/defaults/index.js +130 -32
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{events-CJqwQl8G.d.ts → events-DounT6pP.d.ts} +10 -1
  13. package/dist/execution/index.d.ts +56 -14
  14. package/dist/execution/index.js +74 -18
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/extension/index.d.ts +6 -6
  17. package/dist/{goal-store-_Er467ya.d.ts → goal-store-HHgaq5ue.d.ts} +1 -1
  18. package/dist/{index-CXnWsGBp.d.ts → index-BlVITqm-.d.ts} +6 -9
  19. package/dist/{index-DcnXDPdY.d.ts → index-DiIGZh5I.d.ts} +20 -5
  20. package/dist/index.d.ts +28 -28
  21. package/dist/index.js +251 -131
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/index.d.ts +6 -6
  24. package/dist/kernel/index.d.ts +9 -9
  25. package/dist/kernel/index.js.map +1 -1
  26. package/dist/{mcp-servers-CevFHHM1.d.ts → mcp-servers-CXFfDN_d.d.ts} +3 -3
  27. package/dist/models/index.d.ts +2 -2
  28. package/dist/{multi-agent-D5IbASk_.d.ts → multi-agent-Iy8YUe3v.d.ts} +4 -4
  29. package/dist/observability/index.d.ts +2 -2
  30. package/dist/{path-resolver-CBx_q1HA.d.ts → path-resolver-DwJO5XBn.d.ts} +2 -2
  31. package/dist/{plan-templates-BEOllUJV.d.ts → plan-templates-CG_pInJV.d.ts} +4 -4
  32. package/dist/{provider-runner-Byh5TcJs.d.ts → provider-runner-DoohzfyD.d.ts} +3 -3
  33. package/dist/{retry-policy-BZSIMxrJ.d.ts → retry-policy-DOnwHAyz.d.ts} +1 -1
  34. package/dist/sdd/index.d.ts +9 -4
  35. package/dist/sdd/index.js +21 -0
  36. package/dist/sdd/index.js.map +1 -1
  37. package/dist/{secret-scrubber-CT7wefiO.d.ts → secret-scrubber-C9UJxFCJ.d.ts} +1 -1
  38. package/dist/{secret-scrubber-I0QHY_ob.d.ts → secret-scrubber-DcTK9JHC.d.ts} +1 -1
  39. package/dist/security/index.d.ts +3 -3
  40. package/dist/{selector-DDb_mq9X.d.ts → selector-DVo3eT-P.d.ts} +1 -1
  41. package/dist/{session-reader-B9nVkziM.d.ts → session-reader-BXWxFAhS.d.ts} +1 -1
  42. package/dist/storage/index.d.ts +6 -6
  43. package/dist/storage/index.js +3 -2
  44. package/dist/storage/index.js.map +1 -1
  45. package/dist/{system-prompt-gL06H9P4.d.ts → system-prompt-BBGles-N.d.ts} +1 -1
  46. package/dist/{task-graph-BITvWt4t.d.ts → task-graph-D1YQbpxF.d.ts} +1 -0
  47. package/dist/{tool-executor-BF7QfYVE.d.ts → tool-executor-CwpjhwHC.d.ts} +4 -4
  48. package/dist/types/index.d.ts +16 -16
  49. package/dist/types/index.js +1 -3
  50. package/dist/types/index.js.map +1 -1
  51. package/dist/utils/index.d.ts +1 -1
  52. package/package.json +1 -1
  53. package/skills/sdd/SKILL.md +122 -106
@@ -1,4 +1,4 @@
1
- import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-D5IbASk_.js';
1
+ import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-Iy8YUe3v.js';
2
2
 
3
3
  /**
4
4
  * In-memory pub/sub transport for agent-to-agent messaging.
@@ -1,6 +1,6 @@
1
- import { A as Agent, k as AgentInput } from './index-DcnXDPdY.js';
2
- import { E as EventBus } from './events-CJqwQl8G.js';
3
- import { c as SubagentConfig, k as TaskSpec, i as SubagentRunner } from './multi-agent-D5IbASk_.js';
1
+ import { A as Agent, k as AgentInput } from './index-DiIGZh5I.js';
2
+ import { E as EventBus } from './events-DounT6pP.js';
3
+ import { c as SubagentConfig, k as TaskSpec, i as SubagentRunner } from './multi-agent-Iy8YUe3v.js';
4
4
 
5
5
  /**
6
6
  * Single fleet-wide event with subagent attribution. Whatever a child
@@ -1,4 +1,4 @@
1
- import { a2 as Context } from './context-DN5v-uQX.js';
1
+ import { a2 as Context } from './context-C8mBUzBv.js';
2
2
 
3
3
  interface CompactRepairReport {
4
4
  removedToolUses: string[];
@@ -1,5 +1,5 @@
1
1
  import { W as WireFamily } from './models-registry-Y2xbog0E.js';
2
- import { P as Permission } from './context-DN5v-uQX.js';
2
+ import { P as Permission } from './context-C8mBUzBv.js';
3
3
 
4
4
  type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';
5
5
  type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';
@@ -952,11 +952,9 @@ declare class Context implements RunEnv {
952
952
  private _state;
953
953
  get state(): ConversationState;
954
954
  /**
955
- * Register a teardown hook tied to the current run's abort signal. The
956
- * hook fires when the run aborts or ends normally Agent.run wires this
957
- * through a RunController. Hooks registered before a run starts are stored
958
- * and fired when the next run ends; there is no "immediate fire" when no
959
- * run is active.
955
+ * Register a teardown hook tied to the current run's abort signal.
956
+ * Hooks registered before a run starts are stored and fired when the
957
+ * next run ends; there is no immediate fire when no run is active.
960
958
  *
961
959
  * **Scope:** these hooks fire on the **whole agent run's** abort, not on
962
960
  * an individual tool call. For per-tool teardown of resources owned by
@@ -1,15 +1,15 @@
1
- export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as DefaultMultiAgentCoordinator, d as DelegateHost, e as Director, f as DirectorPromptParts, g as DirectorSessionFactory, h as DirectorSessionFactoryOptions, F as FLEET_ROSTER, u as FleetCostCapError, j as FleetManager, k as FleetManagerOptions, l as FleetSpawnBudgetError, I as ICoordinator, m as IFleetManager, M as MultiAgentCoordinatorOptions, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, n as SubagentPromptParts, p as composeDirectorPrompt, q as composeSubagentPrompt, r as createDelegateTool, s as makeDirectorSessionFactory, t as rosterSummaryFromConfigs } from '../index-CXnWsGBp.js';
2
- export { n as BudgetExceededError, o as BudgetKind, p as BudgetLimits, s as BudgetThresholdDecision, t as BudgetThresholdHandler, u as BudgetThresholdSignal, q as BudgetUsage, r as SubagentBudget } from '../multi-agent-D5IbASk_.js';
3
- export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../agent-subagent-runner-DsSm9lKN.js';
4
- export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BBXK_ppx.js';
1
+ export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as DefaultMultiAgentCoordinator, d as DelegateHost, e as Director, f as DirectorPromptParts, g as DirectorSessionFactory, h as DirectorSessionFactoryOptions, F as FLEET_ROSTER, u as FleetCostCapError, j as FleetManager, k as FleetManagerOptions, l as FleetSpawnBudgetError, I as ICoordinator, m as IFleetManager, M as MultiAgentCoordinatorOptions, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, n as SubagentPromptParts, p as composeDirectorPrompt, q as composeSubagentPrompt, r as createDelegateTool, s as makeDirectorSessionFactory, t as rosterSummaryFromConfigs } from '../index-BlVITqm-.js';
2
+ export { n as BudgetExceededError, o as BudgetKind, p as BudgetLimits, s as BudgetThresholdDecision, t as BudgetThresholdHandler, u as BudgetThresholdSignal, q as BudgetUsage, r as SubagentBudget } from '../multi-agent-Iy8YUe3v.js';
3
+ export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../agent-subagent-runner-BTloSwjE.js';
4
+ export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BCVxmrOn.js';
5
5
  import '../director-state-BmYi3DGA.js';
6
- import '../context-DN5v-uQX.js';
6
+ import '../context-C8mBUzBv.js';
7
7
  import 'node:events';
8
- import '../events-CJqwQl8G.js';
9
- import '../index-DcnXDPdY.js';
8
+ import '../events-DounT6pP.js';
9
+ import '../index-DiIGZh5I.js';
10
10
  import '../logger-BMQgxvdy.js';
11
- import '../system-prompt-gL06H9P4.js';
11
+ import '../system-prompt-BBGles-N.js';
12
12
  import '../observability-BhnVLBLS.js';
13
- import '../secret-scrubber-CT7wefiO.js';
14
- import '../config-DfC6g6KV.js';
13
+ import '../secret-scrubber-C9UJxFCJ.js';
14
+ import '../config-BHkYGzUT.js';
15
15
  import '../models-registry-Y2xbog0E.js';
@@ -197,7 +197,7 @@ var DirectorStateCheckpoint = class {
197
197
  this.timer = null;
198
198
  }
199
199
  await this.persist();
200
- if (this.rewriteRequested) {
200
+ while (this.rewriteRequested) {
201
201
  this.rewriteRequested = false;
202
202
  await this.persist();
203
203
  }
@@ -338,10 +338,8 @@ var InMemoryAgentBridge = class {
338
338
  this.pendingRequests.delete(correlationId);
339
339
  reject(new Error(`Request ${correlationId} timed out after ${timeout}ms`));
340
340
  }, timeout);
341
- if (this.stopped) {
341
+ if (!this.inflightGuards.has(correlationId)) {
342
342
  clearTimeout(timer);
343
- this.inflightGuards.delete(correlationId);
344
- this.pendingRequests.delete(correlationId);
345
343
  reject(new Error("Bridge stopped"));
346
344
  return;
347
345
  }
@@ -789,10 +787,10 @@ var SubagentBudget = class _SubagentBudget {
789
787
  * or hung listener (Director not built / event filter detached mid-run)
790
788
  * leaves the budget over-limit and never enforces anything, since
791
789
  * `checkLimit` returns synchronously via `void this.checkLimitAsync`.
792
- * Hardcoded for now most fleets set their own per-task timeout that
793
- * dwarfs this anyway. 30 s matches the existing event-emit timeoutMs.
790
+ * Raised from 30s to 60s to give subagents more headroom before
791
+ * the threshold negotiation times out and triggers a hard stop.
794
792
  */
795
- static DECISION_TIMEOUT_MS = 3e4;
793
+ static DECISION_TIMEOUT_MS = 6e4;
796
794
  /**
797
795
  * Injected by the runner when wiring the budget to its EventBus.
798
796
  * Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
@@ -1155,13 +1153,19 @@ var FLEET_ROSTER = {
1155
1153
  "security-scanner": SECURITY_SCANNER_AGENT
1156
1154
  };
1157
1155
  var FLEET_ROSTER_BUDGETS = {
1158
- "audit-log": { timeoutMs: 8 * 60 * 1e3, maxIterations: 150, maxToolCalls: 500 },
1159
- "bug-hunter": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 },
1160
- "refactor-planner": { timeoutMs: 12 * 60 * 1e3, maxIterations: 180, maxToolCalls: 550 },
1161
- "security-scanner": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 }
1156
+ "audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
1157
+ "bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
1158
+ "refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
1159
+ "security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 }
1160
+ };
1161
+ var GENERIC_SUBAGENT_BUDGET = {
1162
+ timeoutMs: 3 * 60 * 60 * 1e3,
1163
+ maxIterations: 5e3,
1164
+ maxToolCalls: 15e3
1162
1165
  };
1163
1166
  function applyRosterBudget(cfg) {
1164
- const defaultBudget = FLEET_ROSTER_BUDGETS[cfg.role ?? ""];
1167
+ const roleBudget = cfg.role ? FLEET_ROSTER_BUDGETS[cfg.role] : void 0;
1168
+ const defaultBudget = roleBudget ?? (cfg.name ? GENERIC_SUBAGENT_BUDGET : void 0);
1165
1169
  if (!defaultBudget) return cfg;
1166
1170
  return {
1167
1171
  ...cfg,
@@ -1233,7 +1237,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1233
1237
  // hasParentBridge() — the type now reflects this.
1234
1238
  parentBridge: null,
1235
1239
  doneCondition: this.config.doneCondition,
1236
- maxConcurrent: this.config.maxConcurrent ?? 4
1240
+ maxConcurrent: this.config.maxConcurrent ?? 16
1237
1241
  };
1238
1242
  this.subagents.set(id, {
1239
1243
  config: { ...subagent, id },
@@ -1360,7 +1364,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1360
1364
  }
1361
1365
  }
1362
1366
  canDispatch() {
1363
- const max = this.config.maxConcurrent ?? 4;
1367
+ const max = this.config.maxConcurrent ?? 16;
1364
1368
  return this.inFlight < max && this.pendingTasks.length > 0;
1365
1369
  }
1366
1370
  takeNextDispatchableTask() {
@@ -1454,13 +1458,18 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1454
1458
  task.subagentId = subagentId;
1455
1459
  subagent.context.tasks.push(task);
1456
1460
  this.emit("task.assigned", { task, subagentId });
1461
+ const rawMaxIterations = subagent.config.maxIterations;
1462
+ const rawMaxToolCalls = subagent.config.maxToolCalls;
1463
+ const rawMaxTokens = subagent.config.maxTokens;
1464
+ const rawMaxCostUsd = subagent.config.maxCostUsd;
1465
+ const rawTimeoutMs = subagent.config.timeoutMs;
1457
1466
  const configWithRosterDefaults = applyRosterBudget(subagent.config);
1458
1467
  const budget = new SubagentBudget({
1459
- maxIterations: configWithRosterDefaults.maxIterations ?? this.config.defaultBudget?.maxIterations,
1460
- maxToolCalls: task.maxToolCalls ?? configWithRosterDefaults.maxToolCalls ?? this.config.defaultBudget?.maxToolCalls,
1461
- maxTokens: configWithRosterDefaults.maxTokens ?? this.config.defaultBudget?.maxTokens,
1462
- maxCostUsd: configWithRosterDefaults.maxCostUsd ?? this.config.defaultBudget?.maxCostUsd,
1463
- timeoutMs: task.timeoutMs ?? configWithRosterDefaults.timeoutMs ?? this.config.defaultBudget?.timeoutMs
1468
+ maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
1469
+ maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
1470
+ maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
1471
+ maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
1472
+ timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs
1464
1473
  });
1465
1474
  subagent.activeBudget = budget;
1466
1475
  if (!this.runner) {
@@ -1531,7 +1540,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1531
1540
  kind: "timeout",
1532
1541
  used: elapsed,
1533
1542
  limit,
1534
- timeoutMs: 3e4,
1543
+ timeoutMs: 6e4,
1535
1544
  extend: (extra) => resolveDecision({ extend: extra }),
1536
1545
  deny: () => resolveDecision("stop")
1537
1546
  });
@@ -2249,7 +2258,12 @@ var Director = class {
2249
2258
  }
2250
2259
  }
2251
2260
  }
2252
- const result = await this.coordinator.spawn(config);
2261
+ let result;
2262
+ try {
2263
+ result = await this.coordinator.spawn(config);
2264
+ } catch (err) {
2265
+ throw err;
2266
+ }
2253
2267
  if (this.fleetManager) {
2254
2268
  this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
2255
2269
  } else {
@@ -2697,7 +2711,7 @@ var Director = class {
2697
2711
  }
2698
2712
  };
2699
2713
  function createDelegateTool(opts) {
2700
- const defaultTimeoutMs = opts.defaultTimeoutMs ?? 4 * 60 * 60 * 1e3;
2714
+ const defaultTimeoutMs = opts.defaultTimeoutMs ?? 30 * 60 * 1e3;
2701
2715
  const rosterIds = opts.roster ? Object.keys(opts.roster) : [];
2702
2716
  const inputSchema = {
2703
2717
  type: "object",
@@ -2713,7 +2727,7 @@ function createDelegateTool(opts) {
2713
2727
  },
2714
2728
  name: {
2715
2729
  type: "string",
2716
- description: "Display name for the subagent when not using a roster role. Required when `role` is omitted."
2730
+ description: "Display name for free-form subagents (not using a roster role). The subagent gets a large default budget (3h, 5000 iter, 15000 tool calls). Required when `role` is omitted."
2717
2731
  },
2718
2732
  provider: {
2719
2733
  type: "string",
@@ -2744,8 +2758,8 @@ function createDelegateTool(opts) {
2744
2758
  };
2745
2759
  return {
2746
2760
  name: "delegate",
2747
- description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
2748
- usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster or pass `name` + `provider` + `model`. For non-trivial work, also pass `timeoutMs` (the wall-clock budget you actually need), `maxIterations`, and `maxToolCalls` \u2014 defaults are intentionally generous (4 hours) but the right values depend on scope. Returns the subagent's `TaskResult` \u2014 including the textual `result`, iteration count, tool count, and duration. Auto-promotes the host into director mode on first call.",
2761
+ description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). For free-form coding tasks (not tied to a pre-defined role), pass `name` + `task` \u2014 the subagent runs as a general-purpose coding agent with a large default budget. YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
2762
+ usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster (audit-log, bug-hunter, refactor-planner, security-scanner) or pass `name` to run a free-form coding agent. For non-trivial work, also pass `timeoutMs`, `maxIterations`, and `maxToolCalls`. Returns the subagent's `TaskResult` \u2014 including the textual `result`, iteration count, tool count, and duration. Auto-promotes the host into director mode on first call.",
2749
2763
  permission: "auto",
2750
2764
  mutating: false,
2751
2765
  inputSchema,
@@ -2793,6 +2807,7 @@ function createDelegateTool(opts) {
2793
2807
  model: i.model,
2794
2808
  systemPromptOverride: i.systemPromptOverride
2795
2809
  };
2810
+ cfg = applyRosterBudget({ ...cfg, name: i.name });
2796
2811
  }
2797
2812
  if (typeof i.maxIterations === "number" && i.maxIterations > 0) {
2798
2813
  cfg.maxIterations = i.maxIterations;
@@ -2800,7 +2815,7 @@ function createDelegateTool(opts) {
2800
2815
  if (typeof i.maxToolCalls === "number" && i.maxToolCalls > 0) {
2801
2816
  cfg.maxToolCalls = i.maxToolCalls;
2802
2817
  }
2803
- const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 3e4;
2818
+ const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 6e4;
2804
2819
  const desiredSubTimeout = Math.max(3e4, timeoutMs - SUBAGENT_TIMEOUT_BUFFER_MS);
2805
2820
  if (!cfg.timeoutMs || cfg.timeoutMs > desiredSubTimeout) {
2806
2821
  cfg.timeoutMs = desiredSubTimeout;
@@ -2837,6 +2852,7 @@ function createDelegateTool(opts) {
2837
2852
  const errorKind = result.error?.kind;
2838
2853
  const retryable = result.error?.retryable;
2839
2854
  const backoffMs = result.error?.backoffMs;
2855
+ const summary = buildDelegateSummary(i.role, result);
2840
2856
  return {
2841
2857
  ok: result.status === "success",
2842
2858
  status: result.status,
@@ -2852,7 +2868,10 @@ function createDelegateTool(opts) {
2852
2868
  toolCalls: result.toolCalls,
2853
2869
  durationMs: result.durationMs,
2854
2870
  ...partial ? { partial } : {},
2855
- ...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {}
2871
+ ...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {},
2872
+ // Summary is included so callers (TUI, CLI renderer) can surface
2873
+ // it as a chat history line — the LLM also sees it for continuity.
2874
+ summary
2856
2875
  };
2857
2876
  } catch (err) {
2858
2877
  return {
@@ -2865,10 +2884,11 @@ function createDelegateTool(opts) {
2865
2884
  };
2866
2885
  }
2867
2886
  function instantiateRosterConfig2(role, base) {
2887
+ const withBudget = applyRosterBudget({ ...base, role });
2868
2888
  return {
2869
- ...base,
2870
- // Roster entries are templates. Give each spawn a fresh id so
2871
- // parallel or repeated delegates can use the same role safely.
2889
+ ...withBudget,
2890
+ // Give each spawn a fresh id so parallel or repeated delegates
2891
+ // can use the same role safely.
2872
2892
  id: `${role}-${randomUUID().slice(0, 8)}`
2873
2893
  };
2874
2894
  }
@@ -2928,6 +2948,18 @@ ${partial.lastAssistantText}`;
2928
2948
  return retryable ? "Failure classified as retryable. Try again with the same input." : void 0;
2929
2949
  }
2930
2950
  }
2951
+ function buildDelegateSummary(role, result) {
2952
+ const roleLabel = role ?? "subagent";
2953
+ const ms = result.durationMs;
2954
+ const duration = ms < 6e4 ? `${Math.round(ms / 1e3)}s` : ms < 36e5 ? `${Math.round(ms / 6e4)}m` : `${(ms / 36e5).toFixed(1)}h`;
2955
+ if (result.status === "success") {
2956
+ const preview = typeof result.result === "string" ? result.result.trim().slice(0, 120).replace(/\n+/g, " ") : null;
2957
+ const tail = preview ? ` \u2014 ${preview}` : "";
2958
+ return `[${roleLabel}] done in ${duration} (${result.iterations} iter, ${result.toolCalls} tools)${tail}`;
2959
+ }
2960
+ const errLabel = result.error?.kind ?? result.status;
2961
+ return `[${roleLabel}] ${result.status} after ${duration} (${result.iterations} iter, ${result.toolCalls} tools) \u2014 ${errLabel}`;
2962
+ }
2931
2963
  async function readSubagentPartial(opts, subagentId) {
2932
2964
  if (!opts.sessionsRoot) return void 0;
2933
2965
  const candidates = [];