@sema-agent/core 7.55.0 → 7.56.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 (418) hide show
  1. package/CHANGELOG.md +513 -0
  2. package/dist/agents/cascade.js +1 -1
  3. package/dist/agents/cc-peer-directory.js +1 -0
  4. package/dist/agents/child-model-seat.d.ts +0 -11
  5. package/dist/agents/child-model-seat.js +0 -3
  6. package/dist/agents/list-agents-tool.d.ts +3 -1
  7. package/dist/agents/list-agents-tool.js +7 -7
  8. package/dist/agents/peer-directory.d.ts +22 -4
  9. package/dist/agents/peer-directory.js +24 -2
  10. package/dist/agents/peer-session-drain.js +2 -2
  11. package/dist/agents/repair-loop.js +2 -2
  12. package/dist/agents/send-message-tool.js +4 -4
  13. package/dist/agents/subagent.d.ts +6 -4
  14. package/dist/agents/subagent.js +64 -60
  15. package/dist/agents/tool-filter.d.ts +7 -5
  16. package/dist/agents/tool-filter.js +12 -9
  17. package/dist/agents/verify.d.ts +3 -2
  18. package/dist/agents/verify.js +3 -3
  19. package/dist/brain/anthropic.js +30 -73
  20. package/dist/brain/media-degrade.d.ts +18 -7
  21. package/dist/brain/media-degrade.js +13 -2
  22. package/dist/brain/model-capability.d.ts +37 -0
  23. package/dist/brain/model-capability.js +34 -0
  24. package/dist/brain/model-presets.d.ts +2 -8
  25. package/dist/brain/model-presets.js +1 -6
  26. package/dist/brain/open-responses.js +13 -26
  27. package/dist/brain/openai.js +14 -87
  28. package/dist/brain/reasoning-request.d.ts +96 -0
  29. package/dist/brain/reasoning-request.js +174 -0
  30. package/dist/brain/reasoning.d.ts +11 -11
  31. package/dist/brain/reasoning.js +4 -3
  32. package/dist/brain/request-params.d.ts +7 -4
  33. package/dist/brain/request-params.js +7 -4
  34. package/dist/brain/status-sink.d.ts +20 -0
  35. package/dist/brain/status-sink.js +7 -0
  36. package/dist/core/a2a.d.ts +2 -1
  37. package/dist/core/a2a.js +19 -13
  38. package/dist/core/agent-definition.d.ts +10 -0
  39. package/dist/core/allow-entry.d.ts +20 -13
  40. package/dist/core/allow-entry.js +26 -22
  41. package/dist/core/allow-rule-shadow.d.ts +3 -3
  42. package/dist/core/ask-origin.d.ts +64 -18
  43. package/dist/core/ask-origin.js +63 -23
  44. package/dist/core/ask-question.d.ts +51 -8
  45. package/dist/core/ask-question.js +3 -4
  46. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  47. package/dist/core/ask-unresolvable-notice.js +16 -2
  48. package/dist/core/checkpoint-generation.d.ts +53 -0
  49. package/dist/core/checkpoint-generation.js +35 -0
  50. package/dist/core/checkpoint-queries.d.ts +180 -0
  51. package/dist/core/checkpoint-queries.js +272 -0
  52. package/dist/core/checkpoint-requirements.d.ts +13 -1
  53. package/dist/core/checkpoint-requirements.js +4 -0
  54. package/dist/core/checkpoint-store.d.ts +88 -24
  55. package/dist/core/checkpoint-store.js +24 -9
  56. package/dist/core/cross-boundary-taint.d.ts +6 -5
  57. package/dist/core/cross-boundary-taint.js +1 -3
  58. package/dist/core/decision-receipt.d.ts +37 -3
  59. package/dist/core/decision-receipt.js +17 -17
  60. package/dist/core/delegation-not-started.d.ts +6 -0
  61. package/dist/core/delegation-not-started.js +17 -0
  62. package/dist/core/engine-attestation.d.ts +93 -0
  63. package/dist/core/engine-attestation.js +70 -0
  64. package/dist/core/engine-capabilities.d.ts +4 -1
  65. package/dist/core/engine-capabilities.js +1 -1
  66. package/dist/core/engine-notice.d.ts +30 -11
  67. package/dist/core/file-history-store.d.ts +90 -14
  68. package/dist/core/file-history-store.js +23 -15
  69. package/dist/core/gate-fold.d.ts +1 -1
  70. package/dist/core/gate-fold.js +22 -10
  71. package/dist/core/gate-lanes.js +73 -64
  72. package/dist/core/gate-outcome.d.ts +26 -5
  73. package/dist/core/gate-outcome.js +26 -0
  74. package/dist/core/governance-codes.d.ts +5 -1
  75. package/dist/core/governance-codes.js +6 -0
  76. package/dist/core/hooks.d.ts +17 -16
  77. package/dist/core/hooks.js +3 -1
  78. package/dist/core/host-floor.d.ts +128 -0
  79. package/dist/core/host-floor.js +206 -0
  80. package/dist/core/host-target.d.ts +38 -3
  81. package/dist/core/host-target.js +38 -5
  82. package/dist/core/mcp.d.ts +5 -1
  83. package/dist/core/mcp.js +67 -41
  84. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  85. package/dist/core/memory-engine/engine.js +4 -4
  86. package/dist/core/memory-engine/layout.d.ts +60 -8
  87. package/dist/core/memory-engine/layout.js +65 -6
  88. package/dist/core/model-seat.d.ts +10 -3
  89. package/dist/core/mods/classic-events.d.ts +67 -0
  90. package/dist/core/mods/classic-events.js +1 -0
  91. package/dist/core/mods/dollar.d.ts +13 -0
  92. package/dist/core/mods/extension-call.d.ts +31 -0
  93. package/dist/core/mods/extension-call.js +43 -0
  94. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  95. package/dist/core/mods/kernel/dispatch.js +140 -69
  96. package/dist/core/mods/kernel/events.d.ts +47 -11
  97. package/dist/core/mods/kernel/events.js +66 -42
  98. package/dist/core/mods/kernel/index.d.ts +4 -4
  99. package/dist/core/mods/kernel/index.js +2 -2
  100. package/dist/core/mods/kernel/receive.d.ts +39 -5
  101. package/dist/core/mods/kernel/receive.js +290 -17
  102. package/dist/core/mods/kernel/registration.d.ts +33 -2
  103. package/dist/core/mods/kernel/registration.js +6 -7
  104. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  105. package/dist/core/mods/kernel/site-rules.js +24 -42
  106. package/dist/core/mods/spec-seats.d.ts +69 -0
  107. package/dist/core/mods/spec-seats.js +114 -0
  108. package/dist/core/mods/stations.d.ts +28 -8
  109. package/dist/core/mods/stations.js +29 -13
  110. package/dist/core/mods/tool-call.d.ts +79 -0
  111. package/dist/core/mods/tool-call.js +152 -0
  112. package/dist/core/namespaced-rule-name.d.ts +32 -38
  113. package/dist/core/namespaced-rule-name.js +29 -36
  114. package/dist/core/parent-spec-seat.d.ts +6 -1
  115. package/dist/core/parent-spec-seat.js +2 -0
  116. package/dist/core/park-selfcheck.js +1 -0
  117. package/dist/core/permission-rule-consent.d.ts +19 -0
  118. package/dist/core/permission-rule-consent.js +116 -26
  119. package/dist/core/permission-rule-model.d.ts +14 -3
  120. package/dist/core/permission-rule-model.js +39 -24
  121. package/dist/core/permission-rule-org.d.ts +6 -2
  122. package/dist/core/permission-rule-org.js +7 -3
  123. package/dist/core/permission-rule-provider.d.ts +5 -2
  124. package/dist/core/permission-rule-provider.js +41 -11
  125. package/dist/core/permission-rule-store.d.ts +3 -2
  126. package/dist/core/permission-rule-store.js +11 -2
  127. package/dist/core/permission-rule-sync.js +3 -2
  128. package/dist/core/permission-rule-syntax.d.ts +5 -4
  129. package/dist/core/permission-rule-syntax.js +2 -2
  130. package/dist/core/permission-rules.d.ts +4 -4
  131. package/dist/core/permission-rules.js +11 -20
  132. package/dist/core/persisted-rule-arms.d.ts +2 -2
  133. package/dist/core/persisted-rule-arms.js +10 -12
  134. package/dist/core/principal-name.d.ts +20 -0
  135. package/dist/core/principal-name.js +22 -0
  136. package/dist/core/prompt-section-seat.js +4 -6
  137. package/dist/core/protocol-http-auth.d.ts +26 -5
  138. package/dist/core/protocol-http-auth.js +137 -4
  139. package/dist/core/retired-keys.d.ts +16 -0
  140. package/dist/core/retired-keys.js +16 -4
  141. package/dist/core/rewrite-rejudge.d.ts +60 -0
  142. package/dist/core/rewrite-rejudge.js +36 -0
  143. package/dist/core/roles.d.ts +28 -1
  144. package/dist/core/roles.js +31 -19
  145. package/dist/core/rule-lane-reads.d.ts +20 -15
  146. package/dist/core/rule-lane-reads.js +45 -17
  147. package/dist/core/rule-owner.d.ts +3 -3
  148. package/dist/core/rule-owner.js +3 -2
  149. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  150. package/dist/core/runner/announce-once-ledger.js +5 -0
  151. package/dist/core/runner/assemble-result.d.ts +1 -0
  152. package/dist/core/runner/assemble-result.js +1 -1
  153. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  154. package/dist/core/runner/caller-roster.d.ts +16 -4
  155. package/dist/core/runner/caller-roster.js +33 -6
  156. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  157. package/dist/core/runner/capability-withheld-seat.js +24 -0
  158. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  159. package/dist/core/runner/classifier-ladder.js +3 -3
  160. package/dist/core/runner/construction-doors.js +3 -0
  161. package/dist/core/runner/contracts.d.ts +28 -25
  162. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  163. package/dist/core/runner/cross-boundary-lane.js +40 -27
  164. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  165. package/dist/core/runner/denial-limit-arms.js +1 -1
  166. package/dist/core/runner/file-history-request.d.ts +18 -0
  167. package/dist/core/runner/file-history-request.js +21 -13
  168. package/dist/core/runner/file-history-restore.d.ts +45 -0
  169. package/dist/core/runner/file-history-restore.js +46 -0
  170. package/dist/core/runner/gate-exit.d.ts +3 -3
  171. package/dist/core/runner/gate-exit.js +4 -3
  172. package/dist/core/runner/image.d.ts +7 -17
  173. package/dist/core/runner/image.js +9 -60
  174. package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
  175. package/dist/core/runner/permission-rule-lanes.js +26 -10
  176. package/dist/core/runner/person-path-rows.d.ts +12 -9
  177. package/dist/core/runner/person-path-rows.js +18 -7
  178. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  179. package/dist/core/runner/prepare-ask-lane.js +5 -2
  180. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  181. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  182. package/dist/core/runner/prepare-config-doors.d.ts +29 -38
  183. package/dist/core/runner/prepare-config-doors.js +42 -25
  184. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  185. package/dist/core/runner/prepare-defer-classify.js +7 -8
  186. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  187. package/dist/core/runner/prepare-file-history.js +7 -39
  188. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  189. package/dist/core/runner/prepare-gate-stations.js +10 -1
  190. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  191. package/dist/core/runner/prepare-hands-readface.js +15 -14
  192. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  193. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  194. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  195. package/dist/core/runner/prepare-park-ask.js +5 -5
  196. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  197. package/dist/core/runner/prepare-policy-chain.js +65 -72
  198. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  199. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  200. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  201. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  204. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  205. package/dist/core/runner/prepare-safety-scan.js +0 -17
  206. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  207. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  208. package/dist/core/runner/prepare-task.d.ts +1 -1
  209. package/dist/core/runner/prepare-task.js +29 -20
  210. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  211. package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
  212. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  213. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  215. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  216. package/dist/core/runner/resume-admission.js +1 -1
  217. package/dist/core/runner/resume-apply.js +11 -12
  218. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  219. package/dist/core/runner/resume-claim.d.ts +4 -2
  220. package/dist/core/runner/resume-claim.js +15 -8
  221. package/dist/core/runner/retired-runner-deps.js +1 -0
  222. package/dist/core/runner/rewind-files.d.ts +15 -0
  223. package/dist/core/runner/rewind-files.js +132 -0
  224. package/dist/core/runner/run-attachment-seats.js +2 -1
  225. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  226. package/dist/core/runner/run-brain-sinks.js +4 -2
  227. package/dist/core/runner/run-harness-handlers.js +12 -4
  228. package/dist/core/runner/run-leg.d.ts +1 -1
  229. package/dist/core/runner/run-leg.js +30 -18
  230. package/dist/core/runner/run-settle-and-teardown.js +2 -1
  231. package/dist/core/runner/run-turn-boundary.js +1 -10
  232. package/dist/core/runner/runtask.d.ts +3 -0
  233. package/dist/core/runner/runtask.js +8 -9
  234. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  235. package/dist/core/runner/session-read-file-states.js +28 -0
  236. package/dist/core/runner/session-rule-policy.js +4 -3
  237. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  238. package/dist/core/runner/shell-env-withheld.js +51 -0
  239. package/dist/core/runner/skills-seat.js +6 -2
  240. package/dist/core/runner/stream-settle-backstop.js +1 -1
  241. package/dist/core/runner/sub-agent-deny-lists.js +4 -7
  242. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  243. package/dist/core/runner/synthetic-tools.js +4 -1
  244. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  245. package/dist/core/runner/tool-disclosure.js +1 -3
  246. package/dist/core/runner/tool-end-body.d.ts +1 -1
  247. package/dist/core/runner/tool-end-body.js +10 -9
  248. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  249. package/dist/core/runner/tool-not-executed.js +11 -0
  250. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  251. package/dist/core/runner/tool-occurrence.js +7 -0
  252. package/dist/core/runner/turn-attachments.d.ts +33 -15
  253. package/dist/core/runner/turn-attachments.js +62 -37
  254. package/dist/core/runner-deps.d.ts +5 -5
  255. package/dist/core/safety-axis-vocab.d.ts +6 -4
  256. package/dist/core/safety-axis-vocab.js +6 -5
  257. package/dist/core/safety-merge-corpus.js +11 -3
  258. package/dist/core/secret-env.d.ts +26 -3
  259. package/dist/core/secret-env.js +44 -8
  260. package/dist/core/select-model.js +3 -3
  261. package/dist/core/session-policy-store.d.ts +27 -15
  262. package/dist/core/session-policy-store.js +156 -36
  263. package/dist/core/session-store.d.ts +29 -10
  264. package/dist/core/session-store.js +51 -19
  265. package/dist/core/session.d.ts +82 -16
  266. package/dist/core/session.js +53 -0
  267. package/dist/core/shell-read-silence.d.ts +11 -12
  268. package/dist/core/shell-read-silence.js +9 -5
  269. package/dist/core/shell-run-candidates.js +3 -1
  270. package/dist/core/shell-wrapper-projection.js +1 -1
  271. package/dist/core/shell-wrapper-table.d.ts +14 -7
  272. package/dist/core/shell-wrapper-table.js +5 -4
  273. package/dist/core/side-query.js +10 -1
  274. package/dist/core/skill-grant.d.ts +7 -2
  275. package/dist/core/skill-grant.js +5 -0
  276. package/dist/core/skills-directory.js +6 -2
  277. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  278. package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
  279. package/dist/core/store-contracts/file-history-store-contract.js +31 -1
  280. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  281. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  282. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  283. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  284. package/dist/core/store-contracts/session-store-contract.js +150 -14
  285. package/dist/core/stub-env.d.ts +2 -0
  286. package/dist/core/stub-env.js +1 -0
  287. package/dist/core/synthetic-read-verdict.js +3 -3
  288. package/dist/core/task-event.d.ts +32 -4
  289. package/dist/core/task-notification.d.ts +16 -12
  290. package/dist/core/task-registry.d.ts +9 -0
  291. package/dist/core/task-registry.js +11 -1
  292. package/dist/core/task-result.d.ts +18 -0
  293. package/dist/core/task-spec.d.ts +18 -13
  294. package/dist/core/tighten-task-spec.js +2 -1
  295. package/dist/core/tool-catalog-entries.d.ts +17 -0
  296. package/dist/core/tool-catalog-entries.js +13 -2
  297. package/dist/core/tool-check-reading.d.ts +11 -0
  298. package/dist/core/tool-check-reading.js +11 -6
  299. package/dist/core/tool-model-gate.d.ts +2 -2
  300. package/dist/core/tool-name-aliases.d.ts +16 -16
  301. package/dist/core/tool-name-aliases.js +13 -19
  302. package/dist/core/tool-name-readings.d.ts +5 -35
  303. package/dist/core/tool-name-readings.js +1 -9
  304. package/dist/core/tool-policy.d.ts +68 -198
  305. package/dist/core/tool-policy.js +149 -198
  306. package/dist/core/tool-result-store.js +3 -0
  307. package/dist/core/tool-roster.d.ts +14 -19
  308. package/dist/core/tool-roster.js +11 -44
  309. package/dist/core/tool-spec-members.js +7 -2
  310. package/dist/core/tool-spec.d.ts +19 -11
  311. package/dist/core/tools.js +49 -9
  312. package/dist/core/trace.d.ts +2 -2
  313. package/dist/core/types.d.ts +1 -1
  314. package/dist/core/user-attachment.d.ts +8 -1
  315. package/dist/core/user-attachment.js +64 -4
  316. package/dist/core/wiring-manifest.d.ts +9 -0
  317. package/dist/core/wiring-manifest.js +1 -0
  318. package/dist/core/workflow-journal-store.js +1 -1
  319. package/dist/engine/compaction/compaction.js +3 -2
  320. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  321. package/dist/engine/execution-env/node-execution-env.js +11 -2
  322. package/dist/engine/harness/agent-harness.d.ts +25 -1
  323. package/dist/engine/harness/agent-harness.js +54 -7
  324. package/dist/engine/harness/types.d.ts +29 -2
  325. package/dist/engine/llm/types.d.ts +28 -11
  326. package/dist/engine/loop/agent-loop.d.ts +22 -0
  327. package/dist/engine/loop/agent-loop.js +16 -26
  328. package/dist/engine/loop/types.d.ts +16 -6
  329. package/dist/engine/session/memory-repo.d.ts +9 -2
  330. package/dist/engine/session/memory-repo.js +11 -1
  331. package/dist/engine/session/repo-utils.d.ts +6 -5
  332. package/dist/engine/session/repo-utils.js +14 -6
  333. package/dist/index.d.ts +22 -10
  334. package/dist/index.js +15 -7
  335. package/dist/internal/harness-types.d.ts +1 -1
  336. package/dist/internal/llm.d.ts +1 -1
  337. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  338. package/dist/orchestration/run-workflow-tool.js +5 -3
  339. package/dist/orchestration/workflow.d.ts +3 -0
  340. package/dist/orchestration/workflow.js +36 -18
  341. package/dist/prompt-assembly/artifact.d.ts +2 -2
  342. package/dist/prompt-assembly/artifact.js +5 -3
  343. package/dist/prompt-assembly/assemble.d.ts +3 -2
  344. package/dist/prompt-assembly/assemble.js +1 -1
  345. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  346. package/dist/prompt-assembly/catalog/schema.js +34 -2
  347. package/dist/prompt-assembly/catalog/sections.js +0 -1
  348. package/dist/prompt-assembly/composer.d.ts +3 -1
  349. package/dist/prompt-assembly/composer.js +1 -1
  350. package/dist/prompt-assembly/event-registry.js +1 -0
  351. package/dist/prompt-assembly/overlay.js +3 -3
  352. package/dist/prompt-assembly/renderers.d.ts +1 -1
  353. package/dist/prompt-assembly/renderers.js +0 -3
  354. package/dist/prompt-assembly/role-base.d.ts +15 -0
  355. package/dist/prompt-assembly/role-base.js +9 -0
  356. package/dist/prompt-assembly/select.d.ts +39 -14
  357. package/dist/prompt-assembly/select.js +47 -16
  358. package/dist/prompt-assembly/sugar.d.ts +17 -11
  359. package/dist/prompt-assembly/sugar.js +8 -3
  360. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  361. package/dist/prompt-assembly/tool-catalog.js +114 -4
  362. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  363. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  364. package/dist/prompt-assembly/types.d.ts +0 -7
  365. package/dist/scenarios/full-body.d.ts +11 -11
  366. package/dist/scenarios/full-body.js +4 -3
  367. package/dist/shell/lex.js +10 -1
  368. package/dist/stores/file/adoption/adopt.js +4 -3
  369. package/dist/stores/file/adoption/marker.js +3 -2
  370. package/dist/stores/file/checkpoint-store.d.ts +21 -0
  371. package/dist/stores/file/checkpoint-store.js +38 -6
  372. package/dist/stores/file/file-history-store.js +6 -7
  373. package/dist/stores/file/index.js +2 -1
  374. package/dist/stores/file/permission-rule-adopt.js +4 -3
  375. package/dist/stores/file/permission-rule-store.js +11 -5
  376. package/dist/stores/file/session-store.d.ts +29 -6
  377. package/dist/stores/file/session-store.js +42 -50
  378. package/dist/tools/artifact/artifact-tool.js +3 -2
  379. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  380. package/dist/tools/fs/bash-program-position.js +56 -9
  381. package/dist/tools/fs/fs-bash.js +5 -5
  382. package/dist/tools/fs/fs-glob.d.ts +86 -0
  383. package/dist/tools/fs/fs-glob.js +226 -0
  384. package/dist/tools/fs/fs-read.js +14 -14
  385. package/dist/tools/fs/fs-search-tools.js +7 -7
  386. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  387. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  388. package/dist/tools/fs/pdf.d.ts +9 -6
  389. package/dist/tools/fs/pdf.js +3 -3
  390. package/dist/tools/fs/program-read-model.d.ts +57 -7
  391. package/dist/tools/fs/program-read-model.js +11 -1
  392. package/dist/tools/fs/program-read-model.rows.js +78 -21
  393. package/dist/tools/fs/read-deny-home.js +3 -2
  394. package/dist/tools/fs/removal-targets.d.ts +17 -7
  395. package/dist/tools/fs/removal-targets.js +47 -20
  396. package/dist/tools/fs/search.d.ts +10 -0
  397. package/dist/tools/fs/search.js +20 -26
  398. package/dist/tools/fs/shell-read-argv.js +89 -12
  399. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  400. package/dist/tools/fs/shell-read-bindings.js +41 -0
  401. package/dist/tools/fs/shell-read-check.js +6 -19
  402. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  403. package/dist/tools/fs/shell-read-environment.js +3 -2
  404. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  405. package/dist/tools/fs/shell-read-establish.js +19 -20
  406. package/dist/tools/fs/shell-read-plan.js +24 -16
  407. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  408. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  409. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  410. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  411. package/dist/tools/fs/shell-reentry-text.js +40 -2
  412. package/dist/tools/todo.js +63 -63
  413. package/dist/tools/web.d.ts +19 -14
  414. package/dist/tools/web.js +38 -55
  415. package/package.json +1 -1
  416. package/test/export-surface.snapshot.json +143 -5
  417. package/wire-changes/core@7.56.0.json +3891 -0
  418. package/wire-changes/mods-kernel@7.56.0.json +303 -0
@@ -2,7 +2,6 @@ import { Type, type Static, type TSchema } from "typebox";
2
2
  import type { AgentTool } from "../internal/harness-types.js";
3
3
  import { type ReservedApprovalCard, type ToolApprovalCard, type ToolFamily, type ToolHostTarget, type ToolRosterPathTarget, type ToolMountTag, type ToolPathTarget, type ToolRenderHints, type ToolRuleFace } from "./tool-face.js";
4
4
  import type { ToolContentOrigin, ToolEffect } from "./tool-spec.js";
5
- import type { ToolMarkSource } from "./ask-origin.js";
6
5
  export declare const ROSTER_SOURCES: readonly ["builtin", "caller", "host", "mcp", "a2a", "external", "synthetic"];
7
6
  export type RosterSource = (typeof ROSTER_SOURCES)[number];
8
7
  export declare const ToolRosterRenderHints: Type.TObject<{
@@ -322,9 +321,11 @@ export declare function parkedToolIdentity(roster: ToolRoster | undefined, toolN
322
321
  /** design/388 B6 × B18 — the FACE members a park row carries beside its identity: the display family, the declared
323
322
  * path target or URL slot, and the names the parked call was judged under. `names` is copied from the face the gate stamped on the
324
323
  * request (the model's spelling first — the row carries the judged fact, it is not re-derived); a request with no face
325
- * takes the roster's names for its row. A recheck that runs before the leg's roster exists (the pre-CAS resume-edit
326
- * re-adjudication) rebuilds the call face from the row through {@link parkedCallFaceOf}, so it judges the same object
327
- * the live gate judged. An empty object when the name is not on the snapshot (the row then reads pre-face and the
324
+ * takes the roster's names for its row. The mount site (`engineMounted`) is the roster entry's, as the identity and face members
325
+ * beside it are: a fact of the tool, not of the call, and never read off the request's face, which the policy that judges the call
326
+ * can write. A recheck that runs before the leg's roster exists (the pre-CAS resume-edit
327
+ * re-adjudication) rebuilds the call face from the row through {@link parkedCallFaceOf}, so it judges the members the row
328
+ * recorded (identity, family, targets, names, mount site) — not the live face's rule name values or approval card. An empty object when the name is not on the snapshot (the row then reads pre-face and the
328
329
  * recheck falls to the catalog for the name). */
329
330
  export declare function parkedToolFace(roster: ToolRoster | undefined, req: {
330
331
  readonly toolName: string;
@@ -336,6 +337,7 @@ export declare function parkedToolFace(roster: ToolRoster | undefined, req: {
336
337
  pathTarget?: ToolRosterEntry["pathTarget"];
337
338
  hostTarget?: ToolHostTarget;
338
339
  names?: readonly string[];
340
+ engineMounted?: true;
339
341
  };
340
342
  /** The live face a resumed park row is re-judged under: minted under the row's recorded spelling (`names[0]`) when that
341
343
  * spelling still resolves to the row's own tool on this roster, else under the row's wire name — a spelling that no
@@ -356,6 +358,7 @@ export declare function parkedCallFaceOf(pending: {
356
358
  contractId?: string;
357
359
  shapeDigest?: string;
358
360
  implementationRevision?: string;
361
+ engineMounted?: true;
359
362
  }): import("./tool-policy.js").ToolCallFace | undefined;
360
363
  /** The optional `face` seat of a ToolCallRequest: present iff a face was read (a bare request carries no key). */
361
364
  export declare function callFaceSeat(face: import("./tool-policy.js").ToolCallFace | undefined): {
@@ -427,6 +430,8 @@ export declare function ruleFaceOfInstance(schema: TSchema | undefined, declared
427
430
  primaryParams: string[];
428
431
  params: string[];
429
432
  };
433
+ /** The instance `row` describes: what runs when a call is judged by that row. A row no snapshot minted has none. */
434
+ export declare function rowMember(row: ToolRosterEntry): AgentTool | undefined;
430
435
  /** The instance each NAME dispatches to when several are mounted under it: the LATER mount (the harness keeps the
431
436
  * later one). The one selection — the roster's snapshot and every table keyed by a caller tool's name read it here. */
432
437
  export declare function survivorsByName<T extends {
@@ -478,28 +483,18 @@ export interface RosterSnapshotFacts {
478
483
  /** `TaskSpec.memory.trustedTools` — the exemption channel for an undeclared content class. */
479
484
  trustedTools: ReadonlySet<string>;
480
485
  }
481
- /** The leg's per-name safety-axis tables the builder keeps aligned with its mounts beside the effect map (the safety scan mints
482
- * them; the protocol folds and the shell seat also write them). */
483
- export interface RosterAxisTables {
484
- irreversibilityTier: Map<string, "never" | "maybe" | "always">;
485
- irreversibleTools: Set<string>;
486
- reversibilityProbes: Map<string, unknown>;
487
- egressTools: Set<string>;
488
- toolMarkSources: Map<string, Set<ToolMarkSource>>;
489
- }
490
486
  export declare class RosterBuilder {
491
487
  #private;
492
- /** `axes` — the leg's safety-axis tables beside the effect map (a builder for a single probe tool may go without). */
493
- constructor(effects: Map<string, ToolEffect>, axes?: RosterAxisTables);
488
+ /** `effects` — the leg's by-name effect map, which the builder keeps equal to the mounted set's answering members. The leg's
489
+ * safety-axis tables are not the builder's: their marks live under the names they were laid on, and a call reads them under
490
+ * the names it answers to. */
491
+ constructor(effects: Map<string, ToolEffect>);
494
492
  /** The mount array as a READ face. The order is the wire order. */
495
493
  get tools(): readonly AgentTool[];
496
494
  get length(): number;
497
495
  metaOf(tool: AgentTool): RosterMountMeta | undefined;
498
496
  /** Mount one instance at the tail; the leg's effect map then follows the mounted set (`#settleEffects`). The later mount under
499
- * a name is the one the harness dispatches to (`snapshot`'s yield rule). A `scenario` mount (a caller's own `TaskSpec.tools`
500
- * entry, the driver's frozen face — the declaration the safety scan judged) leaves the three safety axes as the scan wrote them;
501
- * any other mount under a name displaces the instance there, and the axes of the aliases the displaced instance answered to
502
- * move to the member they now resolve to (`#resettleAliases`). */
497
+ * a name is the one the harness dispatches to (`snapshot`'s yield rule). */
503
498
  mount(tool: AgentTool, meta: RosterMountMeta): void;
504
499
  /** An ENGINE-INJECTED instance the harness list carries outside the mount array (the ToolSearch lane): a roster
505
500
  * row — the model can call it — never a mount-array element (the disclosure lane owns that list and appends the
@@ -140,7 +140,7 @@ export function parkedToolFace(roster, req) {
140
140
  if (e === undefined)
141
141
  return {};
142
142
  const judged = req.face?.names;
143
- return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}), ...(e.hostTarget !== undefined ? { hostTarget: e.hostTarget } : {}), names: judged !== undefined && judged.includes(req.toolName) ? [...judged] : namesResolvingTo(roster, e) };
143
+ return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}), ...(e.hostTarget !== undefined ? { hostTarget: e.hostTarget } : {}), names: judged !== undefined && judged.includes(req.toolName) ? [...judged] : namesResolvingTo(roster, e), ...(engineMountedRow(e) ? { engineMounted: true } : {}) };
144
144
  }
145
145
  export function parkedRowLiveFace(roster, row) {
146
146
  const spelled = row.names?.[0];
@@ -159,6 +159,7 @@ export function parkedCallFaceOf(pending) {
159
159
  contractId: pending.contractId,
160
160
  shapeDigest: pending.shapeDigest,
161
161
  implementationRevision: pending.implementationRevision,
162
+ ...(pending.engineMounted === true ? { engineMounted: true } : {}),
162
163
  };
163
164
  }
164
165
  export function callFaceSeat(face) {
@@ -305,6 +306,10 @@ function capRenderHints(h) {
305
306
  out.approvalCard = h.approvalCard;
306
307
  return Object.keys(out).length > 0 ? out : undefined;
307
308
  }
309
+ const ROW_MEMBERS = new WeakMap();
310
+ export function rowMember(row) {
311
+ return ROW_MEMBERS.get(row);
312
+ }
308
313
  export function survivorsByName(mounted) {
309
314
  const winner = new Map();
310
315
  for (const t of mounted)
@@ -313,18 +318,6 @@ export function survivorsByName(mounted) {
313
318
  }
314
319
  export const faceOf = (t) => t;
315
320
  const protocolFolded = (source) => source === "mcp" || source === "a2a";
316
- const setOrClear = (m, key, value) => {
317
- if (value === undefined)
318
- m.delete(key);
319
- else
320
- m.set(key, value);
321
- };
322
- const memberIf = (s, key, member) => {
323
- if (member)
324
- s.add(key);
325
- else
326
- s.delete(key);
327
- };
328
321
  function configError(code, message) {
329
322
  const e = new Error(message);
330
323
  e.code = code;
@@ -335,10 +328,8 @@ export class RosterBuilder {
335
328
  #engineLane = [];
336
329
  #meta = new WeakMap();
337
330
  #effects;
338
- #axes;
339
- constructor(effects, axes) {
331
+ constructor(effects) {
340
332
  this.#effects = effects;
341
- this.#axes = axes;
342
333
  }
343
334
  get tools() {
344
335
  return this.#tools;
@@ -356,10 +347,7 @@ export class RosterBuilder {
356
347
  const displaced = this.#survivorNamed(tool.name);
357
348
  this.#admit(tool, meta);
358
349
  lane.push(tool);
359
- const aliases = [...(displaced?.aliases ?? []), ...(tool.aliases ?? [])];
360
- if (meta.mountedBy !== "scenario")
361
- this.#resettleAliases(aliases);
362
- return [tool.name, ...aliases];
350
+ return [tool.name, ...(displaced?.aliases ?? []), ...(tool.aliases ?? [])];
363
351
  }
364
352
  mountEngineLane(tool, meta) {
365
353
  this.#settleEffects(this.#mountOne(tool, meta, this.#engineLane));
@@ -389,28 +377,6 @@ export class RosterBuilder {
389
377
  #survivorNamed(name) {
390
378
  return survivorsByName([...this.#tools, ...this.#engineLane]).get(name);
391
379
  }
392
- #resettleAliases(aliases) {
393
- if (aliases.length === 0)
394
- return;
395
- const answering = toolNameIndex([...survivorsByName([...this.#tools, ...this.#engineLane]).values()]);
396
- for (const a of new Set(aliases)) {
397
- const owner = answering(a);
398
- if (owner?.name === a)
399
- continue;
400
- this.#repoint(a, owner?.name);
401
- }
402
- }
403
- #repoint(key, from) {
404
- if (this.#axes === undefined)
405
- return;
406
- const pick = (m) => (from === undefined ? undefined : m.get(from));
407
- const marks = pick(this.#axes.toolMarkSources);
408
- setOrClear(this.#axes.irreversibilityTier, key, pick(this.#axes.irreversibilityTier));
409
- setOrClear(this.#axes.reversibilityProbes, key, pick(this.#axes.reversibilityProbes));
410
- setOrClear(this.#axes.toolMarkSources, key, marks === undefined ? undefined : new Set(marks));
411
- memberIf(this.#axes.irreversibleTools, key, from !== undefined && this.#axes.irreversibleTools.has(from));
412
- memberIf(this.#axes.egressTools, key, from !== undefined && this.#axes.egressTools.has(from));
413
- }
414
380
  mountAll(tools, meta) {
415
381
  this.#settleEffects(tools.flatMap((t) => this.#mountOne(t, meta, this.#tools)));
416
382
  }
@@ -424,7 +390,6 @@ export class RosterBuilder {
424
390
  }
425
391
  }
426
392
  this.#settleEffects(this.#namesAfterRemoval(removed));
427
- this.#resettleAliases(removed.flatMap((t) => t.aliases ?? []));
428
393
  return removed;
429
394
  }
430
395
  replaceAt(index, tool) {
@@ -465,7 +430,9 @@ export class RosterBuilder {
465
430
  emitted.add(t.name);
466
431
  const survivor = winner.get(t.name);
467
432
  const meta = this.#meta.get(survivor) ?? { source: "caller", mountedBy: "scenario" };
468
- entries.push(mintRosterEntry(survivor, meta, facts));
433
+ const row = mintRosterEntry(survivor, meta, facts);
434
+ ROW_MEMBERS.set(row, survivor);
435
+ entries.push(row);
469
436
  }
470
437
  const roster = { schemaVersion: 1, count: entries.length, entries, digest: rosterDigestOf(entries) };
471
438
  const worn = rosterEngineNamesProblem(roster);
@@ -1,6 +1,9 @@
1
+ import { assertNoRetiredKeys, RETIRED_TOOL_SPEC_KEYS } from "./retired-keys.js";
1
2
  import { UNREADABLE_LIST, snapshotToolNameList } from "./tool-name-list.js";
3
+ import { isCatalogContract } from "./tool-catalog-entries.js";
4
+ import { isEngineDescriptor } from "../prompt-assembly/tool-catalog.js";
2
5
  export const TOOL_SPEC_MEMBERS = Object.keys({
3
- name: true, aliases: true, description: true, descriptionClassic: true, label: true, parameters: true, execute: true, effect: true,
6
+ name: true, aliases: true, description: true, descriptionVariants: true, label: true, parameters: true, execute: true, effect: true,
4
7
  egress: true, irreversibility: true, reversibilityProbe: true, permissionSeat: true, isConcurrencySafe: true, executionMode: true,
5
8
  contentOrigin: true, offload: true, offloadThresholdChars: true, defer: true, alwaysLoad: true, prepareArguments: true,
6
9
  validateInput: true, approvalPreview: true, family: true, pathTarget: true, hostTarget: true, ruleFace: true, renderHints: true, compactable: true,
@@ -14,6 +17,7 @@ const FACE_PLACES = { elementKeys: FACE_LIST_KEYS };
14
17
  const MAX_NODES = 20_000;
15
18
  const MAX_DEPTH = 64;
16
19
  const COPIED = new WeakSet();
20
+ const isEngineMint = (value) => isCatalogContract(value) || isEngineDescriptor(value);
17
21
  class DeclarationRefused extends Error {
18
22
  }
19
23
  function refuse(path, why) {
@@ -46,7 +50,7 @@ function copyNode(value, path, depth, state, lenient, places) {
46
50
  return value;
47
51
  if (typeof value === "function")
48
52
  return lenient ? inertFunction() : refuse(path, "a function inside declaration data");
49
- if (COPIED.has(value))
53
+ if (COPIED.has(value) || isEngineMint(value))
50
54
  return value;
51
55
  const seen = lenient ? state.seenLenient : state.seen;
52
56
  const shared = seen.get(value);
@@ -158,6 +162,7 @@ export function frozenExtra(key, value, state) {
158
162
  }
159
163
  }
160
164
  export function frozenToolSpec(spec) {
165
+ assertNoRetiredKeys(spec, RETIRED_TOOL_SPEC_KEYS, "ToolSpec");
161
166
  const copy = {};
162
167
  const state = newCopyState();
163
168
  for (const name of TOOL_SPEC_MEMBERS) {
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import type { TSchema } from "typebox";
11
11
  import type { ThinkingLevel, ToolInputValidationContext, ToolInputVerdict } from "../internal/harness.js";
12
- import type { DocumentContent, ImageContent, Model, TextContent } from "../internal/llm.js";
12
+ import type { DocumentContent, ImageContent, Model, TextContent, ToolDescriptionVariant } from "../internal/llm.js";
13
13
  import type { AgentDefinition } from "./agent-definition.js";
14
14
  import type { TaskEvent } from "./task-event.js";
15
15
  import type { TaskSpec } from "./task-spec.js";
@@ -148,15 +148,18 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
148
148
  * across a canonical rename. Each alias keeps the same contract as {@link name} (a rule naming an alias reaches the tool).
149
149
  */
150
150
  aliases?: string[];
151
+ /** The model-facing description — the card's unconditional text: what the tool says when none of
152
+ * {@link descriptionVariants} holds. */
151
153
  description: string;
152
154
  /**
153
- * R2 双形轴(2026-07-18 裁):the CLASSIC-profile variant of {@link description}. The reference
154
- * keys its tool descriptions on `LT(model_id)` (simple short form vs classic long form); sema's
155
- * counterpart is {@link TaskSpec.promptProfile} — default "simple" (what CC serves every BYOM
156
- * model id). When the run resolves to "classic" and this field is present, it REPLACES
157
- * `description` at mount time. Absent = the tool has one form (description serves both profiles).
155
+ * The card's conditional variants, in order: at mount, the first whose `traits` condition holds over the run's
156
+ * prompt traits (`Model.promptTraits` with `TaskSpec.promptLean`) replaces {@link description}; none holds ⇒
157
+ * `description`. The reference keys its tool texts on the same capabilities (a long form where `lean_prompt` is
158
+ * absent): that form is a variant `{ id: "classic", traits: { noneOf: ["lean_prompt"] }, text }`. The chosen
159
+ * variant is reported in the tool's `cardId`. A variant whose id, condition or text is malformed refuses the task
160
+ * (`config.tool_face_invalid`).
158
161
  */
159
- descriptionClassic?: string;
162
+ descriptionVariants?: readonly ToolDescriptionVariant[];
160
163
  /**
161
164
  * Human label for UIs. Defaults to `name`. When it differs from `name`, it rides the call's `tool_start` and `tool_end`
162
165
  * frames as `label` (the run builds the table from the leg's mounted tools) — the advisor tool's label is its advisor
@@ -816,6 +819,10 @@ export interface ToolExecuteContext {
816
819
  * the tool runs outside a Runner task.
817
820
  */
818
821
  parentCwd?: string;
822
+ /** The deployment's compiled host floor (`RunnerDeps.hostFloor`; Runner-filled, read-only, never a model argument): an engine executor
823
+ * that connects — the fetch tool on every hop, WebSearch's SearXNG backend (handed it in the backend's `opts.hostFloor`) — judges each URL
824
+ * by it before the request. Absent outside a Runner, or when none is declared. */
825
+ hostFloor?: import("./host-floor.js").HostFloor;
819
826
  /**
820
827
  * The RUNNING task's file-history LINEAGE (Runner-filled, read-only, never a model/tool argument;
821
828
  * present iff the run records file history — a `RunnerDeps.fileHistoryStore` wired, capture not `"off"`, not `"disabled"`): the history scope this run
@@ -1068,10 +1075,11 @@ export interface ToolExecuteContext {
1068
1075
  * dropping the selector in transit would trim a same-model child's roster in a way nobody
1069
1076
  * chose (the gate is a default, not a policy; there is no tighten-only axis to protect). */
1070
1077
  restoreGatedTools?: readonly string[] | true;
1071
- /** R2 双形轴 — the parent's resolved prompt profile, inherited down the delegation tree like the
1072
- * tool-face controls (Runner-filled): a classic-profile parent's children speak classic too
1073
- * unless the child spec says otherwise (child spec wins — profile is presentation, not policy). */
1074
- promptProfile?: "simple" | "classic";
1078
+ /** The parent's task-level switch on the lean shape ({@link TaskSpec.promptLean} — its own, or the one it inherited;
1079
+ * absent when neither was written), inherited down the delegation tree like the tool-face controls
1080
+ * (Runner-filled): a child whose spec writes none takes it. Never the parent's effective traits — the child's model
1081
+ * answers the rest of its own trait set. */
1082
+ promptLean?: boolean;
1075
1083
  /**
1076
1084
  * The parent SPEC seat this run hands its children ({@link import("./parent-spec-seat.js").ParentSpecSeat}):
1077
1085
  * `principal`, `oneShot` (only `true`), `clientContext` (the user's TZ/email facts), `onQuestion` (the FROZEN
@@ -3,13 +3,53 @@ import { formatToolError, formatZodValidationError } from "./tool-errors.js";
3
3
  import { readMember } from "./thrown-value.js";
4
4
  import { frozenToolSpec } from "./tool-spec-members.js";
5
5
  import { carryDelegationName } from "./delegation-name.js";
6
- import { attachToolContract, contractOriginOf } from "../prompt-assembly/tool-catalog.js";
7
- function normalizeContent(ret) {
6
+ import { attachEngineToolContract, attachToolContract, contractOriginOf } from "../prompt-assembly/tool-catalog.js";
7
+ import { isCatalogContract } from "./tool-catalog-entries.js";
8
+ import { types } from "node:util";
9
+ import { appendOwn, dataMember, isPlainRecord, receive } from "./mods/kernel/receive.js";
10
+ import { carryNotStartedReceipt } from "./delegation-not-started.js";
11
+ const TOOL_DATA_MODE = Object.freeze({ accessors: "call-once", depth: Infinity, others: "copy", contain: true, wire: true, isProxy: (v) => types.isProxy(v) });
12
+ function receivedData(v) {
13
+ if (v === null || v === undefined || typeof v === "string" || typeof v === "number" || typeof v === "boolean")
14
+ return v;
15
+ const r = receive(v, TOOL_DATA_MODE);
16
+ if (!r.ok)
17
+ return undefined;
18
+ carryNotStartedReceipt(v, r.value);
19
+ return r.value;
20
+ }
21
+ const CONTENT_BLOCK_FIELDS = Object.freeze({ text: ["text"], image: ["data", "mimeType"], document: ["data", "mimeType"] });
22
+ function blockOf(element) {
23
+ if (!isPlainRecord(element))
24
+ return element;
25
+ const own = (field) => (Object.hasOwn(element, field) ? element[field] : undefined);
26
+ const type = own("type");
27
+ const fields = typeof type === "string" && Object.hasOwn(CONTENT_BLOCK_FIELDS, type) ? CONTENT_BLOCK_FIELDS[type] : undefined;
28
+ if (fields === undefined)
29
+ return element;
30
+ const block = { type };
31
+ for (const field of fields)
32
+ if (own(field) !== undefined)
33
+ Reflect.defineProperty(block, field, dataMember(own(field)));
34
+ return block;
35
+ }
36
+ function receivedContent(raw) {
37
+ const copy = receivedData(raw);
38
+ if (!Array.isArray(copy))
39
+ return undefined;
40
+ const out = [];
41
+ for (let i = 0; i < copy.length; i++)
42
+ if (Object.hasOwn(copy, i) && copy[i] !== undefined)
43
+ appendOwn(out, blockOf(copy[i]));
44
+ return out;
45
+ }
46
+ function receiveToolReturn(ret) {
8
47
  if (typeof ret === "string") {
9
48
  return { content: [{ type: "text", text: ret }], details: undefined, terminate: false, isError: false };
10
49
  }
11
50
  const raw = readMember(ret, "content");
12
- if (typeof raw !== "string" && !Array.isArray(raw)) {
51
+ const content = typeof raw === "string" ? [{ type: "text", text: raw }] : receivedContent(raw);
52
+ if (content === undefined) {
13
53
  return {
14
54
  content: [{ type: "text", text: "Tool error: content must be a string or an array of content blocks." }],
15
55
  details: undefined,
@@ -17,8 +57,7 @@ function normalizeContent(ret) {
17
57
  isError: true,
18
58
  };
19
59
  }
20
- const content = typeof raw === "string" ? [{ type: "text", text: raw }] : raw;
21
- return { content, details: readMember(ret, "details"), terminate: readMember(ret, "terminate") === true, isError: readMember(ret, "isError") === true };
60
+ return { content: content, details: receivedData(readMember(ret, "details")), terminate: readMember(ret, "terminate") === true, isError: readMember(ret, "isError") === true };
22
61
  }
23
62
  function isEmptyToolContent(content) {
24
63
  if (content.length === 0)
@@ -78,7 +117,7 @@ function buildProduct(spec, owner, options) {
78
117
  name: spec.name,
79
118
  ...(spec.aliases && spec.aliases.length > 0 ? { aliases: [...spec.aliases] } : {}),
80
119
  description: spec.description,
81
- ...(spec.descriptionClassic !== undefined ? { descriptionClassic: spec.descriptionClassic } : {}),
120
+ ...(spec.descriptionVariants !== undefined ? { descriptionVariants: spec.descriptionVariants } : {}),
82
121
  label: spec.label ?? spec.name,
83
122
  parameters: spec.parameters,
84
123
  executionMode,
@@ -121,7 +160,7 @@ function buildProduct(spec, owner, options) {
121
160
  const baseCtx = { toolCallId, signal };
122
161
  const ctx = options?.enrichCtx ? stampCallIdentity(options.enrichCtx(baseCtx), toolCallId, signal) : baseCtx;
123
162
  const ret = await spec.execute.call(owner, params, ctx);
124
- const { content, details, terminate, isError } = normalizeContent(ret);
163
+ const { content, details, terminate, isError } = receiveToolReturn(ret);
125
164
  const guarded = isEmptyToolContent(content)
126
165
  ? [{ type: "text", text: isError ? `(${spec.name} reported an error with no further output)` : `(${spec.name} completed with no output)` }]
127
166
  : content;
@@ -129,7 +168,7 @@ function buildProduct(spec, owner, options) {
129
168
  }
130
169
  catch (err) {
131
170
  const wrapped = new Error(formatToolError(err));
132
- const marks = readMember(err, "details");
171
+ const marks = receivedData(readMember(err, "details"));
133
172
  if (marks !== undefined)
134
173
  wrapped.details = marks;
135
174
  const errorKind = readMember(err, "errorKind");
@@ -141,7 +180,8 @@ function buildProduct(spec, owner, options) {
141
180
  };
142
181
  carryDelegationName(spec.execute, tool.execute);
143
182
  if (spec.contract) {
144
- attachToolContract(tool, {
183
+ const attach = isCatalogContract(spec.contract) ? attachEngineToolContract : attachToolContract;
184
+ attach(tool, {
145
185
  contractId: spec.contract.contractId,
146
186
  implementationRevision: spec.contract.implementationRevision,
147
187
  origin: contractOriginOf(spec.contract.contractId),
@@ -148,7 +148,7 @@ export type TraceEvent = {
148
148
  */
149
149
  tools?: ToolManifestRow[];
150
150
  totalChars: number;
151
- /** design/148 S3 (additive, §10.2): the nine-element cache identity — digests only. */
151
+ /** design/148 S3 (additive, §10.2): the eight-element cache identity — digests only. */
152
152
  snapshot?: {
153
153
  cacheIdentity: string;
154
154
  elements: import("../prompt-assembly/turn-snapshot.js").CacheIdentityElements;
@@ -226,7 +226,7 @@ export type TraceEvent = {
226
226
  * tier. Absent on every reasoning-capable resolution (old consumers see identical frames).
227
227
  */
228
228
  dropped?: true;
229
- /** design/148 S3 (additive, §10.2): the nine-element cache identity — digests only. */
229
+ /** design/148 S3 (additive, §10.2): the eight-element cache identity — digests only. */
230
230
  snapshot?: {
231
231
  cacheIdentity: string;
232
232
  elements: Record<string, string>;
@@ -23,7 +23,7 @@ export { DECLARATION_PATH_RULES, NO_DECLARATION_PATH_RULES, dataKind, declaratio
23
23
  export type { TaskLimits } from "./task-limits.js";
24
24
  export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
25
25
  export type { TerminalCause, PausedCause } from "./terminal-cause.js";
26
- export type { TaskEventIdentity, BrainStatusPhase, BrainRetryErrClass, BrainStatus, ToolActivity, HumanInputSource, HumanInputDelivery, DelegationTaskType, TaskEvent, HumanInputEvent, HumanInputAttachment, CompactOutcome } from "./task-event.js";
26
+ export type { TaskEventIdentity, BrainStatusPhase, BrainRetryErrClass, BrainStatus, ToolActivity, HumanInputSource, HumanInputDelivery, DelegationTaskType, TaskEvent, HumanInputEvent, HumanInputAttachment, CompactOutcome, ExtensionRequester } from "./task-event.js";
27
27
  export type { TaskStream } from "./task-stream.js";
28
28
  export type { WorkflowGovernanceBaseline, RuntimeCaps, AutoModeDenySource } from "./runtime-caps.js";
29
29
  export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
@@ -30,6 +30,7 @@ import { type ReminderDisclosureCounts } from "./reminder-disclosure.js";
30
30
  import { type AgentMessage } from "../internal/harness.js";
31
31
  import type { ReadEntry } from "../tools/fs/safety.js";
32
32
  import type { ContextWindowOverlay } from "./context-settings.js";
33
+ import { type LegModBus } from "./mods/stations.js";
33
34
  /** At most this many attachments on one objective. */
34
35
  export declare const USER_ATTACHMENTS_MAX = 20;
35
36
  /** The longest path or name an entry may carry (the platform path limit). */
@@ -148,6 +149,12 @@ export interface ReadUserAttachmentsInput {
148
149
  mark: string | undefined;
149
150
  counts: ReminderDisclosureCounts | undefined;
150
151
  signal: AbortSignal;
152
+ /** The leg's bus, where `prompt.mention` is raised for each attachment (absent ⇒ none is raised), and the delegated
153
+ * leg's id its events carry. */
154
+ mentions?: {
155
+ readonly bus: LegModBus;
156
+ readonly agentId?: string;
157
+ };
151
158
  }
152
159
  /**
153
160
  * Read every declared attachment and mint its frame. Side-effect free toward the run: nothing is committed here — each
@@ -165,7 +172,7 @@ export interface AttachmentWindowInput {
165
172
  /** The objective lane's read: once the UserPromptSubmit hook let the objective through (a blocked objective reads
166
173
  * nothing), and before the pre-call gate, which prices the frames (`chars`). Refuses the whole objective when the frames
167
174
  * and the objective cannot ride one request ({@link refuseFramesOverWindow}). Commits nothing. */
168
- export declare function readObjectiveAttachments(prepared: Pick<import("./runner/contracts.js").Prepared, "userAttachments" | "modelFileReader" | "syntheticReadVerdict" | "cwdRef" | "reminderMark" | "reminderDisclosureCounts" | "abortController" | "harness">, inputId: string, blocked: boolean, window: AttachmentWindowInput): Promise<{
175
+ export declare function readObjectiveAttachments(prepared: Pick<import("./runner/contracts.js").Prepared, "userAttachments" | "modelFileReader" | "syntheticReadVerdict" | "cwdRef" | "reminderMark" | "reminderDisclosureCounts" | "abortController" | "harness" | "modBus" | "hookIdentity">, inputId: string, blocked: boolean, window: AttachmentWindowInput): Promise<{
169
176
  frames: MintedAttachmentFrame[];
170
177
  chars: number;
171
178
  }>;
@@ -10,6 +10,8 @@ import { commitReminderDisclosureEffects, planReminderDisclosure } from "./remin
10
10
  import { DEFAULT_CHARS_PER_TOKEN, estimateTokens, uuidv7 } from "../internal/harness.js";
11
11
  import { thrownText } from "./thrown-value.js";
12
12
  import { guardBudget } from "./context-guard.js";
13
+ import { agentIdOf, failedHandlerClause } from "./mods/stations.js";
14
+ import { extensionWords } from "./untrusted-egress.js";
13
15
  export const USER_ATTACHMENTS_MAX = 20;
14
16
  export const USER_ATTACHMENT_LABEL_MAX = 4096;
15
17
  export const USER_ATTACHMENT_KINDS = Object.freeze(["text", "notebook", "image", "pdf", "directory", "client_text", "client_image"]);
@@ -142,9 +144,12 @@ export function refuseUserAttachmentPathsWithoutWorkspace(screened) {
142
144
  throw userAttachmentRefusal(memberRef(entryRef(i), "path"), "this run has no workspace (its hand tools are off), so the engine has no file to read — send the file's bytes as a `text` or `image` entry instead.");
143
145
  }
144
146
  export function userAttachmentDeclarations(screened) {
145
- return screened.map((a, i) => a.supply === "path"
146
- ? { ordinal: i + 1, supply: a.supply, path: a.path }
147
- : { ordinal: i + 1, supply: a.supply, name: a.name, bytes: a.supply === "content_text" ? Buffer.byteLength(a.text, "utf8") : Buffer.from(a.data, "base64").byteLength });
147
+ return screened.map((a, i) => declarationOf(a, i + 1));
148
+ }
149
+ function declarationOf(a, ordinal) {
150
+ return a.supply === "path"
151
+ ? { ordinal, supply: a.supply, path: a.path }
152
+ : { ordinal, supply: a.supply, name: a.name, bytes: a.supply === "content_text" ? Buffer.byteLength(a.text, "utf8") : Buffer.from(a.data, "base64").byteLength };
148
153
  }
149
154
  export async function admitUserAttachmentImages(screened) {
150
155
  const out = new Map();
@@ -218,6 +223,8 @@ function noteSentence(note, origin) {
218
223
  return "The listing was cut short, so it is incomplete.";
219
224
  case "too_large_to_restore":
220
225
  return "The file was read before the conversation was summarized, but its contents are too large to include here. Use the Read tool if you need them.";
226
+ case "extension_declined":
227
+ return "An extension of this deployment did not let this attachment through, so its contents were not attached; what it said is stated above.";
221
228
  }
222
229
  }
223
230
  function disclosureSentence(v) {
@@ -290,13 +297,65 @@ export async function readUserAttachments(input) {
290
297
  const count = input.screened.length;
291
298
  const seat = disclosureSeatOf(input.reader, input.mark, input.counts);
292
299
  const frames = [];
300
+ const mentions = input.mentions !== undefined && input.mentions.bus.hasHandlers("prompt.mention") ? input.mentions : undefined;
293
301
  for (const [i, a] of input.screened.entries()) {
294
302
  const ordinal = i + 1;
295
- const r = await readOne(a, ordinal, input);
303
+ const r = mentions !== undefined ? await readMentioned(a, ordinal, input, mentions) : await readOne(a, ordinal, input);
296
304
  frames.push(mintFrame(r, { inputId: input.inputId, ordinal, count, mark: input.mark, origin: "user" }, seat));
297
305
  }
298
306
  return frames;
299
307
  }
308
+ const declineOf = (x) => isPlainObject(x) && Object.keys(x).length === 1 && ((typeof x["deny"] === "string" && x["deny"] !== "") || (Object.hasOwn(x, "type") && x["type"] === null))
309
+ ? typeof x["deny"] === "string" ? { reason: x["deny"] } : {}
310
+ : undefined;
311
+ async function readMentioned(a, ordinal, input, mentions) {
312
+ const label = a.supply === "path" ? a.path : a.name;
313
+ const declined = (text) => ({ supply: a.supply, label, outcome: "not_attached", shape: "file", data: [{ type: "text", text }], notes: [{ kind: "extension_declined" }], unscanned: [label, text], truncated: false });
314
+ const window = a.supply === "path" && a.lines !== undefined ? { offset: a.lines.start, ...(a.lines.end !== undefined ? { limit: a.lines.end - a.lines.start + 1 } : {}) } : {};
315
+ const e = { mention: declarationOf(a, ordinal), ...(mentions.agentId !== undefined ? { agentId: mentions.agentId } : {}), ...(a.supply === "path" ? { path: a.path, ...window } : {}) };
316
+ const reads = new Map();
317
+ const bottom = async (handed) => {
318
+ const spelled = respelled(a, handed);
319
+ const read = typeof spelled === "string" ? declined(`Not attached: ${spelled}.`) : await readOne(spelled, ordinal, input);
320
+ const answer = Object.freeze({ type: read.outcome === "not_attached" ? null : (read.kind ?? null), outcome: read.outcome });
321
+ reads.set(answer, read);
322
+ return answer;
323
+ };
324
+ let outcome;
325
+ try {
326
+ outcome = await mentions.bus.dispatch("prompt.mention", e, {
327
+ bottom,
328
+ signal: input.signal,
329
+ checkAnswer: (x) => (typeof x === "object" && x !== null && reads.has(x)) || declineOf(x) !== undefined ? undefined : "prompt.mention takes next(e), { deny: <reason> } or { type: null } — an extension does not supply an attachment's contents",
330
+ ranks: { of: (x) => (typeof x === "object" && x !== null && reads.has(x) ? 0 : 1), top: 1 },
331
+ });
332
+ }
333
+ catch (err) {
334
+ outcome = { kind: "failed", registration: "engine", cause: "threw", reason: `could not raise the station: ${thrownText(err)}`, skipped: [] };
335
+ }
336
+ if (outcome.kind === "aborted")
337
+ return declined("Not attached: the run was cancelled while an extension was judging it.");
338
+ if (outcome.kind === "failed")
339
+ return declined(`Not attached: a prompt.mention extension ${failedHandlerClause(outcome)}.`);
340
+ const read = typeof outcome.answer === "object" && outcome.answer !== null ? reads.get(outcome.answer) : undefined;
341
+ if (read !== undefined)
342
+ return read;
343
+ const reason = declineOf(outcome.answer)?.reason;
344
+ return declined(`Not attached: extension "${extensionWords(outcome.answeredBy ?? "engine", 80)}" declined it${reason !== undefined ? `: ${extensionWords(reason, 300)}` : ""}.`);
345
+ }
346
+ function respelled(a, handed) {
347
+ if (a.supply !== "path") {
348
+ return ["path", "offset", "limit"].some((k) => Object.hasOwn(handed, k)) ? "an extension handed down a path or line window for an attachment the host supplied (its bytes are its own; nothing is read)" : a;
349
+ }
350
+ const { path, offset, limit } = handed;
351
+ const line = (v) => v === undefined || (typeof v === "number" && Number.isInteger(v) && v >= 1);
352
+ if (typeof path !== "string" || path === "" || path.length > USER_ATTACHMENT_LABEL_MAX)
353
+ return "an extension handed down a path that is not one";
354
+ if (!line(offset) || !line(limit))
355
+ return "an extension handed down a line window that is not one (offset and limit are whole numbers from 1)";
356
+ const start = typeof offset === "number" ? offset : typeof limit === "number" ? 1 : undefined;
357
+ return start === undefined ? { supply: "path", path } : { supply: "path", path, lines: { start, ...(typeof limit === "number" ? { end: start + limit - 1 } : {}) } };
358
+ }
300
359
  const refusalData = (r) => {
301
360
  const c = r.refusal?.content;
302
361
  return typeof c === "string" && c.length > 0 ? [{ type: "text", text: c }] : [];
@@ -439,6 +498,7 @@ export async function readObjectiveAttachments(prepared, inputId, blocked, windo
439
498
  mark: prepared.reminderMark,
440
499
  counts: prepared.reminderDisclosureCounts,
441
500
  signal: prepared.abortController.signal,
501
+ mentions: { bus: prepared.modBus, ...(agentIdOf(prepared.hookIdentity) !== undefined ? { agentId: agentIdOf(prepared.hookIdentity) } : {}) },
442
502
  });
443
503
  refuseFramesOverWindow(frames, prepared.harness.getModel(), window);
444
504
  return { frames, chars: frames.reduce((n, f) => n + f.seed.content.reduce((m, b) => m + (b.type === "text" ? b.text.length : 0), 0), 0) };
@@ -496,6 +496,13 @@ export interface WiringManifest {
496
496
  sessionRules?: {
497
497
  childrenReadLive: boolean;
498
498
  };
499
+ /**
500
+ * EFFECTIVE half only; present ⇔ the deployment declared a host floor (`RunnerDeps.hostFloor`): its POSTURE — whether an `only` list
501
+ * bounds what is reachable (`onlyMode`; `onlyCount: 0` with it = no structured egress at all) and how many entries each list holds.
502
+ * Deliberately not the entries' text (deployment-supplied hosts, the {@link WiringManifest.readDeny} class). IN the fingerprint: the
503
+ * declaration is the deployment's, so legs of one assembly agree.
504
+ */
505
+ hostFloor?: import("./host-floor.js").HostFloorPosture;
499
506
  /**
500
507
  * EFFECTIVE half only — the advisor tool on this leg, as the leg STARTED (a snapshot: a switch-off that lands later in the
501
508
  * leg is not in it; a host reads the conversation's current state off the transcript, `advisorHoldOf`). Present ⇔ the leg's
@@ -612,6 +619,8 @@ export interface WiringFacts {
612
619
  sessionRulesChildrenReadLive?: boolean;
613
620
  /** Effective half only — the advisor phase's answer ({@link WiringManifest.advisor}), relayed, never re-derived. */
614
621
  advisor?: WiringAdvisorFact;
622
+ /** Effective half only — the compiled host floor's posture ({@link WiringManifest.hostFloor}); absent ⇒ none declared. */
623
+ hostFloor?: import("./host-floor.js").HostFloorPosture;
615
624
  }
616
625
  /** {@link WiringManifest.advisor}. */
617
626
  export interface WiringAdvisorFact {
@@ -228,6 +228,7 @@ export function deriveWiringManifest(facts) {
228
228
  ...(facts.half === "effective" && facts.projectMemory !== undefined ? { projectMemory: readWordFact(facts.projectMemory, ["on", "disabled", "absent"], "project-memory") } : {}),
229
229
  ...(facts.half === "effective" && facts.sessionRulesChildrenReadLive !== undefined ? { sessionRules: readSessionRulesFact(facts.sessionRulesChildrenReadLive) } : {}),
230
230
  ...(facts.half === "effective" && facts.advisor !== undefined ? { advisor: { ...facts.advisor, ...(facts.advisor.hold !== undefined ? { hold: { ...facts.advisor.hold } } : {}) } } : {}),
231
+ ...(facts.half === "effective" && facts.hostFloor !== undefined ? { hostFloor: { onlyMode: facts.hostFloor.onlyMode, denyCount: facts.hostFloor.denyCount, onlyCount: facts.hostFloor.onlyCount } } : {}),
231
232
  ...(facts.half === "effective" && facts.teamRole !== undefined ? { teamRole: facts.teamRole } : {}),
232
233
  ...(facts.half === "effective" && facts.peerPresence !== undefined && (facts.peerPresence.agent !== undefined || facts.peerPresence.intent !== undefined)
233
234
  ? { peerPresence: { ...(facts.peerPresence.agent !== undefined ? { agent: facts.peerPresence.agent } : {}), ...(facts.peerPresence.intent !== undefined ? { intent: facts.peerPresence.intent } : {}) } }
@@ -102,7 +102,7 @@ export function journalOversizeTombstone(result, bytes) {
102
102
  taskId: result.taskId,
103
103
  sessionId: result.sessionId,
104
104
  terminal: { kind: "failed", code: JOURNAL_OVERSIZE_ERROR_CODE, message },
105
- result: message,
105
+ result: message, resultEntryIds: [],
106
106
  stats: result.stats,
107
107
  };
108
108
  }