@sema-agent/core 7.55.0 → 7.57.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 (502) hide show
  1. package/CHANGELOG.md +1054 -0
  2. package/LICENSE +1 -1
  3. package/dist/agents/cascade.js +1 -1
  4. package/dist/agents/cc-peer-directory.js +1 -0
  5. package/dist/agents/child-model-seat.d.ts +0 -11
  6. package/dist/agents/child-model-seat.js +0 -3
  7. package/dist/agents/list-agents-tool.d.ts +3 -1
  8. package/dist/agents/list-agents-tool.js +7 -7
  9. package/dist/agents/org-delivery-gate.js +3 -4
  10. package/dist/agents/peer-directory.d.ts +22 -4
  11. package/dist/agents/peer-directory.js +24 -2
  12. package/dist/agents/peer-held-queue.d.ts +69 -49
  13. package/dist/agents/peer-held-queue.js +255 -106
  14. package/dist/agents/peer-session-drain.js +65 -45
  15. package/dist/agents/repair-loop.js +2 -2
  16. package/dist/agents/send-message-tool.js +7 -6
  17. package/dist/agents/subagent.d.ts +6 -4
  18. package/dist/agents/subagent.js +72 -68
  19. package/dist/agents/tool-filter.d.ts +7 -5
  20. package/dist/agents/tool-filter.js +12 -9
  21. package/dist/agents/verify.d.ts +3 -2
  22. package/dist/agents/verify.js +3 -3
  23. package/dist/brain/anthropic.js +45 -80
  24. package/dist/brain/media-degrade.d.ts +18 -7
  25. package/dist/brain/media-degrade.js +13 -2
  26. package/dist/brain/model-capability.d.ts +37 -0
  27. package/dist/brain/model-capability.js +34 -0
  28. package/dist/brain/model-presets.d.ts +2 -8
  29. package/dist/brain/model-presets.js +1 -6
  30. package/dist/brain/open-responses.js +23 -34
  31. package/dist/brain/openai.js +25 -96
  32. package/dist/brain/provider-dialect.d.ts +3 -2
  33. package/dist/brain/provider-dialect.js +2 -2
  34. package/dist/brain/reasoning-request.d.ts +96 -0
  35. package/dist/brain/reasoning-request.js +174 -0
  36. package/dist/brain/reasoning.d.ts +11 -11
  37. package/dist/brain/reasoning.js +4 -3
  38. package/dist/brain/request-params.d.ts +13 -4
  39. package/dist/brain/request-params.js +21 -5
  40. package/dist/brain/status-sink.d.ts +20 -0
  41. package/dist/brain/status-sink.js +7 -0
  42. package/dist/brain/stream-engine.d.ts +9 -0
  43. package/dist/brain/stream-engine.js +24 -10
  44. package/dist/brain/stream-shared.d.ts +5 -4
  45. package/dist/brain/stream-shared.js +4 -4
  46. package/dist/core/a2a.d.ts +2 -1
  47. package/dist/core/a2a.js +19 -13
  48. package/dist/core/agent-definition.d.ts +10 -0
  49. package/dist/core/allow-entry.d.ts +23 -23
  50. package/dist/core/allow-entry.js +42 -46
  51. package/dist/core/allow-rule-shadow.d.ts +3 -3
  52. package/dist/core/approval-object.d.ts +21 -5
  53. package/dist/core/approval-object.js +44 -17
  54. package/dist/core/ask-origin.d.ts +66 -20
  55. package/dist/core/ask-origin.js +63 -23
  56. package/dist/core/ask-question.d.ts +51 -8
  57. package/dist/core/ask-question.js +3 -4
  58. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  59. package/dist/core/ask-unresolvable-notice.js +16 -2
  60. package/dist/core/auto-compaction.d.ts +71 -6
  61. package/dist/core/auto-compaction.js +42 -26
  62. package/dist/core/background-agent-store.d.ts +6 -2
  63. package/dist/core/background-agent-store.js +1 -1
  64. package/dist/core/checkpoint-generation.d.ts +53 -0
  65. package/dist/core/checkpoint-generation.js +35 -0
  66. package/dist/core/checkpoint-queries.d.ts +180 -0
  67. package/dist/core/checkpoint-queries.js +272 -0
  68. package/dist/core/checkpoint-requirements.d.ts +19 -1
  69. package/dist/core/checkpoint-requirements.js +6 -0
  70. package/dist/core/checkpoint-store.d.ts +105 -53
  71. package/dist/core/checkpoint-store.js +43 -20
  72. package/dist/core/cross-boundary-taint.d.ts +6 -5
  73. package/dist/core/cross-boundary-taint.js +5 -5
  74. package/dist/core/decision-receipt.d.ts +37 -3
  75. package/dist/core/decision-receipt.js +17 -17
  76. package/dist/core/delegation-not-started.d.ts +6 -0
  77. package/dist/core/delegation-not-started.js +17 -0
  78. package/dist/core/engine-attestation.d.ts +93 -0
  79. package/dist/core/engine-attestation.js +70 -0
  80. package/dist/core/engine-capabilities.d.ts +4 -1
  81. package/dist/core/engine-capabilities.js +1 -1
  82. package/dist/core/engine-notice.d.ts +32 -12
  83. package/dist/core/engine-notice.js +6 -0
  84. package/dist/core/file-history-store.d.ts +104 -22
  85. package/dist/core/file-history-store.js +37 -19
  86. package/dist/core/gate-fold.d.ts +1 -1
  87. package/dist/core/gate-fold.js +22 -10
  88. package/dist/core/gate-lanes.js +73 -65
  89. package/dist/core/gate-outcome.d.ts +26 -5
  90. package/dist/core/gate-outcome.js +26 -0
  91. package/dist/core/governance-codes.d.ts +5 -1
  92. package/dist/core/governance-codes.js +6 -0
  93. package/dist/core/hooks.d.ts +19 -18
  94. package/dist/core/hooks.js +3 -1
  95. package/dist/core/host-floor.d.ts +128 -0
  96. package/dist/core/host-floor.js +206 -0
  97. package/dist/core/host-target.d.ts +38 -3
  98. package/dist/core/host-target.js +38 -5
  99. package/dist/core/mailbox-store.d.ts +62 -1
  100. package/dist/core/mailbox-store.js +59 -0
  101. package/dist/core/mcp-name-judge.d.ts +46 -0
  102. package/dist/core/mcp-name-judge.js +61 -0
  103. package/dist/core/mcp-probe.d.ts +1 -1
  104. package/dist/core/mcp-probe.js +2 -5
  105. package/dist/core/mcp.d.ts +5 -1
  106. package/dist/core/mcp.js +70 -64
  107. package/dist/core/memory-engine/consolidation-driver.js +4 -3
  108. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  109. package/dist/core/memory-engine/distiller.js +26 -17
  110. package/dist/core/memory-engine/engine.js +4 -4
  111. package/dist/core/memory-engine/layout.d.ts +60 -8
  112. package/dist/core/memory-engine/layout.js +70 -8
  113. package/dist/core/model-seat.d.ts +10 -3
  114. package/dist/core/mods/classic-events.d.ts +67 -0
  115. package/dist/core/mods/classic-events.js +1 -0
  116. package/dist/core/mods/dollar.d.ts +13 -0
  117. package/dist/core/mods/extension-call.d.ts +31 -0
  118. package/dist/core/mods/extension-call.js +43 -0
  119. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  120. package/dist/core/mods/kernel/dispatch.js +140 -69
  121. package/dist/core/mods/kernel/events.d.ts +47 -11
  122. package/dist/core/mods/kernel/events.js +66 -42
  123. package/dist/core/mods/kernel/index.d.ts +4 -4
  124. package/dist/core/mods/kernel/index.js +2 -2
  125. package/dist/core/mods/kernel/receive.d.ts +39 -5
  126. package/dist/core/mods/kernel/receive.js +290 -17
  127. package/dist/core/mods/kernel/registration.d.ts +33 -2
  128. package/dist/core/mods/kernel/registration.js +6 -7
  129. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  130. package/dist/core/mods/kernel/site-rules.js +24 -42
  131. package/dist/core/mods/spec-seats.d.ts +69 -0
  132. package/dist/core/mods/spec-seats.js +114 -0
  133. package/dist/core/mods/stations.d.ts +28 -8
  134. package/dist/core/mods/stations.js +29 -13
  135. package/dist/core/mods/tool-call.d.ts +79 -0
  136. package/dist/core/mods/tool-call.js +152 -0
  137. package/dist/core/namespaced-rule-name.d.ts +32 -38
  138. package/dist/core/namespaced-rule-name.js +29 -36
  139. package/dist/core/parent-spec-seat.d.ts +6 -1
  140. package/dist/core/parent-spec-seat.js +2 -0
  141. package/dist/core/park-selfcheck.js +3 -0
  142. package/dist/core/permission-rule-consent.d.ts +24 -3
  143. package/dist/core/permission-rule-consent.js +136 -41
  144. package/dist/core/permission-rule-model.d.ts +57 -5
  145. package/dist/core/permission-rule-model.js +90 -31
  146. package/dist/core/permission-rule-org.d.ts +6 -2
  147. package/dist/core/permission-rule-org.js +8 -4
  148. package/dist/core/permission-rule-provider.d.ts +5 -2
  149. package/dist/core/permission-rule-provider.js +41 -11
  150. package/dist/core/permission-rule-store.d.ts +3 -2
  151. package/dist/core/permission-rule-store.js +11 -2
  152. package/dist/core/permission-rule-sync.js +3 -2
  153. package/dist/core/permission-rule-syntax.d.ts +5 -4
  154. package/dist/core/permission-rule-syntax.js +2 -2
  155. package/dist/core/permission-rules.d.ts +4 -4
  156. package/dist/core/permission-rules.js +11 -20
  157. package/dist/core/persisted-rule-arms.d.ts +2 -2
  158. package/dist/core/persisted-rule-arms.js +10 -12
  159. package/dist/core/principal-name.d.ts +20 -0
  160. package/dist/core/principal-name.js +22 -0
  161. package/dist/core/prompt-section-seat.js +4 -6
  162. package/dist/core/protocol-http-auth.d.ts +40 -5
  163. package/dist/core/protocol-http-auth.js +168 -4
  164. package/dist/core/protocol-naming.d.ts +20 -0
  165. package/dist/core/protocol-naming.js +20 -3
  166. package/dist/core/read-only-shell.d.ts +20 -5
  167. package/dist/core/read-only-shell.js +29 -14
  168. package/dist/core/remote-env.d.ts +37 -1
  169. package/dist/core/remote-env.js +11 -0
  170. package/dist/core/resume-startup-cause.d.ts +24 -2
  171. package/dist/core/resume-startup-cause.js +20 -1
  172. package/dist/core/retired-keys.d.ts +16 -0
  173. package/dist/core/retired-keys.js +16 -4
  174. package/dist/core/rewrite-rejudge.d.ts +60 -0
  175. package/dist/core/rewrite-rejudge.js +36 -0
  176. package/dist/core/roles.d.ts +28 -1
  177. package/dist/core/roles.js +81 -26
  178. package/dist/core/rule-lane-reads.d.ts +20 -15
  179. package/dist/core/rule-lane-reads.js +45 -17
  180. package/dist/core/rule-owner.d.ts +3 -3
  181. package/dist/core/rule-owner.js +3 -2
  182. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  183. package/dist/core/runner/announce-once-ledger.js +5 -0
  184. package/dist/core/runner/assemble-result.d.ts +1 -0
  185. package/dist/core/runner/assemble-result.js +1 -1
  186. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  187. package/dist/core/runner/caller-roster.d.ts +16 -4
  188. package/dist/core/runner/caller-roster.js +33 -6
  189. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  190. package/dist/core/runner/capability-withheld-seat.js +24 -0
  191. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  192. package/dist/core/runner/classifier-ladder.js +3 -3
  193. package/dist/core/runner/compact-session.d.ts +10 -0
  194. package/dist/core/runner/compact-session.js +202 -0
  195. package/dist/core/runner/compaction-call-options.d.ts +2 -2
  196. package/dist/core/runner/compaction-seams.d.ts +21 -1
  197. package/dist/core/runner/compaction-seams.js +11 -8
  198. package/dist/core/runner/construction-doors.js +3 -0
  199. package/dist/core/runner/contracts.d.ts +50 -40
  200. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  201. package/dist/core/runner/cross-boundary-lane.js +40 -27
  202. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  203. package/dist/core/runner/denial-limit-arms.js +1 -1
  204. package/dist/core/runner/derived-route-fallback.d.ts +13 -0
  205. package/dist/core/runner/derived-route-fallback.js +6 -0
  206. package/dist/core/runner/env-capability-census.d.ts +3 -2
  207. package/dist/core/runner/env-capability-census.js +9 -3
  208. package/dist/core/runner/file-history-request.d.ts +18 -0
  209. package/dist/core/runner/file-history-request.js +21 -13
  210. package/dist/core/runner/file-history-restore.d.ts +45 -0
  211. package/dist/core/runner/file-history-restore.js +46 -0
  212. package/dist/core/runner/gate-exit.d.ts +3 -3
  213. package/dist/core/runner/gate-exit.js +4 -3
  214. package/dist/core/runner/image.d.ts +7 -17
  215. package/dist/core/runner/image.js +9 -60
  216. package/dist/core/runner/permission-rule-lanes.d.ts +11 -11
  217. package/dist/core/runner/permission-rule-lanes.js +39 -17
  218. package/dist/core/runner/person-path-rows.d.ts +12 -9
  219. package/dist/core/runner/person-path-rows.js +18 -7
  220. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -0
  221. package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
  222. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  223. package/dist/core/runner/prepare-ask-lane.js +5 -2
  224. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  225. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  226. package/dist/core/runner/prepare-config-doors.d.ts +35 -38
  227. package/dist/core/runner/prepare-config-doors.js +46 -28
  228. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  229. package/dist/core/runner/prepare-defer-classify.js +7 -8
  230. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  231. package/dist/core/runner/prepare-file-history.js +7 -39
  232. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  233. package/dist/core/runner/prepare-gate-stations.js +10 -1
  234. package/dist/core/runner/prepare-hands-readface.d.ts +5 -9
  235. package/dist/core/runner/prepare-hands-readface.js +17 -14
  236. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  237. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  238. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  239. package/dist/core/runner/prepare-park-ask.d.ts +2 -0
  240. package/dist/core/runner/prepare-park-ask.js +7 -7
  241. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  242. package/dist/core/runner/prepare-policy-chain.js +67 -76
  243. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  244. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  245. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  246. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  247. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  248. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  249. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  250. package/dist/core/runner/prepare-safety-scan.js +0 -17
  251. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  252. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  253. package/dist/core/runner/prepare-task.d.ts +5 -2
  254. package/dist/core/runner/prepare-task.js +48 -43
  255. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
  256. package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
  257. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  258. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  259. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  260. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  261. package/dist/core/runner/resume-admission.js +1 -1
  262. package/dist/core/runner/resume-apply.js +11 -12
  263. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  264. package/dist/core/runner/resume-claim.d.ts +4 -2
  265. package/dist/core/runner/resume-claim.js +15 -8
  266. package/dist/core/runner/retired-runner-deps.js +1 -0
  267. package/dist/core/runner/rewind-files.d.ts +12 -0
  268. package/dist/core/runner/rewind-files.js +90 -0
  269. package/dist/core/runner/run-attachment-seats.js +2 -1
  270. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  271. package/dist/core/runner/run-brain-sinks.js +4 -2
  272. package/dist/core/runner/run-harness-handlers.js +12 -4
  273. package/dist/core/runner/run-leg.d.ts +1 -1
  274. package/dist/core/runner/run-leg.js +40 -39
  275. package/dist/core/runner/run-notification-lane.d.ts +2 -0
  276. package/dist/core/runner/run-notification-lane.js +2 -2
  277. package/dist/core/runner/run-recovery-lanes.js +3 -4
  278. package/dist/core/runner/run-settle-and-teardown.js +7 -12
  279. package/dist/core/runner/run-terminal-adoption.js +3 -4
  280. package/dist/core/runner/run-turn-boundary.js +4 -15
  281. package/dist/core/runner/runtask.d.ts +10 -0
  282. package/dist/core/runner/runtask.js +35 -42
  283. package/dist/core/runner/send-message-continuation.js +1 -1
  284. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  285. package/dist/core/runner/session-read-file-states.js +28 -0
  286. package/dist/core/runner/session-rule-policy.js +4 -3
  287. package/dist/core/runner/session-verb-doors.d.ts +28 -0
  288. package/dist/core/runner/session-verb-doors.js +48 -0
  289. package/dist/core/runner/session-write-ledger.d.ts +30 -0
  290. package/dist/core/runner/session-write-ledger.js +101 -0
  291. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  292. package/dist/core/runner/shell-env-withheld.js +51 -0
  293. package/dist/core/runner/skills-seat.js +6 -2
  294. package/dist/core/runner/stream-settle-backstop.js +12 -15
  295. package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
  296. package/dist/core/runner/sub-agent-deny-lists.js +25 -17
  297. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  298. package/dist/core/runner/synthetic-tools.js +4 -1
  299. package/dist/core/runner/teardown-bounded.d.ts +1 -0
  300. package/dist/core/runner/teardown-bounded.js +1 -0
  301. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  302. package/dist/core/runner/tool-disclosure.js +1 -3
  303. package/dist/core/runner/tool-end-body.d.ts +1 -1
  304. package/dist/core/runner/tool-end-body.js +10 -9
  305. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  306. package/dist/core/runner/tool-not-executed.js +11 -0
  307. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  308. package/dist/core/runner/tool-occurrence.js +7 -0
  309. package/dist/core/runner/turn-attachments.d.ts +33 -15
  310. package/dist/core/runner/turn-attachments.js +62 -37
  311. package/dist/core/runner-deps.d.ts +7 -7
  312. package/dist/core/safety-axis-vocab.d.ts +6 -4
  313. package/dist/core/safety-axis-vocab.js +6 -5
  314. package/dist/core/safety-merge-corpus.js +11 -3
  315. package/dist/core/secret-env.d.ts +30 -3
  316. package/dist/core/secret-env.js +47 -8
  317. package/dist/core/select-model.js +3 -3
  318. package/dist/core/session-policy-store.d.ts +32 -15
  319. package/dist/core/session-policy-store.js +156 -36
  320. package/dist/core/session-store.d.ts +29 -10
  321. package/dist/core/session-store.js +51 -19
  322. package/dist/core/session.d.ts +82 -16
  323. package/dist/core/session.js +53 -0
  324. package/dist/core/shell-read-silence.d.ts +11 -12
  325. package/dist/core/shell-read-silence.js +9 -5
  326. package/dist/core/shell-run-candidates.js +3 -1
  327. package/dist/core/shell-wrapper-projection.d.ts +1 -1
  328. package/dist/core/shell-wrapper-projection.js +1 -1
  329. package/dist/core/shell-wrapper-table.d.ts +14 -7
  330. package/dist/core/shell-wrapper-table.js +5 -4
  331. package/dist/core/side-query.js +10 -1
  332. package/dist/core/skill-grant.d.ts +7 -2
  333. package/dist/core/skill-grant.js +5 -0
  334. package/dist/core/skills-directory.js +6 -2
  335. package/dist/core/store-contracts/background-agent-store-contract.js +1 -0
  336. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  337. package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
  338. package/dist/core/store-contracts/file-history-store-contract.js +40 -1
  339. package/dist/core/store-contracts/mailbox-store-contract.js +49 -1
  340. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  341. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  342. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  343. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  344. package/dist/core/store-contracts/session-store-contract.js +150 -14
  345. package/dist/core/stub-env.d.ts +2 -0
  346. package/dist/core/stub-env.js +1 -0
  347. package/dist/core/synthetic-read-verdict.js +3 -3
  348. package/dist/core/task-event.d.ts +32 -4
  349. package/dist/core/task-notification.d.ts +16 -12
  350. package/dist/core/task-registry-agent.d.ts +8 -4
  351. package/dist/core/task-registry-agent.js +14 -8
  352. package/dist/core/task-registry-shared.d.ts +35 -6
  353. package/dist/core/task-registry-shared.js +11 -0
  354. package/dist/core/task-registry.d.ts +10 -1
  355. package/dist/core/task-registry.js +12 -2
  356. package/dist/core/task-result.d.ts +18 -0
  357. package/dist/core/task-spec.d.ts +18 -13
  358. package/dist/core/tighten-task-spec.js +2 -1
  359. package/dist/core/tool-catalog-entries.d.ts +23 -0
  360. package/dist/core/tool-catalog-entries.js +14 -2
  361. package/dist/core/tool-check-reading.d.ts +11 -0
  362. package/dist/core/tool-check-reading.js +11 -6
  363. package/dist/core/tool-model-gate.d.ts +2 -2
  364. package/dist/core/tool-name-aliases.d.ts +48 -18
  365. package/dist/core/tool-name-aliases.js +36 -19
  366. package/dist/core/tool-name-readings.d.ts +6 -32
  367. package/dist/core/tool-name-readings.js +2 -9
  368. package/dist/core/tool-policy.d.ts +78 -204
  369. package/dist/core/tool-policy.js +152 -204
  370. package/dist/core/tool-result-store.js +3 -0
  371. package/dist/core/tool-roster.d.ts +14 -19
  372. package/dist/core/tool-roster.js +11 -44
  373. package/dist/core/tool-spec-members.js +7 -2
  374. package/dist/core/tool-spec.d.ts +19 -11
  375. package/dist/core/tools.js +49 -9
  376. package/dist/core/trace.d.ts +6 -3
  377. package/dist/core/trace.js +2 -1
  378. package/dist/core/types.d.ts +1 -1
  379. package/dist/core/untrusted-egress.d.ts +20 -0
  380. package/dist/core/untrusted-egress.js +77 -3
  381. package/dist/core/user-attachment.d.ts +8 -1
  382. package/dist/core/user-attachment.js +64 -4
  383. package/dist/core/wiring-manifest.d.ts +9 -0
  384. package/dist/core/wiring-manifest.js +1 -0
  385. package/dist/core/workflow-journal-store.js +1 -1
  386. package/dist/engine/compaction/compaction.js +3 -2
  387. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  388. package/dist/engine/execution-env/node-execution-env.js +11 -2
  389. package/dist/engine/harness/agent-harness.d.ts +32 -6
  390. package/dist/engine/harness/agent-harness.js +65 -9
  391. package/dist/engine/harness/types.d.ts +29 -2
  392. package/dist/engine/llm/types.d.ts +28 -11
  393. package/dist/engine/loop/agent-loop.d.ts +23 -4
  394. package/dist/engine/loop/agent-loop.js +42 -30
  395. package/dist/engine/loop/types.d.ts +16 -6
  396. package/dist/engine/session/memory-repo.d.ts +9 -2
  397. package/dist/engine/session/memory-repo.js +11 -1
  398. package/dist/engine/session/repo-utils.d.ts +6 -5
  399. package/dist/engine/session/repo-utils.js +14 -6
  400. package/dist/index.d.ts +34 -17
  401. package/dist/index.js +22 -11
  402. package/dist/internal/harness-types.d.ts +1 -1
  403. package/dist/internal/harness.d.ts +2 -1
  404. package/dist/internal/harness.js +1 -0
  405. package/dist/internal/llm.d.ts +1 -1
  406. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  407. package/dist/orchestration/run-workflow-tool.js +5 -3
  408. package/dist/orchestration/workflow.d.ts +3 -0
  409. package/dist/orchestration/workflow.js +36 -18
  410. package/dist/primitives/credential-ref.d.ts +89 -0
  411. package/dist/primitives/credential-ref.js +125 -0
  412. package/dist/primitives/index.d.ts +2 -0
  413. package/dist/primitives/index.js +1 -0
  414. package/dist/prompt-assembly/artifact.d.ts +2 -2
  415. package/dist/prompt-assembly/artifact.js +5 -3
  416. package/dist/prompt-assembly/assemble.d.ts +3 -2
  417. package/dist/prompt-assembly/assemble.js +1 -1
  418. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  419. package/dist/prompt-assembly/catalog/schema.js +34 -2
  420. package/dist/prompt-assembly/catalog/sections.js +0 -1
  421. package/dist/prompt-assembly/composer.d.ts +3 -1
  422. package/dist/prompt-assembly/composer.js +1 -1
  423. package/dist/prompt-assembly/event-registry.js +1 -0
  424. package/dist/prompt-assembly/overlay.js +3 -3
  425. package/dist/prompt-assembly/renderers.d.ts +1 -1
  426. package/dist/prompt-assembly/renderers.js +0 -3
  427. package/dist/prompt-assembly/role-base.d.ts +15 -0
  428. package/dist/prompt-assembly/role-base.js +9 -0
  429. package/dist/prompt-assembly/select.d.ts +39 -14
  430. package/dist/prompt-assembly/select.js +47 -16
  431. package/dist/prompt-assembly/sugar.d.ts +17 -11
  432. package/dist/prompt-assembly/sugar.js +8 -3
  433. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  434. package/dist/prompt-assembly/tool-catalog.js +114 -4
  435. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  436. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  437. package/dist/prompt-assembly/types.d.ts +0 -7
  438. package/dist/scenarios/full-body.d.ts +11 -11
  439. package/dist/scenarios/full-body.js +4 -3
  440. package/dist/shell/lex.js +10 -1
  441. package/dist/stores/file/adoption/adopt.js +4 -3
  442. package/dist/stores/file/adoption/marker.js +3 -2
  443. package/dist/stores/file/checkpoint-store.d.ts +21 -4
  444. package/dist/stores/file/checkpoint-store.js +38 -7
  445. package/dist/stores/file/file-history-store.js +18 -11
  446. package/dist/stores/file/index.js +2 -1
  447. package/dist/stores/file/mailbox-store.d.ts +2 -1
  448. package/dist/stores/file/mailbox-store.js +26 -1
  449. package/dist/stores/file/permission-rule-adopt.js +4 -3
  450. package/dist/stores/file/permission-rule-store.js +11 -5
  451. package/dist/stores/file/session-store.d.ts +29 -6
  452. package/dist/stores/file/session-store.js +42 -50
  453. package/dist/tools/artifact/artifact-tool.js +3 -2
  454. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  455. package/dist/tools/fs/bash-program-position.js +56 -9
  456. package/dist/tools/fs/bash-readonly-classifier.d.ts +15 -19
  457. package/dist/tools/fs/bash-readonly-classifier.js +5 -10
  458. package/dist/tools/fs/fs-bash.js +15 -8
  459. package/dist/tools/fs/fs-glob.d.ts +86 -0
  460. package/dist/tools/fs/fs-glob.js +226 -0
  461. package/dist/tools/fs/fs-read.js +14 -14
  462. package/dist/tools/fs/fs-search-tools.js +7 -7
  463. package/dist/tools/fs/pattern-kill-guard.d.ts +23 -0
  464. package/dist/tools/fs/pattern-kill-guard.js +429 -0
  465. package/dist/tools/fs/pdf.d.ts +9 -6
  466. package/dist/tools/fs/pdf.js +3 -3
  467. package/dist/tools/fs/program-read-model.d.ts +57 -7
  468. package/dist/tools/fs/program-read-model.js +11 -1
  469. package/dist/tools/fs/program-read-model.rows.js +78 -21
  470. package/dist/tools/fs/read-deny-home.js +3 -2
  471. package/dist/tools/fs/removal-targets.d.ts +17 -7
  472. package/dist/tools/fs/removal-targets.js +47 -20
  473. package/dist/tools/fs/search.d.ts +10 -0
  474. package/dist/tools/fs/search.js +20 -26
  475. package/dist/tools/fs/shell-read-argv.js +89 -12
  476. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  477. package/dist/tools/fs/shell-read-bindings.js +41 -0
  478. package/dist/tools/fs/shell-read-check.d.ts +10 -0
  479. package/dist/tools/fs/shell-read-check.js +13 -20
  480. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  481. package/dist/tools/fs/shell-read-environment.js +3 -2
  482. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  483. package/dist/tools/fs/shell-read-establish.js +19 -20
  484. package/dist/tools/fs/shell-read-identity.d.ts +12 -9
  485. package/dist/tools/fs/shell-read-identity.js +9 -4
  486. package/dist/tools/fs/shell-read-plan.js +24 -16
  487. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  488. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  489. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  490. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  491. package/dist/tools/fs/shell-reentry-text.js +40 -2
  492. package/dist/tools/todo.js +63 -63
  493. package/dist/tools/web.d.ts +19 -14
  494. package/dist/tools/web.js +46 -61
  495. package/package.json +1 -1
  496. package/test/export-surface.snapshot.json +221 -7
  497. package/wire-changes/core-stores-sql@7.57.0.json +29 -0
  498. package/wire-changes/core@7.56.0.json +3891 -0
  499. package/wire-changes/core@7.57.0.json +1487 -0
  500. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  501. package/wire-changes/mods-kernel@7.57.0.json +29 -0
  502. package/wire-changes/primitives@7.57.0.json +245 -0
@@ -90,7 +90,6 @@ export const SECTIONS = [
90
90
  ],
91
91
  },
92
92
  },
93
- { id: "core/behavior.model-guidance", band: "behavior", rank: 450, block: { id: "model.guidance" }, body: { renderer: "model-guidance" } },
94
93
  { id: "core/discovery.mcp-instructions", band: "discovery", rank: 500, block: { id: "mcp.instructions" }, body: { renderer: "mcp-instructions" } },
95
94
  { id: "core/harness.reminder-mark", band: "constitution", rank: 590, block: { id: "harness.reminder-mark" }, body: { renderer: "reminder-mark" } },
96
95
  { id: "core/environment.context", band: "environment", rank: 600, block: { id: "env.context" }, body: { renderer: "environment" } },
@@ -1,4 +1,4 @@
1
- import type { HostForm, HostRole, PromptCatalog } from "./catalog/schema.js";
1
+ import type { HostForm, HostRole, PromptCatalog, PromptTraitName } from "./catalog/schema.js";
2
2
  import { type SourcedOverlay, type SupersededOverlay } from "./overlay.js";
3
3
  import type { CompiledSystemBlock, ComposedPrompt, SectionRenderInputs, SystemLayout } from "./types.js";
4
4
  /** What one composition renders: the catalog, the host selector values, and the overlays in application order. */
@@ -11,6 +11,8 @@ export interface CompositionPlan {
11
11
  };
12
12
  /** The run's binding (`TaskSpec.promptBinding`; absent ⇒ none) — what every overlay's `when.binding` reads. */
13
13
  readonly binding?: string;
14
+ /** The run's effective traits (`effectiveTraitsOf`; absent ⇒ those of a model that declares none). */
15
+ readonly traits?: ReadonlySet<PromptTraitName>;
14
16
  /** Validated overlays, already in application order (`bundled < task < center < deploy`, then declaration order). */
15
17
  readonly overlays?: readonly SourcedOverlay[];
16
18
  }
@@ -91,7 +91,7 @@ function renderAdded(e, fold) {
91
91
  };
92
92
  }
93
93
  export function composeCatalog(plan, inputs) {
94
- const s = selectorsOf(inputs.facts, plan.host, plan.binding);
94
+ const s = selectorsOf(inputs.facts, plan.host, plan.binding, plan.traits);
95
95
  const bases = basesOf(plan.catalog, inputs, s);
96
96
  const selectedText = selectedTextOf(plan.catalog, bases);
97
97
  const overlayText = (o) => {
@@ -11,6 +11,7 @@ export const EVENT_PROMPT_REGISTRY = new Map([
11
11
  { kind: "total_tokens_reminder", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "on", rendererRef: "turn-attachments.ts#renderTotalTokensReminder" },
12
12
  { kind: "background_tasks", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "on", rendererRef: "turn-attachments.ts#renderBackgroundTasks" },
13
13
  { kind: "tools_delta", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderToolsDelta" },
14
+ { kind: "mcp_unavailable", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "on", rendererRef: "turn-attachments.ts#renderMcpUnavailable" },
14
15
  { kind: "agent_listing", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "on", rendererRef: "turn-attachments.ts#renderAgentListingDelta" },
15
16
  { kind: "skills_listing", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "on", rendererRef: "turn-attachments.ts#renderSkillsListingDelta" },
16
17
  { kind: "mcp_instructions", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderMcpInstructionsDelta" },
@@ -3,7 +3,7 @@ import { describeFault, isPlainRecord, receive } from "../core/mods/kernel/recei
3
3
  import { egressText } from "../core/untrusted-egress.js";
4
4
  import { bandOf, isBandId } from "./bands.js";
5
5
  import { SEMA_DEFAULT_CATALOG, catalogMessage } from "./catalog/index.js";
6
- import { HOST_FORMS, HOST_ROLES, OVERLAY_OPS, PROMPT_FACT_NAMES, PROMPT_TRAITS, isHostRole, isWordOf, } from "./catalog/schema.js";
6
+ import { HOST_FORMS, HOST_ROLES, OVERLAY_OPS, PROMPT_FACT_NAMES, PROMPT_TRAITS, PROMPT_TRAIT_BUNDLES, isHostRole, isPromptTraitName, isWordOf, } from "./catalog/schema.js";
7
7
  import { RENDERERS } from "./renderers.js";
8
8
  import { canonicalWhen } from "./select.js";
9
9
  export const OVERLAY_SOURCE_ORDER = Object.freeze(["bundled", "task", "center", "deploy"]);
@@ -116,8 +116,8 @@ function whenViolation(when) {
116
116
  if (!Array.isArray(list))
117
117
  return `"when.traits.${k}" is not an array`;
118
118
  for (const name of list)
119
- if (!isWordOf(PROMPT_TRAITS, name))
120
- return `"when.traits.${k}" names ${str(name)}, not a trait (${PROMPT_TRAITS.join(", ")})`;
119
+ if (!isPromptTraitName(name))
120
+ return `"when.traits.${k}" names ${str(name)}, not a trait (${PROMPT_TRAITS.join(", ")}; a bundle: ${Object.keys(PROMPT_TRAIT_BUNDLES).join(", ")}; or a deployment's own "x-<namespace>-<name>")`;
121
121
  }
122
122
  }
123
123
  if (w["host"] !== undefined) {
@@ -5,7 +5,7 @@ export interface RendererSpec {
5
5
  readonly id: RendererId;
6
6
  readonly version: number;
7
7
  readonly stability: "static" | "session" | "leg";
8
- readonly reads: "inputs" | "facts" | "env" | "memory" | "mcp" | "mark" | "selectors";
8
+ readonly reads: "facts" | "env" | "memory" | "mcp" | "mark" | "selectors";
9
9
  readonly external: boolean;
10
10
  /** The catalog messages this renderer's output is (an overlay targets them). */
11
11
  readonly messages?: readonly string[];
@@ -4,7 +4,6 @@ import { catalogMessage } from "./catalog/index.js";
4
4
  import { selectVariant } from "./select.js";
5
5
  export const RENDERERS = {
6
6
  "role-base": { id: "role-base", version: 2, stability: "session", reads: "selectors", external: false, messages: ["core/role.base"] },
7
- "model-guidance": { id: "model-guidance", version: 1, stability: "session", reads: "inputs", external: false },
8
7
  "mcp-instructions": { id: "mcp-instructions", version: 1, stability: "session", reads: "mcp", external: true },
9
8
  "reminder-mark": { id: "reminder-mark", version: 1, stability: "session", reads: "mark", external: false },
10
9
  environment: { id: "environment", version: 2, stability: "leg", reads: "env", external: false },
@@ -25,8 +24,6 @@ export function runRenderer(id, inputs, selectors) {
25
24
  const sections = renderCoworkBase({ tools: inputs.toolNames ?? [], workspaceFolder: inputs.workspaceFolder });
26
25
  return sections.length === 0 ? undefined : { text: sections.map((s) => s.text).join("\n\n"), variant: v.id };
27
26
  }
28
- case "model-guidance":
29
- return plain(inputs.modelGuidance);
30
27
  case "mcp-instructions":
31
28
  return plain(inputs.mcpInstructionsBlock);
32
29
  case "reminder-mark":
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The role base's one decision rule (a leaf): of an ordered list of sources — the task, the requested model role's
3
+ * preset, an engine spawner's child persona — the first that names a role base decides it wholly (the sugar's header).
4
+ */
5
+ import type { HostRole } from "./catalog/schema.js";
6
+ /** A source's statement of the role base — its word (the host role; selects the `core/role.base` variant), its text
7
+ * (replaces that base), or both. `TaskSpec`, a role preset and the delegation tool's options have this shape. */
8
+ export interface RoleBaseDeclaration {
9
+ readonly promptRole?: HostRole;
10
+ readonly systemPrompt?: string;
11
+ }
12
+ /** Whether a source names a role base — the one reading of "this seat has spoken". */
13
+ export declare function namesRoleBase(d: RoleBaseDeclaration | undefined): boolean;
14
+ /** The first source that names a role base, whole; `undefined` ⇒ none did. */
15
+ export declare function roleBaseOf(sources: readonly (RoleBaseDeclaration | undefined)[]): RoleBaseDeclaration | undefined;
@@ -0,0 +1,9 @@
1
+ export function namesRoleBase(d) {
2
+ return d !== undefined && (d.promptRole !== undefined || d.systemPrompt !== undefined);
3
+ }
4
+ export function roleBaseOf(sources) {
5
+ for (const source of sources)
6
+ if (namesRoleBase(source))
7
+ return source;
8
+ return undefined;
9
+ }
@@ -3,8 +3,8 @@
3
3
  * whether an overlay's `when` applies to this run (every source class alike). Four dimensions, each with exactly one
4
4
  * writer, so no value ever needs a precedence order:
5
5
  *
6
- * - `traits` — derived from the run's two prompt-shape axes by {@link promptTraitsOf} (the prompt profile and the
7
- * fable-family model); catalog data reads traits, never the axes.
6
+ * - `traits` — the model's declared traits (`Model.promptTraits`) with the task's one switch on `lean_prompt`
7
+ * (`TaskSpec.promptLean`), bundles expanded: {@link effectiveTraitsOf}. The engine reads no model id to choose text.
8
8
  * - `host` — `role` (which role base the run is assembled for; `TaskSpec.promptRole`, absent ⇒ `general`) and
9
9
  * `form` (`TaskSpec.promptForm`, which every engine-built child receives through the parent spec seat; absent ⇒
10
10
  * `standard`).
@@ -15,11 +15,11 @@
15
15
  * fact equal, the binding inside its `anyOf` (or outside its `noneOf`). No disjunction across dimensions.
16
16
  */
17
17
  import type { PromptManifestSelectors } from "../core/trace.js";
18
- import { type CatalogMessage, type FactConjunction, type HostForm, type HostRole, type PromptFactName, type PromptTrait, type Variant, type VariantWhen } from "./catalog/schema.js";
18
+ import { type CatalogMessage, type FactConjunction, type HostForm, type HostRole, type PromptFactName, type PromptTraitName, type TraitCondition, type Variant, type VariantWhen } from "./catalog/schema.js";
19
19
  import type { PromptRuntimeFacts } from "./types.js";
20
20
  /** The run's selector values, resolved once per assembly. */
21
21
  export interface PromptSelectors {
22
- readonly traits: ReadonlySet<PromptTrait>;
22
+ readonly traits: ReadonlySet<PromptTraitName>;
23
23
  readonly host: {
24
24
  readonly role: HostRole;
25
25
  readonly form: HostForm;
@@ -28,17 +28,29 @@ export interface PromptSelectors {
28
28
  readonly binding?: string;
29
29
  }
30
30
  /**
31
- * The run's prompt traits, derived from the two prompt-shape axes the engine resolves today: the simple
32
- * profile is `lean_prompt`, a fable-family model is `fable_5_mitigations`. This is the only place those
33
- * axes become traits.
31
+ * The run's effective traits — the one place a trait set is formed: the model's declared set (exact: nothing is added
32
+ * to what it lists; absent ⇒ `["lean_prompt"]`), then the task's one switch (`promptLean`: `true` adds `lean_prompt`,
33
+ * `false` removes it, absent leaves the model's answer), then each declared bundle's members. The task can move
34
+ * nothing else: a model-family trait stays the model's.
34
35
  */
35
- export declare function promptTraitsOf(facts: Pick<PromptRuntimeFacts, "promptProfile" | "fableMitigations">): ReadonlySet<PromptTrait>;
36
+ export declare function effectiveTraitsOf(declared: readonly PromptTraitName[] | undefined, lean: boolean | undefined): ReadonlySet<PromptTraitName>;
37
+ /**
38
+ * The model door's reading of `Model.promptTraits`: absent, or a list whose every entry is a trait name
39
+ * ({@link isPromptTraitName}). Anything else is refused by name (`config.prompt_trait_unknown`), never read as the
40
+ * default — a model that names a trait the engine cannot read would silently receive another prompt shape.
41
+ */
42
+ export declare function readModelPromptTraits(model: {
43
+ readonly id?: unknown;
44
+ readonly promptTraits?: unknown;
45
+ }): readonly PromptTraitName[] | undefined;
36
46
  /** The predicate facts a condition may test; optional runtime facts read as false when absent. */
37
47
  export declare function catalogFactsOf(facts: PromptRuntimeFacts): Readonly<Record<PromptFactName, boolean>>;
38
48
  /**
39
- * The host selector's two values as their one writer gave them: the task (`TaskSpec.promptRole` /
40
- * `TaskSpec.promptForm`; an engine-built child's spec carries its parent's form through the parent spec seat).
41
- * A value outside the closed set is refused by name (`config.prompt_selector_invalid`), never read as the default.
49
+ * The task seat's two host values as its door judges them (`TaskSpec.promptRole` / `TaskSpec.promptForm`; an
50
+ * engine-built child's spec carries its parent's form through the parent spec seat). The form is the run's; the role
51
+ * word is the task's statement of its role base, the first source of the role-base decision (`roleBaseOf`, the
52
+ * request-body sugar), which gives the run's host role. A value outside the closed set is refused by name
53
+ * (`config.prompt_selector_invalid`), never read as the default.
42
54
  */
43
55
  export declare function resolveHost(task: {
44
56
  readonly promptRole?: unknown;
@@ -47,16 +59,29 @@ export declare function resolveHost(task: {
47
59
  readonly role?: HostRole;
48
60
  readonly form?: HostForm;
49
61
  };
50
- /** The run's selectors — their one mint: traits and facts from the runtime facts, the host from its two writers' values,
51
- * the binding as the task's door validated it. */
62
+ /** The task's switch on the lean shape as its one writer gave it (`TaskSpec.promptLean`): a boolean or absent; any other
63
+ * value is refused by name (`config.prompt_selector_invalid`), never read as absent. */
64
+ export declare function resolvePromptLean(task: {
65
+ readonly promptLean?: unknown;
66
+ }): boolean | undefined;
67
+ /** A role-base seat's role word as its writer gave it — the one door every seat that may name a role base passes
68
+ * (`TaskSpec.promptRole`, a role preset's `promptRole`, the delegation tool's `promptRole`; `seat` names where it was
69
+ * written): absent, or a word of {@link HOST_ROLES}; anything else is refused by name (`config.prompt_selector_invalid`). */
70
+ export declare function readPromptRole(seat: string, value: unknown): HostRole | undefined;
71
+ /** The run's selectors — their one mint: the facts from the runtime facts, the host from its two writers' values, the
72
+ * binding as the task's door validated it, and the effective traits ({@link effectiveTraitsOf}; absent ⇒ those of a
73
+ * model that declares none, with no task switch). */
52
74
  export declare function selectorsOf(facts: PromptRuntimeFacts, host?: {
53
75
  readonly role?: HostRole;
54
76
  readonly form?: HostForm;
55
- }, binding?: string): PromptSelectors;
77
+ }, binding?: string, traits?: ReadonlySet<PromptTraitName>): PromptSelectors;
56
78
  /** The selectors' plain form (traits sorted): what the manifest shows, the identity's `binding` element digests and the
57
79
  * `prompt.compose` event carries — one record. */
58
80
  export declare function selectorRecordOf(s: PromptSelectors): PromptManifestSelectors;
59
81
  export declare function factsHold(conj: FactConjunction | undefined, facts: Readonly<Record<PromptFactName, boolean>>): boolean;
82
+ /** Whether a trait condition holds over a trait set — every `allOf` present, no `noneOf` present. The one trait reading:
83
+ * a catalog variant's, an overlay's and a tool description variant's condition all go through it. */
84
+ export declare function traitsHold(cond: TraitCondition | undefined, traits: ReadonlySet<PromptTraitName>): boolean;
60
85
  /** Whether a `when` holds under the run's selectors. */
61
86
  export declare function whenHolds(when: VariantWhen | undefined, s: PromptSelectors): boolean;
62
87
  /**
@@ -1,12 +1,36 @@
1
- import { HOST_ROLES, isHostRole } from "./catalog/schema.js";
2
- export function promptTraitsOf(facts) {
3
- const traits = new Set();
4
- if (facts.promptProfile !== "classic")
1
+ import { bundleMembersOf, HOST_ROLES, isHostRole, isPromptTraitName } from "./catalog/schema.js";
2
+ const UNDECLARED_MODEL_TRAITS = Object.freeze(["lean_prompt"]);
3
+ export function effectiveTraitsOf(declared, lean) {
4
+ const traits = new Set(declared ?? UNDECLARED_MODEL_TRAITS);
5
+ if (lean === true)
5
6
  traits.add("lean_prompt");
6
- if (facts.fableMitigations === true)
7
- traits.add("fable_5_mitigations");
7
+ else if (lean === false)
8
+ traits.delete("lean_prompt");
9
+ for (const name of [...traits])
10
+ for (const member of bundleMembersOf(name))
11
+ traits.add(member);
8
12
  return traits;
9
13
  }
14
+ export function readModelPromptTraits(model) {
15
+ const raw = model.promptTraits;
16
+ if (raw === undefined)
17
+ return undefined;
18
+ const refuse = (why) => {
19
+ throw Object.assign(new Error(`Model.promptTraits of model ${JSON.stringify(String(model.id)).slice(0, 80)} ${why}; a trait is one of the reference's prompt capability names, a bundle name, or a deployment's own "x-<namespace>-<name>"`), {
20
+ code: "config.prompt_trait_unknown",
21
+ });
22
+ };
23
+ if (!Array.isArray(raw))
24
+ return refuse(`is ${raw === null ? "null" : typeof raw}, not a list`);
25
+ const out = [];
26
+ const names = raw;
27
+ for (const name of names) {
28
+ if (!isPromptTraitName(name))
29
+ return refuse(`names ${typeof name === "string" ? JSON.stringify(name.slice(0, 64)) : typeof name}, not a trait`);
30
+ out.push(name);
31
+ }
32
+ return Object.freeze(out);
33
+ }
10
34
  export function catalogFactsOf(facts) {
11
35
  return {
12
36
  policyEnabled: facts.policyEnabled,
@@ -27,18 +51,25 @@ export function catalogFactsOf(facts) {
27
51
  };
28
52
  }
29
53
  export function resolveHost(task) {
30
- const refuse = (key, value, allowed) => {
31
- throw Object.assign(new Error(`TaskSpec.${key} is ${typeof value === "string" ? JSON.stringify(value.slice(0, 64)) : typeof value}; it is one of ${allowed.map((a) => `"${a}"`).join(", ")} (or absent)`), {
32
- code: "config.prompt_selector_invalid",
33
- });
34
- };
35
- const role = task.promptRole === undefined ? undefined : isHostRole(task.promptRole) ? task.promptRole : refuse("promptRole", task.promptRole, HOST_ROLES);
36
- const form = task.promptForm === undefined ? undefined : task.promptForm === "minimal" ? "minimal" : refuse("promptForm", task.promptForm, ["minimal"]);
54
+ const role = readPromptRole("TaskSpec.promptRole", task.promptRole);
55
+ const form = task.promptForm === undefined ? undefined : task.promptForm === "minimal" ? "minimal" : refuseSelector("TaskSpec.promptForm", task.promptForm, ['"minimal"']);
37
56
  return Object.freeze({ ...(role !== undefined ? { role } : {}), ...(form !== undefined ? { form } : {}) });
38
57
  }
39
- export function selectorsOf(facts, host = {}, binding) {
58
+ export function resolvePromptLean(task) {
59
+ const v = task.promptLean;
60
+ return v === undefined || v === true || v === false ? v : refuseSelector("TaskSpec.promptLean", v, ["true", "false"]);
61
+ }
62
+ export function readPromptRole(seat, value) {
63
+ return value === undefined ? undefined : isHostRole(value) ? value : refuseSelector(seat, value, HOST_ROLES.map((a) => `"${a}"`));
64
+ }
65
+ function refuseSelector(seat, value, allowed) {
66
+ throw Object.assign(new Error(`${seat} is ${typeof value === "string" ? JSON.stringify(value.slice(0, 64)) : typeof value}; it is one of ${allowed.join(", ")} (or absent)`), {
67
+ code: "config.prompt_selector_invalid",
68
+ });
69
+ }
70
+ export function selectorsOf(facts, host = {}, binding, traits = effectiveTraitsOf(undefined, undefined)) {
40
71
  return Object.freeze({
41
- traits: promptTraitsOf(facts),
72
+ traits,
42
73
  host: Object.freeze({ role: host.role ?? "general", form: host.form ?? "standard" }),
43
74
  facts: Object.freeze(catalogFactsOf(facts)),
44
75
  ...(binding !== undefined ? { binding } : {}),
@@ -60,7 +91,7 @@ export function factsHold(conj, facts) {
60
91
  return false;
61
92
  return true;
62
93
  }
63
- function traitsHold(cond, traits) {
94
+ export function traitsHold(cond, traits) {
64
95
  if (cond === undefined)
65
96
  return true;
66
97
  return (cond.allOf ?? []).every((t) => traits.has(t)) && !(cond.noneOf ?? []).some((t) => traits.has(t));
@@ -1,31 +1,37 @@
1
1
  /**
2
2
  * The request-body sugar: the one place the task's role-layer prompt inputs are read and turned into overlays of
3
- * the `task` source class. Three inputs, one expression each:
3
+ * the `task` source class. Two inputs, one reading each:
4
4
  *
5
- * - the role base — `TaskSpec.systemPrompt ?? resolvedRole.systemPrompt ?? internals.defaultSystemPrompt` (the
6
- * task's own text, else the role preset the task named, else the persona a core spawner hands its child) — a
7
- * `replace` of `core/role.base`, applied after the selector chose the role base's variant;
8
- * - the appended block — `TaskSpec.appendSystemPrompt` — an `add` to the `task-append` band (entry
9
- * `core/role.append`);
5
+ * - the role base — the first of three sources that names one decides it ({@link roleBaseOf}): the task (its door-judged
6
+ * `promptRole` and its `systemPrompt`), then the requested model role's preset, then the persona a core spawner hands
7
+ * its child (`internals.defaultSystemPrompt`). The deciding source's word is the run's host role; its text, when it
8
+ * names one, is a `replace` of `core/role.base`, applied after the selector chose the variant;
9
+ * - the appended block — `TaskSpec.appendSystemPrompt` — an `add` to the `task-append` band (entry `core/role.append`);
10
10
  *
11
11
  * and nothing else reads them for assembly (`gate:sugar-single-site`). The sugar is applied first within its class,
12
12
  * the task-seat mods after it. Its one possible violation is locked text: a role-layer input carrying, verbatim,
13
13
  * the canonical text of a `constitution` entry is an already-assembled prompt, and the task is refused by name
14
14
  * (`prompt.assembled_role_refused`) — never passed through, never silently dropped.
15
15
  */
16
+ import type { HostRole } from "./catalog/schema.js";
16
17
  import { type SourcedOverlay } from "./overlay.js";
18
+ import { type RoleBaseDeclaration } from "./role-base.js";
17
19
  /** The task's role-layer prompt inputs, as prepare holds them. */
18
20
  export interface SugarInputs {
19
21
  readonly spec: {
20
22
  readonly systemPrompt?: string;
21
23
  readonly appendSystemPrompt?: string;
22
24
  };
23
- readonly resolvedRole: {
24
- readonly systemPrompt?: string;
25
- };
25
+ /** The task seat's role word as its door judged it (`TaskSpec.promptRole`, `resolveHost`). */
26
+ readonly taskRole?: HostRole;
27
+ readonly resolvedRole: RoleBaseDeclaration;
26
28
  readonly internals?: {
27
29
  readonly defaultSystemPrompt?: string;
28
30
  };
29
31
  }
30
- /** The task-class overlays the request body carries, in application order (role base, then the appended block). */
31
- export declare function sugarOverlays(inputs: SugarInputs): readonly SourcedOverlay[];
32
+ /** The task class's first overlays (role base, then the appended block) and the run's host role, from ONE decision. */
33
+ export interface RequestBodySugar {
34
+ readonly overlays: readonly SourcedOverlay[];
35
+ readonly hostRole?: HostRole;
36
+ }
37
+ export declare function requestBodySugar(inputs: SugarInputs): RequestBodySugar;
@@ -1,7 +1,12 @@
1
1
  import { assembledRoleRefused, lockedTextIn } from "./overlay.js";
2
+ import { roleBaseOf } from "./role-base.js";
2
3
  const SUGAR = { source: "task", by: "sugar" };
3
- export function sugarOverlays(inputs) {
4
- const roleBase = inputs.spec.systemPrompt ?? inputs.resolvedRole.systemPrompt ?? inputs.internals?.defaultSystemPrompt;
4
+ export function requestBodySugar(inputs) {
5
+ const taskText = inputs.spec.systemPrompt;
6
+ const task = { ...(inputs.taskRole !== undefined ? { promptRole: inputs.taskRole } : {}), ...(taskText !== undefined ? { systemPrompt: taskText } : {}) };
7
+ const engineText = inputs.internals?.defaultSystemPrompt;
8
+ const decided = roleBaseOf([task, inputs.resolvedRole, engineText !== undefined ? { systemPrompt: engineText } : undefined]);
9
+ const roleBase = decided?.systemPrompt;
5
10
  const append = inputs.spec.appendSystemPrompt;
6
11
  const out = [];
7
12
  if (roleBase !== undefined) {
@@ -16,5 +21,5 @@ export function sugarOverlays(inputs) {
16
21
  throw assembledRoleRefused("the task's appendSystemPrompt", hits);
17
22
  out.push({ overlay: Object.freeze({ id: "core/role.append", op: "add", target: "task-append", text: append }), origin: SUGAR });
18
23
  }
19
- return Object.freeze(out);
24
+ return Object.freeze({ overlays: Object.freeze(out), ...(decided?.promptRole !== undefined ? { hostRole: decided.promptRole } : {}) });
20
25
  }
@@ -1,12 +1,15 @@
1
1
  import type { TSchema } from "typebox";
2
2
  import type { AgentTool } from "../internal/harness-types.js";
3
3
  import type { ProtocolId } from "../core/protocol-table.js";
4
+ import { type PromptTraitName } from "./catalog/schema.js";
4
5
  /** The protocol slice comes from the protocol table — adding a protocol extends ProtocolId and this
5
6
  * union follows automatically (the origin projection is table-driven, prepare-task). */
6
7
  export type ToolOrigin = "core" | "caller" | "synthetic" | ProtocolId;
7
8
  /** The origin a declared contract id names: a `core.` id is one of the engine's own contracts, any other id a caller's. The one
8
- * reading of the prefix — the definition factory attaches by it, and the caller-tool door refuses a caller spec that declares one. */
9
+ * reading of the prefix — the definition factory labels a descriptor by it, and the caller-tool door refuses a caller entry (a
10
+ * spec's `contract`, a product's descriptor) that claims one the engine did not mint. */
9
11
  export declare function contractOriginOf(contractId: string): "core" | "caller";
12
+ export declare function isEngineDescriptor(value: unknown): boolean;
10
13
  export interface ToolContractDescriptor {
11
14
  /** Stable contract identity, e.g. `core.read@2`. Versioned independently of the wire name. */
12
15
  contractId: string;
@@ -21,7 +24,9 @@ export interface ToolContractDescriptor {
21
24
  shapeDigest: string;
22
25
  /** Full materialized schema digest (incl. descriptions) — the model-visible wire face. */
23
26
  wireSchemaDigest: string;
24
- /** The presentation card in effect. v1: `builtin:<wireName>` (the factory's inline text). */
27
+ /** The presentation card in effect ({@link cardIdOf}): `builtin:<wireName>` for a declared contract's card, the
28
+ * undeclared-contract prefix for any other tool's, and `#<variant id>` after it when the mount chose one of the
29
+ * description's variants (`descriptionVariants`) over its unconditional text. */
25
30
  cardId: string;
26
31
  }
27
32
  /**
@@ -47,6 +52,28 @@ export interface ToolManifestRow {
47
52
  }
48
53
  export declare function computeShapeDigest(schema: TSchema | undefined): string;
49
54
  export declare function computeWireSchemaDigest(schema: TSchema | undefined, description: string): string;
55
+ /**
56
+ * The judge of a caller roster's card declarations where the roster enters, every entry the caller handed, mounted or not: the
57
+ * config-door phase (over the snapshot's faces) and a resume's screen before its claim (one function, so a resume's row stays
58
+ * pending). A description variant table the engine cannot read is refused (`config.tool_face_invalid`); an entry still carrying
59
+ * the retired `descriptionClassic` as plain data is refused by name (`config.deps_retired_key`) — the door and the sentence the
60
+ * snapshot gives the key on the LIVE entry under every reading of it (a prototype's getter, a non-enumerable member), so a face
61
+ * never carries one and the resume's screen is where this line fires. What the receipt cannot take without running the caller's
62
+ * code (an accessor, a Proxy, an entry of another prototype, a non-enumerable member) is not judged here: a variant table is
63
+ * judged again at the mount ({@link mountDescriptionVariant}), a retired member by the snapshot — on a resume, after the claim.
64
+ */
65
+ export declare function assertToolCardDeclarations(tools: unknown): void;
66
+ /**
67
+ * The face a run mounts for a tool under its prompt traits: the first of the tool's description variants whose trait
68
+ * condition holds over the run's traits replaces its description (a shallow copy carrying the chosen variant's id, so the
69
+ * card id reports it); none holds, or the tool declares none, ⇒ the card's unconditional text. A face some run already
70
+ * mounted is judged from its card again, never from the text that run chose. The selection reads traits through the
71
+ * catalog's own trait reading ({@link traitsHold}). A variant the engine cannot read refuses the task by name
72
+ * (`config.tool_face_invalid`) — never mounted as if the tool had one form. One function ({@link descriptionVariantsProblem})
73
+ * judges a table at both places: {@link assertToolCardDeclarations} over the entries the receipt can read as data, and here over
74
+ * every tool the run keeps after the exclusion valve — so a table the door could not read is judged when it is mounted.
75
+ */
76
+ export declare function mountDescriptionVariant(tool: AgentTool, traits: ReadonlySet<PromptTraitName>): AgentTool;
50
77
  export interface AttachContractInput {
51
78
  contractId: string;
52
79
  implementationRevision: string;
@@ -54,8 +81,15 @@ export interface AttachContractInput {
54
81
  aliases?: string[];
55
82
  }
56
83
  /** Attach a contract descriptor to a materialized tool (factory exit point). Digests are computed
57
- * from the tool's REAL mounted schema/description, so they always reflect the wire face. */
84
+ * from the tool's REAL mounted schema/description, so they always reflect the wire face. A descriptor attached here is the
85
+ * caller's word, whatever its `origin`: it is never the engine's mint ({@link attachEngineToolContract}). */
58
86
  export declare function attachToolContract(tool: AgentTool, input: AttachContractInput): void;
87
+ /** The factory's attach for a contract the engine's catalog minted: the descriptor is itself recorded as the engine's mint, frozen
88
+ * (its alias list included), so a roster door can tell a product the engine built from a definition from one a host dressed in a
89
+ * `core.` id. Internal — not exported from the package root. */
90
+ export declare function attachEngineToolContract(tool: AgentTool, input: AttachContractInput): void;
91
+ /** The descriptor `tool` carries, as attached — no shape judgment and no copy. Internal: the caller-roster door reads the claim here. */
92
+ export declare function attachedContractOf(tool: object): ToolContractDescriptor | undefined;
59
93
  /**
60
94
  * Resolve a tool's descriptor. Undeclared tools get a deterministic legacy descriptor derived from
61
95
  * their shape (`legacy:<shapeDigest>`), origin per the mount channel — an external tool NEVER
@@ -1,7 +1,16 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { types } from "node:util";
3
+ import { isPlainRecord, receive } from "../core/mods/kernel/receive.js";
4
+ import { assertNoRetiredKeys, RETIRED_TOOL_SPEC_KEYS } from "../core/retired-keys.js";
5
+ import { isPromptTraitName } from "./catalog/schema.js";
6
+ import { traitsHold } from "./select.js";
2
7
  export function contractOriginOf(contractId) {
3
8
  return contractId.startsWith("core.") ? "core" : "caller";
4
9
  }
10
+ const ENGINE_DESCRIPTORS = new WeakSet();
11
+ export function isEngineDescriptor(value) {
12
+ return typeof value === "object" && value !== null && ENGINE_DESCRIPTORS.has(value);
13
+ }
5
14
  const PRESENTATION_KEYWORDS = new Set(["description", "title", "examples", "$id"]);
6
15
  const SCHEMA_NAME_MAPS = new Set([
7
16
  "properties",
@@ -48,8 +57,96 @@ export function computeWireSchemaDigest(schema, description) {
48
57
  return sha(`${canonical(schema ?? null)}\u0000${description}`);
49
58
  }
50
59
  const TOOL_CONTRACT = Symbol("sema.toolContract");
51
- export function attachToolContract(tool, input) {
52
- const descriptor = {
60
+ const CARD_VARIANT = Symbol("sema.toolCardVariant");
61
+ function cardIdOf(base, tool) {
62
+ const chosen = tool[CARD_VARIANT];
63
+ return chosen === undefined ? base : `${base}#${chosen.id}`;
64
+ }
65
+ const VARIANT_ID = /^[A-Za-z0-9._-]{1,64}$/;
66
+ function descriptionVariantsProblem(variants) {
67
+ if (variants === undefined)
68
+ return undefined;
69
+ if (!Array.isArray(variants))
70
+ return "is not a list";
71
+ const ids = new Set();
72
+ const table = variants;
73
+ for (const [i, v] of table.entries()) {
74
+ const at = `descriptionVariants[${i}]`;
75
+ if (v === null || typeof v !== "object" || Array.isArray(v))
76
+ return `${at} is not an object`;
77
+ const r = v;
78
+ for (const k of Object.keys(r))
79
+ if (k !== "id" && k !== "traits" && k !== "text")
80
+ return `${at} carries ${JSON.stringify(k).slice(0, 40)} (id, traits, text only)`;
81
+ if (typeof r.id !== "string" || !VARIANT_ID.test(r.id))
82
+ return `${at}.id is not 1–64 characters of [A-Za-z0-9._-]`;
83
+ if (ids.has(r.id))
84
+ return `${at}.id ${JSON.stringify(r.id)} repeats an earlier variant's`;
85
+ ids.add(r.id);
86
+ if (typeof r.text !== "string" || r.text.trim() === "")
87
+ return `${at}.text is not a non-blank string`;
88
+ const t = r.traits;
89
+ if (t === null || typeof t !== "object" || Array.isArray(t))
90
+ return `${at}.traits is not an object`;
91
+ const lists = Object.entries(t);
92
+ if (lists.length === 0)
93
+ return `${at}.traits is empty (use \`description\`)`;
94
+ for (const [k, list] of lists) {
95
+ if (k !== "allOf" && k !== "noneOf")
96
+ return `${at}.traits carries ${JSON.stringify(k).slice(0, 40)} (allOf, noneOf only)`;
97
+ if (!Array.isArray(list) || list.length === 0)
98
+ return `${at}.traits.${k} is not a non-empty list`;
99
+ const names = list;
100
+ for (const name of names)
101
+ if (!isPromptTraitName(name))
102
+ return `${at}.traits.${k} names ${typeof name === "string" ? JSON.stringify(name.slice(0, 64)) : typeof name}, not a trait`;
103
+ }
104
+ }
105
+ return undefined;
106
+ }
107
+ function descriptionVariantsRefusal(toolName, problem) {
108
+ const named = typeof toolName === "string" ? JSON.stringify(toolName.slice(0, 80)) : `(a ${typeof toolName} name)`;
109
+ return Object.assign(new Error(`tool ${named}: its ${problem.startsWith("descriptionVariants") ? problem : `descriptionVariants ${problem}`}`), { code: "config.tool_face_invalid" });
110
+ }
111
+ const ROSTER_CARD_RECEIPT = Object.freeze({ accessors: "refuse", depth: 6, others: "as-is", contain: true, isProxy: (v) => types.isProxy(v) });
112
+ export function assertToolCardDeclarations(tools) {
113
+ const got = receive(tools, ROSTER_CARD_RECEIPT);
114
+ if (!got.ok || !Array.isArray(got.value))
115
+ return;
116
+ const unread = new Set();
117
+ for (const f of got.faults ?? []) {
118
+ const [at, member] = f.path;
119
+ if (at !== undefined && (member === "name" || member === "descriptionVariants" || member === "descriptionClassic"))
120
+ unread.add(at);
121
+ }
122
+ got.value.forEach((t, i) => {
123
+ if (!isPlainRecord(t) || unread.has(String(i)))
124
+ return;
125
+ assertNoRetiredKeys(t, RETIRED_TOOL_SPEC_KEYS, "ToolSpec");
126
+ const problem = descriptionVariantsProblem(t["descriptionVariants"]);
127
+ if (problem !== undefined)
128
+ throw descriptionVariantsRefusal(t["name"], problem);
129
+ });
130
+ }
131
+ export function mountDescriptionVariant(tool, traits) {
132
+ const variants = tool.descriptionVariants;
133
+ const problem = descriptionVariantsProblem(variants);
134
+ if (problem !== undefined)
135
+ throw descriptionVariantsRefusal(tool.name, problem);
136
+ const earlier = tool[CARD_VARIANT];
137
+ const unconditional = earlier?.unconditional ?? tool.description;
138
+ const chosen = tool.descriptionVariants?.find((v) => traitsHold(v.traits, traits));
139
+ if (chosen === undefined && earlier === undefined)
140
+ return tool;
141
+ const face = { ...tool, description: chosen?.text ?? unconditional };
142
+ if (chosen !== undefined)
143
+ face[CARD_VARIANT] = Object.freeze({ id: chosen.id, unconditional });
144
+ else
145
+ delete face[CARD_VARIANT];
146
+ return face;
147
+ }
148
+ function descriptorOf(tool, input) {
149
+ return {
53
150
  contractId: input.contractId,
54
151
  implementationRevision: input.implementationRevision,
55
152
  wireName: tool.name,
@@ -59,8 +156,20 @@ export function attachToolContract(tool, input) {
59
156
  wireSchemaDigest: computeWireSchemaDigest(tool.parameters, tool.description ?? ""),
60
157
  cardId: `builtin:${tool.name}`,
61
158
  };
159
+ }
160
+ export function attachToolContract(tool, input) {
161
+ tool[TOOL_CONTRACT] = descriptorOf(tool, input);
162
+ }
163
+ export function attachEngineToolContract(tool, input) {
164
+ const descriptor = descriptorOf(tool, input);
165
+ if (descriptor.aliases !== undefined)
166
+ descriptor.aliases = Object.freeze([...descriptor.aliases]);
167
+ ENGINE_DESCRIPTORS.add(Object.freeze(descriptor));
62
168
  tool[TOOL_CONTRACT] = descriptor;
63
169
  }
170
+ export function attachedContractOf(tool) {
171
+ return tool[TOOL_CONTRACT];
172
+ }
64
173
  export function getToolContract(tool, fallbackOrigin = "caller") {
65
174
  const attached = tool[TOOL_CONTRACT];
66
175
  if (attached) {
@@ -74,7 +183,7 @@ export function getToolContract(tool, fallbackOrigin = "caller") {
74
183
  origin: attached.origin,
75
184
  shapeDigest: mountedShape,
76
185
  wireSchemaDigest: computeWireSchemaDigest(tool.parameters, tool.description ?? ""),
77
- cardId: `legacy:${tool.name}`,
186
+ cardId: cardIdOf(`legacy:${tool.name}`, tool),
78
187
  };
79
188
  }
80
189
  return {
@@ -82,6 +191,7 @@ export function getToolContract(tool, fallbackOrigin = "caller") {
82
191
  wireName: tool.name,
83
192
  shapeDigest: mountedShape,
84
193
  wireSchemaDigest: computeWireSchemaDigest(tool.parameters, tool.description ?? ""),
194
+ cardId: cardIdOf(attached.cardId, tool),
85
195
  };
86
196
  }
87
197
  const shapeDigest = computeShapeDigest(tool.parameters);
@@ -93,7 +203,7 @@ export function getToolContract(tool, fallbackOrigin = "caller") {
93
203
  origin: fallbackOrigin,
94
204
  shapeDigest,
95
205
  wireSchemaDigest: computeWireSchemaDigest(tool.parameters, tool.description ?? ""),
96
- cardId: `legacy:${tool.name}`,
206
+ cardId: cardIdOf(`legacy:${tool.name}`, tool),
97
207
  };
98
208
  }
99
209
  export function hasToolContract(tool) {