@wrongstack/core 0.275.1 → 0.276.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 (83) hide show
  1. package/dist/{agent-bridge-D9JkPvJ0.d.ts → agent-bridge-D7A-eu3C.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-CArSFKFl.d.ts → agent-subagent-runner-CEuw4ATz.d.ts} +16 -10
  3. package/dist/{brain-DCkB5_e7.d.ts → brain-BLOyN5ZP.d.ts} +127 -1
  4. package/dist/{compactor-CzSvxM1g.d.ts → compactor-DcBpaJsI.d.ts} +1 -1
  5. package/dist/{config-BzFRKkg7.d.ts → config-Bf5mj-ad.d.ts} +20 -2
  6. package/dist/{context-BrLe8pJy.d.ts → context-CLnUMW5g.d.ts} +40 -2
  7. package/dist/coordination/index.d.ts +43 -24
  8. package/dist/coordination/index.js +849 -648
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +28 -28
  11. package/dist/defaults/index.js +1636 -845
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +16 -16
  14. package/dist/execution/index.js +218 -49
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +1 -1
  17. package/dist/extension/index.d.ts +7 -7
  18. package/dist/extension/index.js.map +1 -1
  19. package/dist/{global-mailbox-CXkugtNQ.d.ts → global-mailbox-Iqfkgmwu.d.ts} +3 -3
  20. package/dist/{goal-store-DUwdbdoY.d.ts → goal-store-DGb6b5Ed.d.ts} +1 -1
  21. package/dist/hq/index.d.ts +6 -6
  22. package/dist/hq/index.js +178 -75
  23. package/dist/hq/index.js.map +1 -1
  24. package/dist/{index-CtlizLTK.d.ts → index-Cn0NOshr.d.ts} +10 -5
  25. package/dist/{index-neOCEy6q.d.ts → index-L4RZN9jJ.d.ts} +2 -2
  26. package/dist/index.d.ts +56 -48
  27. package/dist/index.js +2789 -1546
  28. package/dist/index.js.map +1 -1
  29. package/dist/infrastructure/index.d.ts +6 -6
  30. package/dist/infrastructure/index.js +26 -7
  31. package/dist/infrastructure/index.js.map +1 -1
  32. package/dist/kernel/index.d.ts +20 -12
  33. package/dist/kernel/index.js +55 -9
  34. package/dist/kernel/index.js.map +1 -1
  35. package/dist/{mailbox-types-_7gaY0Rl.d.ts → mailbox-types-DTl7bRH3.d.ts} +3 -1
  36. package/dist/{mcp-servers-MLL6bMlv.d.ts → mcp-servers-CuZGf9fI.d.ts} +4 -4
  37. package/dist/models/index.d.ts +5 -5
  38. package/dist/models/index.js +223 -139
  39. package/dist/models/index.js.map +1 -1
  40. package/dist/{models-registry-CrkcxQ-g.d.ts → models-registry-8XOdxWQu.d.ts} +16 -1
  41. package/dist/{multi-agent-coordinator-Dc_HuG9p.d.ts → multi-agent-coordinator-CiRtKVTk.d.ts} +8 -1
  42. package/dist/{null-fleet-bus-BMZwMin7.d.ts → null-fleet-bus-d9G-bVy9.d.ts} +26 -22
  43. package/dist/observability/index.d.ts +2 -2
  44. package/dist/{path-resolver-uVK4BatM.d.ts → path-resolver-BhIb6mtd.d.ts} +8 -3
  45. package/dist/{permission-CJR1qfOi.d.ts → permission-BCbQDR2s.d.ts} +1 -1
  46. package/dist/{permission-policy-DLVKKk4w.d.ts → permission-policy-C0ikndX_.d.ts} +2 -18
  47. package/dist/{pipeline-BYR-Vdau.d.ts → pipeline-Dl6XbfE7.d.ts} +10 -6
  48. package/dist/{provider-model-resolve-iREK_1lG.d.ts → provider-model-resolve-B70epO19.d.ts} +3 -3
  49. package/dist/{provider-runner-i7SQXZuC.d.ts → provider-runner-DZ808MSM.d.ts} +3 -3
  50. package/dist/{retry-policy-BmY5ooh3.d.ts → retry-policy-Dt3_z8Aj.d.ts} +1 -1
  51. package/dist/sdd/index.d.ts +19 -10
  52. package/dist/sdd/index.js +411 -240
  53. package/dist/sdd/index.js.map +1 -1
  54. package/dist/{secret-vault-C9leEMzr.d.ts → secret-vault-BUJ2d1gB.d.ts} +1 -1
  55. package/dist/security/index.d.ts +5 -5
  56. package/dist/security/index.js +30 -6
  57. package/dist/security/index.js.map +1 -1
  58. package/dist/{selector-qjpee9BF.d.ts → selector-BCkWgdwy.d.ts} +1 -1
  59. package/dist/{session-event-bridge-m7y--I-H.d.ts → session-event-bridge-CMvIO59_.d.ts} +1 -1
  60. package/dist/{session-reader-BjLH4V9n.d.ts → session-reader-C8aiChUu.d.ts} +1 -1
  61. package/dist/skills/index.js +1 -0
  62. package/dist/skills/index.js.map +1 -1
  63. package/dist/storage/index.d.ts +68 -30
  64. package/dist/storage/index.js +839 -528
  65. package/dist/storage/index.js.map +1 -1
  66. package/dist/{strategy-compactor-C2bmlWYg.d.ts → strategy-compactor-DI1OHVbB.d.ts} +10 -10
  67. package/dist/{todos-checkpoint-oDS9IBNS.d.ts → todos-checkpoint-Ddd2CGr0.d.ts} +56 -9
  68. package/dist/{tool-executor-D4YdaJ-M.d.ts → tool-executor-Bmd5Ygoo.d.ts} +45 -10
  69. package/dist/tools/index.d.ts +2 -2
  70. package/dist/tools/index.js.map +1 -1
  71. package/dist/types/index.d.ts +20 -20
  72. package/dist/types/index.js +331 -98
  73. package/dist/types/index.js.map +1 -1
  74. package/dist/utils/index.d.ts +16 -3
  75. package/dist/utils/index.js +159 -83
  76. package/dist/utils/index.js.map +1 -1
  77. package/dist/{worktree-manager-A1Efnvs0.d.ts → worktree-manager-DBdl_5rs.d.ts} +4 -1
  78. package/instructions/agents/shadow-agent.md +3 -3
  79. package/instructions/coordination/director-preamble.md +3 -3
  80. package/instructions/modes/research-web.md +4 -4
  81. package/package.json +1 -1
  82. package/skills/research-web/SKILL.md +26 -26
  83. package/skills/research-web/SKILL.save.md +1 -1
@@ -1,24 +1,24 @@
1
- export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, U as ContextWindowBudgetSnapshot, D as DefaultDesignKitLoader, d as DefaultPromptLoader, e as DefaultSkillLoader, f as DesignKitLoaderOptions, h as DoneCheckResult, i as DoneConditionChecker, I as IntelligentCompactor, j as IntelligentCompactorOptions, P as PersistedActiveKit, k as PromptLoaderOptions, S as SelectiveCompactor, l as SelectiveCompactorOptions, m as SkillLoaderOptions, n as StrategyCompactorOptions, _ as _resetDesignKitLoaderMemo, o as _resetDesignRulesCache, p as activateDesign, r as buildGoalPreamble, s as clearActiveKit, t as clearPersistedActiveKit, u as createStrategyCompactor, v as designProjectDir, w as detectFrontendFile, x as detectFrontendIntent, y as getDesignKitLoader, z as getDesignState, B as installDesignStudioMiddleware, E as loadActiveKit, F as loadProjectDesignRules, G as makeAutonomyPromptContributor, H as makeDesignDetectToolCallMiddleware, J as makeDesignDetectUserInputMiddleware, K as makeDesignStudioRequestMiddleware, M as recordKitChoice, O as renderPrompt, Q as resolveBundledDesignKitsDir, R as setActiveKit } from '../strategy-compactor-C2bmlWYg.js';
2
- import { P as Provider, a as ReasoningConfig, n as Capabilities, c as Request } from '../context-BrLe8pJy.js';
3
- import { e as BrainDecision, h as BrainDecisionRequest, B as BrainArbiter } from '../brain-DCkB5_e7.js';
4
- export { C as CompactorOptions, h as DefaultErrorHandler, i as DefaultRetryPolicy, E as EternalAutonomyEngine, k as EternalAutonomyOptions, l as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, m as ParallelEternalEngine, n as ParallelEternalOptions, o as ParallelIterationStage, T as ToolExecutor } from '../tool-executor-D4YdaJ-M.js';
5
- import { N as ModelRuntimeConfig } from '../config-BzFRKkg7.js';
6
- import '../pipeline-BYR-Vdau.js';
7
- import '../mailbox-types-_7gaY0Rl.js';
8
- import '../session-event-bridge-m7y--I-H.js';
9
- import '../compactor-CzSvxM1g.js';
10
- import '../agent-subagent-runner-CArSFKFl.js';
11
- import '../index-CtlizLTK.js';
1
+ export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, U as ContextWindowBudgetSnapshot, D as DefaultDesignKitLoader, d as DefaultPromptLoader, e as DefaultSkillLoader, f as DesignKitLoaderOptions, h as DoneCheckResult, i as DoneConditionChecker, I as IntelligentCompactor, j as IntelligentCompactorOptions, P as PersistedActiveKit, k as PromptLoaderOptions, S as SelectiveCompactor, l as SelectiveCompactorOptions, m as SkillLoaderOptions, n as StrategyCompactorOptions, _ as _resetDesignKitLoaderMemo, o as _resetDesignRulesCache, p as activateDesign, r as buildGoalPreamble, s as clearActiveKit, t as clearPersistedActiveKit, u as createStrategyCompactor, v as designProjectDir, w as detectFrontendFile, x as detectFrontendIntent, y as getDesignKitLoader, z as getDesignState, B as installDesignStudioMiddleware, E as loadActiveKit, F as loadProjectDesignRules, G as makeAutonomyPromptContributor, H as makeDesignDetectToolCallMiddleware, J as makeDesignDetectUserInputMiddleware, K as makeDesignStudioRequestMiddleware, M as recordKitChoice, O as renderPrompt, Q as resolveBundledDesignKitsDir, R as setActiveKit } from '../strategy-compactor-DI1OHVbB.js';
2
+ import { P as Provider, a as ReasoningConfig, o as Capabilities, c as Request } from '../context-CLnUMW5g.js';
3
+ import { e as BrainDecision, h as BrainDecisionRequest, B as BrainArbiter } from '../brain-BLOyN5ZP.js';
4
+ export { C as CompactorOptions, h as DefaultErrorHandler, i as DefaultRetryPolicy, E as EternalAutonomyEngine, k as EternalAutonomyOptions, l as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, m as ParallelEternalEngine, n as ParallelEternalOptions, o as ParallelIterationStage, T as ToolExecutor } from '../tool-executor-Bmd5Ygoo.js';
5
+ import { N as ModelRuntimeConfig } from '../config-Bf5mj-ad.js';
6
+ import '../pipeline-Dl6XbfE7.js';
7
+ import '../mailbox-types-DTl7bRH3.js';
8
+ import '../session-event-bridge-CMvIO59_.js';
9
+ import '../compactor-DcBpaJsI.js';
10
+ import '../agent-subagent-runner-CEuw4ATz.js';
11
+ import '../index-Cn0NOshr.js';
12
12
  import '../logger-B63L5bTg.js';
13
13
  import '../observability-D-HZN_mF.js';
14
- import '../permission-CJR1qfOi.js';
15
- import '../retry-policy-BmY5ooh3.js';
16
- import '../selector-qjpee9BF.js';
14
+ import '../permission-BCbQDR2s.js';
15
+ import '../retry-policy-Dt3_z8Aj.js';
16
+ import '../selector-BCkWgdwy.js';
17
17
  import '../skill-DGIXCtdv.js';
18
18
  import '../wstack-paths-_NrRovdr.js';
19
19
  import '../prompt-DLd35n4Q.js';
20
- import '../goal-store-DUwdbdoY.js';
21
- import '../multi-agent-coordinator-Dc_HuG9p.js';
20
+ import '../goal-store-DGb6b5Ed.js';
21
+ import '../multi-agent-coordinator-CiRtKVTk.js';
22
22
  import 'node:events';
23
23
 
24
24
  /**
@@ -1515,6 +1515,7 @@ var ERROR_CODES = {
1515
1515
  SDD_NOT_READY: "SDD_NOT_READY",
1516
1516
  // General
1517
1517
  VALIDATION_ERROR: "VALIDATION_ERROR",
1518
+ PARSE_FAILED: "PARSE_FAILED",
1518
1519
  UNKNOWN: "UNKNOWN"
1519
1520
  };
1520
1521
  var WrongStackError = class extends Error {
@@ -1545,6 +1546,21 @@ function formatContext(ctx) {
1545
1546
  const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
1546
1547
  return parts.length > 0 ? `[${parts.join(" ")}]` : "";
1547
1548
  }
1549
+ var ToolError = class extends WrongStackError {
1550
+ toolName;
1551
+ constructor(opts) {
1552
+ super({
1553
+ message: opts.message,
1554
+ code: opts.code,
1555
+ subsystem: "tool",
1556
+ recoverable: opts.recoverable,
1557
+ context: { tool: opts.toolName, ...opts.context },
1558
+ cause: opts.cause
1559
+ });
1560
+ this.name = "ToolError";
1561
+ this.toolName = opts.toolName;
1562
+ }
1563
+ };
1548
1564
  var AgentError = class extends WrongStackError {
1549
1565
  constructor(opts) {
1550
1566
  super({
@@ -1614,6 +1630,9 @@ var ToolValidationError = class extends WrongStackError {
1614
1630
  this.name = "ToolValidationError";
1615
1631
  }
1616
1632
  };
1633
+ function isWrongStackError(err) {
1634
+ return err instanceof WrongStackError;
1635
+ }
1617
1636
 
1618
1637
  // src/execution/auto-compaction-middleware.ts
1619
1638
  var LEVEL_RANK = { warn: 0, soft: 1, hard: 2 };
@@ -1812,6 +1831,7 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
1812
1831
  const report = await this.compactor.compact(ctx, { aggressive });
1813
1832
  this.recordAttempt(pressure.level, pressure.tokens, report);
1814
1833
  this.events?.emit("compaction.fired", {
1834
+ sessionId: ctx.session.id,
1815
1835
  level: pressure.level,
1816
1836
  tokens: pressure.tokens,
1817
1837
  load: pressure.load,
@@ -1846,6 +1866,7 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
1846
1866
  `Auto-compaction left context above the hard threshold after ${pressure.level} compaction`
1847
1867
  );
1848
1868
  this.events?.emit("compaction.failed", {
1869
+ sessionId: ctx.session.id,
1849
1870
  err: error,
1850
1871
  aggressive,
1851
1872
  level: pressure.level,
@@ -1873,6 +1894,7 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
1873
1894
  const error = err instanceof Error ? err : new Error(String(err));
1874
1895
  const fatal = this.failureMode === "throw" || this.failureMode === "throw_on_hard" && pressure.level === "hard";
1875
1896
  this.events?.emit("compaction.failed", {
1897
+ sessionId: ctx.session.id,
1876
1898
  err: error,
1877
1899
  aggressive,
1878
1900
  level: pressure.level,
@@ -2498,6 +2520,18 @@ function isTextBlock(b) {
2498
2520
  }
2499
2521
 
2500
2522
  // src/execution/compaction-core.ts
2523
+ var FAILURE_PATTERN = /(error|fail|exception|timeout|enonet|eacces|eperm|enoent|abort)/i;
2524
+ var CORRECTION_PATTERN = /\b(wrong|no\b|stop\b|don'?t\b|actually|fix that|undo|revert|forget|ignore|skip)\b/i;
2525
+ var ERROR_LANG_PATTERN = /\b(error|exception|fatal|critical|crash|panic|abort|segfault|core dump|undefined is not|null pointer|typeerror|referenceerror|syntaxerror)\b/i;
2526
+ var SECURITY_PATTERN = /\b(security|vulnerability|injection|xss|csrf|secret|apikey|api.key|hardcoded|leak|exploit|cve)\b/i;
2527
+ var ARCHITECTURE_PATTERN = /\b(architecture|design|approach|strategy|pattern|refactor|migrate|restructure|decision|trade.?off)\b/i;
2528
+ var BOILERPLATE_PATTERN = /\b(files_with_matches|count|found \d+ match|directory tree|\.\.\. and \d+ more)\b/i;
2529
+ var PATH_HINT_PATTERN = /(?:(?:[A-Za-z]:)?[./\\]?[\w@.-]+(?:[\\/][\w@(). -]+)+\.[A-Za-z0-9]{1,12})/g;
2530
+ var PATH_BACKSLASH_PATTERN = /\\/g;
2531
+ var PATH_TRIM_PATTERN = /^["'`]+|["'`),;:]+$/g;
2532
+ var ERROR_LINE_PATTERN = /\b(error|exception|failed|failure|fatal|panic|timeout|denied|enoent|eacces|eperm)\b/i;
2533
+ var NEWLINE_SPLIT_PATTERN = /\r?\n/;
2534
+ var WHITESPACE_COLLAPSE_PATTERN = /\s+/g;
2501
2535
  function compactionDebugEnabled() {
2502
2536
  return process.env["NODE_ENV"] === "development" || process.env["WRONGSTACK_DEBUG"] === "1";
2503
2537
  }
@@ -2733,9 +2767,8 @@ function summarizeToolResultElision(block, tokens) {
2733
2767
  function extractPathHints(content) {
2734
2768
  const text = typeof content === "string" ? content : JSON.stringify(content);
2735
2769
  const out = /* @__PURE__ */ new Set();
2736
- const re = /(?:(?:[A-Za-z]:)?[./\\]?[\w@.-]+(?:[\\/][\w@(). -]+)+\.[A-Za-z0-9]{1,12})/g;
2737
- for (const match of text.matchAll(re)) {
2738
- const clean = match[0]?.replace(/\\/g, "/").replace(/^["'`]+|["'`),;:]+$/g, "");
2770
+ for (const match of text.matchAll(PATH_HINT_PATTERN)) {
2771
+ const clean = match[0]?.replace(PATH_BACKSLASH_PATTERN, "/").replace(PATH_TRIM_PATTERN, "");
2739
2772
  if (clean && clean.length <= 220) out.add(clean);
2740
2773
  if (out.size >= 5) break;
2741
2774
  }
@@ -2743,12 +2776,9 @@ function extractPathHints(content) {
2743
2776
  }
2744
2777
  function firstErrorLine(content) {
2745
2778
  const text = typeof content === "string" ? content : JSON.stringify(content);
2746
- for (const line of text.split(/\r?\n/)) {
2747
- if (!/\b(error|exception|failed|failure|fatal|panic|timeout|denied|enoent|eacces|eperm)\b/i.test(
2748
- line
2749
- ))
2750
- continue;
2751
- const trimmed = line.replace(/\s+/g, " ").trim();
2779
+ for (const line of text.split(NEWLINE_SPLIT_PATTERN)) {
2780
+ if (!ERROR_LINE_PATTERN.test(line)) continue;
2781
+ const trimmed = line.replace(WHITESPACE_COLLAPSE_PATTERN, " ").trim();
2752
2782
  if (trimmed) return trimmed.slice(0, 180);
2753
2783
  }
2754
2784
  return void 0;
@@ -2795,9 +2825,9 @@ function scoreMessage(m, context) {
2795
2825
  if (hasToolUse2(m) || hasResult) return 0;
2796
2826
  }
2797
2827
  if (context?.failureCounts && m.role === "user" && hasToolUse2(m) === false) {
2798
- const isFailure = /error|fail|exception|timeout|enonet|eacces|eperm|enoent|abort/i.test(text);
2799
- if (isFailure) {
2800
- const errKey = /(error|fail|exception|timeout|enonet|eacces|eperm|enoent|abort)/i.exec(text)?.[0]?.toLowerCase() ?? "error";
2828
+ const failureMatch = FAILURE_PATTERN.exec(text);
2829
+ if (failureMatch) {
2830
+ const errKey = failureMatch[0]?.toLowerCase() ?? "error";
2801
2831
  const count = (context.failureCounts.get(errKey) ?? 0) + 1;
2802
2832
  context.failureCounts.set(errKey, count);
2803
2833
  if (count >= 5) return 0;
@@ -2805,29 +2835,21 @@ function scoreMessage(m, context) {
2805
2835
  }
2806
2836
  }
2807
2837
  if (m.role === "user") {
2808
- if (/\b(wrong|no\b|stop\b|don'?t\b|actually|fix that|undo|revert|forget|ignore|skip)\b/i.test(
2809
- text
2810
- )) {
2838
+ if (CORRECTION_PATTERN.test(text)) {
2811
2839
  return 5;
2812
2840
  }
2813
2841
  }
2814
- if (/\b(error|exception|fatal|critical|crash|panic|abort|segfault|core dump|undefined is not|null pointer|typeerror|referenceerror|syntaxerror)\b/i.test(
2815
- text
2816
- )) {
2842
+ if (ERROR_LANG_PATTERN.test(text)) {
2817
2843
  return 5;
2818
2844
  }
2819
- if (/\b(security|vulnerability|injection|xss|csrf|secret|apikey|api.key|hardcoded|leak|exploit|cve)\b/i.test(
2820
- text
2821
- )) {
2845
+ if (SECURITY_PATTERN.test(text)) {
2822
2846
  return 5;
2823
2847
  }
2824
- if (m.role === "assistant" && /\b(architecture|design|approach|strategy|pattern|refactor|migrate|restructure|decision|trade.?off)\b/i.test(
2825
- text
2826
- )) {
2848
+ if (m.role === "assistant" && ARCHITECTURE_PATTERN.test(text)) {
2827
2849
  return 5;
2828
2850
  }
2829
2851
  if (hasLargeToolResult(m)) return 1;
2830
- if (m.role === "user" && !hasToolUse2(m) && /\b(files_with_matches|count|found \d+ match|directory tree|\.\.\. and \d+ more)\b/i.test(text)) {
2852
+ if (m.role === "user" && !hasToolUse2(m) && BOILERPLATE_PATTERN.test(text)) {
2831
2853
  return 1;
2832
2854
  }
2833
2855
  return 3;
@@ -2837,6 +2859,11 @@ function buildSmartDigest(messages) {
2837
2859
  const failureCounts = /* @__PURE__ */ new Map();
2838
2860
  let noiseCount = 0;
2839
2861
  for (const m of messages) {
2862
+ const isPureToolIO = Array.isArray(m.content) && m.content.length > 0 && !hasToolUse2(m) && m.content.every((b) => b.type === "tool_result");
2863
+ if (isPureToolIO) {
2864
+ noiseCount++;
2865
+ continue;
2866
+ }
2840
2867
  const score = scoreMessage(m, { failureCounts });
2841
2868
  const text = extractText2(m);
2842
2869
  const toolCount = countToolBlocks(m);
@@ -3880,7 +3907,7 @@ function buildRecoveryStrategies(opts) {
3880
3907
  label: "downgrade_model",
3881
3908
  async attempt(err, ctx) {
3882
3909
  if (!(err instanceof ProviderError)) return null;
3883
- if (err.status !== 429 && err.status !== 529 && err.status < 500) return null;
3910
+ if (err.status !== 529 && err.status < 500) return null;
3884
3911
  return null;
3885
3912
  }
3886
3913
  }
@@ -4544,6 +4571,7 @@ Deliverables: ${goal.deliverables.length} total, progress ${goal.progress ?? "un
4544
4571
  try {
4545
4572
  const decision = await this.opts.brain.decide({
4546
4573
  id: `goal-done-${goal.iterations}`,
4574
+ sessionId: this.opts.agent.ctx.session?.id,
4547
4575
  source: "system",
4548
4576
  question: `Brainstorm returned DONE ${this.consecutiveBrainstormDone}x. Is the goal truly complete?`,
4549
4577
  context: [
@@ -4937,6 +4965,7 @@ var SubagentBudget = class _SubagentBudget {
4937
4965
  */
4938
4966
  lastActivityTime = null;
4939
4967
  _onThreshold;
4968
+ _sessionId;
4940
4969
  /**
4941
4970
  * Hard cap on how long `_negotiateExtension` waits for the coordinator to
4942
4971
  * respond before defaulting to 'stop'. Without this fallback an absent
@@ -5005,10 +5034,15 @@ var SubagentBudget = class _SubagentBudget {
5005
5034
  get mode() {
5006
5035
  return this._mode;
5007
5036
  }
5008
- constructor(limits = {}, mode = "auto") {
5037
+ constructor(limits = {}, mode = "auto", options = {}) {
5009
5038
  this._mode = mode;
5039
+ this._sessionId = options.sessionId;
5010
5040
  this.limits = { ...limits };
5011
5041
  }
5042
+ currentSessionId() {
5043
+ const value = typeof this._sessionId === "function" ? this._sessionId() : this._sessionId;
5044
+ return typeof value === "string" && value.length > 0 ? value : void 0;
5045
+ }
5012
5046
  start() {
5013
5047
  this.startTime = Date.now();
5014
5048
  this.lastActivityTime = this.startTime;
@@ -5176,7 +5210,9 @@ var SubagentBudget = class _SubagentBudget {
5176
5210
  resolve5(d);
5177
5211
  };
5178
5212
  const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
5213
+ const sessionId = this.currentSessionId();
5179
5214
  bus.emit("budget.threshold_reached", {
5215
+ ...sessionId ? { sessionId } : {},
5180
5216
  kind: entry.kind,
5181
5217
  used: entry.used,
5182
5218
  limit: entry.limit,
@@ -7427,6 +7463,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
7427
7463
  coordinatorId;
7428
7464
  config;
7429
7465
  runner;
7466
+ sessionId;
7430
7467
  fleetBus;
7431
7468
  subagents = /* @__PURE__ */ new Map();
7432
7469
  /**
@@ -7461,6 +7498,11 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
7461
7498
  this.coordinatorId = config.coordinatorId;
7462
7499
  this.config = config;
7463
7500
  this.runner = options.runner;
7501
+ this.sessionId = options.sessionId;
7502
+ }
7503
+ currentSessionId() {
7504
+ const value = typeof this.sessionId === "function" ? this.sessionId() : this.sessionId;
7505
+ return typeof value === "string" && value.length > 0 ? value : void 0;
7464
7506
  }
7465
7507
  /**
7466
7508
  * Replace the runner after construction. Used when the runner depends
@@ -7619,11 +7661,16 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
7619
7661
  status: s.status,
7620
7662
  assigned: s.context.parentBridge !== null
7621
7663
  }));
7664
+ const sessionId = this.currentSessionId();
7622
7665
  this.fleetBus?.emit({
7623
7666
  subagentId: this.coordinatorId,
7624
7667
  ts: Date.now(),
7625
7668
  type: "coordinator.stats",
7626
- payload: { ...stats, subagentStatuses }
7669
+ payload: {
7670
+ ...sessionId ? { sessionId } : {},
7671
+ ...stats,
7672
+ subagentStatuses
7673
+ }
7627
7674
  });
7628
7675
  }
7629
7676
  getStatus() {
@@ -7826,16 +7873,20 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
7826
7873
  const rawTimeoutMs = subagent.config.timeoutMs;
7827
7874
  const rawIdleTimeoutMs = subagent.config.idleTimeoutMs;
7828
7875
  const configWithRosterDefaults = applyRosterBudget(subagent.config);
7829
- const budget = new SubagentBudget({
7830
- maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
7831
- maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
7832
- maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
7833
- maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
7834
- // Wall-clock cap is opt-in (explicit config / defaultBudget only); the
7835
- // roster no longer supplies one. Idle is the default reaper.
7836
- timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs,
7837
- idleTimeoutMs: rawIdleTimeoutMs ?? this.config.defaultBudget?.idleTimeoutMs ?? configWithRosterDefaults.idleTimeoutMs
7838
- });
7876
+ const budget = new SubagentBudget(
7877
+ {
7878
+ maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
7879
+ maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
7880
+ maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
7881
+ maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
7882
+ // Wall-clock cap is opt-in (explicit config / defaultBudget only); the
7883
+ // roster no longer supplies one. Idle is the default reaper.
7884
+ timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs,
7885
+ idleTimeoutMs: rawIdleTimeoutMs ?? this.config.defaultBudget?.idleTimeoutMs ?? configWithRosterDefaults.idleTimeoutMs
7886
+ },
7887
+ "auto",
7888
+ { sessionId: () => this.currentSessionId() }
7889
+ );
7839
7890
  subagent.activeBudget = budget;
7840
7891
  if (!this.runner) {
7841
7892
  return;
@@ -7938,7 +7989,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
7938
7989
  resolveDecision(d);
7939
7990
  };
7940
7991
  const fallback = setTimeout(() => resolve5("stop"), DECISION_TIMEOUT_MS);
7992
+ const sessionId = this.currentSessionId();
7941
7993
  budget._events?.emit("budget.threshold_reached", {
7994
+ ...sessionId ? { sessionId } : {},
7942
7995
  kind: "timeout",
7943
7996
  used,
7944
7997
  limit,
@@ -7972,7 +8025,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
7972
8025
  const wallExceeded = wallLimit !== void 0 && elapsed >= wallLimit;
7973
8026
  const idleExceeded = idleLimit !== void 0 && budget.idleMs() >= idleLimit;
7974
8027
  if (idleExceeded && !wallExceeded) {
8028
+ const sessionId = this.currentSessionId();
7975
8029
  budget._events?.emit("budget.threshold_reached", {
8030
+ ...sessionId ? { sessionId } : {},
7976
8031
  kind: "idle_timeout",
7977
8032
  used: budget.idleMs(),
7978
8033
  limit: idleLimit ?? 0,
@@ -9762,6 +9817,64 @@ var ToolExecutor = class _ToolExecutor {
9762
9817
  const mode = resolveToolResultRenderMode(modes, toolName);
9763
9818
  renderer.setResultRenderMode(toolName, mode);
9764
9819
  }
9820
+ toolLogBase(ctx, use, toolName, durationMs) {
9821
+ return {
9822
+ event: "tool.execution",
9823
+ traceId: ctx.traceId,
9824
+ sessionId: ctx.session.id,
9825
+ agentId: ctx.agentId ?? "<unknown>",
9826
+ toolName,
9827
+ toolUseId: use.id,
9828
+ durationMs
9829
+ };
9830
+ }
9831
+ logToolSuccess(ctx, use, toolName, durationMs, outputChars) {
9832
+ this.opts.events?.emit("tool.completed", {
9833
+ name: toolName,
9834
+ id: use.id,
9835
+ sessionId: ctx.session.id,
9836
+ ...ctx.traceId ? { traceId: ctx.traceId } : {},
9837
+ agentId: ctx.agentId ?? "<unknown>",
9838
+ durationMs,
9839
+ outputChars
9840
+ });
9841
+ this.opts.logger?.info("tool execution completed", {
9842
+ ...this.toolLogBase(ctx, use, toolName, durationMs),
9843
+ outcome: "success",
9844
+ isError: false,
9845
+ outputChars
9846
+ });
9847
+ }
9848
+ logToolFailure(ctx, use, toolName, durationMs, err) {
9849
+ const { category, retryable, detail } = classifyToolError(err);
9850
+ const structured = isWrongStackError(err);
9851
+ const structuredError = structured ? {
9852
+ errorCode: err.code,
9853
+ errorSubsystem: err.subsystem,
9854
+ errorSeverity: err.severity
9855
+ } : {};
9856
+ this.opts.events?.emit("tool.failed", {
9857
+ name: toolName,
9858
+ id: use.id,
9859
+ sessionId: ctx.session.id,
9860
+ ...ctx.traceId ? { traceId: ctx.traceId } : {},
9861
+ agentId: ctx.agentId ?? "<unknown>",
9862
+ durationMs,
9863
+ category,
9864
+ retryable,
9865
+ ...detail ? { detail } : {},
9866
+ ...structuredError
9867
+ });
9868
+ this.opts.logger?.warn("tool execution failed", {
9869
+ ...this.toolLogBase(ctx, use, toolName, durationMs),
9870
+ outcome: "failure",
9871
+ isError: true,
9872
+ errorCategory: category,
9873
+ retryable,
9874
+ errorDetail: detail,
9875
+ ...structuredError
9876
+ });
9877
+ }
9765
9878
  /**
9766
9879
  * Execute a batch of tool uses using the configured strategy.
9767
9880
  * Returns the execution results and the remaining output budget.
@@ -9892,7 +10005,8 @@ ${errorDetails}`,
9892
10005
  "tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
9893
10006
  });
9894
10007
  try {
9895
- let { block: result, bytes } = await this.executeTool(tool, use, ctx, budget);
10008
+ const producedText = await this.produceToolOutput(tool, use, ctx, budget);
10009
+ let { block: result, bytes } = this.settleToolOutput(tool, use, producedText, budget);
9896
10010
  budget -= bytes;
9897
10011
  if (this.opts.hookRunner?.has("PostToolUse")) {
9898
10012
  const post = await this.opts.hookRunner.postToolUse(
@@ -9909,13 +10023,18 @@ ${post.additionalContext}`;
9909
10023
  budget = Math.max(0, budget - Buffer.byteLength(appended, "utf8"));
9910
10024
  }
9911
10025
  }
10026
+ const outputChars = typeof result.content === "string" ? result.content.length : 0;
9912
10027
  span?.setAttribute("tool.is_error", !!result.is_error);
9913
- span?.setAttribute(
9914
- "tool.output_bytes",
9915
- typeof result.content === "string" ? result.content.length : 0
9916
- );
10028
+ span?.setAttribute("tool.output_bytes", outputChars);
10029
+ this.logToolSuccess(ctx, use, tool.name, Date.now() - start, outputChars);
9917
10030
  return { result, tool, durationMs: Date.now() - start };
9918
10031
  } catch (err) {
10032
+ if (isWrongStackError(err)) {
10033
+ if (err instanceof Error) span?.recordError(err);
10034
+ span?.setAttribute("tool.is_error", true);
10035
+ this.logToolFailure(ctx, use, tool.name, Date.now() - start, err);
10036
+ throw err;
10037
+ }
9919
10038
  const msg = toErrorMessage(err);
9920
10039
  const scrubbed = this.opts.secretScrubber.scrub(msg);
9921
10040
  const { category, retryable, detail } = classifyToolError(err);
@@ -9933,6 +10052,7 @@ ${post.additionalContext}`;
9933
10052
  span?.setAttribute("tool.error_category", category);
9934
10053
  span?.setAttribute("tool.error_retryable", retryable);
9935
10054
  if (detail) span?.setAttribute("tool.error_detail", detail);
10055
+ this.logToolFailure(ctx, use, tool.name, Date.now() - start, err);
9936
10056
  return { result, tool, durationMs: Date.now() - start };
9937
10057
  } finally {
9938
10058
  span?.end();
@@ -9942,7 +10062,8 @@ ${post.additionalContext}`;
9942
10062
  try {
9943
10063
  return await runOne(use);
9944
10064
  } catch (err) {
9945
- const msg = toErrorMessage(err);
10065
+ const isStructured = isWrongStackError(err);
10066
+ const msg = isStructured ? err.describe() : toErrorMessage(err);
9946
10067
  const scrubbed = this.opts.secretScrubber.scrub(msg);
9947
10068
  const { category, retryable, detail } = classifyToolError(err);
9948
10069
  const tool = this.registry.get(use.name);
@@ -9952,7 +10073,7 @@ ${post.additionalContext}`;
9952
10073
  const result = {
9953
10074
  type: "tool_result",
9954
10075
  tool_use_id: use.id,
9955
- content: `Tool "${use.name}" execution failed: ${scrubbed}`,
10076
+ content: isStructured ? scrubbed : `Tool "${use.name}" execution failed: ${scrubbed}`,
9956
10077
  is_error: true
9957
10078
  };
9958
10079
  budget = this.budgetForString(result.content, budget);
@@ -9995,7 +10116,23 @@ ${post.additionalContext}`;
9995
10116
  * to call a tool" and "tool.executed".
9996
10117
  */
9997
10118
  async executeTool(tool, use, ctx, budget) {
10119
+ const text = await this.produceToolOutput(tool, use, ctx, budget);
10120
+ return this.settleToolOutput(tool, use, text, budget);
10121
+ }
10122
+ /**
10123
+ * Async "produce" phase: run the tool, serialize, scrub, and spill an
10124
+ * oversized output to a disk artifact. Returns the pre-cap text. This is
10125
+ * the long-running, concurrency-safe part — it touches NO shared budget
10126
+ * state, so multiple invocations can run in parallel without racing.
10127
+ *
10128
+ * The `budgetHint` only gates the disk-spill threshold (a heuristic for
10129
+ * "is this output large enough to persist"); it is NOT the output cap.
10130
+ * The authoritative cap is applied synchronously in settleToolOutput()
10131
+ * against the live budget.
10132
+ */
10133
+ async produceToolOutput(tool, use, ctx, budgetHint) {
9998
10134
  this.opts.events?.emit("tool.started", {
10135
+ sessionId: ctx.session.id,
9999
10136
  name: tool.name,
10000
10137
  id: use.id,
10001
10138
  input: use.input
@@ -10004,8 +10141,20 @@ ${post.additionalContext}`;
10004
10141
  const output = await this.runWithTimeout(tool, use.input, ctx.signal, ctx, use.id);
10005
10142
  const text = this.serializer.serialize(output, { toolName: tool.name, input: use.input, tool });
10006
10143
  const scrubbed = this.opts.secretScrubber.scrub(text);
10007
- const withArtifact = await maybePersistLargeToolOutput(tool.name, scrubbed, budget);
10008
- const { text: capped, newBudget } = this.serializer.enforceCap(withArtifact, budget);
10144
+ return maybePersistLargeToolOutput(tool.name, scrubbed, budgetHint);
10145
+ }
10146
+ /**
10147
+ * Synchronous "settle" phase: enforce the output cap against the CURRENT
10148
+ * budget, render, and build the result block. This MUST stay synchronous
10149
+ * (no awaits) so that, in the parallel/smart strategies, two tools settling
10150
+ * one after another against the shared closure budget can't interleave a
10151
+ * stale read with a write. The first to settle consumes its bytes; the next
10152
+ * settles against the reduced budget; once the budget hits 0, enforceCap
10153
+ * truncates — making the per-iteration cap genuinely CUMULATIVE across
10154
+ * parallel tools instead of degrading into a per-tool cap.
10155
+ */
10156
+ settleToolOutput(tool, use, text, budget) {
10157
+ const { text: capped, newBudget } = this.serializer.enforceCap(text, budget);
10009
10158
  this.hintRenderMode(tool.name);
10010
10159
  this.opts.renderer?.writeToolResult(tool.name, capped, false);
10011
10160
  return {
@@ -10058,7 +10207,12 @@ ${post.additionalContext}`;
10058
10207
  let finalOutput;
10059
10208
  let sawFinal = false;
10060
10209
  if (!tool.executeStream) {
10061
- throw new Error(`Tool "${tool.name}" does not support streaming execution`);
10210
+ throw new ToolError({
10211
+ message: `Tool "${tool.name}" does not support streaming execution`,
10212
+ code: "TOOL_EXECUTION_FAILED",
10213
+ toolName: tool.name,
10214
+ context: { reason: "streaming_not_supported" }
10215
+ });
10062
10216
  }
10063
10217
  const stream = tool.executeStream(input, ctx, { signal });
10064
10218
  const iter = stream[Symbol.asyncIterator]();
@@ -10068,6 +10222,7 @@ ${post.additionalContext}`;
10068
10222
  let lastProgressEmitAt = 0;
10069
10223
  const emitProgress = (ev) => {
10070
10224
  this.opts.events?.emit("tool.progress", {
10225
+ sessionId: ctx.session.id,
10071
10226
  name: tool.name,
10072
10227
  id: toolUseId ?? "<unknown>",
10073
10228
  event: ev
@@ -10123,7 +10278,12 @@ ${progressTail}`;
10123
10278
  await iter.return?.(void 0);
10124
10279
  }
10125
10280
  if (!sawFinal) {
10126
- throw new Error(`tool "${tool.name}" executeStream completed without a 'final' event`);
10281
+ throw new ToolError({
10282
+ message: `tool "${tool.name}" executeStream completed without a 'final' event`,
10283
+ code: "TOOL_EXECUTION_FAILED",
10284
+ toolName: tool.name,
10285
+ context: { reason: "missing_final_event" }
10286
+ });
10127
10287
  }
10128
10288
  return finalOutput;
10129
10289
  }
@@ -10247,6 +10407,15 @@ function classifyToolError(err) {
10247
10407
  if (err instanceof Error && err.message.includes("validation")) {
10248
10408
  return { category: "validation" /* VALIDATION */, retryable: false, detail: "validation" };
10249
10409
  }
10410
+ if (err instanceof WrongStackError) {
10411
+ const wse = err;
10412
+ const category = wse.severity === "warning" ? "transient" /* TRANSIENT */ : "fatal" /* FATAL */;
10413
+ return {
10414
+ category,
10415
+ retryable: wse.recoverable,
10416
+ detail: `${wse.code} [${wse.subsystem}]`
10417
+ };
10418
+ }
10250
10419
  return {
10251
10420
  category: "fatal" /* FATAL */,
10252
10421
  retryable: false,