@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
@@ -55,7 +55,7 @@ export interface AgentTranscriptToolOptions {
55
55
  * with retain off/expired/evicted). Only when BOTH miss does the call return the honest
56
56
  * "not retained" / "not found".
57
57
  */
58
- export declare function createAgentTranscriptTool(opts: AgentTranscriptToolOptions): import("../internal/harness-types.js").AgentTool<Type.TObject<{
58
+ export declare function createAgentTranscriptTool(opts: AgentTranscriptToolOptions): import("../core/types.js").AgentTool<Type.TObject<{
59
59
  id: Type.TString;
60
60
  lastN: Type.TOptional<Type.TInteger>;
61
61
  }>, unknown>;
@@ -42,6 +42,7 @@ export async function runCascade(runner, spec, config, internals) {
42
42
  let ownCacheWrite = 0, ownCacheWriteLong = 0;
43
43
  let nestedTokens = 0, nestedTurns = 0, nestedTasks = 0, nestedCostMicro = 0;
44
44
  let ownLlmRootMicro = 0, ownCompactionMicro = 0;
45
+ let ownSideCallMicro;
45
46
  let anyRungUnpriced = false;
46
47
  let hrCount = 0, hrWaitMs = 0;
47
48
  const hrGates = [];
@@ -58,6 +59,7 @@ export async function runCascade(runner, spec, config, internals) {
58
59
  anyLegUnpriced: anyRungUnpriced,
59
60
  llmRootMicroUsd: ownLlmRootMicro,
60
61
  compactionMicroUsd: ownCompactionMicro,
62
+ ...(ownSideCallMicro !== undefined ? { sideCallMicroUsd: ownSideCallMicro } : {}),
61
63
  nested: { tokens: nestedTokens, turns: nestedTurns, tasks: nestedTasks, costMicroUsd: nestedCostMicro },
62
64
  humanReview: { count: hrCount, totalWaitMs: hrWaitMs, gates: hrGates },
63
65
  });
@@ -120,6 +122,8 @@ export async function runCascade(runner, spec, config, internals) {
120
122
  if (s.costBreakdown) {
121
123
  ownLlmRootMicro += s.costBreakdown.llmRootMicroUsd;
122
124
  ownCompactionMicro += s.costBreakdown.compactionMicroUsd;
125
+ if (s.costBreakdown.sideCallMicroUsd !== undefined)
126
+ ownSideCallMicro = (ownSideCallMicro ?? 0) + s.costBreakdown.sideCallMicroUsd;
123
127
  }
124
128
  if (s.humanReview) {
125
129
  hrCount += s.humanReview.count;
@@ -69,6 +69,9 @@ export interface CumulativeStatsAccumulator {
69
69
  llmRootMicroUsd: number;
70
70
  /** Cumulative within-task compaction LLM cost for the `costBreakdown` taxonomy. */
71
71
  compactionMicroUsd: number;
72
+ /** Cumulative side-call (permission classifier, mods) LLM cost — the "of which" line of `costBreakdown`, INSIDE
73
+ * `llmRootMicroUsd`, never a partition member. Undefined until a leg booked one: the cumulative key is then absent too. */
74
+ sideCallMicroUsd?: number;
72
75
  nested: CumulativeNestedTotals;
73
76
  humanReview: CumulativeHumanReviewTotals;
74
77
  }
@@ -21,6 +21,7 @@ export function buildCumulativeStats(base, acc) {
21
21
  nestedSubagentMicroUsd: acc.nested.costMicroUsd,
22
22
  memoryConsolidationMicroUsd: 0,
23
23
  compactionMicroUsd: acc.compactionMicroUsd,
24
+ ...(acc.sideCallMicroUsd !== undefined ? { sideCallMicroUsd: acc.sideCallMicroUsd } : {}),
24
25
  },
25
26
  humanReview: acc.humanReview.count > 0
26
27
  ? { count: acc.humanReview.count, totalWaitMs: acc.humanReview.totalWaitMs, gates: acc.humanReview.gates }
@@ -65,6 +66,8 @@ export function createCumulativeStatsTracker() {
65
66
  if (s.costBreakdown) {
66
67
  acc.llmRootMicroUsd += s.costBreakdown.llmRootMicroUsd;
67
68
  acc.compactionMicroUsd += s.costBreakdown.compactionMicroUsd;
69
+ if (s.costBreakdown.sideCallMicroUsd !== undefined)
70
+ acc.sideCallMicroUsd = (acc.sideCallMicroUsd ?? 0) + s.costBreakdown.sideCallMicroUsd;
68
71
  }
69
72
  if (s.humanReview) {
70
73
  acc.humanReview.count += s.humanReview.count;
@@ -104,6 +104,6 @@ export interface ListAgentsRow {
104
104
  * roster row with no live row. */
105
105
  agentState?: AgentState;
106
106
  }
107
- export declare function createListAgentsTool(opts: ListAgentsToolOptions): import("../internal/harness-types.js").AgentTool<Type.TObject<{
107
+ export declare function createListAgentsTool(opts: ListAgentsToolOptions): import("../core/types.js").AgentTool<Type.TObject<{
108
108
  includeAll: Type.TOptional<Type.TBoolean>;
109
109
  }>, unknown>;
@@ -17,6 +17,6 @@ export interface ReadInboxToolOptions {
17
17
  /** The bound drain's pull face, read LATE (the drain binds after the roster is minted). Absent ⇒ no box. */
18
18
  pull: () => ((limit?: number, toolCallId?: string, charBudget?: number) => Promise<PulledInbox>) | undefined;
19
19
  }
20
- export declare function createReadInboxTool(opts: ReadInboxToolOptions): import("../internal/harness-types.js").AgentTool<Type.TObject<{
20
+ export declare function createReadInboxTool(opts: ReadInboxToolOptions): import("../core/types.js").AgentTool<Type.TObject<{
21
21
  limit: Type.TOptional<Type.TInteger>;
22
22
  }>, unknown>;
@@ -99,6 +99,7 @@ export async function runRepairLoop(runner, implSpec, config) {
99
99
  let ownTokens = 0, ownTurns = 0, ownPrompt = 0, ownTotalInput = 0, ownCached = 0, ownOutput = 0;
100
100
  let ownCacheWrite = 0, ownCacheWriteLong = 0, ownCostMicro = 0;
101
101
  let ownLlmRootMicro = 0, ownCompactionMicro = 0;
102
+ let ownSideCallMicro;
102
103
  let anyAttemptUnpriced = false;
103
104
  let nestedTokens = 0, nestedTurns = 0, nestedTasks = 0, nestedCostMicro = 0;
104
105
  let hrCount = 0, hrWaitMs = 0;
@@ -119,6 +120,8 @@ export async function runRepairLoop(runner, implSpec, config) {
119
120
  if (s.costBreakdown) {
120
121
  ownLlmRootMicro += s.costBreakdown.llmRootMicroUsd;
121
122
  ownCompactionMicro += s.costBreakdown.compactionMicroUsd;
123
+ if (s.costBreakdown.sideCallMicroUsd !== undefined)
124
+ ownSideCallMicro = (ownSideCallMicro ?? 0) + s.costBreakdown.sideCallMicroUsd;
122
125
  }
123
126
  if (s.humanReview) {
124
127
  hrCount += s.humanReview.count;
@@ -145,6 +148,7 @@ export async function runRepairLoop(runner, implSpec, config) {
145
148
  anyLegUnpriced: anyAttemptUnpriced,
146
149
  llmRootMicroUsd: ownLlmRootMicro,
147
150
  compactionMicroUsd: ownCompactionMicro,
151
+ ...(ownSideCallMicro !== undefined ? { sideCallMicroUsd: ownSideCallMicro } : {}),
148
152
  nested: { tokens: nestedTokens, turns: nestedTurns, tasks: nestedTasks, costMicroUsd: nestedCostMicro },
149
153
  humanReview: { count: hrCount, totalWaitMs: hrWaitMs, gates: hrGates },
150
154
  });
@@ -212,23 +212,18 @@ export interface SendMessageToolOptions {
212
212
  * pair). Absent = unknown ⇒ the phrase is hedged. */
213
213
  peerListingMounted?: boolean;
214
214
  }
215
- /** RB-382 — max chars of the `summary` arg (the short recap label, distinct from `message`'s much
216
- * larger {@link UPLINK_RESULT_MAX}) before ITS OWN truncation. Exported for direct unit-testing only
217
- * (module-internal path, same convention as MONITOR_SPILL_CAP_BYTES — not part of the src/index.ts
218
- * public surface): the tool's OWN schema already declares `summary: Type.String({ maxLength: 200 })`,
219
- * so a call arriving through the normal `AgentTool.execute` gate (`defineTool`'s `Value.Check`, see
220
- * core/tools.ts) can never carry a summary longer than this — the clip below is a defense-in-depth
221
- * belt for any caller that reaches this function body without going through that gate, not a live
222
- * truncation a model-facing call can trigger today. */
215
+ /** Max chars of the `summary` label (the short recap, distinct from `message`'s much larger
216
+ * {@link UPLINK_RESULT_MAX}) before its own truncation. The schema declares NO length bound on the field: a
217
+ * longer summary — the model's own, or the first line of a long message taken as the default — reaches the
218
+ * executor and is cut there by {@link clipSendMessageSummary}, with the cut disclosed. Exported for direct
219
+ * unit-testing only (module-internal path, same convention as MONITOR_SPILL_CAP_BYTES — not part of the
220
+ * src/index.ts public surface). */
223
221
  export declare const SEND_MESSAGE_SUMMARY_MAX = 200;
224
- /** RB-382 — clip a trimmed, non-empty `summary` to {@link SEND_MESSAGE_SUMMARY_MAX} chars, appending
225
- * the SAME "[… truncated: N chars total]" marker style every `message` truncation site in this file
226
- * already uses (the four delivery legs each silently did `slice(0, 200)` with no marker at all — a
227
- * double standard against `message`'s disclosed truncation in the same file, at least on paper — see
228
- * this constant's own doc comment for why the schema gate makes the branch unreachable in practice
229
- * today). The cap itself is unchanged; only the missing disclosure is added. RB-419 then folded those
230
- * four re-derivations into a SINGLE call site, immediately after the gate that makes the argument
231
- * non-empty — so this helper now has exactly one caller in the tool body. */
222
+ /** Clip a trimmed `summary` to {@link SEND_MESSAGE_SUMMARY_MAX} chars, appending the SAME
223
+ * "[… truncated: N chars total]" marker style every `message` truncation site in this file uses. This is
224
+ * the live truncation of an over-long summary (see the constant's doc: the schema does not bound it), and
225
+ * its one caller in the tool body is the label binding right after the argument is read. The cut keeps
226
+ * whole code points — a pair straddling the bound is dropped whole, never halved. */
232
227
  export declare function clipSendMessageSummary(raw: string): string;
233
228
  /**
234
229
  * design/276 (direct-mount guidance): the engine's first-party auto-mount declares this tool's safety
@@ -18,6 +18,7 @@ import { appendHopToken, judgePeerAdmission, peerAxisToken, resolvePeerLaneConfi
18
18
  import { toolFace } from "../core/tool-catalog-entries.js";
19
19
  import { thrownText } from "../core/thrown-value.js";
20
20
  import { assertNoRetiredKeys } from "../core/retired-keys.js";
21
+ import { sliceHeadSafe } from "../core/surrogate-safe-slice.js";
21
22
  import { clampValuesOf } from "../core/child-clamp-seats.js";
22
23
  import { resolveSubagentTranscriptTier } from "../core/wiring-manifest.js";
23
24
  export const SEND_MESSAGE_TOOL_NAME = "SendMessage";
@@ -35,9 +36,13 @@ function assertNoRetiredSendMessageOptions(opts) {
35
36
  }
36
37
  export function clipSendMessageSummary(raw) {
37
38
  return raw.length > SEND_MESSAGE_SUMMARY_MAX
38
- ? `${raw.slice(0, SEND_MESSAGE_SUMMARY_MAX)} [summary truncated: ${raw.length} chars total]`
39
+ ? `${sliceHeadSafe(raw, SEND_MESSAGE_SUMMARY_MAX)} [summary truncated: ${raw.length} chars total]`
39
40
  : raw;
40
41
  }
42
+ function defaultSendMessageSummary(message) {
43
+ const nl = message.indexOf("\n");
44
+ return (nl === -1 ? message : message.slice(0, nl)).trim();
45
+ }
41
46
  const TEAMMATE_MESSAGE_TAG = "teammate-message";
42
47
  function frameTeammateMessage(args) {
43
48
  const summaryAttr = args.summary !== undefined ? ` summary="${escapeAttributeValue(args.summary)}"` : "";
@@ -88,7 +93,9 @@ export function createSendMessageTool(opts) {
88
93
  const baseParameters = Type.Object({
89
94
  to: Type.String({ description: 'Recipient: the agent\'s name, or its task_id (a…) returned by the Agent tool with run_in_background. "main" is reserved for the spawning conversation.' }),
90
95
  message: Type.String({ description: "The follow-up request. The agent continues from its full prior context." }),
91
- summary: Type.Optional(Type.String({ maxLength: 200, description: "A 5-10 word summary shown as a preview in the UI (required when message is a string)" })),
96
+ summary: Type.Optional(Type.String({
97
+ description: `A 5-10 word summary shown as a one-line preview in the UI. Defaults to the first line of a plain-text message; longer summaries are truncated to ${SEND_MESSAGE_SUMMARY_MAX} characters rather than rejected.`,
98
+ })),
92
99
  });
93
100
  const sendMessageParameters = peerLane.active
94
101
  ? Type.Object({ ...baseParameters.properties, message: Type.Optional(Type.String({ description: `${baseParameters.properties.message.description ?? ""} Optional only for a pure notify_when_idle subscription.`.trim() })), ...notifyWhenIdleParameter })
@@ -208,14 +215,7 @@ export function createSendMessageTool(opts) {
208
215
  };
209
216
  }
210
217
  const summaryArg = typeof a.summary === "string" ? a.summary.trim() : "";
211
- if (summaryArg === "" && message !== "") {
212
- return {
213
- content: "Message not sent: summary is required when message is a string — pass a 5-10 word summary of the follow-up.",
214
- details: { error: "summary_required", to },
215
- isError: true,
216
- };
217
- }
218
- const summary = clipSendMessageSummary(summaryArg);
218
+ const summary = clipSendMessageSummary(summaryArg !== "" ? summaryArg : defaultSendMessageSummary(message));
219
219
  const senderId = ctx.taskId ?? opts.owner;
220
220
  const [parentTaskId, parentSessionId] = ctx.parentTaskId !== undefined ? [ctx.parentTaskId, ctx.parentSessionId] : [opts.parentTaskId, opts.parentSessionId];
221
221
  const senderName = ctx.spawnedAgentName ?? opts.senderName;
@@ -1103,9 +1103,7 @@ export function createAgentContinuationVerb(opts) {
1103
1103
  return enriched;
1104
1104
  },
1105
1105
  });
1106
- const summaryRaw = (o?.summary ?? content).replace(/\s+/g, " ").trim().slice(0, 200);
1107
- const summary = summaryRaw === "" ? "operator follow-up" : summaryRaw;
1108
- const out = await tool.execute(`op-${uuidv7()}`, { to: handle, message: content, summary });
1106
+ const out = await tool.execute(`op-${uuidv7()}`, { to: handle, message: content, ...(o?.summary !== undefined ? { summary: o.summary } : {}) });
1109
1107
  const text = out.content
1110
1108
  .filter((c) => c.type === "text")
1111
1109
  .map((c) => c.text)
@@ -1,6 +1,7 @@
1
1
  import { Type } from "typebox";
2
2
  import { isAbsolute } from "node:path";
3
3
  import { backgroundChildTerminal } from "../core/delegation-frames.js";
4
+ import { bindDelegationName } from "../core/delegation-name.js";
4
5
  import { resumeStartupCauseOf } from "../core/resume-startup-cause.js";
5
6
  import { errorCodeOf } from "../core/runner/terminal-account.js";
6
7
  import { applyParentSpecSeat, memoryTurnedOff, parentSpecSeatOfCtx } from "../core/parent-spec-seat.js";
@@ -1358,7 +1359,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1358
1359
  ...(forkOffered ? [{ name: FORK_SUBAGENT_TYPE, ...(depthPermitsNesting ? { canRedelegate: true } : {}) }] : []),
1359
1360
  ];
1360
1361
  const agentToolPool = delegationPoolFace(opts.tools ?? opts.inheritedTools ?? [], opts.extraTools !== undefined, opts.extraToolNames);
1361
- return {
1362
+ return bindDelegationName(delegationToolName, {
1362
1363
  name: opts.name ?? DEFAULT_SUBAGENT_TOOL_NAME,
1363
1364
  ...toolFace("agent"),
1364
1365
  agentListing,
@@ -1813,7 +1814,8 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1813
1814
  }
1814
1815
  const governingLists = def !== undefined ? { allow: def.allowTools, deny: def.denyTools } : { allow: opts.allowTools, deny: opts.denyTools };
1815
1816
  const childOwnLayer = Object.freeze({ ...(governingLists.allow != null ? { allow: Object.freeze([...governingLists.allow]) } : {}), deny: Object.freeze([...(governingLists.deny ?? [])]) });
1816
- const childListsJudged = toolListsDigest(childOwnLayer.allow, childOwnLayer.deny);
1817
+ const childListsDigest = toolListsDigest(childOwnLayer.allow, childOwnLayer.deny);
1818
+ const childListsJudged = agentToolPool !== undefined ? childListsDigest : undefined;
1817
1819
  const childCeiling = ctx.toolSelector?.layers ?? [];
1818
1820
  const parentMcp = opts.tools === undefined && extraToolsNote === undefined ? ctx.mountedMcp?.() : undefined;
1819
1821
  const childMcp = parentMcp !== undefined ? inheritedMcpDeclarations(parentMcp, compileToolSelector([...childCeiling, childOwnLayer])) : undefined;
@@ -2079,7 +2081,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2079
2081
  : undefined;
2080
2082
  const childInternals = {
2081
2083
  ...(ctx.toolSelector !== undefined ? { toolCeiling: childCeiling, ...(childListsJudged !== undefined ? { toolListsJudged: childListsJudged } : {}) } : {}),
2082
- ownToolListsWhere: delegationListWhere(toolName, def?.name),
2084
+ ...(childListsDigest !== undefined ? { ownToolLists: { toolName, ...(def !== undefined ? { definition: def.name } : {}), lists: childListsDigest } } : {}),
2083
2085
  ...(parentMcp?.pool !== undefined && childMcp !== undefined && childMcp.length > 0 ? { mcpPool: parentMcp.pool } : {}),
2084
2086
  ...(childPick.modelRef !== undefined ? { inheritedModelRef: childPick.modelRef } : {}),
2085
2087
  ...(inheritedSkillGrants.length > 0 ? { inheritedSkillGrants } : {}),
@@ -3853,5 +3855,5 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3853
3855
  }),
3854
3856
  };
3855
3857
  },
3856
- };
3858
+ });
3857
3859
  }
@@ -9,30 +9,36 @@ import { type ToolNameListReading } from "../core/tool-name-list.js";
9
9
  * root run (`TaskSpec.allowTools` / `TaskSpec.excludeTools`) and every child (its definition's lists, under the ceiling of the
10
10
  * run that spawned it), so there is no spawn-time filter and no complement anywhere.
11
11
  *
12
- * - an allowed list absent, or holding `"*"`, sets no allowlist on its layer; otherwise the layer keeps only what it names
12
+ * - an allowed list absent, or holding `"*"` (any spelling the rule syntax reads as it: `*()`, `*(*)`), sets no allowlist on
13
+ * its layer; otherwise the layer keeps only what it names
13
14
  * (`[]` keeps nothing — intentional, not a mistake);
14
15
  * - a denied list removes what it names from whatever remains (a denied tool always loses);
15
16
  * - a layer above a run (its ceiling) bounds it: a child's `"*"` never widens what its parent could use.
16
17
  *
17
- * An entry is read as the reference reads a rule string ({@link readDeniedEntry}: `Tool(content)` names `Tool`, the content is
18
- * not read, the whole tool is hidden); a protocol spelling (`mcp__srv`, `mcp__srv__*`, a glob over the tool segment) reaches the
18
+ * An entry is read by the rule syntax ({@link readDeniedEntry}: `Tool(content)` names `Tool`, the content is not read, the
19
+ * whole tool is hidden; an entry the syntax cannot read names no tool); a protocol spelling (`mcp__srv`, `mcp__srv__*`, a glob over the tool segment) reaches the
19
20
  * 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
21
  * 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
22
  *
22
- * Note: `"*"` in an allowed list is the "allow all" sentinel, so a tool literally NAMED `"*"` cannot be
23
- * the sole allowed tool via this path (tool names are conventionally identifiers, so this is moot).
23
+ * `"*"` in an allowed list is the "allow all" sentinel and never a name: no tool is named `*` (the caller tool name
24
+ * contract, `caller-tool-name.ts`, refuses it at the mount; engine and protocol-minted names never are).
24
25
  */
25
26
  /**
26
- * How ONE denied-tools entry is read — the reference reads each as a rule string, without trimming: `Tool(content)` names
27
- * `Tool` (the content is dropped, so the whole tool is hidden), `Tool()` and `Tool(*)` are the bare name, and anything else
28
- * — a malformed paren form, an entry with surrounding whitespace — is the whole string, which names no tool. A value that is
29
- * not a string (a list a host read from a file can hold anything) names no tool either: it reads as `not_a_string` with a
30
- * fixed label of its TYPE, and nothing about the value is read, converted or printed — `typeof` and the array test only.
27
+ * How ONE denied-tools entry is read — by the rule syntax's own test of a rule spelling (`ruleSpellingOf`, the one every entry
28
+ * list's reader asks), exactly as written: `Tool(content)` names `Tool` (the content is not read here, so the whole tool is
29
+ * hidden), `Tool()` and `Tool(*)` are the bare name. An entry the syntax cannot read — surrounding whitespace, a tool name
30
+ * outside its spelling (a blank or an invisible character before the `(`, a leading `-`), a parenthesis that does not close
31
+ * the entry — names no tool: `unreadable`, the entry as written. A value that is not a string (a list a host read from a file
32
+ * can hold anything) names no tool either: it reads as `not_a_string` with a fixed label of its TYPE, and nothing about the
33
+ * value is read, converted or printed — `typeof` and the array test only.
31
34
  */
32
35
  export type DeniedEntryReading = {
33
36
  readonly kind: "name";
34
37
  readonly name: string;
35
38
  readonly content: boolean;
39
+ } | {
40
+ readonly kind: "unreadable";
41
+ readonly entry: string;
36
42
  } | {
37
43
  readonly kind: "not_a_string";
38
44
  readonly type: string;
@@ -79,13 +85,31 @@ export interface ToolNameListReach {
79
85
  readonly covering: readonly string[];
80
86
  readonly wholeProtocols: ReadonlySet<ProtocolId>;
81
87
  }
88
+ /**
89
+ * The tool ONE entry of a list on `side` reaches ({@link readDeniedEntry}) — the one per-entry reading every list reader takes:
90
+ * `Tool()` / `Tool(*)` are the bare `Tool` (`*()` / `*(*)` the wildcard `*`); a denied `Tool(content)` hides the whole `Tool`;
91
+ * an allowed one, an unreadable entry or a non-string reaches nothing (`undefined`).
92
+ */
93
+ export declare function toolNameOfEntry(entry: unknown, side: ToolNameListSide): string | undefined;
94
+ /**
95
+ * Is this entry a bare tool name as the rule syntax reads it, written as such (`Read`, `mcp__srv__*`, `*`; never `Read()`,
96
+ * `Read(*)`, `Read(x)`, an unreadable spelling or a non-string)? The one form a checkpoint row records and is read back in.
97
+ */
98
+ export declare function isCanonicalToolName(entry: unknown): boolean;
99
+ /**
100
+ * A tool-name list as a checkpoint row records it: each entry as {@link toolNameOfEntry} reads it, in canonical spelling, an
101
+ * allowed entry that admits nothing left out — the copy reaches what the list reached, in the spelling a reader accepts
102
+ * ({@link isCanonicalToolName}). An unreadable entry stays as written: prepare refuses it before the park, the reader again.
103
+ */
104
+ export declare function persistedToolNameList(entries: readonly string[], side: ToolNameListSide): string[];
82
105
  /**
83
106
  * What an allowed-tools value admits, or `undefined` when it names no allowlist: absent, `null`, or a list holding the
84
- * wildcard. A list admits its string entries (an entry that is not a string admits nothing); a value that is not a list admits
85
- * NOTHING — the judge before the run refuses it, and a reader that meets it first fails closed.
107
+ * wildcard — an entry {@link toolNameOfEntry} reads as `*` (`*`, `*()`, `*(*)`). A list admits its string entries (an entry that
108
+ * is not a string admits nothing); a value that is not a list admits NOTHING — the judge before the run refuses it, and a
109
+ * reader that meets it first fails closed.
86
110
  */
87
111
  export declare function readAllowedToolList(allowTools: unknown): ToolNameListReach | undefined;
88
- /** What a denied value hides: its string entries read as {@link readDeniedEntry} reads them (an entry that is not a string, or a value that is not a list, hides nothing). */
112
+ /** What a denied value hides: its string entries read as {@link readDeniedEntry} reads them (an entry it reads as `unreadable` or not a string, or a value that is not a list, hides nothing here — the judgment before the run refuses each). */
89
113
  export declare function readDeniedToolList(denyTools: unknown): ToolNameListReach;
90
114
  /** Does the list reach this tool — through its wire name, any alias it declares, or a protocol spelling that covers it? The one matcher. */
91
115
  export declare function listReaches(reach: ToolNameListReach, tool: {
@@ -99,6 +123,9 @@ type UniverseTool = {
99
123
  };
100
124
  /** The wire names a leg of these kinds relies on (the catalog's protocol column). */
101
125
  export declare function protocolToolNames(legs: readonly ToolLegKind[]): string[];
126
+ /** Is this value a layer — an object (not a list) with the two lists `allow` / `deny`? One that is not admits NOTHING here;
127
+ * the judge before the run (`judgeRunToolLists`) refuses it, and a reader that meets it first fails closed. */
128
+ export declare function isToolSelectorLayer(layer: unknown): layer is ToolSelectorLayer;
102
129
  /**
103
130
  * Compile ONE run's tool selector from its layers (the ceiling it was spawned under, then its own lists — the LAST layer is its own)
104
131
  * and the kinds of leg it is. Each list is read by the one reading ({@link readAllowedToolList} / {@link readDeniedToolList}) and
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { canonicalize, UNCANONICALIZABLE } from "../core/canonical-json.js";
3
- import { parsePermissionRule } from "../core/permission-rule-syntax.js";
3
+ import { ruleSpellingOf } from "../core/permission-rule-syntax.js";
4
4
  import { TOOL_CATALOG_ENTRIES } from "../core/tool-catalog-entries.js";
5
5
  import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "../core/namespaced-rule-name.js";
6
6
  import { protocolOf } from "../core/protocol-table.js";
@@ -9,9 +9,9 @@ import { readToolNameList, snapshotToolNameList, valueTypeLabel } from "../core/
9
9
  export function readDeniedEntry(entry) {
10
10
  if (typeof entry !== "string")
11
11
  return { kind: "not_a_string", type: valueTypeLabel(entry) };
12
- if (entry !== entry.trim())
13
- return { kind: "name", name: entry, content: false };
14
- const parsed = parsePermissionRule(entry);
12
+ const parsed = ruleSpellingOf(entry);
13
+ if (parsed === undefined)
14
+ return { kind: "unreadable", entry };
15
15
  return { kind: "name", name: parsed.toolName, content: parsed.ruleContent !== undefined };
16
16
  }
17
17
  const LIST_NOUN = { allowed: "allowed tools", denied: "denied tools" };
@@ -52,18 +52,28 @@ export function snapshotDefinitionLists(def) {
52
52
  copy.denyTools = snapshotToolNameList(copy.denyTools);
53
53
  return copy;
54
54
  }
55
+ export function toolNameOfEntry(entry, side) {
56
+ const read = readDeniedEntry(entry);
57
+ return read.kind === "name" && (side === "denied" || !read.content) ? read.name : undefined;
58
+ }
59
+ export function isCanonicalToolName(entry) {
60
+ const read = readDeniedEntry(entry);
61
+ return read.kind === "name" && !read.content && read.name === entry;
62
+ }
63
+ export function persistedToolNameList(entries, side) {
64
+ return entries.flatMap((entry) => {
65
+ const name = toolNameOfEntry(entry, side);
66
+ if (name !== undefined)
67
+ return [name];
68
+ return readDeniedEntry(entry).kind === "name" ? [] : [entry];
69
+ });
70
+ }
55
71
  function reachOf(entries, side) {
56
72
  const names = new Set();
57
73
  const covering = [];
58
74
  const wholeProtocols = new Set();
59
75
  for (const entry of entries) {
60
- let name;
61
- if (side === "denied") {
62
- const read = readDeniedEntry(entry);
63
- name = read.kind === "name" ? read.name : undefined;
64
- }
65
- else
66
- name = typeof entry === "string" ? entry : undefined;
76
+ const name = toolNameOfEntry(entry, side);
67
77
  if (name === undefined)
68
78
  continue;
69
79
  const split = splitNamespacedName(name);
@@ -85,7 +95,7 @@ export function readAllowedToolList(allowTools) {
85
95
  const list = readToolNameList(allowTools);
86
96
  if (list.kind !== "entries")
87
97
  return reachOf([], "allowed");
88
- if (list.entries.includes("*"))
98
+ if (list.entries.some((entry) => toolNameOfEntry(entry, "allowed") === "*"))
89
99
  return undefined;
90
100
  return reachOf(list.entries, "allowed");
91
101
  }
@@ -129,9 +139,13 @@ function reachCoversPeer(reach, peer) {
129
139
  return split !== undefined && split.ns.id === peer.ns && split.peer === peer.peer && (split.tool === undefined || split.tool === "*");
130
140
  });
131
141
  }
142
+ export function isToolSelectorLayer(layer) {
143
+ return typeof layer === "object" && layer !== null && !Array.isArray(layer);
144
+ }
145
+ const NO_TOOL_LAYER = Object.freeze({ allow: reachOf([], "allowed"), deny: reachOf([], "denied") });
132
146
  export function compileToolSelector(layers, legs = []) {
133
147
  const kept = Object.freeze([...layers]);
134
- const compiled = kept.map((l) => ({ allow: readAllowedToolList(l.allow), deny: readDeniedToolList(l.deny) }));
148
+ const compiled = kept.map((l) => (isToolSelectorLayer(l) ? { allow: readAllowedToolList(l.allow), deny: readDeniedToolList(l.deny) } : NO_TOOL_LAYER));
135
149
  const admittedBy = (ls, tool) => ls.every((l) => (l.allow === undefined || listReaches(l.allow, tool)) && !listReaches(l.deny, tool));
136
150
  const protocol = new Map(PROTOCOL_ROWS.filter((r) => r.legs.some((l) => legs.includes(l))).map((r) => [r.name, r.underCeiling]));
137
151
  return Object.freeze({
@@ -154,7 +168,7 @@ export function compileToolSelector(layers, legs = []) {
154
168
  });
155
169
  }
156
170
  export function deniedProtocolTools(layers, legs) {
157
- const denies = layers.map((l) => readDeniedToolList(l.deny));
171
+ const denies = layers.map((l) => readDeniedToolList(isToolSelectorLayer(l) ? l.deny : undefined));
158
172
  const own = denies.slice(-1);
159
173
  const inherited = denies.slice(0, -1);
160
174
  const hits = new Map();
@@ -158,6 +158,7 @@ export interface CoreStatsSubset {
158
158
  nestedSubagentMicroUsd: number;
159
159
  memoryConsolidationMicroUsd: number;
160
160
  compactionMicroUsd: number;
161
+ sideCallMicroUsd?: number;
161
162
  };
162
163
  nested?: {
163
164
  costMicroUsd?: number;
@@ -6,8 +6,8 @@ import { STREAM_TORN_WARNING, createRepetitionPoll, createStreamEndLedger, model
6
6
  import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCallIds } from "./tool-call-id.js";
7
7
  import { emitBrainTelemetry, reportReasoningWireFacts } from "./status-sink.js";
8
8
  import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, modelSupportsVision, sendableImages } from "./media-degrade.js";
9
- import { ANTHROPIC_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, lockHeader, mergeHeaders, takeHeaderCasefold } from "./request-params.js";
10
- import { adjudicateModelRoute, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential, routeRefusalText } from "./route-adjudicator.js";
9
+ import { ANTHROPIC_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, headerBagOnce, lockHeader, mergeHeaders, takeHeaderCasefold } from "./request-params.js";
10
+ import { admitRouteRequest, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential } 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";
@@ -227,6 +227,7 @@ function closeToolUseBlock(acc, responseIds, closed) {
227
227
  return acc.closedTc;
228
228
  }
229
229
  const ANTHROPIC_LANE_DEFAULT = "https://api.anthropic.com";
230
+ const ANTHROPIC_KEY_HEADER = "x-api-key";
230
231
  export function createAnthropicBrain(given = {}) {
231
232
  const config = brainConfigSnapshot(given, "createAnthropicBrain config");
232
233
  assertServableRequestRoot(config.baseUrl, "config.baseUrl");
@@ -246,17 +247,19 @@ export function createAnthropicBrain(given = {}) {
246
247
  maxRetries: options?.maxRetries,
247
248
  stallTimeouts: options?.stallTimeouts,
248
249
  buildRequest: (overrides) => {
249
- const { root, origin: rootOrigin } = resolveRequestRootOf(model.baseUrl, config.baseUrl, ANTHROPIC_LANE_DEFAULT);
250
+ const routed = { id: model.id, baseUrl: model.baseUrl };
251
+ const { root, origin: rootOrigin } = resolveRequestRootOf(routed.baseUrl, config.baseUrl, ANTHROPIC_LANE_DEFAULT);
252
+ const modelHeaders = headerBagOnce(model.headers);
253
+ const optionsHeaders = headerBagOnce(options?.headers);
250
254
  const routeCredential = resolveRouteCredential({
251
255
  optionsApiKey: options?.apiKey,
252
- optionsHeaders: options?.headers,
253
- modelHeaders: model.headers,
256
+ optionsHeaders,
257
+ modelHeaders,
254
258
  configApiKey: config.apiKey,
255
259
  configHeaders: config.headers,
260
+ keyHeader: ANTHROPIC_KEY_HEADER,
256
261
  });
257
- const routeVerdict = adjudicateModelRoute(model, routeCredential, { baseUrl: config.baseUrl, laneDefault: ANTHROPIC_LANE_DEFAULT });
258
- if (!routeVerdict.ok)
259
- throw new BrainError("invalid_request", routeRefusalText(routeVerdict));
262
+ const routeAdmission = admitRouteRequest(routed, routeCredential, { baseUrl: config.baseUrl, laneDefault: ANTHROPIC_LANE_DEFAULT });
260
263
  const apiKey = routeCredential.apiKey;
261
264
  const nonEmptyBlocks = context.systemBlocks?.filter((b) => b.text.length > 0);
262
265
  const system = nonEmptyBlocks?.length
@@ -329,8 +332,8 @@ export function createAnthropicBrain(given = {}) {
329
332
  if (anthCompat.interleavedThinking) {
330
333
  betas.push("interleaved-thinking-2025-05-14");
331
334
  }
332
- const headers = mergeHeaders(model.headers, config.headers, options?.headers);
333
- applyRouteCredentialHeaders(headers, routeCredential, { model: model.headers, options: options?.headers });
335
+ const headers = mergeHeaders(modelHeaders, config.headers, optionsHeaders);
336
+ applyRouteCredentialHeaders(headers, routeCredential);
334
337
  if (betas.length > 0) {
335
338
  const existing = (takeHeaderCasefold(headers, "anthropic-beta") ?? "").split(",").map((b) => b.trim()).filter(Boolean);
336
339
  for (const beta of betas) {
@@ -342,7 +345,7 @@ export function createAnthropicBrain(given = {}) {
342
345
  lockHeader(headers, "content-type", "application/json");
343
346
  lockHeader(headers, "anthropic-version", config.version ?? "2023-06-01");
344
347
  if (apiKey)
345
- headers["x-api-key"] = apiKey;
348
+ lockHeader(headers, ANTHROPIC_KEY_HEADER, apiKey);
346
349
  const builtThinkingRequested = body.thinking !== undefined;
347
350
  const builtMaxTokens = body.max_tokens;
348
351
  const builtMaxTokensLane = overrides?.maxOutputTokens !== undefined
@@ -362,6 +365,7 @@ export function createAnthropicBrain(given = {}) {
362
365
  outputCapTokens: effectiveOutputCap(wire, OUTPUT_CAP_KEYS.anthropic),
363
366
  capDerivedPaths: [...OUTPUT_CAP_KEYS.anthropic, "thinking.budget_tokens"],
364
367
  onCommitted: () => {
368
+ routeAdmission();
365
369
  thinkingRequested = builtThinkingRequested;
366
370
  sentMaxTokens = builtMaxTokens;
367
371
  sentMaxTokensLane = builtMaxTokensLane;
@@ -768,5 +772,5 @@ export function createAnthropicBrain(given = {}) {
768
772
  },
769
773
  });
770
774
  };
771
- return { stream, adjudicateRoute: createBrainRouteJudge({ ...config, laneDefault: ANTHROPIC_LANE_DEFAULT }) };
775
+ return { stream, adjudicateRoute: createBrainRouteJudge({ ...config, laneDefault: ANTHROPIC_LANE_DEFAULT, keyHeader: ANTHROPIC_KEY_HEADER }) };
772
776
  }
@@ -20,12 +20,11 @@ import type { AnthropicMessagesCompat, Model } from "../internal/llm.js";
20
20
  */
21
21
  export declare const FABLE_5_COMPAT: AnthropicMessagesCompat;
22
22
  /**
23
- * Fable-5 behavioral guidance (CC 2.1.198 `fable_5_mitigations` — Anthropic's own runtime patches
24
- * for this model class's known behavior pitfalls, adapted; design/119 S3). Carried on the Model as
25
- * `promptGuidance` DATA — the injection mechanism (`Model.promptGuidance` → system-prompt tail) is
26
- * generic and model-name-free.
23
+ * The fable lines the classic prompt shape serves. They are prompt text, so they live with the prompt
24
+ * text; this name stays exported for hosts that read them. The preset below no longer carries them as
25
+ * `promptGuidance`: the prompt composes them itself, once, where they are the only fable text.
27
26
  */
28
- export declare const FABLE_5_PROMPT_GUIDANCE: string[];
27
+ export declare const FABLE_5_PROMPT_GUIDANCE: readonly string[];
29
28
  /**
30
29
  * A ready-to-use `claude-fable-5` {@link Model} (CC 2.1.198 registry facts: 1M-token native context
31
30
  * window, 64k default max output — the 128k tier is opt-in via `maxTokens` override, knowledge
@@ -1,12 +1,13 @@
1
+ import { catalogText } from "../prompt-assembly/catalog/index.js";
1
2
  export const FABLE_5_COMPAT = {
2
3
  thinkingMode: "adaptive",
3
4
  effortLevels: ["low", "medium", "high", "xhigh", "max"],
4
5
  supportsTemperature: false,
5
6
  };
6
7
  export const FABLE_5_PROMPT_GUIDANCE = [
7
- "Your final message of a turn is the only text the caller is guaranteed to read. Put every conclusion, answer, and deliverable in it — lead with the outcome, then supporting detail. Never leave a result only in an intermediate message or in your reasoning.",
8
- "When operating autonomously: before ending your turn, check that the task is actually complete (not just planned); before any state-changing action, re-verify that the evidence supports that specific action rather than pattern-matching a familiar case.",
9
- "When calling tools, provide exactly ONE complete JSON value per parameter — never concatenate multiple values, never truncate, never wrap a value in commentary.",
8
+ catalogText("core/behavior.fable-classic.final-message"),
9
+ catalogText("core/behavior.fable-classic.autonomy"),
10
+ catalogText("core/behavior.fable-classic.tool-json"),
10
11
  ];
11
12
  export function fable5Model(overrides = {}) {
12
13
  return {
@@ -23,7 +24,6 @@ export function fable5Model(overrides = {}) {
23
24
  maxTokens: 64_000,
24
25
  charsPerToken: 3,
25
26
  compat: { ...FABLE_5_COMPAT },
26
- promptGuidance: [...FABLE_5_PROMPT_GUIDANCE],
27
27
  ...overrides,
28
28
  };
29
29
  }