@sema-agent/server 7.131.0 → 7.133.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 (509) hide show
  1. package/MIGRATION.md +575 -0
  2. package/README.md +12 -9
  3. package/README.zh-CN.md +9 -6
  4. package/USAGE.md +326 -98
  5. package/deploy/sema-up/README.md +19 -1
  6. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
  7. package/deploy/sema-up/chart/templates/server.yaml +5 -2
  8. package/deploy/sema-up/stack/compose.yaml +3 -0
  9. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  10. package/dist/adoption/plan.d.ts +3 -2
  11. package/dist/adoption/plan.js +7 -5
  12. package/dist/adoption/runner.js +3 -10
  13. package/dist/adoption/sql.d.ts +3 -2
  14. package/dist/adoption/sql.js +3 -5
  15. package/dist/adoption/wire.d.ts +4 -1
  16. package/dist/adoption/wire.js +1 -0
  17. package/dist/approval-ask-audit-store.d.ts +31 -13
  18. package/dist/approval-ask-audit-store.js +272 -74
  19. package/dist/approval-ask-machine.d.ts +15 -0
  20. package/dist/approval-ask-machine.js +6 -0
  21. package/dist/approval-ask-retention.d.ts +136 -0
  22. package/dist/approval-ask-retention.js +102 -0
  23. package/dist/approval-card.d.ts +82 -20
  24. package/dist/approval-card.js +46 -16
  25. package/dist/approval-deny-reasons.d.ts +1 -1
  26. package/dist/approval.d.ts +9 -0
  27. package/dist/approval.js +24 -3
  28. package/dist/audit.d.ts +33 -19
  29. package/dist/audit.js +12 -16
  30. package/dist/auth-bridge.d.ts +4 -0
  31. package/dist/auth-bridge.js +10 -11
  32. package/dist/bake-runner/main.js +3 -2
  33. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  34. package/dist/boot/deployment-mods.d.ts +31 -0
  35. package/dist/boot/deployment-mods.js +26 -0
  36. package/dist/boot/execution-env.d.ts +1 -1
  37. package/dist/boot/execution-env.js +27 -12
  38. package/dist/boot/execution-lane.js +11 -0
  39. package/dist/boot/leader.js +2 -0
  40. package/dist/boot/memory-boundary.d.ts +2 -2
  41. package/dist/boot/memory-boundary.js +2 -2
  42. package/dist/boot/memory-consolidation.d.ts +5 -4
  43. package/dist/boot/memory-consolidation.js +7 -6
  44. package/dist/boot/org-delivery.d.ts +28 -0
  45. package/dist/boot/org-delivery.js +20 -0
  46. package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
  47. package/dist/boot/read-deny-anchor-audit.js +36 -0
  48. package/dist/boot/reapers.d.ts +3 -0
  49. package/dist/boot/reapers.js +21 -1
  50. package/dist/boot/resolve-spec.d.ts +4 -5
  51. package/dist/boot/resolve-spec.js +74 -123
  52. package/dist/boot/runner-deps.d.ts +19 -8
  53. package/dist/boot/runner-deps.js +15 -2
  54. package/dist/boot/session-faces.d.ts +2 -7
  55. package/dist/boot/session-faces.js +4 -2
  56. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  57. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  58. package/dist/boot/stage-03-store-backend.js +2 -2
  59. package/dist/boot/stage-04-stores.d.ts +1 -1
  60. package/dist/boot/stage-05-execution-env.d.ts +4 -4
  61. package/dist/boot/stage-05-execution-env.js +7 -10
  62. package/dist/boot/stage-06-runners.d.ts +4 -2
  63. package/dist/boot/stage-06-runners.js +11 -7
  64. package/dist/boot/stage-07-capability-layer.d.ts +4 -2
  65. package/dist/boot/stage-07-capability-layer.js +27 -6
  66. package/dist/boot/stage-08-reapers.d.ts +4 -2
  67. package/dist/boot/stage-08-reapers.js +2 -2
  68. package/dist/boot/stage-09-leader.d.ts +6 -9
  69. package/dist/boot/stage-10-http-server.d.ts +6 -9
  70. package/dist/boot/stage-10-http-server.js +7 -9
  71. package/dist/boot/stores.d.ts +1 -1
  72. package/dist/boot/stores.js +7 -8
  73. package/dist/boot/web-admin.d.ts +4 -3
  74. package/dist/boot/web-admin.js +186 -98
  75. package/dist/boot/workflow-orchestration.d.ts +2 -0
  76. package/dist/boot/workflow-orchestration.js +2 -1
  77. package/dist/brain.js +25 -25
  78. package/dist/breaker-key.d.ts +6 -0
  79. package/dist/breaker-key.js +29 -0
  80. package/dist/budget.js +5 -4
  81. package/dist/caller-text-echo.d.ts +23 -0
  82. package/dist/caller-text-echo.js +21 -0
  83. package/dist/capabilities/brand-identity.d.ts +26 -0
  84. package/dist/capabilities/brand-identity.js +27 -0
  85. package/dist/capabilities/center-plugins.d.ts +7 -0
  86. package/dist/capabilities/center-plugins.js +1 -1
  87. package/dist/capabilities/center-prompts.d.ts +32 -59
  88. package/dist/capabilities/center-prompts.js +18 -32
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/engine-capabilities.js +2 -1
  92. package/dist/capabilities/execution-lane.js +2 -2
  93. package/dist/capabilities/hands-lane.d.ts +30 -6
  94. package/dist/capabilities/hands-lane.js +11 -1
  95. package/dist/capabilities/mcp-probe.d.ts +48 -3
  96. package/dist/capabilities/mcp-probe.js +47 -135
  97. package/dist/capabilities/scenarios.d.ts +95 -45
  98. package/dist/capabilities/scenarios.js +53 -38
  99. package/dist/capabilities/skills.d.ts +19 -4
  100. package/dist/capabilities/skills.js +30 -10
  101. package/dist/capability-facts.d.ts +34 -4
  102. package/dist/capability-facts.js +28 -2
  103. package/dist/center-config-tier.d.ts +69 -0
  104. package/dist/center-config-tier.js +42 -0
  105. package/dist/checkpoint-identity.d.ts +16 -0
  106. package/dist/checkpoint-identity.js +19 -0
  107. package/dist/config-catalog.d.ts +17 -10
  108. package/dist/config-catalog.js +47 -32
  109. package/dist/config-d-migration.d.ts +3 -1
  110. package/dist/config-d-migration.js +2 -2
  111. package/dist/config-dir-trust.d.ts +114 -0
  112. package/dist/config-dir-trust.js +388 -0
  113. package/dist/config-invariants.d.ts +18 -5
  114. package/dist/config-invariants.js +35 -3
  115. package/dist/config-lkg.d.ts +9 -9
  116. package/dist/config-lkg.js +20 -4
  117. package/dist/config-provider.d.ts +9 -2
  118. package/dist/config-provider.js +18 -6
  119. package/dist/config-types.d.ts +75 -20
  120. package/dist/config-types.js +8 -0
  121. package/dist/config.d.ts +13 -0
  122. package/dist/config.js +137 -62
  123. package/dist/delegated-session-owner.d.ts +185 -0
  124. package/dist/delegated-session-owner.js +119 -0
  125. package/dist/device-protocol.d.ts +5 -3
  126. package/dist/device-protocol.js +1 -1
  127. package/dist/device-ws-hub.js +21 -2
  128. package/dist/device-ws-protocol.d.ts +70 -6
  129. package/dist/device-ws-protocol.js +50 -22
  130. package/dist/elicitation.js +3 -2
  131. package/dist/entry-problems.d.ts +34 -0
  132. package/dist/entry-problems.js +14 -0
  133. package/dist/env-name-allowlist-knobs.d.ts +12 -2
  134. package/dist/env-name-allowlist-knobs.js +5 -4
  135. package/dist/exec-bounds.d.ts +15 -3
  136. package/dist/exec-bounds.js +4 -0
  137. package/dist/execution-lane-caps.d.ts +56 -10
  138. package/dist/execution-lane-caps.js +50 -0
  139. package/dist/field-conflict.d.ts +43 -0
  140. package/dist/field-conflict.js +20 -0
  141. package/dist/fleet/fleet-bus.d.ts +80 -6
  142. package/dist/fleet/fleet-bus.js +41 -9
  143. package/dist/hooks/classic-stations.d.ts +91 -0
  144. package/dist/hooks/classic-stations.js +27 -0
  145. package/dist/hooks/command-spawn.d.ts +57 -0
  146. package/dist/hooks/command-spawn.js +139 -0
  147. package/dist/hooks/hook-llm.d.ts +8 -5
  148. package/dist/hooks/hook-llm.js +79 -36
  149. package/dist/hooks/hook-runner.d.ts +349 -95
  150. package/dist/hooks/hook-runner.js +855 -568
  151. package/dist/hooks/hook-source.d.ts +44 -0
  152. package/dist/hooks/hook-source.js +40 -0
  153. package/dist/http/active-run-conflict.d.ts +5 -13
  154. package/dist/http/active-run-conflict.js +17 -27
  155. package/dist/http/admission.d.ts +8 -2
  156. package/dist/http/admission.js +188 -101
  157. package/dist/http/approval-sweeps.js +99 -21
  158. package/dist/http/caller-trust.d.ts +77 -0
  159. package/dist/http/caller-trust.js +143 -0
  160. package/dist/http/checkpoint-ctx.d.ts +41 -24
  161. package/dist/http/checkpoint-ctx.js +23 -16
  162. package/dist/http/claimed-run.d.ts +14 -0
  163. package/dist/http/claimed-run.js +15 -0
  164. package/dist/http/device-placement.d.ts +2 -4
  165. package/dist/http/device-placement.js +7 -11
  166. package/dist/http/dispatch.d.ts +0 -4
  167. package/dist/http/dispatch.js +15 -13
  168. package/dist/http/durable-run-leg.d.ts +6 -33
  169. package/dist/http/durable-run-leg.js +36 -10
  170. package/dist/http/health-self-report.d.ts +7 -5
  171. package/dist/http/health-self-report.js +4 -18
  172. package/dist/http/owner-access.d.ts +56 -0
  173. package/dist/http/owner-access.js +42 -0
  174. package/dist/http/principal-gate.d.ts +70 -28
  175. package/dist/http/principal-gate.js +61 -15
  176. package/dist/http/readiness.d.ts +11 -5
  177. package/dist/http/readiness.js +10 -3
  178. package/dist/http/refusal-body.d.ts +21 -0
  179. package/dist/http/refusal-body.js +4 -0
  180. package/dist/http/request-guards.d.ts +43 -23
  181. package/dist/http/request-guards.js +53 -17
  182. package/dist/http/resume-ctx-read.d.ts +2 -5
  183. package/dist/http/resume-ctx-read.js +7 -4
  184. package/dist/http/resume-legs.d.ts +28 -4
  185. package/dist/http/resume-legs.js +169 -91
  186. package/dist/http/retired-service-deps.d.ts +43 -0
  187. package/dist/http/retired-service-deps.js +18 -0
  188. package/dist/http/route-ctx.d.ts +44 -28
  189. package/dist/http/route-ctx.js +4 -0
  190. package/dist/http/route-table.js +2 -0
  191. package/dist/http/routes/a2a-serve.js +3 -4
  192. package/dist/http/routes/admin-config-refresh.js +1 -1
  193. package/dist/http/routes/admin-drain.js +1 -1
  194. package/dist/http/routes/admin-memory-optout.js +5 -1
  195. package/dist/http/routes/adoption.js +2 -9
  196. package/dist/http/routes/approvals-assistant.js +49 -48
  197. package/dist/http/routes/background.js +3 -2
  198. package/dist/http/routes/capabilities.js +21 -5
  199. package/dist/http/routes/config-catalog.d.ts +3 -3
  200. package/dist/http/routes/config-catalog.js +1 -1
  201. package/dist/http/routes/devices.js +3 -17
  202. package/dist/http/routes/diagnostics.js +6 -2
  203. package/dist/http/routes/images.js +6 -7
  204. package/dist/http/routes/leader.js +1 -8
  205. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  206. package/dist/http/routes/mcp-reconnect.js +3 -2
  207. package/dist/http/routes/memory-bundle.js +1 -1
  208. package/dist/http/routes/memory-compliance.js +1 -1
  209. package/dist/http/routes/memory-consolidation.js +1 -1
  210. package/dist/http/routes/memory-origin.js +1 -1
  211. package/dist/http/routes/memory-policy.d.ts +1 -1
  212. package/dist/http/routes/memory-policy.js +3 -2
  213. package/dist/http/routes/notify-wake.js +8 -21
  214. package/dist/http/routes/observability.js +2 -2
  215. package/dist/http/routes/principal-inbox.d.ts +39 -0
  216. package/dist/http/routes/principal-inbox.js +76 -0
  217. package/dist/http/routes/retention-ops.js +2 -9
  218. package/dist/http/routes/rules.js +5 -18
  219. package/dist/http/routes/runs.d.ts +5 -0
  220. package/dist/http/routes/runs.js +34 -107
  221. package/dist/http/routes/session-sync.js +15 -26
  222. package/dist/http/routes/sessions.js +30 -40
  223. package/dist/http/routes/shared-memory.js +2 -13
  224. package/dist/http/routes/side-query.js +8 -7
  225. package/dist/http/routes/tasks.js +67 -21
  226. package/dist/http/routes/workflows.d.ts +351 -0
  227. package/dist/http/routes/workflows.js +153 -119
  228. package/dist/http/send.d.ts +33 -10
  229. package/dist/http/send.js +21 -4
  230. package/dist/http/server.d.ts +27 -18
  231. package/dist/http/server.js +34 -6
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +25 -0
  234. package/dist/http/submit-ctx.js +40 -0
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +11 -8
  238. package/dist/index.d.ts +2 -2
  239. package/dist/index.js +1 -2
  240. package/dist/lane-home-probe.d.ts +112 -0
  241. package/dist/lane-home-probe.js +101 -0
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/limit-refusal.d.ts +59 -0
  245. package/dist/limit-refusal.js +15 -0
  246. package/dist/main.js +1 -1
  247. package/dist/mcp-assertion-header.d.ts +32 -19
  248. package/dist/mcp-assertion-header.js +10 -9
  249. package/dist/mcp-tool-faces.d.ts +5 -0
  250. package/dist/mcp-tool-faces.js +6 -4
  251. package/dist/memory-project-layer.d.ts +37 -0
  252. package/dist/memory-project-layer.js +46 -0
  253. package/dist/memory-scope.d.ts +24 -17
  254. package/dist/memory-scope.js +24 -8
  255. package/dist/memory-sync-client.d.ts +27 -13
  256. package/dist/memory-sync-client.js +107 -18
  257. package/dist/model-entry-refusal.d.ts +9 -1
  258. package/dist/model-entry-refusal.js +6 -1
  259. package/dist/model-plane-face.d.ts +51 -0
  260. package/dist/model-plane-face.js +24 -0
  261. package/dist/model-provider.d.ts +44 -12
  262. package/dist/model-provider.js +21 -2
  263. package/dist/model-route-endpoint.d.ts +9 -12
  264. package/dist/model-route-endpoint.js +8 -11
  265. package/dist/model-route-env.d.ts +22 -0
  266. package/dist/model-route-env.js +2 -0
  267. package/dist/model-route-gap.d.ts +60 -30
  268. package/dist/model-route-gap.js +21 -15
  269. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  270. package/dist/observability/corrupt-read-seat.js +9 -0
  271. package/dist/observability/cost-taxonomy.d.ts +7 -7
  272. package/dist/observability/err-text.d.ts +6 -0
  273. package/dist/observability/err-text.js +18 -4
  274. package/dist/observability/fail-open.d.ts +76 -14
  275. package/dist/observability/fail-open.js +76 -14
  276. package/dist/observability/metrics.js +4 -1
  277. package/dist/observability/prompt-manifest.d.ts +33 -82
  278. package/dist/observability/prompt-manifest.js +122 -17
  279. package/dist/observability/run-terminal.js +14 -6
  280. package/dist/observability/secret-env-scrub.d.ts +13 -1
  281. package/dist/observability/secret-env-scrub.js +13 -1
  282. package/dist/observability/tool-trace.d.ts +16 -21
  283. package/dist/observability/tool-trace.js +58 -49
  284. package/dist/operator-ask.d.ts +10 -0
  285. package/dist/operator-ask.js +3 -0
  286. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  287. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  288. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  289. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  290. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  291. package/dist/orchestration/workflow-notify-journal.js +27 -34
  292. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  293. package/dist/orchestration/workflow-park-decision.js +118 -0
  294. package/dist/org-delivery-gate.d.ts +81 -0
  295. package/dist/org-delivery-gate.js +59 -0
  296. package/dist/panel-tool-names.d.ts +23 -0
  297. package/dist/panel-tool-names.js +8 -0
  298. package/dist/parked-decide.d.ts +39 -6
  299. package/dist/parked-decide.js +98 -51
  300. package/dist/parked-revive-surface.d.ts +9 -2
  301. package/dist/parked-revive-surface.js +11 -8
  302. package/dist/per-task-image.d.ts +7 -1
  303. package/dist/per-task-image.js +3 -3
  304. package/dist/permission-rule-list.d.ts +1 -1
  305. package/dist/permission-rule-list.js +2 -2
  306. package/dist/plain-string-record.d.ts +25 -0
  307. package/dist/plain-string-record.js +32 -0
  308. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  309. package/dist/plugins/approval-ask-store-file.js +21 -0
  310. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  311. package/dist/plugins/approval-ask-store-memory.js +34 -2
  312. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  313. package/dist/plugins/approval-ask-store-sql.js +37 -1
  314. package/dist/plugins/blob-backend.d.ts +83 -15
  315. package/dist/plugins/blob-backend.js +68 -15
  316. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  317. package/dist/plugins/breaker-state-sql.js +4 -4
  318. package/dist/plugins/caching-session-store.d.ts +3 -0
  319. package/dist/plugins/caching-session-store.js +3 -0
  320. package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
  321. package/dist/plugins/checkpoint-store-sql.js +59 -28
  322. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  323. package/dist/plugins/file-history-store-sql.js +3 -1
  324. package/dist/plugins/file-run-store.d.ts +5 -13
  325. package/dist/plugins/file-run-store.js +9 -0
  326. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  327. package/dist/plugins/fork-routing-session-store.js +12 -1
  328. package/dist/plugins/host-platform.d.ts +2 -0
  329. package/dist/plugins/host-platform.js +2 -1
  330. package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
  331. package/dist/plugins/k8s-bg-scripts.js +22 -0
  332. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  333. package/dist/plugins/local-checkpoint-store.js +11 -3
  334. package/dist/plugins/local-session-store.d.ts +1 -1
  335. package/dist/plugins/local-session-store.js +1 -1
  336. package/dist/plugins/local-session-window.d.ts +39 -0
  337. package/dist/plugins/local-session-window.js +54 -0
  338. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  339. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  340. package/dist/plugins/mailbox-store-sql.js +77 -52
  341. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  342. package/dist/plugins/memory-run-store.d.ts +5 -13
  343. package/dist/plugins/memory-run-store.js +8 -0
  344. package/dist/plugins/one-time-migrations.d.ts +245 -93
  345. package/dist/plugins/one-time-migrations.js +668 -207
  346. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  347. package/dist/plugins/org-delivery-quota-store.js +228 -0
  348. package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
  349. package/dist/plugins/permission-rule-store-sql.js +4 -18
  350. package/dist/plugins/pg-pool.js +39 -7
  351. package/dist/plugins/pg-session-storage.d.ts +20 -8
  352. package/dist/plugins/pg-session-storage.js +34 -21
  353. package/dist/plugins/remote-env-adb.d.ts +12 -12
  354. package/dist/plugins/remote-env-adb.js +21 -6
  355. package/dist/plugins/remote-env-device.js +3 -0
  356. package/dist/plugins/remote-env-e2b.d.ts +1 -1
  357. package/dist/plugins/remote-env-e2b.js +21 -9
  358. package/dist/plugins/remote-env-host.d.ts +9 -9
  359. package/dist/plugins/remote-env-host.js +10 -32
  360. package/dist/plugins/remote-env-k8s.d.ts +103 -38
  361. package/dist/plugins/remote-env-k8s.js +288 -95
  362. package/dist/plugins/remote-env-local-docker.d.ts +27 -13
  363. package/dist/plugins/remote-env-local-docker.js +82 -11
  364. package/dist/plugins/remote-env-ssh.d.ts +21 -12
  365. package/dist/plugins/remote-env-ssh.js +117 -5
  366. package/dist/plugins/remote-shell.d.ts +0 -1
  367. package/dist/plugins/remote-shell.js +1 -2
  368. package/dist/plugins/retention-store-sql.js +6 -2
  369. package/dist/plugins/run-store-sql.d.ts +16 -14
  370. package/dist/plugins/run-store-sql.js +22 -2
  371. package/dist/plugins/schema-consistency.d.ts +54 -0
  372. package/dist/plugins/schema-consistency.js +52 -0
  373. package/dist/plugins/schema-indexes.js +2 -0
  374. package/dist/plugins/send-user-file.js +2 -2
  375. package/dist/plugins/session-epoch-anchor.d.ts +39 -0
  376. package/dist/plugins/session-epoch-anchor.js +22 -0
  377. package/dist/plugins/session-store.d.ts +18 -8
  378. package/dist/plugins/session-store.js +15 -4
  379. package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
  380. package/dist/plugins/shared-memory-store-sql.js +5 -16
  381. package/dist/plugins/sql-driver.d.ts +205 -1
  382. package/dist/plugins/sql-driver.js +325 -13
  383. package/dist/plugins/sql-errors.d.ts +64 -0
  384. package/dist/plugins/sql-errors.js +57 -0
  385. package/dist/plugins/store-backend.d.ts +36 -1
  386. package/dist/plugins/store-backend.js +42 -15
  387. package/dist/plugins/store-contracts.d.ts +42 -0
  388. package/dist/plugins/store-contracts.js +1 -0
  389. package/dist/plugins/tidb-pool.d.ts +6 -1
  390. package/dist/plugins/tidb-pool.js +44 -10
  391. package/dist/plugins/tidb-session-storage.d.ts +8 -11
  392. package/dist/plugins/tidb-session-storage.js +6 -16
  393. package/dist/plugins/tidb-session-store.d.ts +24 -4
  394. package/dist/plugins/tidb-session-store.js +29 -5
  395. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  396. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  397. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  398. package/dist/plugins/workflow-run-store-sql.js +50 -9
  399. package/dist/posture-source.d.ts +18 -10
  400. package/dist/posture-source.js +4 -1
  401. package/dist/project-identity.d.ts +45 -6
  402. package/dist/project-identity.js +162 -8
  403. package/dist/project-layer-key.d.ts +28 -0
  404. package/dist/project-layer-key.js +29 -0
  405. package/dist/prompts-domain-validate.d.ts +17 -61
  406. package/dist/prompts-domain-validate.js +9 -119
  407. package/dist/question.js +3 -2
  408. package/dist/read-deny-entry.d.ts +25 -0
  409. package/dist/read-deny-entry.js +12 -0
  410. package/dist/read-face-posture.d.ts +37 -11
  411. package/dist/read-face-posture.js +32 -3
  412. package/dist/request-key-closure.d.ts +9 -2
  413. package/dist/request-key-closure.js +11 -5
  414. package/dist/request-value-closure.d.ts +5 -0
  415. package/dist/request-value-closure.js +11 -3
  416. package/dist/rule-entry-list.d.ts +38 -11
  417. package/dist/rule-entry-list.js +106 -30
  418. package/dist/rules-consent.js +3 -4
  419. package/dist/run-acceptance.d.ts +19 -3
  420. package/dist/run-acceptance.js +13 -1
  421. package/dist/run-local.js +54 -24
  422. package/dist/runs.d.ts +15 -8
  423. package/dist/runs.js +35 -1
  424. package/dist/runtime-caps-resolver.d.ts +16 -6
  425. package/dist/runtime-caps-resolver.js +18 -5
  426. package/dist/sandbox-pkg-source.d.ts +19 -1
  427. package/dist/sandbox-pkg-source.js +29 -7
  428. package/dist/security.d.ts +87 -9
  429. package/dist/security.js +52 -9
  430. package/dist/server-secret-env.d.ts +44 -18
  431. package/dist/server-secret-env.js +49 -8
  432. package/dist/session-error-wire.d.ts +19 -2
  433. package/dist/session-error-wire.js +5 -1
  434. package/dist/session-incarnation.d.ts +15 -5
  435. package/dist/session-incarnation.js +16 -9
  436. package/dist/session-titled-frame.d.ts +33 -0
  437. package/dist/session-titled-frame.js +4 -0
  438. package/dist/session-titler.d.ts +9 -1
  439. package/dist/session-titler.js +27 -6
  440. package/dist/spec-fields.d.ts +28 -16
  441. package/dist/spec-fields.js +66 -54
  442. package/dist/sql-engine-posture.d.ts +31 -4
  443. package/dist/sql-engine-posture.js +36 -1
  444. package/dist/stored-request-tool-axes-m19.d.ts +19 -4
  445. package/dist/stored-request-tool-axes-m19.js +30 -2
  446. package/dist/task-a2a.d.ts +9 -1
  447. package/dist/task-a2a.js +73 -47
  448. package/dist/task-cwd.d.ts +1 -1
  449. package/dist/task-mcp.d.ts +46 -58
  450. package/dist/task-mcp.js +82 -107
  451. package/dist/task-settings.d.ts +95 -108
  452. package/dist/task-settings.js +77 -98
  453. package/dist/text-bidi.d.ts +1 -48
  454. package/dist/text-bidi.js +3 -5
  455. package/dist/tighten-only-seats.d.ts +150 -0
  456. package/dist/tighten-only-seats.js +196 -0
  457. package/dist/tool-approval.d.ts +304 -88
  458. package/dist/tool-approval.js +623 -239
  459. package/dist/trace/core-keyset-guard.d.ts +122 -20
  460. package/dist/trace/engine-notice-wire.d.ts +11 -3
  461. package/dist/trace/engine-notice-wire.js +8 -1
  462. package/dist/trace/exit-seat.d.ts +28 -0
  463. package/dist/trace/exit-seat.js +76 -0
  464. package/dist/trace/ledger-events.d.ts +6 -3
  465. package/dist/trace/ledger-sink.js +4 -1
  466. package/dist/trace/model-segment.js +1 -1
  467. package/dist/trace/project.d.ts +98 -17
  468. package/dist/trace/project.js +98 -50
  469. package/dist/trace/projection-table.d.ts +100 -0
  470. package/dist/trace/projection-table.js +130 -0
  471. package/dist/trace/redact.d.ts +54 -0
  472. package/dist/trace/redact.js +778 -152
  473. package/dist/trace/self-minted-wire.d.ts +345 -1
  474. package/dist/trace/self-minted-wire.js +117 -1
  475. package/dist/trace/wire-projection-faces.d.ts +377 -3
  476. package/dist/trace/wire-projection-faces.js +164 -1
  477. package/dist/url-refusal.js +2 -0
  478. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  479. package/dist/web-admin-client/apply-effective.js +56 -5
  480. package/dist/web-admin-client/candidate-gate.d.ts +6 -6
  481. package/dist/web-admin-client/candidate-gate.js +3 -3
  482. package/dist/web-admin-client/facade.d.ts +1 -1
  483. package/dist/web-admin-client/facade.js +1 -1
  484. package/dist/web-admin-client/http-client.js +0 -6
  485. package/dist/web-admin-client/read-face.js +5 -9
  486. package/dist/web-admin-client/read-warnings.d.ts +13 -0
  487. package/dist/web-admin-client/read-warnings.js +10 -0
  488. package/dist/web-admin-client/skills-mcp.d.ts +3 -0
  489. package/dist/web-admin-client/skills-mcp.js +11 -9
  490. package/dist/web-admin-client/types.d.ts +2 -3
  491. package/dist/workspace-cache.d.ts +35 -0
  492. package/dist/workspace-cache.js +36 -0
  493. package/dist/workspace-space.d.ts +3 -2
  494. package/dist/workspace-space.js +2 -0
  495. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
  496. package/package.json +8 -4
  497. package/scripts/drain-check-local.mjs +34 -1
  498. package/scripts/drain-check.mysql.sql +30 -2
  499. package/scripts/drain-check.pg.sql +29 -2
  500. package/dist/capabilities/memory-notice.d.ts +0 -138
  501. package/dist/capabilities/memory-notice.js +0 -64
  502. package/dist/capabilities/prompt.d.ts +0 -17
  503. package/dist/capabilities/prompt.js +0 -6
  504. package/dist/mcp-content-origin.d.ts +0 -34
  505. package/dist/mcp-content-origin.js +0 -10
  506. package/dist/tool-axis-words.d.ts +0 -27
  507. package/dist/tool-axis-words.js +0 -9
  508. package/dist/wire-name-bound.d.ts +0 -14
  509. package/dist/wire-name-bound.js +0 -13
@@ -1,6 +1,6 @@
1
1
  import { SessionError, materializeA2aTools, materializeMcpTools, sanitizePathComponent } from "@sema-agent/core";
2
2
  import { a2aForScenario, mcpForScenario } from "../../web-admin-client/facade.js";
3
- import { HttpError, isUuidShape, legacyUnownedSessionOk } from "../../security.js";
3
+ import { HttpError, isUuidShape, legacyUnownedSessionOk, sessionOwnerCellOf } from "../../security.js";
4
4
  import { windowMessages, truncateMessageBlobs, redactSessionViewForRead } from "../../audit.js";
5
5
  import { redactSecrets } from "../../trace/redact.js";
6
6
  import { recordFailOpen } from "../../observability/fail-open.js";
@@ -9,18 +9,19 @@ import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.
9
9
  import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS } from "../../task-settings.js";
10
10
  import { readWritableSessionPermissionRules } from "../../session-policy-wire.js";
11
11
  import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
12
- import { gatedPrincipal, explicitOperatorOk, sessionOwnerReadable, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
12
+ import { gatedPrincipal, explicitOperatorOk, sessionCallerOf, sessionOwnerReadable, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
13
+ import { runRowReadableOnSessionFace } from "../owner-access.js";
13
14
  import { assertNever, SESSION_NOT_FOUND_MESSAGE } from "../route-ctx.js";
14
15
  import * as facts from "../../capability-facts.js";
15
16
  import { rosterAgentId } from "./agents-roster.js";
16
17
  import { projectSessionListRow } from "./sessions-list.js";
17
18
  import { readSessionRowPatch } from "../../session-row.js";
19
+ import { buildBoundedToolNames } from "../../panel-tool-names.js";
18
20
  const MCP_STATUS_TTL_MS = 5_000;
19
21
  const A2A_STATUS_TTL_MS = 5_000;
20
22
  const A2A_MATERIALIZE_TIMEOUT_MS = 10_000;
21
23
  const MEMORY_STATUS_TTL_MS = 5_000;
22
24
  const LAST_LEG_LEDGER_TIMEOUT_MS = 2_000;
23
- const A2A_PANEL_MAX_TOOL_NAMES = 200;
24
25
  export function createSessionsLocal() {
25
26
  return {
26
27
  sseConnections: 0,
@@ -30,11 +31,11 @@ export function createSessionsLocal() {
30
31
  memoryStatusCache: new Map(),
31
32
  };
32
33
  }
33
- async function lastLegMcpFor(deps, sessionId, principal) {
34
+ async function lastLegMcpFor(deps, sessionId, caller) {
34
35
  let timer;
35
36
  try {
36
37
  return await Promise.race([
37
- readLastLegMcp(deps, sessionId, principal),
38
+ readLastLegMcp(deps, sessionId, caller),
38
39
  new Promise((r) => { timer = setTimeout(() => { recordFailOpen("server.mcp-panel.last-leg-unreadable", `ledger read exceeded ${LAST_LEG_LEDGER_TIMEOUT_MS}ms`); r(undefined); }, LAST_LEG_LEDGER_TIMEOUT_MS); }),
39
40
  ]);
40
41
  }
@@ -47,14 +48,14 @@ async function lastLegMcpFor(deps, sessionId, principal) {
47
48
  clearTimeout(timer);
48
49
  }
49
50
  }
50
- async function readLastLegMcp(deps, sessionId, principal) {
51
+ async function readLastLegMcp(deps, sessionId, caller) {
51
52
  const runStore = deps.runStore;
52
53
  if (!runStore || sessionId === null)
53
54
  return undefined;
54
55
  const latest = await runStore.latestRunForSession(sessionId);
55
56
  if (latest === undefined)
56
57
  return undefined;
57
- if (!sessionOwnerReadable(principal, latest.owner, deps.config) && !explicitOperatorOk(principal, deps.config.operatorPrincipals))
58
+ if (!runRowReadableOnSessionFace(deps, caller, latest.owner, "owner_or_operator"))
58
59
  return undefined;
59
60
  const events = await runStore.getEvents(latest.taskId, 0);
60
61
  for (let i = events.length - 1; i >= 0; i--) {
@@ -79,7 +80,7 @@ export async function handleSessions(req, res, match, ctx) {
79
80
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
80
81
  return undefined;
81
82
  }
82
- if (!sessionOwnerOk(req, res, owner))
83
+ if (!sessionOwnerOk(req, res, await sessionOwnerCellOf(deps.sessionStorage, sessionId, owner)))
83
84
  return undefined;
84
85
  }
85
86
  let audit;
@@ -95,7 +96,7 @@ export async function handleSessions(req, res, match, ctx) {
95
96
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
96
97
  return undefined;
97
98
  }
98
- if (!sessionOwnerOk(req, res, audit.owner))
99
+ if (!sessionOwnerOk(req, res, await sessionOwnerCellOf(deps.sessionStorage, sessionId, audit.owner)))
99
100
  return undefined;
100
101
  return audit;
101
102
  };
@@ -138,12 +139,13 @@ export async function handleSessions(req, res, match, ctx) {
138
139
  }
139
140
  {
140
141
  if (match.decl.id === "session-mcp") {
141
- const principal = gatedPrincipal(req, deps.config);
142
+ const caller = sessionCallerOf(req, deps);
143
+ const principal = caller.principal;
142
144
  if (deps.config.requirePrincipal && !principal) {
143
145
  sendPrincipalRefusal(res, req, deps.config);
144
146
  return;
145
147
  }
146
- const lastLegMcp = await lastLegMcpFor(deps, safeDecode(match.params.sessionId), principal);
148
+ const lastLegMcp = await lastLegMcpFor(deps, safeDecode(match.params.sessionId), caller);
147
149
  const ledgerHalf = lastLegMcp === undefined ? {} : { lastLegMcp };
148
150
  let scenarioName;
149
151
  try {
@@ -233,13 +235,7 @@ export async function handleSessions(req, res, match, ctx) {
233
235
  ...(s.agentName ? { agentName: s.agentName } : {}),
234
236
  ...(s.agentDescription ? { agentDescription: s.agentDescription } : {}),
235
237
  ...(s.endpoint ? { endpoint: redactSecrets(String(s.endpoint)).slice(0, 2048) } : {}),
236
- ...(s.toolNames
237
- ? {
238
- toolCount: s.toolNames.length,
239
- toolNames: s.toolNames.slice(0, A2A_PANEL_MAX_TOOL_NAMES),
240
- ...(s.toolNames.length > A2A_PANEL_MAX_TOOL_NAMES ? { toolNamesTruncated: true } : {}),
241
- }
242
- : {}),
238
+ ...(s.toolNames ? { toolCount: s.toolNames.length, ...buildBoundedToolNames(s.toolNames) } : {}),
243
239
  ...(s.error ? { error: redactSecrets(String(s.error)).slice(0, 200) } : {}),
244
240
  })),
245
241
  };
@@ -277,7 +273,7 @@ export async function handleSessions(req, res, match, ctx) {
277
273
  return;
278
274
  }
279
275
  owner = head.owner;
280
- if (!sessionOwnerOk(req, res, owner ?? null))
276
+ if (!sessionOwnerOk(req, res, await sessionOwnerCellOf(deps.sessionStorage, headSession, owner ?? null)))
281
277
  return;
282
278
  leafId = head.leafId;
283
279
  }
@@ -287,7 +283,7 @@ export async function handleSessions(req, res, match, ctx) {
287
283
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
288
284
  return;
289
285
  }
290
- if (!sessionOwnerOk(req, res, owner ?? null))
286
+ if (!sessionOwnerOk(req, res, await sessionOwnerCellOf(deps.sessionStorage, headSession, owner ?? null)))
291
287
  return;
292
288
  leafId = await getLeafId(headSession);
293
289
  }
@@ -344,13 +340,13 @@ export async function handleSessions(req, res, match, ctx) {
344
340
  return;
345
341
  }
346
342
  sse.sseOwnerLookups++;
347
- const ownerP = ownerOf(evSession);
348
- void ownerP.catch(() => undefined).then(() => { sse.sseOwnerLookups--; });
343
+ const cellP = ownerOf(evSession).then((o) => (o === undefined ? undefined : sessionOwnerCellOf(evFact.sessionStorage, evSession, o)));
344
+ void cellP.catch(() => undefined).then(() => { sse.sseOwnerLookups--; });
349
345
  let stallTimer;
350
- let owner;
346
+ let cell;
351
347
  try {
352
- owner = await Promise.race([
353
- ownerP,
348
+ cell = await Promise.race([
349
+ cellP,
354
350
  new Promise((r) => { stallTimer = setTimeout(() => r("__stall__"), stallBound); stallTimer.unref?.(); }),
355
351
  ]);
356
352
  }
@@ -360,21 +356,22 @@ export async function handleSessions(req, res, match, ctx) {
360
356
  }
361
357
  if (closed)
362
358
  return;
363
- if (owner === "__stall__") {
359
+ if (cell === "__stall__") {
364
360
  cleanup();
365
361
  res.setHeader("retry-after", "5");
366
362
  sendError(res, 503, "state.sse_owner_lookup_stalled", "session-events owner lookup stalled — retry");
367
363
  return;
368
364
  }
369
- if (owner === undefined) {
365
+ if (cell === undefined) {
370
366
  cleanup();
371
367
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
372
368
  return;
373
369
  }
374
- if (!sessionOwnerOk(req, res, owner ?? null)) {
370
+ if (!sessionOwnerOk(req, res, cell)) {
375
371
  cleanup();
376
372
  return;
377
373
  }
374
+ const owner = cell.owner;
378
375
  const q = new URLSearchParams(match.search);
379
376
  const lastLeafId = q.get("lastLeafId");
380
377
  let first = true;
@@ -678,7 +675,7 @@ export async function handleSessions(req, res, match, ctx) {
678
675
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
679
676
  return;
680
677
  }
681
- if (!sessionOwnerOk(req, res, face.owner))
678
+ if (!sessionOwnerOk(req, res, await sessionOwnerCellOf(store, sessionId, face.owner)))
682
679
  return;
683
680
  const read = readSessionRowPatch(await readJson(req));
684
681
  if ("problem" in read) {
@@ -717,7 +714,7 @@ export async function handleSessions(req, res, match, ctx) {
717
714
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
718
715
  return;
719
716
  }
720
- if (!scope.fleetWide && owner !== scope.gateOwner && !legacyUnownedSessionOk(deps.config.requirePrincipal, scope.gateOwner, owner)) {
717
+ if (!scope.fleetWide && owner !== scope.gateOwner && !legacyUnownedSessionOk(deps.config.requirePrincipal, sessionCallerOf(req, deps), await sessionOwnerCellOf(forkFact.sessionStorage, sourceId, owner))) {
721
718
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
722
719
  return;
723
720
  }
@@ -755,7 +752,7 @@ export async function handleSessions(req, res, match, ctx) {
755
752
  sendJson(res, 200, { deleted: false });
756
753
  return;
757
754
  }
758
- if (!scope.fleetWide && owner !== scope.gateOwner && !legacyUnownedSessionOk(deps.config.requirePrincipal, scope.gateOwner, owner)) {
755
+ if (!scope.fleetWide && owner !== scope.gateOwner && !legacyUnownedSessionOk(deps.config.requirePrincipal, sessionCallerOf(req, deps), await sessionOwnerCellOf(deleteFact.sessionStorage, sessionId, owner))) {
759
756
  sendJson(res, 200, { deleted: false });
760
757
  return;
761
758
  }
@@ -805,7 +802,7 @@ export async function handleSessions(req, res, match, ctx) {
805
802
  sendError(res, 409, "conflict.session_ownerless", "this session has no recorded owner, so its rules can be neither read nor changed through this route; rules already stored for it keep applying to the runs of the principal they were stored under. Ways out: on the local backend, during the upgrade window, the first task submitted with a principal on a session written by an earlier version claims it for that principal (this route then serves its owner); or delete the session (DELETE /v1/sessions/:id), which removes its rules with it");
806
803
  return;
807
804
  }
808
- const operator = explicitOperatorOk(principal, deps.config.operatorPrincipals);
805
+ const operator = explicitOperatorOk(principal, deps.config);
809
806
  if (!operator && owner !== (principal ?? null)) {
810
807
  sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
811
808
  return;
@@ -822,14 +819,7 @@ export async function handleSessions(req, res, match, ctx) {
822
819
  }
823
820
  return;
824
821
  }
825
- let body;
826
- try {
827
- body = (await readJson(req));
828
- }
829
- catch {
830
- sendError(res, 400, "request.invalid_json", "invalid JSON body");
831
- return;
832
- }
822
+ const body = (await readJson(req));
833
823
  const read = readWritableSessionPermissionRules(body.rules);
834
824
  if (read.refusal !== undefined) {
835
825
  sendSessionPolicyError(res, read.refusal);
@@ -1,21 +1,10 @@
1
- import { SHARED_MEMORY_READ_CAP_BYTES, SharedMemoryStoreError } from "@sema-agent/core";
1
+ import { isSharedMemoryDocumentPath, SHARED_MEMORY_READ_CAP_BYTES, SharedMemoryStoreError } from "@sema-agent/core";
2
2
  import { sendJson, sendError } from "../send.js";
3
3
  import { gatedPrincipal, sendUnauthorized } from "../principal-gate.js";
4
4
  import { assertNever } from "../route-ctx.js";
5
5
  import * as facts from "../../capability-facts.js";
6
6
  const RETRY_AFTER_SEC = 10;
7
7
  const HTTP_LIST_LIMIT = 100;
8
- const FORBIDDEN_PATH_CHARS = /[\p{Cc}\p{Cf}\p{Co}\p{Cn}\p{Default_Ignorable_Code_Point}\u2028\u2029\\]/u;
9
- const DOCUMENT_SUFFIXES = [".md", ".txt", ".json", ".jsonl"];
10
- function isDocumentPath(path) {
11
- if (!path.startsWith("/") || FORBIDDEN_PATH_CHARS.test(path))
12
- return false;
13
- const segments = path.slice(1).split("/");
14
- const last = segments.at(-1);
15
- if (last === undefined || !segments.every((s) => s !== "" && !s.startsWith(".")))
16
- return false;
17
- return DOCUMENT_SUFFIXES.some((s) => last.endsWith(s));
18
- }
19
8
  function refuseStore(res) {
20
9
  sendError(res, 404, "not_found.shared_memory_store", "not found");
21
10
  }
@@ -120,7 +109,7 @@ export async function handleSharedMemory(req, res, match, ctx) {
120
109
  return;
121
110
  }
122
111
  const path = query.get("path");
123
- if (path === null || path === "" || !isDocumentPath(path)) {
112
+ if (path === null || path === "" || !isSharedMemoryDocumentPath(path)) {
124
113
  sendError(res, 400, "request.query_invalid", "missing or malformed ?path= (absolute, .md/.txt/.json/.jsonl)");
125
114
  return;
126
115
  }
@@ -1,10 +1,11 @@
1
1
  import { MODEL_ROLES, expandTiers, isThinkingLevel } from "@sema-agent/core";
2
2
  import { HttpError } from "../../security.js";
3
+ import { echoCallerText } from "../../caller-text-echo.js";
3
4
  import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../../model-select.js";
4
- import { modelUnavailableMessage } from "../../model-entry-refusal.js";
5
+ import { echoModelRef, modelUnavailableMessage } from "../../model-entry-refusal.js";
5
6
  import { redactSecrets } from "../../trace/redact.js";
6
7
  import { admitProviderEcho, redactErrorMessage } from "../../observability/run-terminal.js";
7
- import { sendJson, sendError, httpErrorCode, msg } from "../send.js";
8
+ import { sendJson, sendError, sendHttpError, msg } from "../send.js";
8
9
  import { gatedPrincipal, sendPrincipalRefusal } from "../principal-gate.js";
9
10
  import { assertNever } from "../route-ctx.js";
10
11
  const CORE_PREFLIGHT_VALIDATION_PREFIXES = ["Unknown model ref ", "No model for role "];
@@ -12,6 +13,7 @@ export function isCorePreflightValidationError(message) {
12
13
  return CORE_PREFLIGHT_VALIDATION_PREFIXES.some((prefix) => message.startsWith(prefix));
13
14
  }
14
15
  export const CORE_PREFLIGHT_VALIDATION_ANCHORS = CORE_PREFLIGHT_VALIDATION_PREFIXES;
16
+ const MODEL_ROLE_ECHO_CHARS = 80;
15
17
  function isModelRole(value) {
16
18
  return typeof value === "string" && MODEL_ROLES.includes(value);
17
19
  }
@@ -50,8 +52,7 @@ export async function handleSideQuery(req, res, match, ctx) {
50
52
  body = raw;
51
53
  }
52
54
  catch (e) {
53
- const he = e instanceof HttpError ? e : new HttpError(400, msg(e));
54
- sendError(res, he.status, httpErrorCode(he.status, he.code), he.message);
55
+ sendHttpError(res, e instanceof HttpError ? e : new HttpError(400, msg(e)));
55
56
  return;
56
57
  }
57
58
  if (!Array.isArray(body.messages) || body.messages.length === 0) {
@@ -63,7 +64,7 @@ export async function handleSideQuery(req, res, match, ctx) {
63
64
  return;
64
65
  }
65
66
  if (body.modelRole !== undefined && !isModelRole(body.modelRole)) {
66
- const shown = (typeof body.modelRole === "string" ? JSON.stringify(body.modelRole.slice(0, 80)) : `of type ${body.modelRole === null ? "null" : Array.isArray(body.modelRole) ? "array" : typeof body.modelRole}`);
67
+ const shown = (typeof body.modelRole === "string" ? JSON.stringify(echoCallerText(body.modelRole, { maxChars: MODEL_ROLE_ECHO_CHARS })) : `of type ${body.modelRole === null ? "null" : Array.isArray(body.modelRole) ? "array" : typeof body.modelRole}`);
67
68
  sendError(res, 400, "request.field_invalid", `invalid modelRole ${shown} — must be a string, one of ${MODEL_ROLES.join(" / ")} (the engine's role vocabulary); a value outside it is refused before any model call`);
68
69
  return;
69
70
  }
@@ -71,12 +72,12 @@ export async function handleSideQuery(req, res, match, ctx) {
71
72
  const catalog = selectableCatalog(deps.config.models ?? {}, deps.config.tiers, deps.config.modelRefusals);
72
73
  const unavailable = matchCatalogModel(body.model, catalog, deps.config.modelRefusals) === undefined ? refusedCatalogEntry(body.model, deps.config.modelRefusals) : undefined;
73
74
  if (unavailable !== undefined) {
74
- const message = modelUnavailableMessage("model", body.model.slice(0, 120), unavailable.name, unavailable.refusal);
75
+ const message = modelUnavailableMessage("model", body.model, unavailable.name, unavailable.refusal);
75
76
  sendError(res, 400, "request.model_unavailable", message);
76
77
  return;
77
78
  }
78
79
  if (!isAtMentionable(body.model, catalog, deps.config.atMention, deps.config.modelRefusals)) {
79
- sendError(res, 400, "request.model_not_allowed", `model is not @-mentionable on this deployment: "${body.model.slice(0, 120)}" — which models can be @-mentioned is configured by the operator (models.atMention)`);
80
+ sendError(res, 400, "request.model_not_allowed", `model is not @-mentionable on this deployment: "${echoModelRef(body.model)}" — which models can be @-mentioned is configured by the operator (models.atMention)`);
80
81
  return;
81
82
  }
82
83
  }
@@ -1,6 +1,6 @@
1
1
  import { redactErrorMessage, redactHead, redactTerminalResult } from "../../observability/run-terminal.js";
2
2
  import { runWithVerification, runCascade, taskNotificationDedupKey, uuidv7 } from "@sema-agent/core";
3
- import { graftParkToolCallId, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, HEARTBEAT_MS } from "../../runs.js";
3
+ import { graftParkToolCallId, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, HEARTBEAT_MS } from "../../runs.js";
4
4
  import { sealResultForExit, outwardPlane } from "../../terminal.js";
5
5
  import { withPrincipal } from "../../observability/principal-context.js";
6
6
  import { fleetRunPublisher, fleetRunLabels, fleetRunResiduals, isFleetAgentTerminalNotification } from "../../fleet/fleet-bus.js";
@@ -14,11 +14,11 @@ import { buildCancelledLedgerRow, createRunAbort, mintCancelledResult } from "..
14
14
  import { recordResourceWindow } from "../../resource-window.js";
15
15
  import { redactSecrets } from "../../trace/redact.js";
16
16
  import { liveToolEndForBacklog } from "../../trace/tool-output-media.js";
17
- import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, textEndEventData, liveIdentityFields } from "../../trace/project.js";
17
+ import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, textEndEventData, liveIdentityFields } from "../../trace/project.js";
18
18
  import { cascadeConfig, runMeta } from "../run-meta.js";
19
19
  import { idemCallerOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
20
20
  import { replayOfExistingRun } from "../submit-replay.js";
21
- import { sendJson, sendError, sseHeaders } from "../send.js";
21
+ import { httpErrorCode, sendJson, sendError, sseHeaders } from "../send.js";
22
22
  import { collectSsePreamble } from "../sse-log.js";
23
23
  import { buildApprovalPreamble, buildApprovalPreambleSseFrames } from "../../approval-card.js";
24
24
  import { createApprovalCardEmitter, resolveApprovalLeg, resolveStreamApprovalGate } from "../../tool-approval.js";
@@ -30,10 +30,13 @@ import { failOpenTagForDroppedFrame, recordFailOpen } from "../../observability/
30
30
  import { buildSyncSubmitBody } from "../sync-submit-body.js";
31
31
  import { assertNever } from "../route-ctx.js";
32
32
  import * as facts from "../../capability-facts.js";
33
- import { buildCheckpointCtx } from "../checkpoint-ctx.js";
33
+ import { persistSubmitCtx } from "../submit-ctx.js";
34
34
  import { serviceVersion } from "../../service-version.js";
35
35
  import { withModelReachScope } from "../../model-reach-scope.js";
36
36
  import { createInstructionSelectionLeg } from "../../instruction-selection.js";
37
+ import { fieldConflictFacts } from "../../field-conflict.js";
38
+ import { refusalBody } from "../refusal-body.js";
39
+ import { heldWorkflowParkDecisions } from "../../parked-decide.js";
37
40
  const DISCONNECT_PARK_GRACE_MS = 10_000;
38
41
  function sseData(res, payload) {
39
42
  const anchor = payload.eventId;
@@ -60,8 +63,8 @@ function sendSubmitResult(res, resp) {
60
63
  : raw;
61
64
  sendJson(res, 200, body);
62
65
  }
63
- function writeMetaFrame(res, taskId, sessionId) {
64
- res.write(`event: meta\ndata: ${JSON.stringify({ type: "meta", taskId, ...(sessionId ? { sessionId } : {}) })}\n\n`);
66
+ function writeMetaFrame(res, taskId, sessionId, warnings) {
67
+ res.write(`event: meta\ndata: ${JSON.stringify({ type: "meta", taskId, ...(sessionId ? { sessionId } : {}), ...(warnings !== undefined ? { warnings } : {}) })}\n\n`);
65
68
  }
66
69
  function refusalDoneResult(body) {
67
70
  if (isActiveRunConflictBody(body))
@@ -148,13 +151,13 @@ export async function handleTasks(req, res, match, ctx) {
148
151
  if (!prepared)
149
152
  return;
150
153
  const principal = prepared.auth?.principal;
151
- const wiringOperatorFace = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config.operatorPrincipals);
154
+ const wiringOperatorFace = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config);
152
155
  let wiringReceipt;
153
156
  const instructionLeg = createInstructionSelectionLeg();
154
157
  const withRunReceipt = (out) => wiringReceipt !== undefined ? { ...out, wiringManifest: wiringReceipt } : out;
155
158
  if (liveStream) {
156
159
  if (prepared.verify || prepared.cascade) {
157
- sendError(res, 400, "request.field_conflict", "verify / cascade are not supported on /v1/tasks/stream (both are multi-attempt, not a single stream) — use /v1/tasks or /v1/runs");
160
+ sendError(res, 400, "request.field_conflict", "verify / cascade are not supported on /v1/tasks/stream (both are multi-attempt, not a single stream) — use /v1/tasks or /v1/runs", fieldConflictFacts("cascade_verify", prepared.verify ? (prepared.cascade ? ["verify", "cascade"] : ["verify"]) : ["cascade"]));
158
161
  return;
159
162
  }
160
163
  const earlyDurableTid = facts.durableRuns(deps).available && prepared.spec.sessionId ? uuidv7() : undefined;
@@ -169,7 +172,7 @@ export async function handleTasks(req, res, match, ctx) {
169
172
  reqState.streamDetached = detachOnDisconnect;
170
173
  sseHeaders(res, earlyDurableTid ? { "x-task-id": earlyDurableTid } : undefined);
171
174
  if (earlyDurableTid)
172
- writeMetaFrame(res, earlyDurableTid, prepared.spec.sessionId);
175
+ writeMetaFrame(res, earlyDurableTid, prepared.spec.sessionId, prepared.warnings);
173
176
  const ac = createRunAbort();
174
177
  let closed = false;
175
178
  let detachLogged = false;
@@ -215,14 +218,26 @@ export async function handleTasks(req, res, match, ctx) {
215
218
  parkFacility: deps.checkpointStore !== undefined,
216
219
  });
217
220
  const replaySessionId = replayGate.active ? prepared.spec.sessionId : undefined;
221
+ const presentedOnConnection = new Set();
222
+ const presentedCompleted = new Set();
223
+ const admitPresentedComplete = (askId) => {
224
+ if (!presentedOnConnection.has(askId))
225
+ return true;
226
+ if (presentedCompleted.has(askId))
227
+ return false;
228
+ presentedCompleted.add(askId);
229
+ return true;
230
+ };
218
231
  if (replaySessionId) {
219
232
  const replayOwner = gatedPrincipal(req, deps.config) ?? null;
220
233
  const askStore = replayGate.active ? replayGate.askStore : undefined;
234
+ let presentedAskIds = [];
221
235
  const preambleFrames = await collectSsePreamble(async (signal) => {
222
236
  if (!askStore)
223
237
  return [];
224
238
  const rows = await askStore.listPendingBySession(replaySessionId, replayOwner, signal);
225
239
  const { frames, skipped, dropped } = buildApprovalPreamble(rows, Date.now(), deps.config.streamApproval.replayMax);
240
+ presentedAskIds = frames.map((f) => f.askId);
226
241
  if (skipped > 0)
227
242
  deps.logger?.warn?.("approval_preamble_row_skipped", { sessionId: replaySessionId, skipped, face: "tasks.stream" });
228
243
  if (dropped > 0)
@@ -232,6 +247,16 @@ export async function handleTasks(req, res, match, ctx) {
232
247
  if (!res.writableEnded && !res.destroyed) {
233
248
  for (const f of preambleFrames)
234
249
  res.write(`event: ${f.event}\ndata: ${JSON.stringify(f.data)}\n\n`);
250
+ if (deps.toolApproval && preambleFrames.length > 0) {
251
+ for (const askId of presentedAskIds)
252
+ presentedOnConnection.add(askId);
253
+ const unwatch = deps.toolApproval.watchPresentedCards(presentedAskIds, (frame) => {
254
+ if (res.writableEnded || res.destroyed || !admitPresentedComplete(frame.askId))
255
+ return;
256
+ res.write(`event: ${frame.type}\ndata: ${JSON.stringify(frame)}\n\n`);
257
+ });
258
+ res.once("close", unwatch);
259
+ }
235
260
  }
236
261
  }
237
262
  const hb = setInterval(() => {
@@ -286,14 +311,18 @@ export async function handleTasks(req, res, match, ctx) {
286
311
  }
287
312
  durableTaskId = tid;
288
313
  }
314
+ if (deps.checkpointStore && prepared.spec.sessionId) {
315
+ const ctxRefusal = await persistSubmitCtx(deps.checkpointStore, deps, durableTaskId !== undefined && deps.runStore ? { runStore: deps.runStore, taskId: durableTaskId } : undefined, prepared.spec.sessionId, { body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() });
316
+ if (ctxRefusal) {
317
+ sseData(res, { type: "done", result: doneResultOfOutcome(ctxRefusal) });
318
+ return ctxRefusal;
319
+ }
320
+ }
289
321
  commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
290
322
  if (prepared.spec.sessionId)
291
323
  markChildrenStoppedByUserOnAbort(ac.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.principal);
292
324
  let ledgerSink;
293
325
  let ledgerTerminal = false;
294
- if (deps.checkpointStore && prepared.spec.sessionId) {
295
- await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() }));
296
- }
297
326
  if (durableTaskId && deps.runStore) {
298
327
  const rs = deps.runStore;
299
328
  const tid = durableTaskId;
@@ -374,7 +403,9 @@ export async function handleTasks(req, res, match, ctx) {
374
403
  const tailContentMode = prepared.spec.forwardSubagentEvents === true ? "on" : "progress_only";
375
404
  const childReasoning = createReasoningSegments();
376
405
  const topReasoning = createReasoningSegments();
406
+ const heldDecisions = prepared.spec.sessionId !== undefined ? await heldWorkflowParkDecisions(deps, prepared.spec.sessionId) : {};
377
407
  const fwdInternals = {
408
+ ...heldDecisions,
378
409
  onForwardEvent: (e) => {
379
410
  fleetPub?.onForwardEvent(e);
380
411
  ledgerSink?.onForwardEvent(e);
@@ -453,6 +484,7 @@ export async function handleTasks(req, res, match, ctx) {
453
484
  liveStreamRef = liveStream;
454
485
  if (durableTaskId)
455
486
  steerableRuns.set(durableTaskId, liveStream);
487
+ prepared.acceptance.attachStream({ reachable: () => !closed && !res.writableEnded && !res.destroyed, write: (frame) => sseData(res, { ...frame }) });
456
488
  for await (const ev of liveStream) {
457
489
  if (closed)
458
490
  break;
@@ -541,6 +573,9 @@ export async function handleTasks(req, res, match, ctx) {
541
573
  else if (ev.type === "compaction_outcome") {
542
574
  sseData(res, { type: "compaction_outcome", ...compactionOutcomeEventData(ev) });
543
575
  }
576
+ else if (ev.type === "compaction_started") {
577
+ sseData(res, { type: "compaction_started", ...compactionStartedEventData(ev) });
578
+ }
544
579
  else if (ev.type === "wiring_manifest") {
545
580
  const wiringFace = wiringManifestFaceEventData(ev, wiringOperatorFace, instructionLeg.segment());
546
581
  wiringReceipt ??= wiringFace;
@@ -652,6 +687,8 @@ export async function handleTasks(req, res, match, ctx) {
652
687
  writeLive: (frame) => {
653
688
  if (res.writableEnded || res.destroyed)
654
689
  throw new Error("live stream ended");
690
+ if (frame.type === "approval_complete" && !admitPresentedComplete(frame.askId))
691
+ return;
655
692
  emitAsk(frame);
656
693
  },
657
694
  });
@@ -663,7 +700,6 @@ export async function handleTasks(req, res, match, ctx) {
663
700
  ? {
664
701
  taskId: askTaskId,
665
702
  owner: askOwner,
666
- emit: emitApproval,
667
703
  abortSignal: ac.signal,
668
704
  ...(prepared.spec.sessionId ? { sessionId: prepared.spec.sessionId } : {}),
669
705
  ...(streamApprovalOn
@@ -673,7 +709,7 @@ export async function handleTasks(req, res, match, ctx) {
673
709
  legKey: "",
674
710
  ...(legDeadlineMonotonic !== undefined ? { legDeadlineMonotonic } : {}),
675
711
  }
676
- : {}),
712
+ : { emit: emitApproval }),
677
713
  }
678
714
  : undefined;
679
715
  if (deps.toolApproval) {
@@ -836,7 +872,13 @@ export async function handleTasks(req, res, match, ctx) {
836
872
  res.end();
837
873
  }
838
874
  else {
839
- const withSyncSubmitKeys = (body) => prepared.verify || prepared.cascade ? { ...body, notice: MULTI_ATTEMPT_NO_EVENT_CHANNEL_NOTICE } : body;
875
+ const withSyncSubmitKeys = (body) => {
876
+ const extra = {
877
+ ...(prepared.verify || prepared.cascade ? { notice: MULTI_ATTEMPT_NO_EVENT_CHANNEL_NOTICE } : {}),
878
+ ...(prepared.warnings !== undefined ? { warnings: prepared.warnings } : {}),
879
+ };
880
+ return Object.keys(extra).length > 0 ? { ...body, ...extra } : body;
881
+ };
840
882
  const runSyncSubmitLeg = async () => {
841
883
  const syncLegStartedAt = Date.now();
842
884
  let durableTaskId;
@@ -857,10 +899,12 @@ export async function handleTasks(req, res, match, ctx) {
857
899
  return { status: placementReject.status, body: devicePlacementErrorBody(placementReject) };
858
900
  durableTaskId = tid;
859
901
  }
860
- commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
861
902
  if (deps.checkpointStore && prepared.spec.sessionId) {
862
- await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() }));
903
+ const ctxRefusal = await persistSubmitCtx(deps.checkpointStore, deps, durableTaskId !== undefined && deps.runStore ? { runStore: deps.runStore, taskId: durableTaskId } : undefined, prepared.spec.sessionId, { body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() });
904
+ if (ctxRefusal)
905
+ return ctxRefusal;
863
906
  }
907
+ commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
864
908
  const syncCancelCtrl = createRunAbort();
865
909
  if (prepared.spec.sessionId)
866
910
  markChildrenStoppedByUserOnAbort(syncCancelCtrl.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.principal);
@@ -893,10 +937,11 @@ export async function handleTasks(req, res, match, ctx) {
893
937
  let result;
894
938
  counters.uncountedBillableInflight++;
895
939
  try {
896
- const verifyLeg = (v) => runWithVerification(prepared.runner, specWithSignal, v);
897
- const cascadeLeg = () => runCascade(prepared.runner, specWithSignal, cascadeConfig(deps.config.cascadeLadder, prepared.spec.limits?.maxCostUsd));
940
+ const heldDecisions = prepared.spec.sessionId !== undefined ? await heldWorkflowParkDecisions(deps, prepared.spec.sessionId) : {};
941
+ const verifyLeg = (v) => runWithVerification(prepared.runner, specWithSignal, v, heldDecisions);
942
+ const cascadeLeg = () => runCascade(prepared.runner, specWithSignal, cascadeConfig(deps.config.cascadeLadder, prepared.spec.limits?.maxCostUsd), heldDecisions);
898
943
  const plainLeg = async () => {
899
- const stream = prepared.runner.runTaskStream(specWithSignal);
944
+ const stream = prepared.runner.runTaskStream(specWithSignal, undefined, heldDecisions);
900
945
  for await (const ev of stream) {
901
946
  observeSyncLegEvent(ev);
902
947
  prepared.acceptance.observe(ev);
@@ -933,7 +978,8 @@ export async function handleTasks(req, res, match, ctx) {
933
978
  const retryAfterSec = resumeAtPlane.errorCode === "memory.admission_required" && result.retryAfterMs !== undefined
934
979
  ? Math.max(1, Math.ceil(result.retryAfterMs / 1000))
935
980
  : undefined;
936
- return { status: resumeAtStatus, body: { errorCode: resumeAtPlane.errorCode, error: redactErrorMessage(resumeAtPlane.errorMessage) ?? "resume-at failed", ...(retryAfterSec !== undefined ? { retryAfterSec } : {}) } };
981
+ const refusalFacts = zeroWorkRefusalFacts(redactTerminalResult(sealResultForExit(result)).terminal, prepared.warnings);
982
+ return { status: resumeAtStatus, body: refusalBody({ errorCode: httpErrorCode(resumeAtStatus, resumeAtPlane.errorCode), message: redactErrorMessage(resumeAtPlane.errorMessage) ?? "resume-at failed", facts: { ...(retryAfterSec !== undefined ? { retryAfterSec } : {}), ...refusalFacts } }) };
937
983
  }
938
984
  const exitResult = await mintSubmitExitResult(result, deps.checkpointStore);
939
985
  const syncPlane = outwardPlane(result.terminal);