@sema-agent/core 7.51.2 → 7.52.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 (363) hide show
  1. package/CHANGELOG.md +504 -2
  2. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  3. package/dist/agents/cascade.js +4 -0
  4. package/dist/agents/cumulative-stats.d.ts +3 -0
  5. package/dist/agents/cumulative-stats.js +3 -0
  6. package/dist/agents/list-agents-tool.d.ts +1 -1
  7. package/dist/agents/read-inbox-tool.d.ts +1 -1
  8. package/dist/agents/repair-loop.js +4 -0
  9. package/dist/agents/send-message-tool.d.ts +11 -16
  10. package/dist/agents/send-message-tool.js +11 -13
  11. package/dist/agents/subagent.js +6 -4
  12. package/dist/agents/tool-filter.d.ts +40 -13
  13. package/dist/agents/tool-filter.js +28 -14
  14. package/dist/bench/metrics.d.ts +1 -0
  15. package/dist/brain/anthropic.js +16 -12
  16. package/dist/brain/model-presets.d.ts +4 -5
  17. package/dist/brain/model-presets.js +4 -4
  18. package/dist/brain/open-responses.js +16 -12
  19. package/dist/brain/openai.js +16 -12
  20. package/dist/brain/request-params.d.ts +12 -33
  21. package/dist/brain/request-params.js +5 -2
  22. package/dist/brain/request-route.d.ts +9 -8
  23. package/dist/brain/request-route.js +1 -0
  24. package/dist/brain/route-adjudicator.d.ts +117 -47
  25. package/dist/brain/route-adjudicator.js +171 -42
  26. package/dist/brain/route-conformance.js +2 -2
  27. package/dist/brain/status-sink.d.ts +18 -0
  28. package/dist/brain/status-sink.js +7 -0
  29. package/dist/core/allow-entry.d.ts +40 -8
  30. package/dist/core/allow-entry.js +23 -16
  31. package/dist/core/auto-compaction.d.ts +23 -20
  32. package/dist/core/auto-compaction.js +37 -16
  33. package/dist/core/auto-promote.d.ts +2 -1
  34. package/dist/core/auto-promote.js +2 -2
  35. package/dist/core/caller-tool-name.d.ts +9 -0
  36. package/dist/core/caller-tool-name.js +13 -0
  37. package/dist/core/checkpoint-requirements.d.ts +7 -1
  38. package/dist/core/checkpoint-requirements.js +2 -0
  39. package/dist/core/checkpoint-store.d.ts +36 -12
  40. package/dist/core/checkpoint-store.js +1 -1
  41. package/dist/core/child-clamp-seats.d.ts +6 -0
  42. package/dist/core/child-clamp-seats.js +2 -1
  43. package/dist/core/credential-vocabulary.d.ts +33 -8
  44. package/dist/core/credential-vocabulary.js +32 -7
  45. package/dist/core/decision-receipt.d.ts +2 -2
  46. package/dist/core/delegation-frames.d.ts +9 -2
  47. package/dist/core/delegation-name.d.ts +18 -0
  48. package/dist/core/delegation-name.js +47 -0
  49. package/dist/core/engine-capabilities.d.ts +8 -1
  50. package/dist/core/engine-capabilities.js +1 -1
  51. package/dist/core/engine-notice.d.ts +36 -19
  52. package/dist/core/frontmatter-fence.d.ts +10 -0
  53. package/dist/core/frontmatter-fence.js +6 -0
  54. package/dist/core/gate-fold.js +5 -23
  55. package/dist/core/gate-lanes.js +356 -270
  56. package/dist/core/governance-codes.d.ts +9 -4
  57. package/dist/core/governance-codes.js +9 -3
  58. package/dist/core/hooks.d.ts +276 -734
  59. package/dist/core/hooks.js +97 -192
  60. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  61. package/dist/{tools/fs → core}/image-admission.js +24 -6
  62. package/dist/core/mcp-connection-pool.d.ts +4 -1
  63. package/dist/core/mcp-connection-pool.js +7 -2
  64. package/dist/core/mcp-probe.d.ts +12 -9
  65. package/dist/core/mcp-probe.js +2 -2
  66. package/dist/core/mcp-server-spec.d.ts +16 -0
  67. package/dist/core/mcp.d.ts +11 -7
  68. package/dist/core/mcp.js +11 -5
  69. package/dist/core/memory-engine/data-plane.js +5 -1
  70. package/dist/core/memory-engine/distiller.js +16 -2
  71. package/dist/core/memory-engine/engine.d.ts +8 -11
  72. package/dist/core/memory-engine/engine.js +9 -5
  73. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  74. package/dist/core/memory-engine/frontmatter.js +19 -16
  75. package/dist/core/memory.d.ts +2 -2
  76. package/dist/core/mode-policy.d.ts +4 -0
  77. package/dist/core/mode-policy.js +7 -5
  78. package/dist/core/model-seat.d.ts +4 -1
  79. package/dist/core/mods/dollar.d.ts +109 -0
  80. package/dist/core/mods/dollar.js +154 -0
  81. package/dist/core/mods/host.d.ts +23 -0
  82. package/dist/core/mods/host.js +21 -0
  83. package/dist/core/mods/kernel/budget.d.ts +43 -0
  84. package/dist/core/mods/kernel/budget.js +83 -0
  85. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  86. package/dist/core/mods/kernel/dispatch.js +701 -0
  87. package/dist/core/mods/kernel/events.d.ts +242 -0
  88. package/dist/core/mods/kernel/events.js +210 -0
  89. package/dist/core/mods/kernel/index.d.ts +6 -0
  90. package/dist/core/mods/kernel/index.js +5 -0
  91. package/dist/core/mods/kernel/receive.d.ts +65 -0
  92. package/dist/core/mods/kernel/receive.js +123 -0
  93. package/dist/core/mods/kernel/registration.d.ts +131 -0
  94. package/dist/core/mods/kernel/registration.js +102 -0
  95. package/dist/core/mods/kernel/site-rules.d.ts +84 -0
  96. package/dist/core/mods/kernel/site-rules.js +104 -0
  97. package/dist/core/mods/stations.d.ts +350 -0
  98. package/dist/core/mods/stations.js +444 -0
  99. package/dist/core/own-property-receipt.js +11 -23
  100. package/dist/core/parent-spec-seat.d.ts +18 -7
  101. package/dist/core/parent-spec-seat.js +6 -2
  102. package/dist/core/path-identity.js +2 -1
  103. package/dist/core/permission-rule-syntax.d.ts +15 -0
  104. package/dist/core/permission-rule-syntax.js +24 -16
  105. package/dist/core/permission-rules.d.ts +7 -1
  106. package/dist/core/permission-rules.js +26 -15
  107. package/dist/core/prompt-section-seat.d.ts +15 -27
  108. package/dist/core/prompt-section-seat.js +73 -40
  109. package/dist/core/protocol-http-auth.d.ts +3 -1
  110. package/dist/core/protocol-http-auth.js +2 -0
  111. package/dist/core/reminder-mint.d.ts +2 -2
  112. package/dist/core/remote-env.d.ts +24 -12
  113. package/dist/core/remote-env.js +1 -0
  114. package/dist/core/resume-startup-cause.d.ts +16 -1
  115. package/dist/core/resume-startup-cause.js +4 -1
  116. package/dist/core/retired-keys.d.ts +4 -0
  117. package/dist/core/retired-keys.js +3 -0
  118. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  119. package/dist/core/runner/announce-once-ledger.js +22 -0
  120. package/dist/core/runner/assemble-result.d.ts +9 -0
  121. package/dist/core/runner/assemble-result.js +3 -1
  122. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  123. package/dist/core/runner/call-hook-stations.js +58 -42
  124. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  125. package/dist/core/runner/caller-stop-gate.js +7 -0
  126. package/dist/core/runner/compaction-seams.d.ts +8 -22
  127. package/dist/core/runner/compaction-seams.js +28 -53
  128. package/dist/core/runner/construction-doors.js +11 -1
  129. package/dist/core/runner/contracts.d.ts +85 -83
  130. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  131. package/dist/core/runner/credential-origin-seat.js +19 -0
  132. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  133. package/dist/core/runner/gate-exit.d.ts +47 -36
  134. package/dist/core/runner/gate-exit.js +8 -2
  135. package/dist/core/runner/image.js +1 -2
  136. package/dist/core/runner/inline-image.js +1 -1
  137. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  138. package/dist/core/runner/notice-seat-input.js +1 -0
  139. package/dist/core/runner/person-path-rows.js +1 -0
  140. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  141. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  142. package/dist/core/runner/prepare-ask-lane.js +6 -15
  143. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  144. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  145. package/dist/core/runner/prepare-config-doors.d.ts +5 -0
  146. package/dist/core/runner/prepare-config-doors.js +9 -0
  147. package/dist/core/runner/prepare-defer-classify.js +3 -4
  148. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  149. package/dist/core/runner/prepare-gate-stations.js +11 -10
  150. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  151. package/dist/core/runner/prepare-inherited-gate.js +8 -21
  152. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  153. package/dist/core/runner/prepare-park-ask.js +10 -14
  154. package/dist/core/runner/prepare-policy-chain.d.ts +17 -15
  155. package/dist/core/runner/prepare-policy-chain.js +95 -100
  156. package/dist/core/runner/prepare-project-context.js +7 -10
  157. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  158. package/dist/core/runner/prepare-prompt-assembly.js +134 -101
  159. package/dist/core/runner/prepare-prompt-inputs.d.ts +18 -19
  160. package/dist/core/runner/prepare-prompt-inputs.js +5 -7
  161. package/dist/core/runner/prepare-protocol-tools.d.ts +6 -4
  162. package/dist/core/runner/prepare-protocol-tools.js +2 -2
  163. package/dist/core/runner/prepare-safety-scan.js +6 -10
  164. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  165. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  166. package/dist/core/runner/prepare-task.js +33 -15
  167. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  168. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  169. package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -6
  170. package/dist/core/runner/prepare-wiring-manifest.js +7 -7
  171. package/dist/core/runner/resume-apply.d.ts +5 -2
  172. package/dist/core/runner/resume-apply.js +24 -42
  173. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  174. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  175. package/dist/core/runner/resume-preflight.js +38 -16
  176. package/dist/core/runner/retired-runner-deps.js +3 -1
  177. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  178. package/dist/core/runner/run-brain-sinks.js +5 -1
  179. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  180. package/dist/core/runner/run-compaction-machinery.js +7 -33
  181. package/dist/core/runner/run-harness-handlers.js +4 -2
  182. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  183. package/dist/core/runner/run-identity-wiring.js +3 -2
  184. package/dist/core/runner/run-leg.js +62 -84
  185. package/dist/core/runner/run-notification-lane.js +1 -0
  186. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  187. package/dist/core/runner/run-recovery-lanes.js +11 -10
  188. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  189. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  190. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  191. package/dist/core/runner/run-terminal-adoption.js +33 -22
  192. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  193. package/dist/core/runner/run-turn-boundary.js +23 -34
  194. package/dist/core/runner/runtask.d.ts +6 -7
  195. package/dist/core/runner/runtask.js +14 -72
  196. package/dist/core/runner/session-rule-policy.d.ts +5 -5
  197. package/dist/core/runner/session-rule-policy.js +13 -8
  198. package/dist/core/runner/side-call-account.d.ts +68 -0
  199. package/dist/core/runner/side-call-account.js +61 -0
  200. package/dist/core/runner/stream-halt-verbs.js +12 -17
  201. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  202. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  203. package/dist/core/runner/stream-steer-verb.js +20 -38
  204. package/dist/core/runner/sub-agent-deny-lists.d.ts +121 -22
  205. package/dist/core/runner/sub-agent-deny-lists.js +228 -71
  206. package/dist/core/runner/tool-end-body.d.ts +5 -6
  207. package/dist/core/runner/tool-end-body.js +6 -4
  208. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  209. package/dist/core/runner/tool-not-executed.js +30 -0
  210. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  211. package/dist/core/runner/tool-occurrence.js +5 -5
  212. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  213. package/dist/core/runner-deps.d.ts +20 -28
  214. package/dist/core/safety-merge-corpus.js +18 -2
  215. package/dist/core/secret-env.d.ts +88 -20
  216. package/dist/core/secret-env.js +192 -38
  217. package/dist/core/session-policy-store.d.ts +52 -16
  218. package/dist/core/session-policy-store.js +118 -28
  219. package/dist/core/session-reconcile.d.ts +4 -0
  220. package/dist/core/session-reconcile.js +2 -1
  221. package/dist/core/shell-read-silence.js +3 -32
  222. package/dist/core/side-query.d.ts +5 -3
  223. package/dist/core/skill-grant.d.ts +3 -2
  224. package/dist/core/skill-grant.js +17 -9
  225. package/dist/core/skills-directory.d.ts +31 -11
  226. package/dist/core/skills-directory.js +655 -104
  227. package/dist/core/task-event.d.ts +13 -3
  228. package/dist/core/task-result.d.ts +8 -0
  229. package/dist/core/task-spec.d.ts +20 -19
  230. package/dist/core/task-stream.d.ts +14 -4
  231. package/dist/core/tighten-task-spec.d.ts +4 -3
  232. package/dist/core/tighten-task-spec.js +2 -4
  233. package/dist/core/tool-check-reading.d.ts +74 -0
  234. package/dist/core/tool-check-reading.js +80 -0
  235. package/dist/core/tool-policy.d.ts +59 -18
  236. package/dist/core/tool-policy.js +77 -12
  237. package/dist/core/tool-registry.d.ts +20 -0
  238. package/dist/core/tool-registry.js +4 -0
  239. package/dist/core/tool-spec.d.ts +10 -6
  240. package/dist/core/tools.js +2 -0
  241. package/dist/core/trace.d.ts +51 -32
  242. package/dist/core/unc-spelling.d.ts +10 -0
  243. package/dist/core/unc-spelling.js +3 -0
  244. package/dist/core/untrusted-egress.d.ts +8 -0
  245. package/dist/core/untrusted-egress.js +4 -1
  246. package/dist/core/user-attachment.d.ts +12 -2
  247. package/dist/core/user-attachment.js +17 -2
  248. package/dist/core/wiring-manifest.d.ts +14 -13
  249. package/dist/core/wiring-manifest.js +2 -2
  250. package/dist/engine/compaction/utils.js +1 -2
  251. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  252. package/dist/engine/execution-env/symlink-chain.js +1 -1
  253. package/dist/engine/harness/agent-harness.d.ts +1 -1
  254. package/dist/engine/harness/agent-harness.js +3 -3
  255. package/dist/engine/harness/types.d.ts +17 -16
  256. package/dist/engine/harness/types.js +7 -1
  257. package/dist/engine/llm/types.d.ts +12 -7
  258. package/dist/engine/loop/agent-loop.js +1 -1
  259. package/dist/engine/loop/types.d.ts +1 -1
  260. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  261. package/dist/engine/session/import-validate.js +3 -10
  262. package/dist/engine/session/session.d.ts +4 -4
  263. package/dist/engine/session/session.js +4 -4
  264. package/dist/index.d.ts +20 -16
  265. package/dist/index.js +13 -11
  266. package/dist/internal/harness.d.ts +1 -1
  267. package/dist/internal/harness.js +1 -1
  268. package/dist/orchestration/run-spec.d.ts +4 -6
  269. package/dist/orchestration/run-spec.js +39 -63
  270. package/dist/orchestration/run-workflow-tool.js +1 -2
  271. package/dist/orchestration/workflow.d.ts +11 -3
  272. package/dist/orchestration/workflow.js +11 -2
  273. package/dist/prompt-assembly/artifact-store.d.ts +37 -56
  274. package/dist/prompt-assembly/artifact-store.js +31 -49
  275. package/dist/prompt-assembly/artifact.d.ts +89 -76
  276. package/dist/prompt-assembly/artifact.js +167 -146
  277. package/dist/prompt-assembly/assemble.d.ts +34 -29
  278. package/dist/prompt-assembly/assemble.js +33 -220
  279. package/dist/prompt-assembly/bands.d.ts +20 -0
  280. package/dist/prompt-assembly/bands.js +18 -0
  281. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  282. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  283. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  284. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  285. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  286. package/dist/prompt-assembly/catalog/index.js +59 -0
  287. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  288. package/dist/prompt-assembly/catalog/modes.js +137 -0
  289. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  290. package/dist/prompt-assembly/catalog/role.js +157 -0
  291. package/dist/prompt-assembly/catalog/schema.d.ts +124 -0
  292. package/dist/prompt-assembly/catalog/schema.js +25 -0
  293. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  294. package/dist/prompt-assembly/catalog/sections.js +98 -0
  295. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  296. package/dist/prompt-assembly/catalog/team.js +258 -0
  297. package/dist/prompt-assembly/composer.d.ts +24 -28
  298. package/dist/prompt-assembly/composer.js +124 -46
  299. package/dist/prompt-assembly/epoch.d.ts +89 -79
  300. package/dist/prompt-assembly/epoch.js +115 -142
  301. package/dist/prompt-assembly/explain.d.ts +58 -34
  302. package/dist/prompt-assembly/explain.js +21 -24
  303. package/dist/prompt-assembly/overlay.d.ts +127 -0
  304. package/dist/prompt-assembly/overlay.js +301 -0
  305. package/dist/prompt-assembly/renderers.d.ts +21 -0
  306. package/dist/prompt-assembly/renderers.js +39 -0
  307. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  308. package/dist/prompt-assembly/section-usage.js +1 -1
  309. package/dist/prompt-assembly/select.d.ts +56 -0
  310. package/dist/prompt-assembly/select.js +69 -0
  311. package/dist/prompt-assembly/sugar.d.ts +31 -0
  312. package/dist/prompt-assembly/sugar.js +20 -0
  313. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  314. package/dist/prompt-assembly/types.d.ts +45 -148
  315. package/dist/prompts/coordinator.d.ts +2 -21
  316. package/dist/prompts/coordinator.js +3 -255
  317. package/dist/prompts/cowork.d.ts +27 -16
  318. package/dist/prompts/cowork.js +2 -23
  319. package/dist/prompts/default.d.ts +38 -500
  320. package/dist/prompts/default.js +20 -285
  321. package/dist/prompts/supervisor.d.ts +6 -71
  322. package/dist/prompts/supervisor.js +6 -117
  323. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  324. package/dist/tools/fs/dir-entries.d.ts +4 -2
  325. package/dist/tools/fs/dir-entries.js +16 -4
  326. package/dist/tools/fs/fs-bash.d.ts +1 -1
  327. package/dist/tools/fs/fs-bash.js +22 -11
  328. package/dist/tools/fs/fs-pdf.js +17 -13
  329. package/dist/tools/fs/fs-read.js +4 -3
  330. package/dist/tools/fs/fs-shared.d.ts +1 -10
  331. package/dist/tools/fs/fs-shared.js +3 -4
  332. package/dist/tools/fs/fs-write.js +2 -1
  333. package/dist/tools/fs/notebook.js +1 -1
  334. package/dist/tools/fs/pdf.d.ts +20 -10
  335. package/dist/tools/fs/pdf.js +19 -10
  336. package/dist/tools/fs/program-read-model.d.ts +68 -8
  337. package/dist/tools/fs/program-read-model.js +112 -33
  338. package/dist/tools/fs/program-read-model.rows.js +30 -10
  339. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  340. package/dist/tools/fs/read-deny-home.js +28 -27
  341. package/dist/tools/fs/read-deny.d.ts +41 -11
  342. package/dist/tools/fs/read-deny.js +51 -5
  343. package/dist/tools/fs/safety.d.ts +4 -26
  344. package/dist/tools/fs/safety.js +10 -32
  345. package/dist/tools/fs/search.js +15 -10
  346. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  347. package/dist/tools/fs/shell-read-argv.js +118 -38
  348. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  349. package/dist/tools/fs/shell-read-establish.js +11 -61
  350. package/dist/tools/fs/shell-read-identity.js +6 -3
  351. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  352. package/dist/tools/fs/shell-read-judge.js +18 -4
  353. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  354. package/dist/tools/web.js +1 -1
  355. package/package.json +13 -1
  356. package/test/export-surface.snapshot.json +242 -99
  357. package/wire-changes/core@7.52.0.json +5859 -0
  358. package/dist/core/hook-seats.d.ts +0 -66
  359. package/dist/core/hook-seats.js +0 -37
  360. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  361. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  362. package/dist/prompts/simple-sections.d.ts +0 -58
  363. package/dist/prompts/simple-sections.js +0 -43
@@ -3,6 +3,7 @@ import { egressText } from "../untrusted-egress.js";
3
3
  import { inlineUntrusted } from "../untrusted-text.js";
4
4
  import { thrownText } from "../thrown-value.js";
5
5
  export const ANNOUNCE_ONCE_MAX_DIGESTS = 200;
6
+ const RUNNER_ANNOUNCED = new WeakMap();
6
7
  const DROPPED_TOOL_MODEL_LANE = "mcp_dropped_tools";
7
8
  export function announceDigest(lane, text) {
8
9
  return createHash("sha256").update(lane).update("\n").update(text).digest("hex");
@@ -13,6 +14,14 @@ export function warningDigest(err) {
13
14
  const message = thrownText(err);
14
15
  return announceDigest(code, egressText("same-principal", message));
15
16
  }
17
+ const MEMORY_MOUNT_ADVISORY = {
18
+ shared: { label: "Shared memory tools", classification: "shared-memory-not-mounted", tail: "the pair mounts together or not at all" },
19
+ engine: { label: "Memory tools", classification: "memory-tools-not-mounted", tail: "these tools mount together or not at all" },
20
+ };
21
+ export function announceMemoryNotMounted(sink, sessionId, pair, names, reason) {
22
+ const p = MEMORY_MOUNT_ADVISORY[pair];
23
+ sink.onErrorOncePerRunner(new Error(`${p.label} ${names.join("/")} were NOT mounted: ${reason} — ${p.tail}.`), { phase: "config", sessionId, classification: p.classification });
24
+ }
16
25
  export function droppedToolDigest(d) {
17
26
  return announceDigest(DROPPED_TOOL_MODEL_LANE, `${d.server}\n${d.tool}\n${d.reason}`);
18
27
  }
@@ -62,6 +71,19 @@ export async function loadAnnounceOnceLedger(session, checkpointMirror, onError)
62
71
  advisories.add(digest);
63
72
  dirty = true;
64
73
  },
74
+ onErrorOncePerRunner: (err, ctx) => {
75
+ if (onError === undefined)
76
+ return;
77
+ const digest = warningDigest(err);
78
+ const told = RUNNER_ANNOUNCED.get(onError) ?? new Set();
79
+ RUNNER_ANNOUNCED.set(onError, told);
80
+ if (told.has(digest))
81
+ return;
82
+ onError(err, ctx);
83
+ told.add(digest);
84
+ if (told.size > ANNOUNCE_ONCE_MAX_DIGESTS)
85
+ told.delete(told.values().next().value);
86
+ },
65
87
  mcpFailuresToAnnounce: (statuses) => {
66
88
  const current = statuses
67
89
  .filter((s) => s.status === "failed")
@@ -67,6 +67,11 @@ export interface Stats {
67
67
  * (so it can't be re-derived from `costMicroUsd` alone). The {@link costBreakdown.compactionMicroUsd}
68
68
  * source. Run-loop internal — not a public `TaskResult.stats` field. */
69
69
  compactionMicroUsd?: number;
70
+ /** The permission classifier's and a mod's model-call cost (micro-USD), accumulated by `recordSideCallUsage`. Folded
71
+ * into `costMicroUsd` like compaction, but it STAYS inside {@link costBreakdown.llmRootMicroUsd} (an "of which" line,
72
+ * not a partition member). Absent until a call is booked. Run-loop internal — the public figure is
73
+ * `costBreakdown.sideCallMicroUsd`. */
74
+ sideCallMicroUsd?: number;
70
75
  /**
71
76
  * A thin FINANCE TAXONOMY of the LLM-derived costs the engine actually
72
77
  * prices, decomposing the task's spend into report categories (no new persisted structure — derived from
@@ -92,6 +97,10 @@ export interface Stats {
92
97
  /** Within-task compaction LLM cost (micro-USD) = the running `compactionMicroUsd` accumulator (the
93
98
  * category Framing-4 missed). This IS part of `costMicroUsd`, so it is subtracted from `llmRoot`. */
94
99
  compactionMicroUsd: number;
100
+ /** Side model-call LLM cost (micro-USD) — the permission classifier's and mods' calls — present once one is booked.
101
+ * An "of which" line: it is part of `costMicroUsd` AND of `llmRootMicroUsd` (not subtracted from root), so the
102
+ * partition `llmRoot + compaction === costMicroUsd` keeps holding. */
103
+ sideCallMicroUsd?: number;
95
104
  };
96
105
  }
97
106
  /** The two cumulative budget ceilings a task can trip. Tokens outrank cost when both are
@@ -161,6 +161,7 @@ export function assembleResult(spec, sessionId, final, stats, flags) {
161
161
  nestedSubagentMicroUsd,
162
162
  memoryConsolidationMicroUsd: 0,
163
163
  compactionMicroUsd,
164
+ ...(stats.sideCallMicroUsd !== undefined ? { sideCallMicroUsd: stats.sideCallMicroUsd } : {}),
164
165
  };
165
166
  }
166
167
  const result = text;
@@ -171,8 +172,9 @@ export function assembleResult(spec, sessionId, final, stats, flags) {
171
172
  salvagedOutput = text.trim() || undefined;
172
173
  }
173
174
  const retryAfterMs = errorCode === "usage.window_exhausted" || errorCode === "memory.admission_required" ? flags.retryAfterMs : undefined;
174
- const { compactionMicroUsd: _internalCompaction, ...publicStats } = stats;
175
+ const { compactionMicroUsd: _internalCompaction, sideCallMicroUsd: _internalSideCall, ...publicStats } = stats;
175
176
  void _internalCompaction;
177
+ void _internalSideCall;
176
178
  if (flags.unpricedSpend)
177
179
  delete publicStats.costMicroUsd;
178
180
  const stampHaltedByUser = haltConsumed(flags.haltConsumption);
@@ -8,7 +8,8 @@
8
8
  * the decide that approved it — and the station through `AgentHarness.finalizeToolCall`, the loop's own finalize.
9
9
  */
10
10
  import type { DocumentContent, ImageContent, TextContent } from "../../internal/llm.js";
11
- import { type HookEnvCapabilities, type HookInvocationIdentity, type Hooks } from "../hooks.js";
11
+ import { type HookEnvCapabilities, type HookInvocationIdentity } from "../hooks.js";
12
+ import { type LegModBus } from "../mods/stations.js";
12
13
  import type { PermissionModeController } from "../mode-policy.js";
13
14
  import type { TaskSpec } from "../types.js";
14
15
  import type { CwdRef } from "../../tools/fs/fs-shared.js";
@@ -30,32 +31,29 @@ export type ToolResultStation = (e: ToolResultSeatEvent) => Promise<{
30
31
  content: Array<TextContent | ImageContent | DocumentContent>;
31
32
  } | undefined>;
32
33
  export interface ToolResultStationInput {
33
- /** borrowed-readonly — the resolved hook record: the two post seats and the failure seat, called through the record. */
34
- hooks: Hooks | undefined;
34
+ /** borrowed-readonly — the leg's mods bus: `classic.PostToolUse` / `classic.PostToolUseFailure` are raised on it, and a
35
+ * `classic.PreToolUse` handler arms the station too (its context is drained onto the result here). */
36
+ modBus: LegModBus;
35
37
  /** borrowed-mutable — the blocked/suspended call ids. Writer here: the one-shot `delete`. */
36
38
  blockedToolCalls: Set<string>;
37
- /** borrowed-readonly — the leg's delta seat: the post seats receive the call's wire name off its current roster. */
39
+ /** borrowed-readonly — the leg's delta seat: the post events carry the call's wire name off its current roster. */
38
40
  toolRosterDeltas: ToolRosterDeltaSeat;
39
41
  /** borrowed-mutable — PreToolUse `additionalContext` per call id. Writer here: the one-shot drain (`delete`). */
40
42
  preToolContexts: Map<string, string[]>;
41
- /** borrowed-readonly — the validated per-prepare hook seat bound. */
42
- hookTimeoutMs: number;
43
- /** borrowed-readonly — prepare's abort seat; `.signal` bounds the post seats and is the failure seat's interrupt fact. */
43
+ /** borrowed-readonly — prepare's abort seat; `.signal` is the post events' abort and the failure event's interrupt fact. */
44
44
  abortController: {
45
45
  readonly signal: AbortSignal;
46
46
  };
47
- /** borrowed-readonly — the REBOUND spec's `signal` (the failure seat's interrupt fact). */
47
+ /** borrowed-readonly — the REBOUND spec's `signal` (the failure event's interrupt fact). */
48
48
  spec: Pick<TaskSpec, "signal">;
49
- /** borrowed-readonly — the hand's live tracked cwd, or undefined; `current` is read per post seat. */
49
+ /** borrowed-readonly — the hand's live tracked cwd, or undefined; `current` is read per post event. */
50
50
  handsCwdRef: CwdRef | undefined;
51
- /** borrowed-readonly — the env face the post seats' contexts carry, or undefined. */
51
+ /** borrowed-readonly — the env face the post events carry, or undefined. */
52
52
  hookEnvFace: HookEnvCapabilities | undefined;
53
- /** borrowed-readonly — the leg's identity envelope every HookToolContext carries. */
53
+ /** borrowed-readonly — the leg's identity envelope every post event carries. */
54
54
  hookIdentity: HookInvocationIdentity;
55
- /** borrowed-readonly — the leg's live permission-mode seat (each context reads `observed`). */
55
+ /** borrowed-readonly — the leg's live permission-mode seat (each event reads `observed`). */
56
56
  permissionMode: PermissionModeController;
57
- /** borrowed-readonly — where an expired post seat is reported (the leg's own hook-crash lane). */
58
- notifyOwnHookCrash: (err: unknown) => void;
59
57
  /** borrowed-readonly — the leg's reminder provenance mark (every hook context line carries it). */
60
58
  reminderMark: string;
61
59
  /** borrowed-mutable — the leg's settlement seam. Writer here: a carrier whose output a host hook rewrote (`noteHostRewrite`). */
@@ -69,11 +67,11 @@ export declare function createToolResultStation(input: ToolResultStationInput):
69
67
  export type ApprovedCallScreen = NonNullable<Prepared["approvedCallScreen"]>;
70
68
  export type ApprovedCallVerdict = Awaited<ReturnType<ApprovedCallScreen>>;
71
69
  export interface ApprovedCallScreenInput {
72
- /** borrowed-readonly — the face the gate screens with (the observational wrapper when declared; the leg's mode on every context). */
73
- preToolUse: Hooks["preToolUse"] | undefined;
74
- /** borrowed-readonly — the validated per-prepare hook seat bound. */
75
- hookTimeoutMs: number;
76
- /** borrowed-readonly — prepare's abort seat (the screening seat is abort-ended on it). */
70
+ /** borrowed-readonly — the leg's mods bus (the re-screen raises `classic.PreToolUse` on it, as the gate does). */
71
+ modBus: LegModBus;
72
+ /** borrowed-readonly — the leg's live permission-mode seat (each screening e reads `observed`). */
73
+ permissionMode: PermissionModeController;
74
+ /** borrowed-readonly — prepare's abort seat (the screening is abort-ended on it). */
77
75
  abortController: {
78
76
  readonly signal: AbortSignal;
79
77
  };
@@ -83,18 +81,16 @@ export interface ApprovedCallScreenInput {
83
81
  hookEnvFace: HookEnvCapabilities | undefined;
84
82
  /** borrowed-readonly — the leg's identity envelope. */
85
83
  hookIdentity: HookInvocationIdentity;
86
- /** borrowed-readonly — the own hook-crash reporter (a crashing or timed-out screening face is reported through it). */
87
- notifyOwnHookCrash: (err: unknown) => void;
88
84
  /** borrowed-mutable — PreToolUse `additionalContext` per call id. Writer here: `admit`'s stash (the station drains it). */
89
85
  preToolContexts: Map<string, string[]>;
90
86
  }
91
87
  /**
92
- * The approved call's PreToolUse screening — the gate's own seat, its answer FOLDED UNDER THE DECIDE that approved the
93
- * call (the decide is the upper bound; the screen can only narrow): a deny, a crash, a silence or a refused answer
94
- * refuses the call in the live gate's own sentences; an ask is the question the decide already answered — unless it
95
- * demands a person and the decide was the deployment's policy (the one predicate every resume station holds a decide
96
- * against); a rewrite is what executes when the decide carried none of its own (the person's bytes are the upper bound);
97
- * context rides the result. Undefined when no face is wired.
88
+ * The approved call's PreToolUse screening — the gate's own screening, its answer FOLDED UNDER THE DECIDE that approved
89
+ * the call (the decide is the upper bound; the screen can only narrow): a deny, a failed or cancelled screening, or a
90
+ * refused answer refuses the call in the live gate's own sentences; an ask is the question the decide already answered —
91
+ * unless it demands a person and the decide was the deployment's policy (the one predicate every resume station holds a
92
+ * decide against); a rewrite is what executes when the decide carried none of its own (the person's bytes are the upper
93
+ * bound); context rides the result. Undefined when no handler hangs on `classic.PreToolUse`.
98
94
  */
99
95
  export declare function createApprovedCallScreen(input: ApprovedCallScreenInput): ApprovedCallScreen | undefined;
100
96
  /**
@@ -1,14 +1,28 @@
1
- import { createPreToolUseScreening, formatHookFeedback, hookSeatExpiredError, runHookSeat } from "../hooks.js";
2
- import { isEngineRefusal } from "../tool-policy.js";
1
+ import { createPreToolUseScreening, formatHookFeedback } from "../hooks.js";
2
+ import { classicEventBase, dispatchClassic, stringMembersAnswer, stringMembersOf } from "../mods/stations.js";
3
3
  import { policyCannotAnswer } from "../real-approval.js";
4
- import { traceHookCrash } from "../gate-crash-trace.js";
5
- import { createSafeNotifier } from "../safe-notify.js";
6
4
  import { rosterToolName } from "../tool-roster.js";
7
5
  import { wireOf } from "../tool-name-readings.js";
8
6
  import { noteHostRewrite } from "../frame-settlement.js";
7
+ function postToolUseAnswer(answer) {
8
+ const strings = stringMembersAnswer("classic.PostToolUse", ["additionalContext"])(answer);
9
+ if (strings !== undefined || typeof answer !== "object" || answer === null)
10
+ return strings;
11
+ const out = Reflect.get(answer, "updatedOutput");
12
+ return out === undefined || Array.isArray(out) ? undefined : "answered a non-array \"updatedOutput\"; it replaces the content array";
13
+ }
14
+ function updatedOutputOf(answer) {
15
+ if (typeof answer !== "object" || answer === null)
16
+ return undefined;
17
+ const out = Reflect.get(answer, "updatedOutput");
18
+ return Array.isArray(out) ? out.filter(isContentBlock) : undefined;
19
+ }
20
+ function isContentBlock(c) {
21
+ return typeof c === "object" && c !== null && typeof Reflect.get(c, "type") === "string";
22
+ }
9
23
  export function createToolResultStation(input) {
10
- const { hooks, blockedToolCalls, toolRosterDeltas, preToolContexts, hookTimeoutMs, abortController, spec, handsCwdRef, hookEnvFace, hookIdentity, permissionMode, notifyOwnHookCrash, reminderMark, frameSettlement } = input;
11
- const toolResultStationArmed = Boolean(hooks?.postToolUse || hooks?.preToolUse || hooks?.postToolUseFailure);
24
+ const { modBus, blockedToolCalls, toolRosterDeltas, preToolContexts, abortController, spec, handsCwdRef, hookEnvFace, hookIdentity, permissionMode, reminderMark, frameSettlement } = input;
25
+ const toolResultStationArmed = modBus.hasHandlers("classic.PostToolUse") || modBus.hasHandlers("classic.PreToolUse") || modBus.hasHandlers("classic.PostToolUseFailure");
12
26
  if (toolResultStationArmed) {
13
27
  return async (e) => {
14
28
  if (blockedToolCalls.delete(e.toolCallId)) {
@@ -17,16 +31,23 @@ export function createToolResultStation(input) {
17
31
  let content = e.content;
18
32
  let changed = false;
19
33
  const post = { toolName: rosterToolName(toolRosterDeltas.current, e.toolName) };
34
+ const callFacts = (tool) => ({
35
+ ...classicEventBase(hookIdentity, permissionMode.observed),
36
+ tool,
37
+ tool_use_id: e.toolCallId,
38
+ input: e.input,
39
+ ...(handsCwdRef?.current !== undefined ? { cwd: handsCwdRef.current } : {}),
40
+ ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}),
41
+ });
20
42
  if (e.isError) {
21
- if (hooks?.postToolUseFailure) {
43
+ if (modBus.hasHandlers("classic.PostToolUseFailure")) {
22
44
  let clonedDetails = e.details;
23
45
  try {
24
46
  clonedDetails = structuredClone(e.details);
25
47
  }
26
48
  catch {
27
49
  }
28
- const failedName = wireOf("hook.postToolUseFailure", post);
29
- const failureSeat = await runHookSeat("postToolUseFailure", { timeoutMs: hookTimeoutMs, signal: abortController.signal }, (sig) => hooks.postToolUseFailure(failedName, e.input, {
50
+ const failure = {
30
51
  error: e.content
31
52
  .filter((c) => c.type === "text")
32
53
  .map((c) => c.text)
@@ -34,30 +55,26 @@ export function createToolResultStation(input) {
34
55
  isInterrupt: abortController.signal.aborted || spec.signal?.aborted === true,
35
56
  content: e.content.map((c) => ({ ...c })),
36
57
  details: clonedDetails,
37
- }, { toolCallId: e.toolCallId, toolName: failedName, signal: sig, ...(handsCwdRef?.current !== undefined ? { cwd: handsCwdRef.current } : {}), ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}), identity: hookIdentity, permissionMode: permissionMode.observed }));
38
- if (failureSeat.expired) {
39
- notifyOwnHookCrash(hookSeatExpiredError("postToolUseFailure", hookTimeoutMs, failureSeat.cause, "the observation was abandoned and its additionalContext dropped; the failure result itself is unchanged"));
40
- }
41
- const patch = failureSeat.expired ? undefined : failureSeat.value;
58
+ };
59
+ const outcome = await dispatchClassic(modBus, "classic.PostToolUseFailure", { ...callFacts(wireOf("hook.postToolUseFailure", post)), failure }, { signal: abortController.signal, checkAnswer: stringMembersAnswer("classic.PostToolUseFailure", ["additionalContext"]) }).catch(() => undefined);
60
+ const patch = outcome?.kind === "answered" ? stringMembersOf(outcome.answer, ["additionalContext"]) : undefined;
42
61
  if (patch?.additionalContext) {
43
62
  content = [...content, { type: "text", text: formatHookFeedback(patch.additionalContext, reminderMark) }];
44
63
  changed = true;
45
64
  }
46
65
  }
47
66
  }
48
- else if (hooks?.postToolUse) {
49
- const ranName = wireOf("hook.postToolUse", post);
50
- const successSeat = await runHookSeat("postToolUse", { timeoutMs: hookTimeoutMs, signal: abortController.signal }, (sig) => hooks.postToolUse(ranName, e.input, { content: e.content, details: e.details, isError: e.isError }, { toolCallId: e.toolCallId, toolName: ranName, signal: sig, ...(handsCwdRef?.current !== undefined ? { cwd: handsCwdRef.current } : {}), ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}), identity: hookIdentity, permissionMode: permissionMode.observed }));
51
- if (successSeat.expired) {
52
- notifyOwnHookCrash(hookSeatExpiredError("postToolUse", hookTimeoutMs, successSeat.cause, "the seat was abandoned; the tool result is delivered to the model UNMODIFIED (no updatedOutput, no additionalContext)"));
53
- }
54
- const patch = successSeat.expired ? undefined : successSeat.value;
55
- if (patch?.updatedOutput) {
56
- content = patch.updatedOutput;
67
+ else if (modBus.hasHandlers("classic.PostToolUse")) {
68
+ const outcome = await dispatchClassic(modBus, "classic.PostToolUse", { ...callFacts(wireOf("hook.postToolUse", post)), output: { content: e.content, details: e.details, isError: e.isError } }, { signal: abortController.signal, checkAnswer: postToolUseAnswer }).catch(() => undefined);
69
+ const answer = outcome?.kind === "answered" ? outcome.answer : undefined;
70
+ const updatedOutput = updatedOutputOf(answer);
71
+ const patch = stringMembersOf(answer, ["additionalContext"]);
72
+ if (updatedOutput) {
73
+ content = updatedOutput;
57
74
  changed = true;
58
75
  noteHostRewrite(frameSettlement, e.toolCallId);
59
76
  }
60
- if (patch?.additionalContext) {
77
+ if (patch.additionalContext) {
61
78
  content = [...content, { type: "text", text: formatHookFeedback(patch.additionalContext, reminderMark) }];
62
79
  changed = true;
63
80
  }
@@ -74,27 +91,26 @@ export function createToolResultStation(input) {
74
91
  return undefined;
75
92
  }
76
93
  export function createApprovedCallScreen(input) {
77
- const { preToolUse, hookTimeoutMs, abortController, handsCwdRef, hookEnvFace, hookIdentity, notifyOwnHookCrash, preToolContexts } = input;
78
- if (preToolUse === undefined)
94
+ const { modBus, permissionMode, abortController, handsCwdRef, hookEnvFace, hookIdentity, preToolContexts } = input;
95
+ if (!modBus.hasHandlers("classic.PreToolUse"))
79
96
  return undefined;
80
97
  return async ({ toolCallId, toolName, args, decidedBy }) => {
81
- const notifier = createSafeNotifier();
82
- const seatInput = { event: { toolCallId, toolName, input: args }, ...(handsCwdRef !== undefined ? { trackedCwd: () => handsCwdRef.current } : {}), ...(hookEnvFace !== undefined ? { hookEnv: hookEnvFace } : {}), identity: hookIdentity, onHookError: notifyOwnHookCrash, abortSignal: abortController.signal };
83
- const screening = createPreToolUseScreening(preToolUse, seatInput, hookTimeoutMs, notifier);
98
+ const screening = createPreToolUseScreening({
99
+ event: { toolCallId, toolName, input: {} },
100
+ modBus,
101
+ observedPermissionMode: () => permissionMode.observed,
102
+ ...(handsCwdRef !== undefined ? { trackedCwd: () => handsCwdRef.current } : {}),
103
+ ...(hookEnvFace !== undefined ? { hookEnv: hookEnvFace } : {}),
104
+ identity: hookIdentity,
105
+ abortSignal: abortController.signal,
106
+ });
107
+ if (screening === undefined)
108
+ return { args, admit: () => undefined };
84
109
  const subject = `this call to "${toolName}"`;
85
- let r;
86
- try {
87
- const seat = await screening.screen(args);
88
- if (seat.expired)
89
- return { refused: await screening.unansweredReason(subject, seat.cause) };
90
- r = screening.screened(seat.value);
91
- }
92
- catch (err) {
93
- traceHookCrash(seatInput, err, notifier);
94
- return { refused: screening.crashReason(subject, err) };
95
- }
96
- if (r !== undefined && isEngineRefusal(r))
97
- return { refused: screening.refusedReason(r) };
110
+ const screened = await screening.screen(args, subject);
111
+ if (screened.kind === "refused")
112
+ return { refused: screened.reason };
113
+ const r = screened.answer;
98
114
  if (r?.action === "deny")
99
115
  return { refused: screening.deniedReason(r) };
100
116
  if (r !== undefined && policyCannotAnswer(r, decidedBy))
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The run's ONE caller-stop gate: tripped by every channel through which the run's CALLER asks it to stop — the
3
+ * `halt()`, `interrupt()` and `destroy()` verbs (`stop()`) and the caller's own `TaskSpec.signal` (composed into
4
+ * `signal` at the mint) — at any moment until the run publishes its result, the loop's end included. It answers one
5
+ * question, "did the caller ask this run to stop?", and every compaction pass of the run reads it the same way: a
6
+ * tripped gate admits no pass, and a pass in flight carries it both as an abort and as its withdrawal signal, so a
7
+ * stop landing mid-pass cuts the summary call and the pass reports a cancel. It is not an attribution: who OWNS the
8
+ * run's ending stays on the loop latch's first-writer seats, and an engine stop (a limit, an output retry cap, a
9
+ * gate) never trips it.
10
+ *
11
+ * Minted once per run beside the loop latch and carried on it (`LiveHandle.loop.callerStop`), so the verbs and the
12
+ * run body hold the same object.
13
+ */
14
+ export interface CallerStopGate {
15
+ /** The verbs' write face; idempotent. */
16
+ stop(): void;
17
+ /** The read face: aborted once any caller channel fired. */
18
+ readonly signal: AbortSignal;
19
+ }
20
+ /**
21
+ * The caller's own signal is COMPOSED into the read face, not listened to: there is nothing to release, so the gate
22
+ * keeps answering after the leg dropped its own listener on that signal — which is exactly when the end-of-task
23
+ * pass runs.
24
+ */
25
+ export declare function mintCallerStopGate(callerSignal: AbortSignal | undefined): CallerStopGate;
@@ -0,0 +1,7 @@
1
+ export function mintCallerStopGate(callerSignal) {
2
+ const verbs = new AbortController();
3
+ return {
4
+ stop: () => verbs.abort(),
5
+ signal: callerSignal !== undefined ? AbortSignal.any([verbs.signal, callerSignal]) : verbs.signal,
6
+ };
7
+ }
@@ -1,5 +1,4 @@
1
1
  import type { MaybeCompactOptions } from "../auto-compaction.js";
2
- import type { TaskSpec } from "../types.js";
3
2
  import type { Prepared, RunnerDepsSeat } from "./contracts.js";
4
3
  /**
5
4
  * The cost-optimization compaction options threaded into BOTH `maybeCompact` call
@@ -13,27 +12,14 @@ import type { Prepared, RunnerDepsSeat } from "./contracts.js";
13
12
  * function itself always returns an object.
14
13
  */
15
14
  export declare function seamCCompactionOptions(runner: RunnerDepsSeat, prepared: Prepared): Pick<MaybeCompactOptions, "summaryProvider" | "onCompaction" | "maxConsecutiveProviderReuse" | "consecutiveProviderReuse" | "onCommitted">;
16
- /** Resolve the pre/postCompact lifecycle callbacks (whole-slot `spec.hooks ??
17
- * deps.hooks`, same resolution as the stop hook) and wrap each in a SWALLOW+TRACE shell before
18
- * threading them into maybeCompact. The wrapper owns the observability half of the R3 MED contract
19
- * (maybeCompact swallows defensively too, but has no sink): a throwing callback is reported via
20
- * `onError(phase:"hook")` and treated as absent; a `block` returned under a "forced" trigger is
21
- * reported as ignored (maybeCompact enforces the ignore — blocking a compaction the provider/trim
22
- * layer already demanded would kill the run). */
23
- export declare function compactionHookOptions(runner: RunnerDepsSeat, spec: TaskSpec, sessionId: string, trigger: "auto" | "manual" | "forced",
24
- /** The leg's identity envelope, spread onto both compaction contexts by the wrappers
25
- * below (the compaction module builds its contexts below the runner and cannot know the leg;
26
- * the wrapper is the runner's seam). Every runner call site supplies `prepared.hookIdentity`;
27
- * optional only so a context built without a leg stays honestly identity-less. */
28
- identity?: import("../hooks.js").HookInvocationIdentity,
29
- /** The leg's already-validated seat bound (`Prepared.hookTimeoutMs`) and its abort signal. Optional
30
- * for the same reason `identity` is — a wrapper built without a prepared leg still works, on the
31
- * default bound and with no signal. The signal is what keeps a hung compaction hook from holding a
32
- * CANCELLED run's turn boundary for the whole deadline (the seat's post-abort grace). */
33
- seatBound?: {
34
- timeoutMs: number;
35
- signal?: AbortSignal;
36
- }): Pick<MaybeCompactOptions, "trigger" | "preCompact" | "postCompact">;
15
+ /** The pre/postCompact stations threaded into maybeCompact: `classic.PreCompact` and `classic.PostCompact` raised on the
16
+ * leg's bus (a station is wired only when a handler hangs on its event). Their failure and abort columns are the
17
+ * bus's — a handler that throws or runs past its budget is skipped and reported, so a failed gate is "no block, no
18
+ * instructions" and the compaction that was already deemed necessary proceeds. A `block` answered under a "forced"
19
+ * trigger is reported as ignored (maybeCompact enforces the ignore — blocking a compaction the provider/trim layer
20
+ * already demanded would kill the run). `signal` is the pass's abort (absent ⇒ each handler's own budget is the
21
+ * whole bound). */
22
+ export declare function compactionHookOptions(runner: RunnerDepsSeat, prepared: Pick<Prepared, "modBus" | "hookIdentity" | "sessionId">, trigger: "auto" | "manual" | "forced", signal: AbortSignal | undefined): Pick<MaybeCompactOptions, "trigger" | "preCompact" | "postCompact">;
37
23
  /** Fold a finished compaction's `reused` flag into the run-scoped consecutive-reuse
38
24
  * counter: a reused (provider) summary increments it, a real (LLM) summary resets it to 0. A no-op
39
25
  * compaction (`compacted:false`) leaves the counter untouched. No-op when no provider is wired. */
@@ -1,5 +1,4 @@
1
- import { hookSeatExpiredError, resolveHookTimeoutMs, runHookSeat } from "../hooks.js";
2
- import { asThrownError } from "../thrown-value.js";
1
+ import { classicEventBase, dispatchClassic, observeClassic, stringMembersAnswer, stringMembersOf } from "../mods/stations.js";
3
2
  export function seamCCompactionOptions(runner, prepared) {
4
3
  return {
5
4
  ...(runner.deps.summaryProvider
@@ -17,66 +16,42 @@ export function seamCCompactionOptions(runner, prepared) {
17
16
  },
18
17
  };
19
18
  }
20
- export function compactionHookOptions(runner, spec, sessionId, trigger, identity, seatBound) {
21
- const hooks = spec.hooks ?? runner.deps.hooks;
22
- const pre = hooks?.preCompact;
23
- const post = hooks?.postCompact;
24
- const seatMs = seatBound?.timeoutMs ?? resolveHookTimeoutMs(hooks?.timeoutMs);
25
- const seatSignal = seatBound?.signal;
26
- const withIdentity = (ctx) => identity !== undefined ? { ...ctx, identity } : ctx;
19
+ export function compactionHookOptions(runner, prepared, trigger, signal) {
20
+ const bus = prepared.modBus;
21
+ const base = classicEventBase(prepared.hookIdentity);
22
+ const report = (err) => {
23
+ try {
24
+ runner.deps.onError?.(err, { phase: "hook", sessionId: prepared.sessionId });
25
+ }
26
+ catch {
27
+ }
28
+ };
27
29
  return {
28
30
  trigger,
29
- ...(pre
31
+ ...(bus.hasHandlers("classic.PreCompact")
30
32
  ? {
31
- preCompact: async (rawCtx) => {
32
- const ctx = withIdentity(rawCtx);
33
- const report = (err) => {
34
- try {
35
- runner.deps.onError?.(err, { phase: "hook", sessionId });
36
- }
37
- catch {
38
- }
39
- };
40
- try {
41
- const seat = await runHookSeat("preCompact", { timeoutMs: seatMs, ...(seatSignal !== undefined ? { signal: seatSignal } : {}) }, (sig) => pre.call(hooks, { ...ctx, signal: sig }));
42
- if (seat.expired) {
43
- report(hookSeatExpiredError("preCompact", seatMs, seat.cause, `the "${ctx.trigger}" compaction PROCEEDED unblocked and with no additional instructions`));
44
- return undefined;
45
- }
46
- const r = seat.value;
47
- if (r?.block && ctx.trigger === "forced") {
48
- report(new Error(`a preCompact callback blocked a "forced" compaction — ignored (PTL/trim-pressure compaction is not optional): ${r.block}`));
49
- }
50
- return r;
51
- }
52
- catch (err) {
53
- report(asThrownError(err));
33
+ preCompact: async (ctx) => {
34
+ const outcome = await dispatchClassic(bus, "classic.PreCompact", { ...base, trigger: ctx.trigger, ...(ctx.customInstructions !== undefined ? { customInstructions: ctx.customInstructions } : {}) }, { ...(signal !== undefined ? { signal } : {}), checkAnswer: stringMembersAnswer("classic.PreCompact", ["block", "additionalInstructions"]) });
35
+ if (outcome?.kind !== "answered")
54
36
  return undefined;
37
+ const r = stringMembersOf(outcome.answer, ["block", "additionalInstructions"]);
38
+ if (r.block && ctx.trigger === "forced") {
39
+ report(new Error(`a preCompact handler blocked a "forced" compaction — ignored (PTL/trim-pressure compaction is not optional): ${r.block}`));
55
40
  }
41
+ return r;
56
42
  },
57
43
  }
58
44
  : {}),
59
- ...(post
45
+ ...(bus.hasHandlers("classic.PostCompact")
60
46
  ? {
61
- postCompact: async (rawCtx) => {
62
- try {
63
- const seat = await runHookSeat("postCompact", { timeoutMs: seatMs, ...(seatSignal !== undefined ? { signal: seatSignal } : {}) }, (sig) => post.call(hooks, { ...withIdentity(rawCtx), signal: sig }));
64
- if (seat.expired) {
65
- try {
66
- runner.deps.onError?.(hookSeatExpiredError("postCompact", seatMs, seat.cause, "the observation was abandoned; the compaction that already landed is unchanged"), { phase: "hook", sessionId });
67
- }
68
- catch {
69
- }
70
- }
71
- }
72
- catch (err) {
73
- try {
74
- runner.deps.onError?.(asThrownError(err), { phase: "hook", sessionId });
75
- }
76
- catch {
77
- }
78
- }
79
- },
47
+ postCompact: (ctx) => observeClassic(bus, "classic.PostCompact", {
48
+ ...base,
49
+ trigger: ctx.trigger,
50
+ summary: ctx.summary,
51
+ ...(ctx.tokensBefore !== undefined ? { tokensBefore: ctx.tokensBefore } : {}),
52
+ ...(ctx.tokensAfter !== undefined ? { tokensAfter: ctx.tokensAfter } : {}),
53
+ ...(ctx.freedTokens !== undefined ? { freedTokens: ctx.freedTokens } : {}),
54
+ }, signal),
80
55
  }
81
56
  : {}),
82
57
  };
@@ -1,8 +1,9 @@
1
1
  import { checkedAgentConfigDir } from "../agent-config-dir.js";
2
2
  import { checkedMediaByteCap } from "../media-byte-cap.js";
3
- import { receiveOwnProperties, refuseProxy } from "../own-property-receipt.js";
3
+ import { receiptRefusal, receiveOwnProperties, refuseProxy } from "../own-property-receipt.js";
4
4
  import { assertNoRetiredRunnerDeps } from "./retired-runner-deps.js";
5
5
  import { copyReadDenySeat, READ_DENY_DEPLOYMENT_SEATS } from "../read-face-seats.js";
6
+ import { holdOwnCredentialValues } from "../secret-env.js";
6
7
  export function retainRunnerDeps(deps) {
7
8
  const words = { subject: "RunnerDeps", unit: "seat", moment: "at new Runner" };
8
9
  refuseProxy(deps, words);
@@ -14,5 +15,14 @@ export function retainRunnerDeps(deps) {
14
15
  if (Object.hasOwn(retained, seat))
15
16
  Object.defineProperty(retained, seat, { value: copyReadDenySeat(Reflect.get(retained, seat)), enumerable: true, writable: true, configurable: true });
16
17
  }
18
+ let consolidationKey;
19
+ try {
20
+ const chat = retained.memoryConsolidationDriver?.chat;
21
+ consolidationKey = typeof chat === "object" && chat !== null ? Reflect.get(chat, "apiKey") : undefined;
22
+ }
23
+ catch {
24
+ throw receiptRefusal("RunnerDeps.memoryConsolidationDriver.chat threw while its apiKey was read at new Runner — refused (the thrown value is not repeated)");
25
+ }
26
+ holdOwnCredentialValues([typeof consolidationKey === "string" ? consolidationKey : undefined], retained.onNotice);
17
27
  return retained;
18
28
  }