@sema-agent/core 7.50.2 → 7.51.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.
Files changed (188) hide show
  1. package/CHANGELOG.md +263 -0
  2. package/dist/agents/child-failure.d.ts +5 -16
  3. package/dist/agents/child-failure.js +4 -24
  4. package/dist/agents/subagent-steps.js +2 -2
  5. package/dist/agents/subagent.d.ts +4 -13
  6. package/dist/agents/subagent.js +94 -204
  7. package/dist/agents/tool-filter.d.ts +2 -2
  8. package/dist/brain/anthropic.d.ts +1 -1
  9. package/dist/brain/anthropic.js +7 -5
  10. package/dist/brain/open-responses.d.ts +1 -1
  11. package/dist/brain/open-responses.js +3 -2
  12. package/dist/brain/openai.d.ts +1 -1
  13. package/dist/brain/openai.js +3 -2
  14. package/dist/brain/request-route.d.ts +2 -2
  15. package/dist/brain/route-adjudicator.d.ts +16 -7
  16. package/dist/brain/route-adjudicator.js +23 -7
  17. package/dist/brain/route-conformance.js +23 -5
  18. package/dist/brain/stream-engine.js +9 -3
  19. package/dist/core/a2a.js +6 -8
  20. package/dist/core/allow-entry.d.ts +45 -26
  21. package/dist/core/allow-entry.js +48 -24
  22. package/dist/core/arg-summary.d.ts +8 -85
  23. package/dist/core/arg-summary.js +4 -386
  24. package/dist/core/ask-origin.d.ts +35 -33
  25. package/dist/core/ask-origin.js +9 -11
  26. package/dist/core/checkpoint-requirements.d.ts +6 -0
  27. package/dist/core/checkpoint-requirements.js +1 -0
  28. package/dist/core/checkpoint-store.d.ts +15 -34
  29. package/dist/core/checkpoint-store.js +5 -4
  30. package/dist/core/classifier-unavailable-arm.d.ts +12 -8
  31. package/dist/core/classifier-unavailable-arm.js +7 -2
  32. package/dist/core/credential-vocabulary.d.ts +3 -2
  33. package/dist/core/credential-vocabulary.js +27 -18
  34. package/dist/core/delegation-frames.d.ts +40 -15
  35. package/dist/core/delegation-frames.js +34 -0
  36. package/dist/core/engine-notice.d.ts +35 -11
  37. package/dist/core/gate-fold.js +9 -7
  38. package/dist/core/gate-lanes.js +6 -4
  39. package/dist/core/gate-outcome.d.ts +81 -15
  40. package/dist/core/gate-outcome.js +168 -67
  41. package/dist/core/governance-codes.d.ts +7 -1
  42. package/dist/core/governance-codes.js +9 -0
  43. package/dist/core/hooks.d.ts +4 -4
  44. package/dist/core/hooks.js +4 -3
  45. package/dist/core/mcp-connection-pool.d.ts +2 -0
  46. package/dist/core/mcp-connection-pool.js +2 -1
  47. package/dist/core/mcp-failure.js +2 -1
  48. package/dist/core/mcp-server-spec.d.ts +27 -5
  49. package/dist/core/mcp.d.ts +13 -38
  50. package/dist/core/mcp.js +28 -23
  51. package/dist/core/media-byte-cap.d.ts +25 -0
  52. package/dist/core/media-byte-cap.js +18 -2
  53. package/dist/core/memory-engine/consolidation-driver.js +1 -1
  54. package/dist/core/mode-policy.d.ts +25 -1
  55. package/dist/core/mode-policy.js +28 -13
  56. package/dist/core/own-property-receipt.d.ts +18 -0
  57. package/dist/core/own-property-receipt.js +39 -0
  58. package/dist/core/permission-rule-model.d.ts +32 -11
  59. package/dist/core/permission-rule-model.js +12 -7
  60. package/dist/core/persisted-rule-arms.d.ts +3 -3
  61. package/dist/core/prompt-section-seat.d.ts +54 -0
  62. package/dist/core/prompt-section-seat.js +49 -0
  63. package/dist/core/protocol-http-auth.d.ts +44 -0
  64. package/dist/core/protocol-http-auth.js +45 -0
  65. package/dist/core/read-face-seats.d.ts +30 -0
  66. package/dist/core/read-face-seats.js +38 -0
  67. package/dist/core/redaction-passes.d.ts +82 -0
  68. package/dist/core/redaction-passes.js +378 -0
  69. package/dist/core/remote-env.d.ts +4 -3
  70. package/dist/core/resume-startup-cause.d.ts +56 -0
  71. package/dist/core/resume-startup-cause.js +43 -0
  72. package/dist/core/rule-denial-sentence.d.ts +2 -2
  73. package/dist/core/runner/announce-once-ledger.js +2 -2
  74. package/dist/core/runner/classifier-ladder.d.ts +17 -13
  75. package/dist/core/runner/classifier-ladder.js +12 -10
  76. package/dist/core/runner/construction-doors.js +9 -20
  77. package/dist/core/runner/contracts.d.ts +4 -4
  78. package/dist/core/runner/gate-exit.js +2 -2
  79. package/dist/core/runner/memory-consolidation-write-judge.d.ts +53 -9
  80. package/dist/core/runner/memory-consolidation-write-judge.js +39 -1
  81. package/dist/core/runner/permission-rule-lanes.d.ts +8 -13
  82. package/dist/core/runner/person-path-rows.d.ts +4 -3
  83. package/dist/core/runner/policy-throw.js +4 -4
  84. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -3
  85. package/dist/core/runner/prepare-caps-and-workflow.js +8 -6
  86. package/dist/core/runner/prepare-gate-stations.js +4 -4
  87. package/dist/core/runner/prepare-hands-readface.js +1 -19
  88. package/dist/core/runner/prepare-inherited-gate.js +10 -9
  89. package/dist/core/runner/prepare-policy-chain.d.ts +3 -5
  90. package/dist/core/runner/prepare-policy-chain.js +10 -13
  91. package/dist/core/runner/prepare-project-context.d.ts +4 -4
  92. package/dist/core/runner/prepare-project-context.js +2 -1
  93. package/dist/core/runner/prepare-prompt-assembly.js +1 -0
  94. package/dist/core/runner/prepare-prompt-inputs.d.ts +1 -1
  95. package/dist/core/runner/prepare-prompt-inputs.js +4 -4
  96. package/dist/core/runner/prepare-protocol-tools.d.ts +4 -3
  97. package/dist/core/runner/prepare-protocol-tools.js +3 -2
  98. package/dist/core/runner/prepare-task.js +6 -4
  99. package/dist/core/runner/prepare-turn-wiring.d.ts +16 -13
  100. package/dist/core/runner/prepare-turn-wiring.js +8 -7
  101. package/dist/core/runner/run-harness-handlers.js +2 -2
  102. package/dist/core/runner/run-leg.js +10 -9
  103. package/dist/core/runner/run-settle-and-teardown.js +5 -5
  104. package/dist/core/runner/run-turn-boundary.js +3 -2
  105. package/dist/core/runner/runtask.d.ts +1 -2
  106. package/dist/core/runner/runtask.js +8 -12
  107. package/dist/core/runner/session-rule-policy.d.ts +15 -11
  108. package/dist/core/runner/session-rule-policy.js +43 -33
  109. package/dist/core/runner/stream-lifecycle-verbs.js +2 -2
  110. package/dist/core/runner/stream-settle-backstop.js +2 -1
  111. package/dist/core/runner/sub-agent-deny-lists.d.ts +12 -8
  112. package/dist/core/runner/sub-agent-deny-lists.js +23 -12
  113. package/dist/core/runner/terminal-account.js +3 -3
  114. package/dist/core/runner/tool-output-projection.js +3 -8
  115. package/dist/core/runner/tool-result-media-seat.d.ts +19 -0
  116. package/dist/core/runner/tool-result-media-seat.js +13 -0
  117. package/dist/core/runner/turn-attachments.d.ts +13 -12
  118. package/dist/core/runner/turn-attachments.js +11 -7
  119. package/dist/core/runner-deps.d.ts +4 -3
  120. package/dist/core/safety-merge-corpus.js +21 -21
  121. package/dist/core/secret-env.js +1 -1
  122. package/dist/core/session-policy-store.d.ts +89 -72
  123. package/dist/core/session-policy-store.js +100 -93
  124. package/dist/core/shell-read-silence.d.ts +38 -4
  125. package/dist/core/shell-read-silence.js +102 -0
  126. package/dist/core/side-query.d.ts +7 -8
  127. package/dist/core/skill-grant-binding.d.ts +32 -11
  128. package/dist/core/skill-grant-binding.js +11 -3
  129. package/dist/core/skill-grant.d.ts +4 -3
  130. package/dist/core/skill-grant.js +5 -4
  131. package/dist/core/skills-directory.d.ts +12 -1
  132. package/dist/core/skills-directory.js +17 -8
  133. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +2 -0
  134. package/dist/core/store-contracts/checkpoint-store-contract.js +3 -0
  135. package/dist/core/swappable-deps.d.ts +15 -1
  136. package/dist/core/swappable-deps.js +25 -1
  137. package/dist/core/synthetic-read-verdict.d.ts +16 -14
  138. package/dist/core/synthetic-read-verdict.js +28 -8
  139. package/dist/core/task-notification.d.ts +13 -3
  140. package/dist/core/task-notification.js +12 -1
  141. package/dist/core/task-spec.d.ts +14 -15
  142. package/dist/core/tool-name-readings.d.ts +0 -4
  143. package/dist/core/tool-name-readings.js +0 -1
  144. package/dist/core/tool-policy.d.ts +40 -9
  145. package/dist/core/tool-policy.js +25 -7
  146. package/dist/core/types.d.ts +3 -3
  147. package/dist/core/types.js +1 -1
  148. package/dist/core/untrusted-egress.d.ts +60 -11
  149. package/dist/core/untrusted-egress.js +120 -9
  150. package/dist/core/untrusted-text.js +16 -0
  151. package/dist/core/wiring-manifest.d.ts +22 -8
  152. package/dist/core/wiring-manifest.js +12 -4
  153. package/dist/engine/harness/agent-harness.d.ts +2 -1
  154. package/dist/engine/harness/agent-harness.js +4 -1
  155. package/dist/engine/harness/types.d.ts +3 -0
  156. package/dist/engine/llm/types.d.ts +7 -9
  157. package/dist/engine/loop/agent-loop.d.ts +8 -3
  158. package/dist/engine/loop/agent-loop.js +26 -9
  159. package/dist/engine/loop/types.d.ts +10 -0
  160. package/dist/index.d.ts +17 -5
  161. package/dist/index.js +14 -5
  162. package/dist/orchestration/run-workflow-tool.js +8 -8
  163. package/dist/orchestration/workflow.js +2 -2
  164. package/dist/prompt-assembly/assemble.d.ts +3 -1
  165. package/dist/prompt-assembly/assemble.js +6 -0
  166. package/dist/prompts/cowork.d.ts +42 -0
  167. package/dist/prompts/cowork.js +529 -0
  168. package/dist/prompts/default.d.ts +14 -1
  169. package/dist/prompts/default.js +3 -0
  170. package/dist/stores/file/session-policy-store.d.ts +6 -3
  171. package/dist/stores/file/session-policy-store.js +5 -16
  172. package/dist/tools/artifact/artifact-tool.js +2 -0
  173. package/dist/tools/fs/image-admission.d.ts +57 -4
  174. package/dist/tools/fs/image-admission.js +85 -0
  175. package/dist/tools/fs/path-containment.d.ts +2 -0
  176. package/dist/tools/fs/path-containment.js +5 -0
  177. package/dist/tools/fs/shell-read-check.d.ts +31 -6
  178. package/dist/tools/fs/shell-read-check.js +2 -4
  179. package/dist/tools/fs/shell-read-environment.d.ts +10 -25
  180. package/dist/tools/fs/shell-read-environment.js +6 -18
  181. package/dist/tools/fs/shell-read-establish.d.ts +3 -2
  182. package/dist/tools/fs/shell-read-establish.js +5 -5
  183. package/dist/tools/fs/shell-read-judge.d.ts +38 -8
  184. package/dist/tools/fs/shell-read-judge.js +12 -10
  185. package/dist/tools/web.js +2 -2
  186. package/package.json +1 -1
  187. package/test/export-surface.snapshot.json +94 -10
  188. package/wire-changes/core@7.51.0.json +2421 -0
@@ -30,11 +30,10 @@ import { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX } from "../config/defaults.js
30
30
  * key is ABSENT rather than zeroed — a fabricated 0 reads as "ran no tools", which is a claim, not a
31
31
  * gap. Duration is always knowable (the caller holds the lane's launch instant), so it is unconditional.
32
32
  *
33
- * TWO SPELLINGS, one meaning, matching each face's established vocabulary: the observer
34
- * ({@link import("../core/types.js").BackgroundChildEvent}) `usage` face is camelCase and already
35
- * DECLARES `toolUses`/`durationMs`; the model-facing `TaskNotificationPayload.usage` is rendered into
36
- * `<usage>` as JSON where the workflow lane and the Agent sync footer both spell them snake_case. No new
37
- * word is minted on either side.
33
+ * ONE mint, in the model-facing `TaskNotificationPayload.usage` spelling (rendered into `<usage>` as JSON,
34
+ * where the workflow lane and the Agent sync footer both spell them snake_case); the observer
35
+ * ({@link import("../core/types.js").BackgroundChildEvent}) face's camelCase `toolUses`/`durationMs` is
36
+ * that frame's projection (`backgroundChildTerminal`), so the two faces cannot report different numbers.
38
37
  *
39
38
  * Exported at MODULE level (not from the package index — the same posture as `completedAgentCard` and
40
39
  * `classifySubagentError`): the ABSENT arm is the point of the knownness rule and is not reachable
@@ -43,13 +42,6 @@ import { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX } from "../config/defaults.js
43
42
  * optional-and-missing shape the stats face declares, and a pin that only sees a live child cannot
44
43
  * tell "absent" apart from "zero".
45
44
  */
46
- export declare function delegatedGranularityFields(stats: {
47
- toolCalls?: number;
48
- }, elapsedMs: number): {
49
- toolUses?: number;
50
- durationMs: number;
51
- };
52
- /** {@link delegatedGranularityFields}'s snake_case twin for the model-facing notification `usage`. */
53
45
  export declare function delegatedGranularityFieldsWire(stats: {
54
46
  toolCalls?: number;
55
47
  }, elapsedMs: number): {
@@ -60,7 +52,6 @@ export { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX };
60
52
  import { SubagentRetainLedger } from "./retain-ledger.js";
61
53
  import { type PeerSelfRef } from "./peer-admission.js";
62
54
  export type { SubagentStep, SubagentEditedFile } from "./subagent-steps.js";
63
- export declare function notifyResultField(result: string | undefined): string | undefined;
64
55
  /** What {@link layeredReviewSample} produced: the text actually sent, plus the honest read/total counts. */
65
56
  interface ReviewSample {
66
57
  text: string;
@@ -1,5 +1,8 @@
1
1
  import { Type } from "typebox";
2
2
  import { isAbsolute } from "node:path";
3
+ import { backgroundChildTerminal } from "../core/delegation-frames.js";
4
+ import { resumeStartupCauseOf } from "../core/resume-startup-cause.js";
5
+ import { errorCodeOf } from "../core/runner/terminal-account.js";
3
6
  import { applyParentSpecSeat, memoryTurnedOff, parentSpecSeatOfCtx } from "../core/parent-spec-seat.js";
4
7
  import { assertClampRecord, childClampSeats, clampSeatsOf, clampSourceOf, engineHeadlessLegSeats, foldClampSources, postureUnderClamps } from "../core/child-clamp-seats.js";
5
8
  import { assertNoRetiredKeys } from "../core/retired-keys.js";
@@ -36,7 +39,7 @@ import { BG_AGENT_REAP_STOP_ERROR } from "../core/task-registry.js";
36
39
  import { readDurableOrgAdmission } from "../core/memory-admission.js";
37
40
  import { governanceRetryClass } from "../core/governance-codes.js";
38
41
  import { readSkillGrantCapture } from "../core/skill-grant.js";
39
- import { terminalFrameFacets } from "../core/task-notification.js";
42
+ import { notifyResultField, terminalFrameFacets } from "../core/task-notification.js";
40
43
  import { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX, RUNNING_AGENT_OBSERVE_EVERY_BEATS, DELEGATION_MAX_CONCURRENT_DEFAULT, DELEGATION_MAX_PER_SESSION_DEFAULT } from "../config/defaults.js";
41
44
  function rollupDelegatedCost(stats, nested) {
42
45
  if (stats.costMicroUsd === undefined)
@@ -49,8 +52,8 @@ function delegatedCostField(stats) {
49
52
  const total = rollupDelegatedCost(stats, stats.nested);
50
53
  return total !== undefined ? { costMicroUsd: total } : {};
51
54
  }
52
- export function delegatedGranularityFields(stats, elapsedMs) {
53
- return { ...(stats.toolCalls !== undefined ? { toolUses: stats.toolCalls } : {}), durationMs: elapsedMs };
55
+ export function delegatedGranularityFieldsWire(stats, elapsedMs) {
56
+ return { ...(stats.toolCalls !== undefined ? { tool_uses: stats.toolCalls } : {}), duration_ms: elapsedMs };
54
57
  }
55
58
  function providerFaultField(child) {
56
59
  if (child.apiFailure === undefined)
@@ -62,9 +65,6 @@ function providerFaultField(child) {
62
65
  },
63
66
  };
64
67
  }
65
- export function delegatedGranularityFieldsWire(stats, elapsedMs) {
66
- return { ...(stats.toolCalls !== undefined ? { tool_uses: stats.toolCalls } : {}), duration_ms: elapsedMs };
67
- }
68
68
  export { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX };
69
69
  import { SUBAGENT_RESUME_CAP, SubagentRetainLedger, getOrCreateSessionRetainLedger, ensureSessionReapHook, createResumePrompt, } from "./retain-ledger.js";
70
70
  import { createPeerInboundChainRef, createPeerSelfRef } from "./peer-admission.js";
@@ -84,14 +84,6 @@ function resultSettleFields(result) {
84
84
  const display = full.length > BG_AGENT_RESULT_MAX ? boundedRedactedSummary(result, BG_AGENT_RESULT_MAX) : full;
85
85
  return display === full ? { result: display } : { result: display, resultFull: full };
86
86
  }
87
- const BG_AGENT_NOTIFY_RESULT_MAX = 2_000;
88
- export function notifyResultField(result) {
89
- if (!result)
90
- return undefined;
91
- return result.length > BG_AGENT_NOTIFY_RESULT_MAX
92
- ? `${result.slice(0, BG_AGENT_NOTIFY_RESULT_MAX)}\n[result truncated: ${result.length} chars total — ask the agent for it via SendMessage, or read it with TaskOutput where mounted]`
93
- : result;
94
- }
95
87
  const HANDBACK_REVIEW_SAMPLE_BUDGET = 12_000;
96
88
  const HANDBACK_REVIEW_SAMPLE_WINDOWS = 5;
97
89
  const HANDBACK_REVIEW_SAMPLE_MAX_WINDOWS = 16;
@@ -759,23 +751,6 @@ export function createSubagentResume(deps) {
759
751
  named: deps.rowName !== undefined,
760
752
  });
761
753
  const ownsTerminalFacesRevive = deps.registry !== undefined && deps.taskId !== undefined ? deps.registry.claimAgentTerminalNotify(deps.taskId) : true;
762
- if (ownsTerminalFacesRevive)
763
- reviveEmit?.({
764
- kind: "terminal",
765
- taskId: deps.taskId,
766
- sessionScoped: deps.sessionScoped === true,
767
- sessionId: entry.childSessionId,
768
- transcriptId: entry.childSessionId,
769
- ...(deps.parentToolCallId !== undefined ? { parentToolCallId: deps.parentToolCallId } : {}),
770
- status,
771
- seq: entry.cycleSeq,
772
- ...(stoppedByRevive !== undefined ? { stoppedBy: stoppedByRevive } : {}),
773
- summary: reviveTerminalSummary,
774
- ...resumeResidual(),
775
- resumable: resumableRevive,
776
- usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFields(child.stats, reviveElapsedMs) },
777
- ...(completionIdRevive !== undefined ? { completionId: completionIdRevive } : {}),
778
- });
779
754
  const resumeFrame = {
780
755
  task_id: deps.taskId ?? entry.childSessionId,
781
756
  ...(entry.childSessionId !== undefined ? { sessionId: entry.childSessionId } : {}),
@@ -796,6 +771,8 @@ export function createSubagentResume(deps) {
796
771
  usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFieldsWire(child.stats, reviveElapsedMs) },
797
772
  ...(completionIdRevive !== undefined ? { completionId: completionIdRevive } : {}),
798
773
  };
774
+ if (ownsTerminalFacesRevive)
775
+ reviveEmit?.(backgroundChildTerminal(resumeFrame, { taskId: deps.taskId, sessionScoped: deps.sessionScoped === true, sessionId: entry.childSessionId, transcriptId: entry.childSessionId, ...(deps.parentToolCallId !== undefined ? { parentToolCallId: deps.parentToolCallId } : {}) }));
799
776
  const gateOwner = ownsTerminalFacesRevive && status === "completed" && deps.notify !== undefined && deps.registry !== undefined && ledger.get(deps.parentToolCallId) === entry
800
777
  ? entry.childSessionId
801
778
  : undefined;
@@ -838,35 +815,24 @@ export function createSubagentResume(deps) {
838
815
  const completionIdRejectRevive = deps.registry?.getCompletionId(deps.taskId ?? "");
839
816
  const rejectName = deps.rowDescription ?? `sub-agent ${marker}`;
840
817
  const ownsTerminalFacesReviveReject = deps.registry !== undefined && deps.taskId !== undefined ? deps.registry.claimAgentTerminalNotify(deps.taskId) : true;
818
+ const reviveRejectFrame = {
819
+ task_id: deps.taskId ?? entry.childSessionId,
820
+ ...(entry.childSessionId !== undefined ? { sessionId: entry.childSessionId } : {}),
821
+ task_type: "background_agent",
822
+ toolUseId: deps.parentToolCallId,
823
+ status: abort.signal.aborted ? "killed" : "failed",
824
+ seq: entry.cycleSeq,
825
+ ...(stoppedByReject !== undefined ? { stoppedBy: stoppedByReject } : {}),
826
+ summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : `failed: ${msgRevive}`}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300) + (abort.signal.aborted ? "" : errorKindClause(errClassReviveReject)),
827
+ ...(abort.signal.aborted ? {} : { error: msgRevive.slice(0, REPORT_FIELD_MAX) }),
828
+ ...(!abort.signal.aborted && errCodeReviveReject !== undefined ? { errorCode: errCodeReviveReject } : {}),
829
+ ...(completionIdRejectRevive !== undefined ? { completionId: completionIdRejectRevive } : {}),
830
+ };
841
831
  if (ownsTerminalFacesReviveReject)
842
- reviveEmit?.({
843
- kind: "terminal",
844
- taskId: deps.taskId,
845
- sessionScoped: deps.sessionScoped === true,
846
- sessionId: entry.childSessionId,
847
- transcriptId: entry.childSessionId,
848
- ...(deps.parentToolCallId !== undefined ? { parentToolCallId: deps.parentToolCallId } : {}),
849
- status: abort.signal.aborted ? "killed" : "failed",
850
- seq: entry.cycleSeq,
851
- ...(stoppedByReject !== undefined ? { stoppedBy: stoppedByReject } : {}),
852
- summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : "failed"}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300) + (abort.signal.aborted ? "" : errorKindClause(errClassReviveReject)),
853
- ...(completionIdRejectRevive !== undefined ? { completionId: completionIdRejectRevive } : {}),
854
- });
832
+ reviveEmit?.(backgroundChildTerminal(reviveRejectFrame, { taskId: deps.taskId, sessionScoped: deps.sessionScoped === true, sessionId: entry.childSessionId, transcriptId: entry.childSessionId, ...(deps.parentToolCallId !== undefined ? { parentToolCallId: deps.parentToolCallId } : {}) }));
855
833
  try {
856
834
  if (ownsTerminalFacesReviveReject)
857
- deps.notify?.({
858
- task_id: deps.taskId ?? entry.childSessionId,
859
- ...(entry.childSessionId !== undefined ? { sessionId: entry.childSessionId } : {}),
860
- task_type: "background_agent",
861
- toolUseId: deps.parentToolCallId,
862
- status: abort.signal.aborted ? "killed" : "failed",
863
- seq: entry.cycleSeq,
864
- ...(stoppedByReject !== undefined ? { stoppedBy: stoppedByReject } : {}),
865
- summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : `failed: ${msgRevive}`}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300) + (abort.signal.aborted ? "" : errorKindClause(errClassReviveReject)),
866
- ...(abort.signal.aborted ? {} : { error: msgRevive.slice(0, REPORT_FIELD_MAX) }),
867
- ...(!abort.signal.aborted && errCodeReviveReject !== undefined ? { errorCode: errCodeReviveReject } : {}),
868
- ...(completionIdRejectRevive !== undefined ? { completionId: completionIdRejectRevive } : {}),
869
- }, { priority: "next" });
835
+ deps.notify?.(reviveRejectFrame, { priority: "next" });
870
836
  }
871
837
  catch {
872
838
  }
@@ -2557,32 +2523,19 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2557
2523
  const stoppedByReap = bg.registry.getStopAttribution(taskId) ?? "system";
2558
2524
  const completionIdReap = bg.registry.getCompletionId(taskId);
2559
2525
  const seqReap = bg.registry.backgroundAgentCycleSeq(taskId);
2560
- const summaryReap = ccCompletionText(shortDesc, "killed", "killed", Date.now() - forkBgHangAt);
2561
- sinkEmit({
2562
- kind: "terminal",
2563
- taskId,
2564
- sessionScoped: sessionScopedBg === true,
2565
- sessionId: forkedId,
2566
- transcriptId: forkedId,
2567
- parentToolCallId: ctx.toolCallId,
2568
- status: "killed",
2569
- ...(seqReap !== undefined ? { seq: seqReap } : {}),
2570
- stoppedBy: stoppedByReap,
2571
- summary: summaryReap,
2572
- resumable: false,
2573
- ...(completionIdReap !== undefined ? { completionId: completionIdReap } : {}),
2574
- });
2575
- notifier.notify(() => notify?.({
2526
+ const reapFrame = {
2576
2527
  task_id: taskId,
2577
2528
  task_type: "background_agent",
2578
2529
  toolUseId: ctx.toolCallId,
2579
2530
  status: "killed",
2580
2531
  stoppedBy: stoppedByReap,
2581
- summary: summaryReap,
2532
+ summary: ccCompletionText(shortDesc, "killed", "killed", Date.now() - forkBgHangAt),
2582
2533
  sessionId: forkedId,
2583
2534
  resumable: false,
2584
2535
  ...(completionIdReap !== undefined ? { completionId: completionIdReap } : {}),
2585
- }, { priority: "next" }), "subagent.reapTerminalNotify");
2536
+ };
2537
+ sinkEmit(backgroundChildTerminal(reapFrame, { taskId, sessionScoped: sessionScopedBg === true, sessionId: forkedId, transcriptId: forkedId, parentToolCallId: ctx.toolCallId, ...(seqReap !== undefined ? { generation: seqReap } : {}) }));
2538
+ notifier.notify(() => notify?.(reapFrame, { priority: "next" }), "subagent.reapTerminalNotify");
2586
2539
  });
2587
2540
  if (agentName !== undefined) {
2588
2541
  recordRosterSpawn(ctx.roster, { name: agentName, agentId: taskId, sessionId: forkedId, toolUseId: ctx.toolCallId, owner: bgOwner, scope: bgScope, ...(rowModelKey !== undefined ? { model: rowModelKey } : {}), ...(modelFallback !== undefined ? { modelFallback } : {}), ...((ctx.rootSessionId ?? ctx.sessionId) !== undefined ? { rootSessionId: ctx.rootSessionId ?? ctx.sessionId } : {}), ...(sessionScopedBg ? { sessionScoped: true } : {}), createdAt: Date.now() }, (err) => opts.onObserverError?.(err, { site: "roster.recordSpawn" }));
@@ -2752,44 +2705,30 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2752
2705
  ? `Agent "${shortDesc}" failed: ${failReasonFork}${ccElapsedTag(forkElapsedMs)}`.slice(0, 300) + errorKindClause(errClassFork)
2753
2706
  : `${ccCompletionText(shortDesc, settledBg, childFace.status, forkElapsedMs)}`;
2754
2707
  const ownsTerminalFacesFork = bg.registry.claimAgentTerminalNotify(taskId);
2708
+ const forkFrame = {
2709
+ task_id: taskId,
2710
+ task_type: "background_agent",
2711
+ toolUseId: ctx.toolCallId,
2712
+ status: settledBg,
2713
+ ...terminalFrameFacets({ spawnName: agentName, result: forkBgResult, warning: forkBgWarning, compaction: child.compaction }),
2714
+ ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
2715
+ summary: forkTerminalSummary,
2716
+ ...(failReasonFork !== undefined ? { error: failReasonFork.slice(0, REPORT_FIELD_MAX) } : {}),
2717
+ ...(settledBg === "failed" && errCodeFork !== undefined ? { errorCode: errCodeFork } : {}),
2718
+ ...providerFaultField(child),
2719
+ ...(child.sessionId ? { sessionId: child.sessionId } : {}),
2720
+ ...(forkBgResult ? { result: notifyResultField(forkBgResult) } : {}),
2721
+ ...(settledBg === "killed" && child.result ? { partial: true } : {}),
2722
+ ...residualFork,
2723
+ resumable: resumableFork,
2724
+ usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFieldsWire(child.stats, forkElapsedMs) },
2725
+ ...(completionIdFork !== undefined ? { completionId: completionIdFork } : {}),
2726
+ };
2755
2727
  if (ownsTerminalFacesFork)
2756
- sinkEmit({
2757
- kind: "terminal",
2758
- taskId,
2759
- sessionScoped: sessionScopedBg === true,
2760
- sessionId: forkTranscriptId,
2761
- ...(stillbornFork ? {} : { transcriptId: forkTranscriptId }),
2762
- parentToolCallId: ctx.toolCallId,
2763
- status: settledBg,
2764
- ...(bgForkCycleSeq !== undefined ? { seq: bgForkCycleSeq } : {}),
2765
- ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
2766
- summary: forkTerminalSummary,
2767
- ...residualFork,
2768
- resumable: resumableFork,
2769
- usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFields(child.stats, forkElapsedMs) },
2770
- ...(completionIdFork !== undefined ? { completionId: completionIdFork } : {}),
2771
- });
2728
+ sinkEmit(backgroundChildTerminal(forkFrame, { taskId, sessionScoped: sessionScopedBg === true, sessionId: forkTranscriptId, ...(stillbornFork ? {} : { transcriptId: forkTranscriptId }), parentToolCallId: ctx.toolCallId, ...(bgForkCycleSeq !== undefined ? { generation: bgForkCycleSeq } : {}) }));
2772
2729
  try {
2773
2730
  if (ownsTerminalFacesFork)
2774
- notify?.({
2775
- task_id: taskId,
2776
- task_type: "background_agent",
2777
- toolUseId: ctx.toolCallId,
2778
- status: settledBg,
2779
- ...terminalFrameFacets({ spawnName: agentName, result: forkBgResult, warning: forkBgWarning, compaction: child.compaction }),
2780
- ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
2781
- summary: forkTerminalSummary,
2782
- ...(failReasonFork !== undefined ? { error: failReasonFork.slice(0, REPORT_FIELD_MAX) } : {}),
2783
- ...(settledBg === "failed" && errCodeFork !== undefined ? { errorCode: errCodeFork } : {}),
2784
- ...providerFaultField(child),
2785
- ...(child.sessionId ? { sessionId: child.sessionId } : {}),
2786
- ...(forkBgResult ? { result: notifyResultField(forkBgResult) } : {}),
2787
- ...(settledBg === "killed" && child.result ? { partial: true } : {}),
2788
- ...residualFork,
2789
- resumable: resumableFork,
2790
- usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFieldsWire(child.stats, forkElapsedMs) },
2791
- ...(completionIdFork !== undefined ? { completionId: completionIdFork } : {}),
2792
- }, { priority: "next" });
2731
+ notify?.(forkFrame, { priority: "next" });
2793
2732
  }
2794
2733
  catch {
2795
2734
  }
@@ -2813,35 +2752,24 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2813
2752
  const completionIdForkReject = bg.registry.getCompletionId(taskId);
2814
2753
  const summaryBg = `${shortDesc} — ${settledBg === "failed" ? `failed: ${msgFork}` : settledBg}`.slice(0, 300) + (settledBg === "failed" ? errorKindClause(errClassForkReject) : "");
2815
2754
  const ownsTerminalFacesForkReject = bg.registry.claimAgentTerminalNotify(taskId);
2755
+ const forkRejectFrame = {
2756
+ task_id: taskId,
2757
+ task_type: "background_agent",
2758
+ toolUseId: ctx.toolCallId,
2759
+ status: settledBg,
2760
+ ...terminalFrameFacets({ spawnName: agentName }),
2761
+ sessionId: forkedId,
2762
+ ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
2763
+ summary: summaryBg,
2764
+ ...(settledBg === "failed" ? { error: msgFork.slice(0, REPORT_FIELD_MAX) } : {}),
2765
+ ...(settledBg === "failed" && errCodeForkReject !== undefined ? { errorCode: errCodeForkReject } : {}),
2766
+ ...(completionIdForkReject !== undefined ? { completionId: completionIdForkReject } : {}),
2767
+ };
2816
2768
  if (ownsTerminalFacesForkReject)
2817
- sinkEmit({
2818
- kind: "terminal",
2819
- taskId,
2820
- sessionScoped: sessionScopedBg === true,
2821
- sessionId: forkedId,
2822
- transcriptId: forkedId,
2823
- parentToolCallId: ctx.toolCallId,
2824
- status: settledBg,
2825
- ...(bgForkCycleSeq !== undefined ? { seq: bgForkCycleSeq } : {}),
2826
- ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
2827
- summary: summaryBg,
2828
- ...(completionIdForkReject !== undefined ? { completionId: completionIdForkReject } : {}),
2829
- });
2769
+ sinkEmit(backgroundChildTerminal(forkRejectFrame, { taskId, sessionScoped: sessionScopedBg === true, sessionId: forkedId, transcriptId: forkedId, parentToolCallId: ctx.toolCallId, ...(bgForkCycleSeq !== undefined ? { generation: bgForkCycleSeq } : {}) }));
2830
2770
  try {
2831
2771
  if (ownsTerminalFacesForkReject)
2832
- notify?.({
2833
- task_id: taskId,
2834
- task_type: "background_agent",
2835
- toolUseId: ctx.toolCallId,
2836
- status: settledBg,
2837
- ...terminalFrameFacets({ spawnName: agentName }),
2838
- sessionId: forkedId,
2839
- ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
2840
- summary: summaryBg,
2841
- ...(settledBg === "failed" ? { error: msgFork.slice(0, REPORT_FIELD_MAX) } : {}),
2842
- ...(settledBg === "failed" && errCodeForkReject !== undefined ? { errorCode: errCodeForkReject } : {}),
2843
- ...(completionIdForkReject !== undefined ? { completionId: completionIdForkReject } : {}),
2844
- }, { priority: "next" });
2772
+ notify?.(forkRejectFrame, { priority: "next" });
2845
2773
  }
2846
2774
  catch {
2847
2775
  }
@@ -3147,33 +3075,20 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3147
3075
  const stoppedByReap = bg.registry.getStopAttribution(taskId) ?? "system";
3148
3076
  const completionIdReap = bg.registry.getCompletionId(taskId);
3149
3077
  const seqReap = bg.registry.backgroundAgentCycleSeq(taskId);
3150
- const summaryReap = ccCompletionText(shortDesc, "killed", "killed", Date.now() - bgStartedAt);
3151
- sinkEmit({
3152
- kind: "terminal",
3153
- taskId,
3154
- sessionScoped: sessionScopedBg === true,
3155
- sessionId: bgChildSessionId,
3156
- transcriptId: bgChildSessionId,
3157
- parentToolCallId: ctx.toolCallId,
3158
- status: "killed",
3159
- ...(seqReap !== undefined ? { seq: seqReap } : {}),
3160
- stoppedBy: stoppedByReap,
3161
- summary: summaryReap,
3162
- resumable: false,
3163
- ...(completionIdReap !== undefined ? { completionId: completionIdReap } : {}),
3164
- });
3165
- notifier.notify(() => notify?.({
3078
+ const reapFrame = {
3166
3079
  task_id: taskId,
3167
3080
  task_type: "background_agent",
3168
3081
  toolUseId: ctx.toolCallId,
3169
3082
  status: "killed",
3170
3083
  ...terminalFrameFacets({ spawnName: agentName }),
3171
3084
  stoppedBy: stoppedByReap,
3172
- summary: summaryReap,
3085
+ summary: ccCompletionText(shortDesc, "killed", "killed", Date.now() - bgStartedAt),
3173
3086
  sessionId: bgChildSessionId,
3174
3087
  resumable: false,
3175
3088
  ...(completionIdReap !== undefined ? { completionId: completionIdReap } : {}),
3176
- }, { priority: "next" }), "subagent.reapTerminalNotify");
3089
+ };
3090
+ sinkEmit(backgroundChildTerminal(reapFrame, { taskId, sessionScoped: sessionScopedBg === true, sessionId: bgChildSessionId, transcriptId: bgChildSessionId, parentToolCallId: ctx.toolCallId, ...(seqReap !== undefined ? { generation: seqReap } : {}) }));
3091
+ notifier.notify(() => notify?.(reapFrame, { priority: "next" }), "subagent.reapTerminalNotify");
3177
3092
  });
3178
3093
  const bgDurableProbe = bg.registry.durableAgentRowProbe(taskId);
3179
3094
  const bgRowConfirmed = async () => (bgDurableProbe ? await bgDurableProbe().catch(() => false) : false);
@@ -3346,7 +3261,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3346
3261
  ? `parked resume rolled back — the approval is still pending (retryable): ${msg}`
3347
3262
  : disp === "failed"
3348
3263
  ? `parked resume failed — the approval is no longer redeemable: ${msg}`
3349
- : `parked resume did not proceed (${disp}): ${msg}`);
3264
+ : `parked resume did not proceed (${disp}): ${msg}`, { cause: e });
3350
3265
  };
3351
3266
  try {
3352
3267
  await opts.runner.sessions.acquire(bgChildSessionId, { requireExisting: true });
@@ -3364,7 +3279,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3364
3279
  catch {
3365
3280
  }
3366
3281
  }
3367
- return rollbackAndThrow(e);
3282
+ return rollbackAndThrow(code === "not_found" ? Object.assign(new Error(thrownText(e), { cause: e }), { code: "resume.session_not_found" }) : e);
3368
3283
  }
3369
3284
  if (opts.tools === undefined && (opts.inheritedTools?.length ?? 0) > 0 && ctx.mountsCallerTool === undefined && pr.outcome.gate === "policy_ask" && pr.outcome.decision === "allow") {
3370
3285
  let pending;
@@ -3376,7 +3291,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3376
3291
  }
3377
3292
  const name = pending?.kind === "tool_approval" ? pending.toolName : undefined;
3378
3293
  if (name !== undefined && (opts.inheritedTools ?? []).some((t) => t.name === name) && !(bgSpec.tools ?? []).some((t) => t.name === name)) {
3379
- return rollbackAndThrow(new Error(`the approved tool "${name}" is one the agent inherits from its spawning run, and this resume was driven without the \`mountsCallerTool\` seat, so the resumed agent would not have it. The host must pass the seat built from the row's own session (never a boot-time bundle: its task list has no session and would be shared by every revived agent). Deny still resolves this approval.`));
3294
+ return rollbackAndThrow(Object.assign(new Error(`the approved tool "${name}" is one the agent inherits from its spawning run, and this resume was driven without the \`mountsCallerTool\` seat, so the resumed agent would not have it. The host must pass the seat built from the row's own session (never a boot-time bundle: its task list has no session and would be shared by every revived agent). Deny still resolves this approval.`), { code: "resume.tool_unavailable" }));
3380
3295
  }
3381
3296
  }
3382
3297
  {
@@ -3453,7 +3368,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3453
3368
  return await cpS.expire(pr.ticket.token, cp.scope);
3454
3369
  },
3455
3370
  });
3456
- throw new Error(`parked resume could not complete and the approval was REOPENED (still approvable/retryable): ${childResult.terminal.message ?? "failed"}`);
3371
+ throw new Error(`parked resume could not complete and the approval was REOPENED (still approvable/retryable): ${childResult.terminal.message ?? "failed"}`, { cause: childResult.terminal });
3457
3372
  }
3458
3373
  }
3459
3374
  return childResult;
@@ -3614,22 +3529,6 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3614
3529
  ? `Agent "${shortDesc}" failed: ${failReasonBg}${ccElapsedTag(bgElapsedMs)}${observerNote}`.slice(0, 300) + errorKindClause(errClassBg)
3615
3530
  : `${ccCompletionText(shortDesc, settled, childFace.status, bgElapsedMs)}${observerNote}`;
3616
3531
  const ownsTerminalFaces = bg.registry.claimAgentTerminalNotify(taskId);
3617
- if (ownsTerminalFaces)
3618
- sinkEmit({
3619
- kind: "terminal",
3620
- taskId,
3621
- sessionScoped: sessionScopedBg === true,
3622
- ...(child.sessionId ? { sessionId: child.sessionId, transcriptId: child.sessionId } : {}),
3623
- parentToolCallId: ctx.toolCallId,
3624
- status: settled,
3625
- ...(seqAtSettle !== undefined ? { seq: seqAtSettle } : bgCycleSeq !== undefined ? { seq: bgCycleSeq } : {}),
3626
- ...(stoppedBy !== undefined ? { stoppedBy } : {}),
3627
- summary: bgTerminalSummary,
3628
- ...residual,
3629
- resumable: resumableBg,
3630
- usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFields(child.stats, bgElapsedMs) },
3631
- ...(completionIdBg !== undefined ? { completionId: completionIdBg } : {}),
3632
- });
3633
3532
  const completionFrame = {
3634
3533
  task_id: taskId,
3635
3534
  task_type: "background_agent",
@@ -3650,6 +3549,8 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3650
3549
  usage: { tokens: child.stats.tokens, turns: child.stats.turns, ...delegatedCostField(child.stats), ...delegatedGranularityFieldsWire(child.stats, bgElapsedMs) },
3651
3550
  ...(completionIdBg !== undefined ? { completionId: completionIdBg } : {}),
3652
3551
  };
3552
+ if (ownsTerminalFaces)
3553
+ sinkEmit(backgroundChildTerminal(completionFrame, { taskId, sessionScoped: sessionScopedBg === true, ...(child.sessionId ? { sessionId: child.sessionId, transcriptId: child.sessionId } : {}), parentToolCallId: ctx.toolCallId, ...(bgCycleSeq !== undefined ? { generation: bgCycleSeq } : {}) }));
3653
3554
  const gateOwner = ownsTerminalFaces && settled === "completed" && notify !== undefined ? bgRetain?.childSessionId : undefined;
3654
3555
  const aliveBgCount = gateOwner !== undefined ? bg.registry.countRunningBackgroundForOwner(gateOwner) : 0;
3655
3556
  if (gateOwner !== undefined && bgRetain !== undefined && aliveBgCount > 0) {
@@ -3706,36 +3607,25 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3706
3607
  const completionIdBgReject = bg.registry.getCompletionId(taskId);
3707
3608
  const observerNote = observerNoteFor(await startBoundedObserverDrain());
3708
3609
  const ownsTerminalFacesReject = bg.registry.claimAgentTerminalNotify(taskId);
3610
+ const rejectFrame = {
3611
+ task_id: taskId,
3612
+ task_type: "background_agent",
3613
+ toolUseId: ctx.toolCallId,
3614
+ status: settled,
3615
+ ...terminalFrameFacets({ spawnName: agentName }),
3616
+ sessionId: bgChildSessionId,
3617
+ ...(seqAtSettle !== undefined ? { seq: seqAtSettle } : {}),
3618
+ ...(stoppedBy !== undefined ? { stoppedBy } : {}),
3619
+ summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300) + (settled === "failed" ? errorKindClause(errClassBgReject) : ""),
3620
+ ...(settled === "failed" ? { error: msg.slice(0, REPORT_FIELD_MAX) } : {}),
3621
+ ...(settled === "failed" && errCodeBgReject !== undefined ? { errorCode: errCodeBgReject } : {}),
3622
+ ...(completionIdBgReject !== undefined ? { completionId: completionIdBgReject } : {}),
3623
+ };
3709
3624
  if (ownsTerminalFacesReject)
3710
- sinkEmit({
3711
- kind: "terminal",
3712
- taskId,
3713
- sessionScoped: sessionScopedBg === true,
3714
- sessionId: bgChildSessionId,
3715
- transcriptId: bgChildSessionId,
3716
- parentToolCallId: ctx.toolCallId,
3717
- status: settled,
3718
- ...(seqAtSettle !== undefined ? { seq: seqAtSettle } : bgCycleSeq !== undefined ? { seq: bgCycleSeq } : {}),
3719
- ...(stoppedBy !== undefined ? { stoppedBy } : {}),
3720
- summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300) + (settled === "failed" ? errorKindClause(errClassBgReject) : ""),
3721
- ...(completionIdBgReject !== undefined ? { completionId: completionIdBgReject } : {}),
3722
- });
3625
+ sinkEmit(backgroundChildTerminal(rejectFrame, { taskId, sessionScoped: sessionScopedBg === true, sessionId: bgChildSessionId, transcriptId: bgChildSessionId, parentToolCallId: ctx.toolCallId, ...(bgCycleSeq !== undefined ? { generation: bgCycleSeq } : {}) }));
3723
3626
  try {
3724
3627
  if (ownsTerminalFacesReject)
3725
- notify?.({
3726
- task_id: taskId,
3727
- task_type: "background_agent",
3728
- toolUseId: ctx.toolCallId,
3729
- status: settled,
3730
- ...terminalFrameFacets({ spawnName: agentName }),
3731
- sessionId: bgChildSessionId,
3732
- ...(seqAtSettle !== undefined ? { seq: seqAtSettle } : {}),
3733
- ...(stoppedBy !== undefined ? { stoppedBy } : {}),
3734
- summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300) + (settled === "failed" ? errorKindClause(errClassBgReject) : ""),
3735
- ...(settled === "failed" ? { error: msg.slice(0, REPORT_FIELD_MAX) } : {}),
3736
- ...(settled === "failed" && errCodeBgReject !== undefined ? { errorCode: errCodeBgReject } : {}),
3737
- ...(completionIdBgReject !== undefined ? { completionId: completionIdBgReject } : {}),
3738
- }, { priority: "next" });
3628
+ notify?.(rejectFrame, { priority: "next" });
3739
3629
  }
3740
3630
  catch {
3741
3631
  }
@@ -3747,11 +3637,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3747
3637
  ]);
3748
3638
  if (startup === "settled") {
3749
3639
  if (parkedResume !== undefined) {
3750
- const err = await bgChildPromise.then(() => undefined, (e) => childThrownText(e));
3640
+ const failure = await bgChildPromise.then((r) => ({ err: undefined, cause: resumeStartupCauseOf(r.terminal.kind === "failed" ? r.terminal.code : undefined) }), (e) => ({ err: childThrownText(e), cause: resumeStartupCauseOf(errorCodeOf(e)) }));
3751
3641
  return {
3752
3642
  isError: true,
3753
- content: `Parked resume did not complete: ${(err ?? "the resumed run settled before its delivery lane bound").slice(0, 600)}`,
3754
- details: { error: "parked_resume.startup_failed", task_id: taskId },
3643
+ content: `Parked resume did not complete: ${(failure.err ?? "the resumed run settled before its delivery lane bound").slice(0, 600)}`,
3644
+ details: { error: "parked_resume.startup_failed", task_id: taskId, ...(failure.cause !== undefined ? { cause: failure.cause } : {}) },
3755
3645
  };
3756
3646
  }
3757
3647
  return {
@@ -16,8 +16,8 @@ import { type ToolNameListReading } from "../core/tool-name-list.js";
16
16
  *
17
17
  * An entry is read as the reference reads a rule string ({@link readDeniedEntry}: `Tool(content)` names `Tool`, the content is
18
18
  * not read, the whole tool is hidden); a protocol spelling (`mcp__srv`, `mcp__srv__*`, a glob over the tool segment) reaches the
19
- * tools of that peer, including ones it lists later. Each list is judged at the prepare that receives it: a name that names no
20
- * tool is refused (`sub-agent-deny-lists.ts`).
19
+ * tools of that peer, including ones it lists later; an entry no tool answers to is kept by name and reaches one mounted later.
20
+ * Judged at the prepare that receives it: a spelling no tool name can have is refused, an unknown name told (`sub-agent-deny-lists.ts`).
21
21
  *
22
22
  * Note: `"*"` in an allowed list is the "allow all" sentinel, so a tool literally NAMED `"*"` cannot be
23
23
  * the sole allowed tool via this path (tool names are conventionally identifiers, so this is moot).
@@ -42,4 +42,4 @@ export interface AnthropicBrainConfig extends StreamEngineConfig {
42
42
  * read-loop machinery lives in the shared {@link runStreamingBrain} engine (design/32); this adapter
43
43
  * owns the Anthropic request shaping + typed content-block SSE parsing + finalization.
44
44
  */
45
- export declare function createAnthropicBrain(config?: AnthropicBrainConfig): Brain;
45
+ export declare function createAnthropicBrain(given?: AnthropicBrainConfig): Brain;
@@ -7,7 +7,7 @@ import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCal
7
7
  import { emitBrainTelemetry, reportReasoningWireFacts } from "./status-sink.js";
8
8
  import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, modelSupportsVision, sendableImages } from "./media-degrade.js";
9
9
  import { ANTHROPIC_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, lockHeader, mergeHeaders, takeHeaderCasefold } from "./request-params.js";
10
- import { adjudicateModelRoute, applyRouteCredentialHeaders, assertServableRequestRoot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential, routeRefusalText } from "./route-adjudicator.js";
10
+ import { adjudicateModelRoute, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential, routeRefusalText } from "./route-adjudicator.js";
11
11
  import { requestRouteOf } from "./request-route.js";
12
12
  import { MIN_THINKING_TOKENS, budgetCapSkipsThinking, declaredEffortLevels, reasoningBudgetShare, reasoningRequestCarried, resolveEffort } from "./reasoning.js";
13
13
  import { runStreamingBrain } from "./stream-engine.js";
@@ -226,7 +226,9 @@ function closeToolUseBlock(acc, responseIds, closed) {
226
226
  acc.closedTc = { type: "toolCall", id: engineId, ...(wireId !== engineId ? { wireId } : {}), name: acc.toolName, arguments: args };
227
227
  return acc.closedTc;
228
228
  }
229
- export function createAnthropicBrain(config = {}) {
229
+ const ANTHROPIC_LANE_DEFAULT = "https://api.anthropic.com";
230
+ export function createAnthropicBrain(given = {}) {
231
+ const config = brainConfigSnapshot(given, "createAnthropicBrain config");
230
232
  assertServableRequestRoot(config.baseUrl, "config.baseUrl");
231
233
  refuseRetiredTimeoutKnobs(config, "construction", "createAnthropicBrain config");
232
234
  const doFetch = resolveFetch(config);
@@ -244,7 +246,7 @@ export function createAnthropicBrain(config = {}) {
244
246
  maxRetries: options?.maxRetries,
245
247
  stallTimeouts: options?.stallTimeouts,
246
248
  buildRequest: (overrides) => {
247
- const { root, origin: rootOrigin } = resolveRequestRootOf(model.baseUrl, config.baseUrl, "https://api.anthropic.com");
249
+ const { root, origin: rootOrigin } = resolveRequestRootOf(model.baseUrl, config.baseUrl, ANTHROPIC_LANE_DEFAULT);
248
250
  const routeCredential = resolveRouteCredential({
249
251
  optionsApiKey: options?.apiKey,
250
252
  optionsHeaders: options?.headers,
@@ -252,7 +254,7 @@ export function createAnthropicBrain(config = {}) {
252
254
  configApiKey: config.apiKey,
253
255
  configHeaders: config.headers,
254
256
  });
255
- const routeVerdict = adjudicateModelRoute(model, routeCredential, { baseUrl: config.baseUrl });
257
+ const routeVerdict = adjudicateModelRoute(model, routeCredential, { baseUrl: config.baseUrl, laneDefault: ANTHROPIC_LANE_DEFAULT });
256
258
  if (!routeVerdict.ok)
257
259
  throw new BrainError("invalid_request", routeRefusalText(routeVerdict));
258
260
  const apiKey = routeCredential.apiKey;
@@ -766,5 +768,5 @@ export function createAnthropicBrain(config = {}) {
766
768
  },
767
769
  });
768
770
  };
769
- return { stream, adjudicateRoute: createBrainRouteJudge(config) };
771
+ return { stream, adjudicateRoute: createBrainRouteJudge({ ...config, laneDefault: ANTHROPIC_LANE_DEFAULT }) };
770
772
  }
@@ -28,4 +28,4 @@ export interface OpenResponsesBrainConfig extends StreamEngineConfig {
28
28
  * Create a Brain that talks to an Open Responses endpoint. See the file header for the stateless
29
29
  * invariant, the capability-audit posture, and the reasoning-replay rule.
30
30
  */
31
- export declare function createOpenResponsesBrain(config?: OpenResponsesBrainConfig): Brain;
31
+ export declare function createOpenResponsesBrain(given?: OpenResponsesBrainConfig): Brain;
@@ -6,7 +6,7 @@ import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCal
6
6
  import { emitBrainTelemetry } from "./status-sink.js";
7
7
  import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNote, modelSupportsVision, sendableImages } from "./media-degrade.js";
8
8
  import { OUTPUT_CAP_KEYS, RESPONSES_RESERVED, applyExtraBody, effectiveOutputCap, lockHeader, mergeHeaders } from "./request-params.js";
9
- import { adjudicateModelRoute, applyRouteCredentialHeaders, assertServableRequestRoot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential, routeRefusalText } from "./route-adjudicator.js";
9
+ import { adjudicateModelRoute, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential, routeRefusalText } from "./route-adjudicator.js";
10
10
  import { requestRouteOf } from "./request-route.js";
11
11
  import { declaredOffSpelling, mintEffortWireValue, reasoningRequestCarried } from "./reasoning.js";
12
12
  import { runStreamingBrain } from "./stream-engine.js";
@@ -219,7 +219,8 @@ function mapTerminalStopReason(incompleteReason, hadToolCalls) {
219
219
  return "length";
220
220
  return "stop";
221
221
  }
222
- export function createOpenResponsesBrain(config = {}) {
222
+ export function createOpenResponsesBrain(given = {}) {
223
+ const config = brainConfigSnapshot(given, "createOpenResponsesBrain config");
223
224
  assertServableRequestRoot(config.baseUrl, "config.baseUrl");
224
225
  refuseRetiredTimeoutKnobs(config, "construction", "createOpenResponsesBrain config");
225
226
  const doFetch = resolveFetch(config);
@@ -57,4 +57,4 @@ export declare function inferMaxTokensField(modelId: string): "max_completion_to
57
57
  * machinery lives in the shared {@link runStreamingBrain} engine (design/32); this adapter owns the
58
58
  * OpenAI request shaping + chat-completions SSE parsing + finalization.
59
59
  */
60
- export declare function createOpenAIBrain(config?: OpenAIBrainConfig): Brain;
60
+ export declare function createOpenAIBrain(given?: OpenAIBrainConfig): Brain;