@north-light/cli 0.3.560 → 0.3.562

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 (573) hide show
  1. package/dist/api/client.d.ts +27 -4
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/contract.d.ts +1 -1
  4. package/dist/api/contract.js +1 -1
  5. package/dist/api/dto/bash-jobs.d.ts +5 -1
  6. package/dist/api/dto/broker-ops.d.ts +25 -1
  7. package/dist/api/dto/charges.d.ts +9 -2
  8. package/dist/api/dto/delivery.d.ts +26 -2
  9. package/dist/api/dto/execution-start.d.ts +57 -0
  10. package/dist/api/dto/execution-start.js +0 -0
  11. package/dist/api/dto/modelauth.d.ts +5 -0
  12. package/dist/api/dto/node-records.d.ts +16 -0
  13. package/dist/api/dto/objects.d.ts +1 -1
  14. package/dist/api/dto/reports.d.ts +0 -3
  15. package/dist/api/dto/run-events.d.ts +7 -1
  16. package/dist/api/dto/settings.d.ts +55 -0
  17. package/dist/api/dto/settings.js +0 -0
  18. package/dist/api/index.d.ts +2 -0
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +11 -0
  21. package/dist/api/routes.js +1 -1
  22. package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
  23. package/dist/cli.js +7 -7
  24. package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
  25. package/dist/clients/attach/chrome/bash-jobs.js +1 -1
  26. package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
  27. package/dist/clients/attach/chrome/roster.js +6 -4
  28. package/dist/clients/attach/overlays/auth.js +2 -2
  29. package/dist/clients/attach/render/chat-view.js +1 -1
  30. package/dist/clients/attach/viewer.js +550 -567
  31. package/dist/commands/canvas-config.js +2 -2
  32. package/dist/commands/canvas-use.js +1 -1
  33. package/dist/commands/human.js +2 -2
  34. package/dist/commands/node/bash.js +3 -3
  35. package/dist/commands/node/create.js +2 -2
  36. package/dist/commands/person-settings.d.ts +1 -0
  37. package/dist/commands/person-settings.js +1 -0
  38. package/dist/commands/pkg/market-manage.d.ts +2 -2
  39. package/dist/commands/pkg/market-manage.js +1 -1
  40. package/dist/commands/pkg/plugin-manage.js +13 -13
  41. package/dist/commands/pkg/shared.js +1 -1
  42. package/dist/commands/profile/default.js +1 -1
  43. package/dist/commands/push.js +2 -3
  44. package/dist/commands/sys/config.js +1 -1
  45. package/dist/commands/sys/connect.js +1 -1
  46. package/dist/commands/sys/context/sysprompt.js +2 -2
  47. package/dist/commands/sys/doctor.js +1 -1
  48. package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
  49. package/dist/commands/sys/panels/keybindings-panel.js +1 -1
  50. package/dist/commands/sys/panels/models-panel.d.ts +8 -2
  51. package/dist/commands/sys/panels/models-panel.js +1 -1
  52. package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
  53. package/dist/commands/sys/panels/prefs-panel.js +1 -1
  54. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  55. package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
  56. package/dist/commands/sys/panels/provider-panel.js +1 -1
  57. package/dist/commands/sys/provider-login.js +5 -5
  58. package/dist/commands/sys/setup-core.js +3 -3
  59. package/dist/commands/sys/setup-settings-runner.js +1 -1
  60. package/dist/commands/sys/spend.js +3 -3
  61. package/dist/commands/sys/update.js +1 -1
  62. package/dist/core/auth-file.d.ts +11 -19
  63. package/dist/core/auth-file.js +1 -2
  64. package/dist/core/auto-update.d.ts +1 -1
  65. package/dist/core/auto-update.js +4 -4
  66. package/dist/core/bash-jobs.d.ts +29 -71
  67. package/dist/core/bash-jobs.js +9 -10
  68. package/dist/core/blobs/directory.d.ts +3 -0
  69. package/dist/core/blobs/directory.js +1 -0
  70. package/dist/core/blobs/fault.d.ts +3 -0
  71. package/dist/core/blobs/fault.js +1 -0
  72. package/dist/core/blobs/index.d.ts +21 -0
  73. package/dist/core/blobs/index.js +1 -0
  74. package/dist/core/blobs/r2.d.ts +9 -0
  75. package/dist/core/blobs/r2.js +4 -0
  76. package/dist/core/bootstrap.d.ts +1 -1
  77. package/dist/core/bootstrap.js +2 -2
  78. package/dist/core/canvas/canvas.d.ts +9 -7
  79. package/dist/core/canvas/canvas.js +8 -8
  80. package/dist/core/canvas/crons.d.ts +3 -2
  81. package/dist/core/canvas/crons.js +3 -3
  82. package/dist/core/canvas/daemon-owner.d.ts +5 -0
  83. package/dist/core/canvas/daemon-owner.js +1 -1
  84. package/dist/core/canvas/db.d.ts +10 -9
  85. package/dist/core/canvas/db.js +4 -4
  86. package/dist/core/canvas/executions.d.ts +100 -4
  87. package/dist/core/canvas/executions.js +1 -1
  88. package/dist/core/canvas/export-sqlite.js +1 -1
  89. package/dist/core/canvas/focuses.d.ts +4 -0
  90. package/dist/core/canvas/focuses.js +1 -1
  91. package/dist/core/canvas/history.js +9 -9
  92. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
  93. package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
  94. package/dist/core/canvas/node-tokens.d.ts +1 -4
  95. package/dist/core/canvas/node-tokens.js +3 -3
  96. package/dist/core/canvas/paths.d.ts +0 -1
  97. package/dist/core/canvas/paths.js +1 -1
  98. package/dist/core/canvas/person-state.d.ts +26 -0
  99. package/dist/core/canvas/person-state.js +1 -0
  100. package/dist/core/canvas/person.d.ts +3 -10
  101. package/dist/core/canvas/person.js +7 -7
  102. package/dist/core/canvas/reconciler-leases.d.ts +12 -0
  103. package/dist/core/canvas/reconciler-leases.js +8 -0
  104. package/dist/core/canvas/recovery.d.ts +4 -0
  105. package/dist/core/canvas/recovery.js +1 -1
  106. package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
  107. package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
  108. package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
  109. package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
  110. package/dist/core/canvas/schema-version.d.ts +1 -1
  111. package/dist/core/canvas/schema-version.js +1 -1
  112. package/dist/core/canvas/sessions.d.ts +8 -11
  113. package/dist/core/canvas/sessions.js +1 -4
  114. package/dist/core/canvas/tree.d.ts +4 -2
  115. package/dist/core/canvas/tree.js +6 -6
  116. package/dist/core/canvas/types.d.ts +7 -0
  117. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  118. package/dist/core/command-plugins/bundle.d.ts +1 -1
  119. package/dist/core/command-plugins/bundle.js +1 -1
  120. package/dist/core/command-plugins/compose.d.ts +1 -1
  121. package/dist/core/command-plugins/discovery.d.ts +0 -1
  122. package/dist/core/command-plugins/discovery.js +1 -1
  123. package/dist/core/command-plugins/help-addenda.js +1 -1
  124. package/dist/core/command-plugins/presence.d.ts +2 -0
  125. package/dist/core/command-plugins/presence.js +1 -1
  126. package/dist/core/config.d.ts +16 -15
  127. package/dist/core/config.js +1 -1
  128. package/dist/core/conversation-store/client-worker.js +1 -1
  129. package/dist/core/conversation-store/client.js +2 -2
  130. package/dist/core/conversation-store/index.d.ts +9 -11
  131. package/dist/core/conversation-store/index.js +1 -1
  132. package/dist/core/conversation-store/patch.js +1 -1
  133. package/dist/core/conversation-store/row-store.d.ts +14 -0
  134. package/dist/core/conversation-store/row-store.js +13 -0
  135. package/dist/core/directory/join.js +1 -1
  136. package/dist/core/env-name.d.ts +1 -0
  137. package/dist/core/env-name.js +1 -1
  138. package/dist/core/environment-recipe.d.ts +15 -0
  139. package/dist/core/environment-recipe.js +1 -0
  140. package/dist/core/environments.js +1 -1
  141. package/dist/core/events/emit.js +2 -2
  142. package/dist/core/events/run-event-chunks.d.ts +25 -0
  143. package/dist/core/events/run-event-chunks.js +5 -0
  144. package/dist/core/feed/messages.js +5 -5
  145. package/dist/core/grants/mirror.d.ts +15 -0
  146. package/dist/core/grants/mirror.js +15 -3
  147. package/dist/core/grants/on-sync.d.ts +9 -5
  148. package/dist/core/grants/on-sync.js +1 -1
  149. package/dist/core/grants/remove.d.ts +1 -6
  150. package/dist/core/grants/remove.js +1 -1
  151. package/dist/core/grants/sync.js +1 -1
  152. package/dist/core/grants/watch.d.ts +15 -9
  153. package/dist/core/grants/watch.js +1 -1
  154. package/dist/core/graph/custom.js +8 -8
  155. package/dist/core/graph/jobs.d.ts +83 -5
  156. package/dist/core/graph/jobs.js +11 -2
  157. package/dist/core/graph/kinds/job.js +2 -2
  158. package/dist/core/graph/names.js +7 -7
  159. package/dist/core/graph/objects.d.ts +5 -1
  160. package/dist/core/graph/objects.js +11 -11
  161. package/dist/core/graph/reader.d.ts +3 -0
  162. package/dist/core/graph/reader.js +3 -3
  163. package/dist/core/graph/repo-sync/identity.d.ts +3 -1
  164. package/dist/core/graph/repo-sync/identity.js +1 -1
  165. package/dist/core/graph/repo-sync/repos.d.ts +1 -1
  166. package/dist/core/graph/repo-sync/repos.js +2 -2
  167. package/dist/core/graph/repo-sync/sync.js +2 -2
  168. package/dist/core/installed-plugins.js +1 -1
  169. package/dist/core/keybindings/persistence.d.ts +1 -1
  170. package/dist/core/keybindings/persistence.js +1 -1
  171. package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
  172. package/dist/core/layout-migrate/loose-keys.js +1 -1
  173. package/dist/core/ledger/account.d.ts +12 -0
  174. package/dist/core/ledger/account.js +2 -0
  175. package/dist/core/ledger/charges.d.ts +2 -2
  176. package/dist/core/ledger/charges.js +1 -1
  177. package/dist/core/ledger/check.d.ts +5 -1
  178. package/dist/core/ledger/check.js +1 -7
  179. package/dist/core/ledger/chunks.d.ts +8 -0
  180. package/dist/core/ledger/chunks.js +2 -0
  181. package/dist/core/ledger/index.d.ts +2 -1
  182. package/dist/core/ledger/index.js +1 -1
  183. package/dist/core/ledger/infra-allowance.d.ts +9 -0
  184. package/dist/core/ledger/infra-allowance.js +1 -0
  185. package/dist/core/ledger/limits.js +3 -3
  186. package/dist/core/ledger/payer.d.ts +1 -1
  187. package/dist/core/ledger/payer.js +1 -1
  188. package/dist/core/ledger/read.d.ts +14 -4
  189. package/dist/core/ledger/read.js +2 -3
  190. package/dist/core/ledger/totals.d.ts +5 -16
  191. package/dist/core/ledger/totals.js +4 -4
  192. package/dist/core/ledger/types.d.ts +12 -3
  193. package/dist/core/llm/run.js +2 -2
  194. package/dist/core/managed-providers.d.ts +72 -0
  195. package/dist/core/managed-providers.js +1 -0
  196. package/dist/core/model-auth/api-credential-store.d.ts +10 -0
  197. package/dist/core/model-auth/api-credential-store.js +1 -0
  198. package/dist/core/model-auth/daemon-login.d.ts +1 -1
  199. package/dist/core/model-auth/daemon-login.js +1 -1
  200. package/dist/core/model-auth/flows.d.ts +5 -4
  201. package/dist/core/model-auth/flows.js +1 -1
  202. package/dist/core/model-auth/handoff-jti.d.ts +3 -4
  203. package/dist/core/model-auth/handoff-jti.js +1 -1
  204. package/dist/core/model-auth/readiness.js +1 -1
  205. package/dist/core/model-config.d.ts +1 -1
  206. package/dist/core/model-config.js +1 -1
  207. package/dist/core/model-routes-pool.d.ts +14 -0
  208. package/dist/core/model-routes-pool.js +1 -0
  209. package/dist/core/model-routes.d.ts +11 -16
  210. package/dist/core/model-routes.js +1 -1
  211. package/dist/core/peer/ingest.d.ts +2 -0
  212. package/dist/core/peer/ingest.js +1 -1
  213. package/dist/core/peer/stubs.d.ts +8 -0
  214. package/dist/core/peer/stubs.js +1 -1
  215. package/dist/core/permissions/evaluator.d.ts +7 -2
  216. package/dist/core/permissions/evaluator.js +2 -2
  217. package/dist/core/plugin-env.js +1 -1
  218. package/dist/core/pool-credential-store.d.ts +2 -5
  219. package/dist/core/pool-credential-store.js +1 -1
  220. package/dist/core/profiles/app-env-store.d.ts +5 -5
  221. package/dist/core/profiles/app-env-store.js +1 -2
  222. package/dist/core/profiles/default-binding.d.ts +5 -5
  223. package/dist/core/profiles/default-binding.js +1 -1
  224. package/dist/core/profiles/env-store.d.ts +10 -21
  225. package/dist/core/profiles/env-store.js +1 -2
  226. package/dist/core/profiles/manifest.d.ts +14 -18
  227. package/dist/core/profiles/manifest.js +1 -1
  228. package/dist/core/profiles/relocate.js +1 -1
  229. package/dist/core/profiles/select.js +21 -21
  230. package/dist/core/provider-credential.d.ts +1 -1
  231. package/dist/core/provider-credential.js +1 -1
  232. package/dist/core/provider-management.d.ts +3 -4
  233. package/dist/core/provider-management.js +1 -1
  234. package/dist/core/providers/bundles.js +2 -2
  235. package/dist/core/providers/call.d.ts +3 -34
  236. package/dist/core/providers/description.d.ts +34 -0
  237. package/dist/core/providers/description.js +0 -0
  238. package/dist/core/providers/token-cache.d.ts +14 -14
  239. package/dist/core/providers/token-cache.js +1 -1
  240. package/dist/core/review/companion.js +1 -1
  241. package/dist/core/runs/activity.d.ts +1 -1
  242. package/dist/core/runs/activity.js +1 -1
  243. package/dist/core/runs/events.d.ts +7 -5
  244. package/dist/core/runs/events.js +2 -6
  245. package/dist/core/runs/operations.d.ts +1 -1
  246. package/dist/core/runs/operations.js +6 -6
  247. package/dist/core/runtime/bearings.js +1 -1
  248. package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
  249. package/dist/core/runtime/broker/attachments-fetch.js +1 -0
  250. package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
  251. package/dist/core/runtime/broker/bash-job-launch.js +1 -1
  252. package/dist/core/runtime/broker/boot-state.d.ts +9 -0
  253. package/dist/core/runtime/broker/boot-state.js +1 -0
  254. package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
  255. package/dist/core/runtime/broker/cli-relay.js +1 -1
  256. package/dist/core/runtime/broker/client-registry.d.ts +3 -3
  257. package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
  258. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  259. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  260. package/dist/core/runtime/broker/fault-retry.js +1 -1
  261. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  262. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
  263. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  264. package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
  265. package/dist/core/runtime/broker/job-reporter.js +2 -0
  266. package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
  267. package/dist/core/runtime/broker/model-adapter.js +3 -2
  268. package/dist/core/runtime/broker/signal-stream.js +1 -1
  269. package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
  270. package/dist/core/runtime/broker/spilled-body.js +1 -0
  271. package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
  272. package/dist/core/runtime/broker/summaries-post.js +1 -0
  273. package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
  274. package/dist/core/runtime/broker/tool-groups.js +1 -1
  275. package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
  276. package/dist/core/runtime/broker/turn-replies.js +1 -1
  277. package/dist/core/runtime/broker-persona-guidance.js +2 -2
  278. package/dist/core/runtime/broker.js +1 -1
  279. package/dist/core/runtime/deliver-live.js +1 -1
  280. package/dist/core/runtime/first-boot-rows.d.ts +8 -0
  281. package/dist/core/runtime/first-boot-rows.js +2 -0
  282. package/dist/core/runtime/fleet.d.ts +13 -12
  283. package/dist/core/runtime/front-door-login.js +1 -1
  284. package/dist/core/runtime/front-door.js +6 -6
  285. package/dist/core/runtime/headless-pi.js +1 -1
  286. package/dist/core/runtime/host.d.ts +14 -3
  287. package/dist/core/runtime/host.js +3 -3
  288. package/dist/core/runtime/invocation.d.ts +6 -0
  289. package/dist/core/runtime/kickoff.d.ts +2 -14
  290. package/dist/core/runtime/kickoff.js +17 -19
  291. package/dist/core/runtime/launch-config-worker.js +1 -1
  292. package/dist/core/runtime/launch.js +2 -2
  293. package/dist/core/runtime/model-registry.js +1 -1
  294. package/dist/core/runtime/node-read.d.ts +4 -6
  295. package/dist/core/runtime/node-read.js +3 -3
  296. package/dist/core/runtime/nodes.js +1 -1
  297. package/dist/core/runtime/outcome-document.d.ts +0 -1
  298. package/dist/core/runtime/outcome-document.js +1 -1
  299. package/dist/core/runtime/output-result.d.ts +15 -0
  300. package/dist/core/runtime/output-result.js +5 -0
  301. package/dist/core/runtime/placement.d.ts +17 -1
  302. package/dist/core/runtime/placement.js +1 -1
  303. package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
  304. package/dist/core/runtime/provider-credential-gate.js +2 -2
  305. package/dist/core/runtime/recovery-hold.d.ts +21 -2
  306. package/dist/core/runtime/recovery-hold.js +2 -1
  307. package/dist/core/runtime/recycle.js +1 -1
  308. package/dist/core/runtime/reset.js +1 -1
  309. package/dist/core/runtime/revive.d.ts +2 -2
  310. package/dist/core/runtime/revive.js +2 -2
  311. package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
  312. package/dist/core/runtime/runner/blaxel/client.js +1 -0
  313. package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
  314. package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
  315. package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
  316. package/dist/core/runtime/runner/blaxel/runner.js +3 -0
  317. package/dist/core/runtime/runner/index.d.ts +8 -0
  318. package/dist/core/runtime/runner/index.js +1 -0
  319. package/dist/core/runtime/runner/process.d.ts +11 -0
  320. package/dist/core/runtime/runner/process.js +1 -0
  321. package/dist/core/runtime/runner/types.d.ts +95 -0
  322. package/dist/core/runtime/runner/types.js +0 -0
  323. package/dist/core/runtime/situational-context.d.ts +3 -6
  324. package/dist/core/runtime/situational-context.js +2 -2
  325. package/dist/core/runtime/situational-live.js +1 -1
  326. package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
  327. package/dist/core/runtime/spawn-env-rows.js +1 -0
  328. package/dist/core/runtime/spawn-env.d.ts +4 -18
  329. package/dist/core/runtime/spawn-env.js +1 -1
  330. package/dist/core/runtime/spawn.js +2 -2
  331. package/dist/core/runtime/stop-guard.d.ts +1 -1
  332. package/dist/core/runtime/stop-guard.js +2 -8
  333. package/dist/core/runtime/structured-output.d.ts +0 -67
  334. package/dist/core/runtime/structured-output.js +3 -8
  335. package/dist/core/runtime/tmux-driver.d.ts +8 -0
  336. package/dist/core/runtime/tmux-driver.js +6 -6
  337. package/dist/core/runtime/view-socket.d.ts +20 -0
  338. package/dist/core/runtime/view-socket.js +3 -1
  339. package/dist/core/runtime/warm-pool.d.ts +13 -1
  340. package/dist/core/runtime/warm-pool.js +1 -1
  341. package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
  342. package/dist/core/scoped-state/legacy-profiles.js +1 -0
  343. package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
  344. package/dist/core/scoped-state/materialized-plugins.js +1 -0
  345. package/dist/core/scoped-state/migrate.d.ts +8 -1
  346. package/dist/core/scoped-state/migrate.js +3 -3
  347. package/dist/core/scoped-state/person-rows.d.ts +10 -0
  348. package/dist/core/scoped-state/person-rows.js +6 -0
  349. package/dist/core/scoped-state/person-store.d.ts +72 -0
  350. package/dist/core/scoped-state/person-store.js +1 -0
  351. package/dist/core/secrets/blaxel-launch.d.ts +24 -0
  352. package/dist/core/secrets/blaxel-launch.js +4 -0
  353. package/dist/core/secrets/blaxel-register.d.ts +2 -0
  354. package/dist/core/secrets/blaxel-register.js +1 -0
  355. package/dist/core/secrets/env-rows.d.ts +17 -0
  356. package/dist/core/secrets/env-rows.js +4 -0
  357. package/dist/core/secrets/environment-owner.d.ts +8 -0
  358. package/dist/core/secrets/environment-owner.js +1 -0
  359. package/dist/core/secrets/environment-secrets.d.ts +14 -0
  360. package/dist/core/secrets/environment-secrets.js +1 -0
  361. package/dist/core/secrets/index.d.ts +2 -0
  362. package/dist/core/secrets/index.js +1 -0
  363. package/dist/core/secrets/key.d.ts +3 -0
  364. package/dist/core/secrets/key.js +2 -0
  365. package/dist/core/secrets/seal.d.ts +18 -0
  366. package/dist/core/secrets/seal.js +1 -0
  367. package/dist/core/spaces/mounts.d.ts +1 -1
  368. package/dist/core/spaces/mounts.js +1 -1
  369. package/dist/core/spaces/process.d.ts +1 -1
  370. package/dist/core/spaces/stop.d.ts +7 -5
  371. package/dist/core/spaces/stop.js +2 -2
  372. package/dist/core/spaces/users.d.ts +2 -1
  373. package/dist/core/spaces/users.js +1 -1
  374. package/dist/core/storage/attachments.d.ts +11 -8
  375. package/dist/core/storage/attachments.js +1 -1
  376. package/dist/core/storage/tables.d.ts +4 -0
  377. package/dist/core/storage/tables.js +3 -3
  378. package/dist/core/subscription-state.d.ts +34 -72
  379. package/dist/core/subscription-state.js +1 -4
  380. package/dist/core/substrate/delivery/plan.js +1 -1
  381. package/dist/core/user-settings.js +1 -1
  382. package/dist/daemon/api/app-listener.js +10 -10
  383. package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
  384. package/dist/daemon/api/auth/person-bearer.js +1 -0
  385. package/dist/daemon/api/bridge.js +4 -4
  386. package/dist/daemon/api/document-listener.js +3 -3
  387. package/dist/daemon/api/environment-of.d.ts +18 -0
  388. package/dist/daemon/api/environment-of.js +5 -0
  389. package/dist/daemon/api/handlers/analytics.js +1 -1
  390. package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
  391. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  392. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  393. package/dist/daemon/api/handlers/bash.js +1 -1
  394. package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
  395. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  396. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  397. package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
  398. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  399. package/dist/daemon/api/handlers/canvas.js +4 -4
  400. package/dist/daemon/api/handlers/charges.d.ts +1 -1
  401. package/dist/daemon/api/handlers/charges.js +1 -1
  402. package/dist/daemon/api/handlers/conversations.d.ts +2 -0
  403. package/dist/daemon/api/handlers/conversations.js +3 -0
  404. package/dist/daemon/api/handlers/crons.js +1 -1
  405. package/dist/daemon/api/handlers/daemon.js +1 -1
  406. package/dist/daemon/api/handlers/delivery.d.ts +1 -1
  407. package/dist/daemon/api/handlers/delivery.js +1 -1
  408. package/dist/daemon/api/handlers/docs.js +1 -1
  409. package/dist/daemon/api/handlers/exec.js +1 -1
  410. package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
  411. package/dist/daemon/api/handlers/execution-start.js +2 -0
  412. package/dist/daemon/api/handlers/files.js +1 -1
  413. package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
  414. package/dist/daemon/api/handlers/git-credential.js +1 -0
  415. package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
  416. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  417. package/dist/daemon/api/handlers/human-requests.js +1 -1
  418. package/dist/daemon/api/handlers/inbox.js +1 -1
  419. package/dist/daemon/api/handlers/messages.js +1 -1
  420. package/dist/daemon/api/handlers/model-config.js +1 -1
  421. package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
  422. package/dist/daemon/api/handlers/modelauth.js +1 -1
  423. package/dist/daemon/api/handlers/node-events.d.ts +6 -0
  424. package/dist/daemon/api/handlers/node-events.js +3 -3
  425. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  426. package/dist/daemon/api/handlers/node-records.js +3 -2
  427. package/dist/daemon/api/handlers/nodes.js +1 -1
  428. package/dist/daemon/api/handlers/objects.js +3 -3
  429. package/dist/daemon/api/handlers/profiles.js +1 -1
  430. package/dist/daemon/api/handlers/providers.js +1 -1
  431. package/dist/daemon/api/handlers/reports.js +9 -13
  432. package/dist/daemon/api/handlers/reviews.js +1 -1
  433. package/dist/daemon/api/handlers/runs.js +1 -1
  434. package/dist/daemon/api/handlers/settings.d.ts +2 -0
  435. package/dist/daemon/api/handlers/settings.js +1 -0
  436. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  437. package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
  438. package/dist/daemon/api/handlers/vendor-status.js +1 -1
  439. package/dist/daemon/api/handlers/worktree.js +1 -1
  440. package/dist/daemon/api/map.d.ts +2 -2
  441. package/dist/daemon/api/map.js +2 -2
  442. package/dist/daemon/api/operations.js +1 -1
  443. package/dist/daemon/api/reader.d.ts +8 -1
  444. package/dist/daemon/api/reader.js +1 -1
  445. package/dist/daemon/api/router.d.ts +4 -2
  446. package/dist/daemon/api/router.js +1 -1
  447. package/dist/daemon/api/server.d.ts +15 -3
  448. package/dist/daemon/api/server.js +1 -1
  449. package/dist/daemon/api/vendor-signin.d.ts +2 -1
  450. package/dist/daemon/api/vendor-signin.js +20 -20
  451. package/dist/daemon/api/viewer-presence.d.ts +20 -6
  452. package/dist/daemon/api/viewer-presence.js +2 -1
  453. package/dist/daemon/broker-signals/bus.d.ts +48 -11
  454. package/dist/daemon/broker-signals/bus.js +1 -1
  455. package/dist/daemon/cron/armed-context.js +1 -1
  456. package/dist/daemon/cron/lease-recovery.js +1 -1
  457. package/dist/daemon/cron/live-runs.d.ts +6 -0
  458. package/dist/daemon/cron/live-runs.js +1 -1
  459. package/dist/daemon/cron/run-socket.js +1 -1
  460. package/dist/daemon/cron-run.js +2 -2
  461. package/dist/daemon/crtrd-cli.js +1 -1
  462. package/dist/daemon/crtrd.d.ts +10 -0
  463. package/dist/daemon/crtrd.js +18 -17
  464. package/dist/daemon/delivery/run-delivery.d.ts +1 -1
  465. package/dist/daemon/delivery/run-delivery.js +1 -1
  466. package/dist/daemon/due-sources.d.ts +1 -1
  467. package/dist/daemon/due-sources.js +1 -1
  468. package/dist/daemon/due.js +7 -6
  469. package/dist/daemon/fleet.d.ts +6 -6
  470. package/dist/daemon/fleet.js +9 -9
  471. package/dist/daemon/park-activity.d.ts +2 -1
  472. package/dist/daemon/park-activity.js +1 -1
  473. package/dist/daemon/park-pending.d.ts +20 -13
  474. package/dist/daemon/park-pending.js +3 -1
  475. package/dist/daemon/profile-delete.js +1 -1
  476. package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
  477. package/dist/daemon/reconcilers/bash-deadline.js +1 -3
  478. package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
  479. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  480. package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
  481. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  482. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
  483. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  484. package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
  485. package/dist/daemon/reconcilers/grant-effects.js +1 -0
  486. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
  487. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  488. package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
  489. package/dist/daemon/reconcilers/ledger-r2.js +7 -0
  490. package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
  491. package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
  492. package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
  493. package/dist/daemon/reconcilers/ledger-storage.js +5 -0
  494. package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
  495. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  496. package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
  497. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  498. package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
  499. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  500. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
  501. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  502. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
  503. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
  504. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
  505. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
  506. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  507. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  508. package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
  509. package/dist/daemon/reconcilers/recipe-image.js +7 -0
  510. package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
  511. package/dist/daemon/reconcilers/row-claim.js +2 -0
  512. package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
  513. package/dist/daemon/reconcilers/storage-due-work.js +2 -1
  514. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
  515. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  516. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  517. package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
  518. package/dist/daemon/reconcilers/throttled-lane.js +1 -0
  519. package/dist/daemon/review/finish.js +1 -1
  520. package/dist/daemon/run-notices.d.ts +3 -0
  521. package/dist/daemon/run-notices.js +1 -1
  522. package/dist/daemon/runs/append-section.d.ts +4 -1
  523. package/dist/daemon/runs/append-section.js +2 -2
  524. package/dist/daemon/runs/observer.d.ts +3 -2
  525. package/dist/daemon/runs/observer.js +3 -2
  526. package/dist/daemon/runs/view-transport.d.ts +19 -0
  527. package/dist/daemon/runs/view-transport.js +1 -0
  528. package/dist/daemon/structured-requests/boot.d.ts +2 -1
  529. package/dist/daemon/structured-requests/boot.js +1 -1
  530. package/dist/daemon/structured-requests/effects.d.ts +4 -3
  531. package/dist/daemon/structured-requests/effects.js +1 -1
  532. package/dist/daemon/structured-requests/notifier.d.ts +2 -0
  533. package/dist/daemon/structured-requests/notifier.js +1 -1
  534. package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
  535. package/dist/daemon/structured-requests/sidecar.js +1 -1
  536. package/dist/launcher/validate.js +1 -1
  537. package/dist/migrations/004-canvas-documents/index.js +2 -2
  538. package/dist/pi-extensions/broker-local.d.ts +3 -3
  539. package/dist/pi-extensions/broker-local.js +1 -2
  540. package/dist/pi-extensions/canvas-bash-valve.js +6 -6
  541. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  542. package/dist/pi-extensions/canvas-elapsed.js +2 -2
  543. package/dist/pi-extensions/canvas-goal-capture.js +1 -1
  544. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  545. package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
  546. package/dist/pi-extensions/canvas-review-boundary.js +3 -3
  547. package/dist/pi-extensions/canvas-stophook.js +1 -1
  548. package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
  549. package/dist/pi-extensions/canvas-structured-output.js +6 -11
  550. package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
  551. package/dist/pi-extensions/canvas-tool-guide.js +6 -6
  552. package/dist/shared/inbox-entry-body.js +7 -7
  553. package/dist/types.d.ts +12 -0
  554. package/docs/sdk/release-notes.md +4 -0
  555. package/package.json +7 -4
  556. package/packages/crouter-identity/package.json +1 -1
  557. package/runtime.lock.json +13 -13
  558. package/scripts/git-credential-crtr +33 -0
  559. package/scripts/sandbox-bootstrap.sh +54 -0
  560. package/scripts/sandbox-start.mjs +320 -0
  561. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
  562. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
  563. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
  564. package/dist/core/conversation-store/file-store.d.ts +0 -37
  565. package/dist/core/conversation-store/file-store.js +0 -9
  566. package/dist/core/conversation-store/listener.d.ts +0 -4
  567. package/dist/core/conversation-store/listener.js +0 -8
  568. package/dist/core/scoped-state/profiles.d.ts +0 -27
  569. package/dist/core/scoped-state/profiles.js +0 -1
  570. package/dist/core/scoped-state/providers.d.ts +0 -24
  571. package/dist/core/scoped-state/providers.js +0 -1
  572. package/dist/core/scoped-state/settings.d.ts +0 -28
  573. package/dist/core/scoped-state/settings.js +0 -1
@@ -1 +1 @@
1
- var P=Object.defineProperty;var o=(e,t)=>P(e,"name",{value:t,configurable:!0});import{statSync as N}from"node:fs";import{isAbsolute as T}from"node:path";import{ApiError as s}from"../../../api/index.js";import{readDaemonActionById as C}from"../../../core/canvas/daemon-actions.js";import{isSafeNodeId as I}from"../../../core/canvas/paths.js";import{getNode as b}from"../../../core/canvas/canvas.js";import{assertScope as $}from"../../../core/scopes.js";import{resolvePageComponents as g}from"../../../core/config.js";import{resolveHumanAction as D}from"../../../core/human-actions.js";import{HUMAN_ACTION_NAME_PATTERN as x}from"../../../core/human/action-binding.js";import{createPageRequest as J,getRequest as F}from"../../../core/human/requests.js";import{preparePageSource as M}from"../../../core/human/page-authoring.js";import{PageCompilerError as B}from"../../../core/human/page-errors.js";import{publishPage as G,validatePageTicketResponses as H}from"../../../core/human/tickets.js";import{cancelHumanTicket as L,resolvePageTicket as U}from"../../human/finish.js";import{inboxPageProjection as K}from"./inbox-page.js";import{appOf as X}from"../router.js";const z=1e3,q=200,m={placement:"inline",inbox:!0,reply:!1},v=["sessionName","askedBy","emittedAt","profileName","nodeId"];function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(c,"isPlainObject");function l(e,t,n){for(const r of Object.keys(e))if(!t.includes(r))throw new s(400,"invalid_request",`unexpected field in ${n}: ${r}`)}o(l,"requireNoExtraKeys");function i(e){return new s(400,"invalid_request",e)}o(i,"invalid");function w(e){if(!c(e))throw i("`page` must be an object");if(l(e,["dialect","source"],"`page`"),e.dialect!=="jsx"&&e.dialect!=="html")throw i('`page.dialect` must be "jsx" or "html"');if(typeof e.source!="string"||e.source.trim()==="")throw i("`page.source` must be the authored page text");return{dialect:e.dialect,source:e.source}}o(w,"validatePage");function S(e,t){const n=e??t;if(n!=="inline"&&n!=="panel")throw i('`delivery.placement` must be "inline" or "panel"');return n}o(S,"validatePlacement");function V(e,t){if(e===void 0)return m;if(!c(e))throw i("`delivery` must be an object");l(e,["placement","inbox","reply"],"`delivery`");const n=e.inbox??m.inbox,r=e.reply??m.reply;if(typeof n!="boolean")throw i("`delivery.inbox` must be boolean");if(typeof r!="boolean")throw i("`delivery.reply` must be boolean");if(r&&t===null)throw i("`delivery.reply` requires `requester_node_id`");return{placement:S(e.placement,m.placement),inbox:n,reply:r}}o(V,"validateCreateDelivery");function Y(e,t){if(e===void 0)return t;if(!c(e))throw i("`delivery` must be an object");return l(e,["placement"],"`delivery`"),{...t,placement:S(e.placement,t.placement)}}o(Y,"validateReplaceDelivery");function Q(e){if(e===void 0)return;if(!c(e))throw i("`source` must be an object");l(e,v,"`source`");const t={};for(const n of v){const r=e[n];if(r!==void 0){if(typeof r!="string"||r==="")throw i(`\`source.${n}\` must be a nonempty string`);t[n]=r}}return t}o(Q,"validateSource");function W(e){if(typeof e!="string"||e==="")throw i("`creator_cwd` is required");if(!T(e))throw i("`creator_cwd` must be an absolute path");try{if(!N(e).isDirectory())throw i(`\`creator_cwd\` is not a directory: ${e}`)}catch(t){throw t instanceof s?t:i(`\`creator_cwd\` does not exist: ${e}`)}return e}o(W,"validateCreatorCwd");function Z(e){if(e!==void 0){if(!c(e))throw i("`action` must be an object");if(l(e,["name","payload"],"`action`"),typeof e.name!="string"||!x.test(e.name))throw i("`action.name` must be a declared action name");return{name:e.name,payload:e.payload??null}}}o(Z,"validateActionSelection");function ee(e){if(e==null)return null;if(typeof e!="string"||!I(e))throw i("`requester_node_id` must be a safe node id or null");return e}o(ee,"validateRequesterNodeId");function te(e){if(!c(e))throw i("request body is required");l(e,["page","delivery","source","requester_node_id","creator_cwd","action"],"the request body");const t=Q(e.source),n=ee(e.requester_node_id),r=Z(e.action);return{page:w(e.page),delivery:V(e.delivery,n),...t===void 0?{}:{source:t},requesterNodeId:n,creatorCwd:W(e.creator_cwd),...r===void 0?{}:{action:r}}}o(te,"validateCreateRequest");function ne(e,t){if(!c(e))throw i("request body is required");return l(e,["page","delivery"],"the request body"),{page:w(e.page),delivery:Y(e.delivery,t)}}o(ne,"validateReplaceRequest");function _(e,t,n){if(e!==void 0){if(typeof e!="string"||e.trim()===""||e.length>n)throw i(`\`${t}\` must be nonempty after trim and at most ${n} characters`);return e}}o(_,"optionalBoundedString");function re(e){if(!c(e))throw i("request body is required");if(l(e,["responses","actor"],"the request body"),!c(e.responses))throw i("`responses` must be an object");const t=_(e.actor,"actor",q);return{responses:e.responses,...t===void 0?{}:{actor:t}}}o(re,"validateRespondRequest");function oe(e){if(e===void 0)return{};if(!c(e))throw i("request body must be an object");l(e,["reason","actor"],"the request body");const t=_(e.reason,"reason",z),n=_(e.actor,"actor",q);return{...t===void 0?{}:{reason:t},...n===void 0?{}:{actor:n}}}o(oe,"validateSettleRequest");function h(e){const t=e.params.request_id;if(typeof t!="string"||t==="")throw i("request id is required");return t}o(h,"requestId");async function f(e){const t=await F(e);if(t===null||t.kind!=="page")throw new s(404,"not_found","no request with that id");return t}o(f,"requirePageRequest");function A(e){try{const t=JSON.parse(e.specification_json);if(!c(t))throw new Error("not an object");return t}catch{throw new s(500,"internal","the request specification could not be read")}}o(A,"manifest");function ie(e){if(e.result_json===null)return null;try{return JSON.parse(e.result_json)}catch{throw new s(500,"internal","the request result could not be read")}}o(ie,"terminalResult");function ae(e){if(e.action_json===null)return null;try{const t=JSON.parse(e.action_json);if(t.schema!=="crtr.human-action-binding/v1"||typeof t.name!="string")throw new Error("invalid action");return t}catch{throw new s(500,"internal","the request action could not be read")}}o(ae,"frozenAction");function se(e){return e.state!=="settled"?"pending":e.outcome==="answered"?"answered":e.outcome==="dismissed"?"dismissed":"canceled"}o(se,"requestState");async function de(e){if(e.action_delivery_id===null)return{state:"none",attempt:0};const t=await C(e.action_delivery_id);if(t===null)return{state:"none",attempt:0};const n=t.state==="acknowledged"?"accepted":t.state==="permanent_failed"?"permanent_failed":t.state==="handed_off"?"running":"pending",r={state:n,attempt:t.attempts};return n==="pending"&&t.nextAttemptAt!==null&&(r.next_attempt_at=new Date(t.nextAttemptAt).toISOString()),t.acknowledgedAt!==null&&(r.accepted_at=new Date(t.acknowledgedAt).toISOString()),t.failedAt!==null&&(r.permanent_failed_at=new Date(t.failedAt).toISOString()),t.lastFailure!==null&&(r.last_failure=t.lastFailure),r}o(de,"deliveryDetail");async function y(e){const t=A(e),n=ie(e),r=se(e),a={request_id:e.request_id,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,kind:e.kind,state:r,title:e.title,source:t.source??{},emitted_at:t.source?.emittedAt??e.created_at};e.subtitle!==null&&(a.subtitle=e.subtitle),e.kind==="page"&&(a.page=await K(e)),n!==null&&(a.settled_at=e.settled_at??e.updated_at,n.kind==="page"&&r==="answered"&&(a.responses=n.responses),n.kind==="canceled"&&n.reason!==void 0&&(a.reason=n.reason),n.kind==="page"&&n.actor!==void 0&&(a.actor=n.actor),n.kind==="canceled"&&n.actor!==void 0&&(a.actor=n.actor));const u=ae(e);return u!==null&&(a.action={name:u.name,payload:u.payload},a.delivery=await de(e)),a}o(y,"requestToDTO");function k(e,t,n,r){try{return M({dialect:e,document:t,source:n,delivery:r,productKinds:g()})}catch(a){throw a instanceof B?a:i(a instanceof Error?a.message:"the page could not be prepared")}}o(k,"prepareOrReject");async function ce(e){const t=te(e.body),n=t.requesterNodeId??t.source?.nodeId;if(n!=null){const d=await b(n);d!==null&&$(d,"crtr:act")}let r;if(t.action!==void 0){const d=D(t.action.name,t.creatorCwd);if("kind"in d){const E=d.kind==="unknown_action"?`no action named ${d.name} is declared from ${t.creatorCwd}`:`${d.name} is declared in ${d.configOrigin} but unusable: ${d.reason}`;throw new s(400,d.kind,E)}const p=n==null?null:await b(n);if(n&&!p)throw new s(404,"not_found","action requester node not found");if(p&&e.principal.class!=="person"&&p.grantee!==X(e.principal))throw new s(403,"permission_error","action requester belongs to another app");r=JSON.stringify({schema:"crtr.human-action-binding/v1",name:t.action.name,payload:t.action.payload,creatorCwd:t.creatorCwd,configOrigin:d.configOrigin,argv:d.argv,cwd:d.cwd,app:p?.grantee??(e.principal.class==="broker"?e.principal.app:"app:terminal")})}const a=k(t.page.dialect,t.page.source,t.source,t.delivery),u=await J({prepared:a,requester_node_id:t.requesterNodeId,...r===void 0?{}:{action_json:r}});return{status:201,body:{request_id:u.request_id,request_dir:u.request_dir,state:"pending",...t.action===void 0?{}:{action:{name:t.action.name}},delivery_state:"none"}}}o(ce,"handleCreate");async function ue(e){return{status:200,body:await y(await f(h(e)))}}o(ue,"handleGet");async function le(e){const t=await f(h(e));if(t.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");const n=A(t),r=ne(e.body,n.delivery),a=k(r.page.dialect,r.page.source,n.source,r.delivery);try{await G(t.request_dir,a)}catch(u){throw u instanceof Error&&u.message===`page request is not open: ${t.request_id}`?new s(409,"already_settled","the request already has a terminal result"):u}return{status:200,body:await y(await f(t.request_id))}}o(le,"handleReplace");function O(e){return e instanceof s?e:e instanceof Error&&e.message.includes("unknown page request")?new s(404,"not_found","no request with that id"):e instanceof Error&&e.message==="page_has_no_response_lifecycle"?new s(409,"not_settleable","this request carries no response lifecycle"):new s(500,"internal","the request could not be settled")}o(O,"settlementError");function R(e){if(e.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");if(!e.settleable)throw new s(409,"not_settleable","this request carries no response lifecycle")}o(R,"requireSettleable");async function fe(e){const t=await f(h(e)),n=re(e.body);R(t);try{await H(t.request_dir,n.responses)}catch(r){throw i(r instanceof Error?r.message:"the response map is invalid")}try{await U(t.request_id,n.responses,n.actor===void 0?{}:{actor:n.actor})}catch(r){throw O(r)}return{status:200,body:await y(await f(t.request_id))}}o(fe,"handleRespond");async function j(e,t){const n=await f(h(e)),r=oe(e.body);R(n);try{await L(n.request_id,{...r,disposition:t})}catch(a){throw O(a)}return{status:200,body:await y(await f(n.request_id))}}o(j,"settle");function pe(){return{status:200,body:{components:[...g()]}}}o(pe,"handleComponents");const Te=[{method:"GET",pattern:"/v1/human/components",handler:o(()=>pe(),"handler")},{method:"POST",pattern:"/v1/human/requests",scope:"crtr:act",handler:ce},{method:"GET",pattern:"/v1/human/requests/:request_id",handler:ue},{method:"POST",pattern:"/v1/human/requests/:request_id/replace",handler:le},{method:"POST",pattern:"/v1/human/requests/:request_id/respond",handler:fe},{method:"POST",pattern:"/v1/human/requests/:request_id/dismiss",handler:o(e=>j(e,"dismissed"),"handler")},{method:"POST",pattern:"/v1/human/requests/:request_id/cancel",handler:o(e=>j(e,"canceled"),"handler")}];export{Te as humanRequestRoutes};
1
+ var P=Object.defineProperty;var o=(e,t)=>P(e,"name",{value:t,configurable:!0});import{statSync as N}from"node:fs";import{isAbsolute as T}from"node:path";import{ApiError as s}from"../../../api/index.js";import{readDaemonActionById as C}from"../../../core/canvas/daemon-actions.js";import{isSafeNodeId as I}from"../../../core/canvas/paths.js";import{getNode as b}from"../../../core/canvas/canvas.js";import{assertScope as $}from"../../../core/scopes.js";import{resolvePageComponents as g}from"../../../core/config.js";import{resolveHumanAction as D}from"../../../core/human-actions.js";import{HUMAN_ACTION_NAME_PATTERN as x}from"../../../core/human/action-binding.js";import{createPageRequest as J,getRequest as F}from"../../../core/human/requests.js";import{preparePageSource as M}from"../../../core/human/page-authoring.js";import{PageCompilerError as B}from"../../../core/human/page-errors.js";import{publishPage as G,validatePageTicketResponses as H}from"../../../core/human/tickets.js";import{cancelHumanTicket as L,resolvePageTicket as U}from"../../human/finish.js";import{inboxPageProjection as K}from"./inbox-page.js";import{actsAsPerson as X,appOf as z}from"../router.js";const V=1e3,q=200,m={placement:"inline",inbox:!0,reply:!1},v=["sessionName","askedBy","emittedAt","profileName","nodeId"];function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(c,"isPlainObject");function l(e,t,n){for(const r of Object.keys(e))if(!t.includes(r))throw new s(400,"invalid_request",`unexpected field in ${n}: ${r}`)}o(l,"requireNoExtraKeys");function i(e){return new s(400,"invalid_request",e)}o(i,"invalid");function w(e){if(!c(e))throw i("`page` must be an object");if(l(e,["dialect","source"],"`page`"),e.dialect!=="jsx"&&e.dialect!=="html")throw i('`page.dialect` must be "jsx" or "html"');if(typeof e.source!="string"||e.source.trim()==="")throw i("`page.source` must be the authored page text");return{dialect:e.dialect,source:e.source}}o(w,"validatePage");function A(e,t){const n=e??t;if(n!=="inline"&&n!=="panel")throw i('`delivery.placement` must be "inline" or "panel"');return n}o(A,"validatePlacement");function Y(e,t){if(e===void 0)return m;if(!c(e))throw i("`delivery` must be an object");l(e,["placement","inbox","reply"],"`delivery`");const n=e.inbox??m.inbox,r=e.reply??m.reply;if(typeof n!="boolean")throw i("`delivery.inbox` must be boolean");if(typeof r!="boolean")throw i("`delivery.reply` must be boolean");if(r&&t===null)throw i("`delivery.reply` requires `requester_node_id`");return{placement:A(e.placement,m.placement),inbox:n,reply:r}}o(Y,"validateCreateDelivery");function Q(e,t){if(e===void 0)return t;if(!c(e))throw i("`delivery` must be an object");return l(e,["placement"],"`delivery`"),{...t,placement:A(e.placement,t.placement)}}o(Q,"validateReplaceDelivery");function W(e){if(e===void 0)return;if(!c(e))throw i("`source` must be an object");l(e,v,"`source`");const t={};for(const n of v){const r=e[n];if(r!==void 0){if(typeof r!="string"||r==="")throw i(`\`source.${n}\` must be a nonempty string`);t[n]=r}}return t}o(W,"validateSource");function Z(e){if(typeof e!="string"||e==="")throw i("`creator_cwd` is required");if(!T(e))throw i("`creator_cwd` must be an absolute path");try{if(!N(e).isDirectory())throw i(`\`creator_cwd\` is not a directory: ${e}`)}catch(t){throw t instanceof s?t:i(`\`creator_cwd\` does not exist: ${e}`)}return e}o(Z,"validateCreatorCwd");function ee(e){if(e!==void 0){if(!c(e))throw i("`action` must be an object");if(l(e,["name","payload"],"`action`"),typeof e.name!="string"||!x.test(e.name))throw i("`action.name` must be a declared action name");return{name:e.name,payload:e.payload??null}}}o(ee,"validateActionSelection");function te(e){if(e==null)return null;if(typeof e!="string"||!I(e))throw i("`requester_node_id` must be a safe node id or null");return e}o(te,"validateRequesterNodeId");function ne(e){if(!c(e))throw i("request body is required");l(e,["page","delivery","source","requester_node_id","creator_cwd","action"],"the request body");const t=W(e.source),n=te(e.requester_node_id),r=ee(e.action);return{page:w(e.page),delivery:Y(e.delivery,n),...t===void 0?{}:{source:t},requesterNodeId:n,creatorCwd:Z(e.creator_cwd),...r===void 0?{}:{action:r}}}o(ne,"validateCreateRequest");function re(e,t){if(!c(e))throw i("request body is required");return l(e,["page","delivery"],"the request body"),{page:w(e.page),delivery:Q(e.delivery,t)}}o(re,"validateReplaceRequest");function _(e,t,n){if(e!==void 0){if(typeof e!="string"||e.trim()===""||e.length>n)throw i(`\`${t}\` must be nonempty after trim and at most ${n} characters`);return e}}o(_,"optionalBoundedString");function oe(e){if(!c(e))throw i("request body is required");if(l(e,["responses","actor"],"the request body"),!c(e.responses))throw i("`responses` must be an object");const t=_(e.actor,"actor",q);return{responses:e.responses,...t===void 0?{}:{actor:t}}}o(oe,"validateRespondRequest");function ie(e){if(e===void 0)return{};if(!c(e))throw i("request body must be an object");l(e,["reason","actor"],"the request body");const t=_(e.reason,"reason",V),n=_(e.actor,"actor",q);return{...t===void 0?{}:{reason:t},...n===void 0?{}:{actor:n}}}o(ie,"validateSettleRequest");function h(e){const t=e.params.request_id;if(typeof t!="string"||t==="")throw i("request id is required");return t}o(h,"requestId");async function f(e){const t=await F(e);if(t===null||t.kind!=="page")throw new s(404,"not_found","no request with that id");return t}o(f,"requirePageRequest");function S(e){try{const t=JSON.parse(e.specification_json);if(!c(t))throw new Error("not an object");return t}catch{throw new s(500,"internal","the request specification could not be read")}}o(S,"manifest");function ae(e){if(e.result_json===null)return null;try{return JSON.parse(e.result_json)}catch{throw new s(500,"internal","the request result could not be read")}}o(ae,"terminalResult");function se(e){if(e.action_json===null)return null;try{const t=JSON.parse(e.action_json);if(t.schema!=="crtr.human-action-binding/v1"||typeof t.name!="string")throw new Error("invalid action");return t}catch{throw new s(500,"internal","the request action could not be read")}}o(se,"frozenAction");function de(e){return e.state!=="settled"?"pending":e.outcome==="answered"?"answered":e.outcome==="dismissed"?"dismissed":"canceled"}o(de,"requestState");async function ce(e){if(e.action_delivery_id===null)return{state:"none",attempt:0};const t=await C(e.action_delivery_id);if(t===null)return{state:"none",attempt:0};const n=t.state==="acknowledged"?"accepted":t.state==="permanent_failed"?"permanent_failed":t.state==="handed_off"?"running":"pending",r={state:n,attempt:t.attempts};return n==="pending"&&t.nextAttemptAt!==null&&(r.next_attempt_at=new Date(t.nextAttemptAt).toISOString()),t.acknowledgedAt!==null&&(r.accepted_at=new Date(t.acknowledgedAt).toISOString()),t.failedAt!==null&&(r.permanent_failed_at=new Date(t.failedAt).toISOString()),t.lastFailure!==null&&(r.last_failure=t.lastFailure),r}o(ce,"deliveryDetail");async function y(e){const t=S(e),n=ae(e),r=de(e),a={request_id:e.request_id,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,kind:e.kind,state:r,title:e.title,source:t.source??{},emitted_at:t.source?.emittedAt??e.created_at};e.subtitle!==null&&(a.subtitle=e.subtitle),e.kind==="page"&&(a.page=await K(e)),n!==null&&(a.settled_at=e.settled_at??e.updated_at,n.kind==="page"&&r==="answered"&&(a.responses=n.responses),n.kind==="canceled"&&n.reason!==void 0&&(a.reason=n.reason),n.kind==="page"&&n.actor!==void 0&&(a.actor=n.actor),n.kind==="canceled"&&n.actor!==void 0&&(a.actor=n.actor));const u=se(e);return u!==null&&(a.action={name:u.name,payload:u.payload},a.delivery=await ce(e)),a}o(y,"requestToDTO");function k(e,t,n,r){try{return M({dialect:e,document:t,source:n,delivery:r,productKinds:g()})}catch(a){throw a instanceof B?a:i(a instanceof Error?a.message:"the page could not be prepared")}}o(k,"prepareOrReject");async function ue(e){const t=ne(e.body),n=t.requesterNodeId??t.source?.nodeId;if(n!=null){const d=await b(n);d!==null&&$(d,"crtr:act")}let r;if(t.action!==void 0){const d=D(t.action.name,t.creatorCwd);if("kind"in d){const E=d.kind==="unknown_action"?`no action named ${d.name} is declared from ${t.creatorCwd}`:`${d.name} is declared in ${d.configOrigin} but unusable: ${d.reason}`;throw new s(400,d.kind,E)}const p=n==null?null:await b(n);if(n&&!p)throw new s(404,"not_found","action requester node not found");if(p&&!X(e.principal)&&p.grantee!==z(e.principal))throw new s(403,"permission_error","action requester belongs to another app");r=JSON.stringify({schema:"crtr.human-action-binding/v1",name:t.action.name,payload:t.action.payload,creatorCwd:t.creatorCwd,configOrigin:d.configOrigin,argv:d.argv,cwd:d.cwd,app:p?.grantee??(e.principal.class==="broker"?e.principal.app:"app:terminal")})}const a=k(t.page.dialect,t.page.source,t.source,t.delivery),u=await J({prepared:a,requester_node_id:t.requesterNodeId,...r===void 0?{}:{action_json:r}});return{status:201,body:{request_id:u.request_id,request_dir:u.request_dir,state:"pending",...t.action===void 0?{}:{action:{name:t.action.name}},delivery_state:"none"}}}o(ue,"handleCreate");async function le(e){return{status:200,body:await y(await f(h(e)))}}o(le,"handleGet");async function fe(e){const t=await f(h(e));if(t.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");const n=S(t),r=re(e.body,n.delivery),a=k(r.page.dialect,r.page.source,n.source,r.delivery);try{await G(t.request_dir,a)}catch(u){throw u instanceof Error&&u.message===`page request is not open: ${t.request_id}`?new s(409,"already_settled","the request already has a terminal result"):u}return{status:200,body:await y(await f(t.request_id))}}o(fe,"handleReplace");function O(e){return e instanceof s?e:e instanceof Error&&e.message.includes("unknown page request")?new s(404,"not_found","no request with that id"):e instanceof Error&&e.message==="page_has_no_response_lifecycle"?new s(409,"not_settleable","this request carries no response lifecycle"):new s(500,"internal","the request could not be settled")}o(O,"settlementError");function R(e){if(e.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");if(!e.settleable)throw new s(409,"not_settleable","this request carries no response lifecycle")}o(R,"requireSettleable");async function pe(e){const t=await f(h(e)),n=oe(e.body);R(t);try{await H(t.request_dir,n.responses)}catch(r){throw i(r instanceof Error?r.message:"the response map is invalid")}try{await U(t.request_id,n.responses,n.actor===void 0?{}:{actor:n.actor})}catch(r){throw O(r)}return{status:200,body:await y(await f(t.request_id))}}o(pe,"handleRespond");async function j(e,t){const n=await f(h(e)),r=ie(e.body);R(n);try{await L(n.request_id,{...r,disposition:t})}catch(a){throw O(a)}return{status:200,body:await y(await f(n.request_id))}}o(j,"settle");function me(){return{status:200,body:{components:[...g()]}}}o(me,"handleComponents");const Ce=[{method:"GET",pattern:"/v1/human/components",handler:o(()=>me(),"handler")},{method:"POST",pattern:"/v1/human/requests",scope:"crtr:act",handler:ue},{method:"GET",pattern:"/v1/human/requests/:request_id",handler:le},{method:"POST",pattern:"/v1/human/requests/:request_id/replace",handler:fe},{method:"POST",pattern:"/v1/human/requests/:request_id/respond",handler:pe},{method:"POST",pattern:"/v1/human/requests/:request_id/dismiss",handler:o(e=>j(e,"dismissed"),"handler")},{method:"POST",pattern:"/v1/human/requests/:request_id/cancel",handler:o(e=>j(e,"canceled"),"handler")}];export{Ce as humanRequestRoutes};
@@ -1 +1 @@
1
- var q=Object.defineProperty;var o=(e,i)=>q(e,"name",{value:i,configurable:!0});import{ApiError as t}from"../../../api/index.js";import{inboxPageProjection as T}from"./inbox-page.js";import{getRequestByInboxTicket as p}from"../../../core/human/requests.js";import{getNode as b}from"../../../core/canvas/canvas.js";import{canReadNode as g}from"../router.js";import{parsePage as A}from"../../../core/human/page.js";import{scanInbox as I,scanPageHistory as P}from"../../../core/human/scan.js";import{readPageTicket as h,readTicketResult as k,selectedPageDir as E,validatePageTicketResponses as x,writePageProgress as R}from"../../../core/human/tickets.js";import{describePageAnswer as S}from"../../../core/human/answer.js";import{cancelHumanTicket as O,resolvePageTicket as N}from"../../human/finish.js";import{filterAsync as y}from"../../../core/async-array.js";const C="Canceled from the inbox.",D=1e3,j=/^[a-f0-9]{64}$/;async function c(e){const i=await p(e);return i===null?null:{ticketId:i.request_id,dir:i.request_dir,kind:i.kind}}o(c,"resolveTicket");function l(e){const i=e.ticket_id;if(i===void 0||!j.test(i))throw new t(400,"invalid_request","invalid ticket id");return i}o(l,"requireTicketId");function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(u,"isPlainObject");function f(e,i){for(const n of Object.keys(e))if(!i.includes(n))throw new t(400,"invalid_request",`unexpected field: ${n}`)}o(f,"requireNoExtraKeys");function G(e){if(!u(e))throw new t(400,"invalid_request","respond body is required");if(f(e,["responses"]),!u(e.responses))throw new t(400,"invalid_request","`responses` must be an object");return{responses:e.responses}}o(G,"validateRespondRequest");function L(e){if(!u(e))throw new t(400,"invalid_request","progress body is required");if(f(e,["responses"]),!u(e.responses))throw new t(400,"invalid_request","`responses` must be an object");return{responses:e.responses}}o(L,"validateProgressRequest");function H(e){if(e===void 0)return{};if(!u(e))throw new t(400,"invalid_request","cancel body must be an object");if(f(e,["reason"]),e.reason===void 0)return{};const i=e.reason;if(typeof i!="string")throw new t(400,"invalid_request","`reason` must be a string");if(i.trim()===""||i.length>D)throw new t(400,"invalid_request","`reason` must be nonempty after trim and at most 1000 characters");return{reason:i}}o(H,"validateCancelRequest");const K=[/^slot ".*?" /,/^response names unknown or non-response-bearing slot id/,/^final page response is missing response-bearing slot id/];function _(e){return e instanceof Error&&K.some(i=>i.test(e.message))}o(_,"isSlotValidationError");function v(e){const i={request_id:e.id,request_dir:e.dir,ticket_id:e.inboxTicketId,kind:"page",title:e.title,placement:e.placement,dialect:e.dialect,steps:e.steps,emitted_at:e.emittedAt,source:e.source,slot_kinds:e.slotKinds,inbox:e.inbox,awaits_response:e.awaitsResponse,state:e.state};return e.subtitle!==""&&(i.subtitle=e.subtitle),e.answerDigest!==void 0&&(i.answer_digest=e.answerDigest),e.recommendedOptions.length>0&&(i.recommended_options=e.recommendedOptions.map(n=>({slot_id:n.slotId,option_id:n.optionId,label:n.label}))),e.fastAction!==void 0&&(i.fast_action={kind:e.fastAction.kind,responses:e.fastAction.responses}),i}o(v,"pageSummaryToDTO");async function $(e){return{status:200,body:{tickets:(await y(await I(),async n=>{if(e.principal.class==="person")return!0;const s=await p(n.inboxTicketId),r=s?.requester_node_id?await b(s.requester_node_id):null;return r!==null&&await g(e.principal,r.grantee??"app:terminal",r.node_id)})).map(n=>{if(n.kind==="page")return v(n);if(n.kind==="review")return{request_id:n.id,request_dir:n.dir,ticket_id:n.inboxTicketId,kind:"review",title:n.title,subtitle:n.subtitle,blocked_since:n.blockedSince,source:n.source};throw new Error(`unknown ticket kind: ${n.kind}`)}).sort((n,s)=>{const r=o(d=>d.kind==="page"?d.emitted_at:d.blocked_since,"pageTime"),a=Date.parse(r(s))-Date.parse(r(n));return a!==0?a:n.ticket_id.localeCompare(s.ticket_id)})}}}o($,"handleList");const V=new Set(["pending","resolved","canceled","passive"]);async function z(e){const i=e.query.get("node_id");if(i==="")throw new t(400,"invalid_request","node_id must be nonempty when present");const n=e.query.get("state");if(n!==null&&!V.has(n))throw new t(400,"invalid_request","state must be one of pending, resolved, canceled, passive");const s=(await P(i??void 0)).filter(d=>n===null||d.state===n);return{status:200,body:{tickets:(await y(s,async d=>{if(e.principal.class==="person")return!0;const m=await p(d.inboxTicketId),w=m?.requester_node_id?await b(m.requester_node_id):null;return w!==null&&await g(e.principal,w.grantee??"app:terminal",w.node_id)})).map(v)}}}o(z,"handleHistory");async function B(e){const i=l(e.params),n=await c(i);if(n===null)throw new t(404,"ticket_not_found","no matching ticket");if(n.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets have no page read operation");const s=await p(i);if(s===null||s.kind!=="page")throw new t(404,"ticket_not_found","no matching ticket");try{return{status:200,body:await T(s)}}catch{throw new t(500,"internal","the ticket could not be read")}}o(B,"handleGetPage");async function F(e){const i=l(e.params),n=G(e.body),s=await c(i);if(s===null)throw new t(404,"ticket_not_found","no matching ticket");if(s.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets submit through their own path");if((await h(s.dir)).state==="passive")throw new t(409,"page_has_no_response_lifecycle","this page has no response lifecycle");const r=await k(s.dir);if(r!==null&&r.kind!=="canceled")throw new t(409,"ticket_already_resolved","ticket was already resolved");if(r?.kind==="canceled")throw new t(409,"ticket_canceled","canceled tickets cannot be answered");try{await x(s.dir,n.responses)}catch(a){throw _(a)?new t(400,"invalid_ticket_response",a.message):new t(500,"internal","validation failed")}try{const a=await N(s.ticketId,n.responses);if(a.kind!=="page")throw new t(409,"ticket_kind_mismatch","unexpected result kind");return{status:200,body:a}}catch(a){throw a instanceof t?a:_(a)?new t(400,"invalid_ticket_response",a.message):new t(500,"internal","the ticket could not be finalized")}}o(F,"handleRespond");async function M(e){const i=l(e.params),n=L(e.body),s=await c(i);if(s===null)throw new t(404,"ticket_not_found","no matching ticket");if(s.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets do not support progress autosave");if((await h(s.dir)).state==="passive")throw new t(409,"page_has_no_response_lifecycle","this page has no response lifecycle");const r=await k(s.dir);if(r!==null&&r.kind!=="canceled")throw new t(409,"ticket_already_resolved","ticket was already resolved");try{return await R(s.dir,n.responses),{status:200,body:{}}}catch(a){throw _(a)?new t(400,"invalid_ticket_response",a.message):new t(500,"internal","progress could not be saved")}}o(M,"handleProgress");async function U(e){const i=l(e.params),n=H(e.body),s=await c(i);if(s===null)throw new t(404,"ticket_not_found","no matching ticket");if(s.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets have their own cancel path");if((await h(s.dir)).state==="passive")throw new t(409,"page_has_no_response_lifecycle","this page has no response lifecycle");try{const r=await O(s.ticketId,{reason:n.reason??C,actor:"human",disposition:"dismissed"});if(r.outcome==="already_settled"||r.result.kind!=="canceled")throw new t(409,"ticket_already_resolved","ticket was already resolved");return{status:200,body:r.result}}catch(r){throw r instanceof t?r:new t(500,"internal","the ticket could not be canceled")}}o(U,"handleCancel");async function X(e){const i=l(e.params),n=await c(i);if(n===null)throw new t(404,"ticket_not_found","no matching ticket");if(n.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets fetch responses through their own path");const s=await k(n.dir);if(s===null)throw new t(404,"ticket_pending","ticket has no response yet");if(s.kind==="canceled")throw new t(404,"ticket_canceled","canceled tickets have no response");if(s.kind!=="page")throw new t(409,"ticket_kind_mismatch","unexpected result kind");try{const r=A(await E(n.dir));return{status:200,body:{...s,answer:S(r,s.responses,{completedAt:s.completedAt})}}}catch{throw new t(500,"internal","the ticket answer could not be read")}}o(X,"handleGetResponse");const ae=[{method:"GET",pattern:"/v1/human/inbox",handler:$},{method:"GET",pattern:"/v1/human/inbox/history",handler:z},{method:"GET",pattern:"/v1/human/inbox/:ticket_id",handler:B},{method:"GET",pattern:"/v1/human/inbox/:ticket_id/response",handler:X},{method:"POST",pattern:"/v1/human/inbox/:ticket_id/respond",handler:F},{method:"POST",pattern:"/v1/human/inbox/:ticket_id/progress",handler:M},{method:"POST",pattern:"/v1/human/inbox/:ticket_id/cancel",handler:U}];export{ae as inboxRoutes,l as requireTicketId,c as resolveTicket};
1
+ var T=Object.defineProperty;var o=(e,i)=>T(e,"name",{value:i,configurable:!0});import{ApiError as t}from"../../../api/index.js";import{inboxPageProjection as A}from"./inbox-page.js";import{getRequestByInboxTicket as p}from"../../../core/human/requests.js";import{getNode as b}from"../../../core/canvas/canvas.js";import{actsAsPerson as g,canReadNode as y}from"../router.js";import{parsePage as I}from"../../../core/human/page.js";import{scanInbox as P,scanPageHistory as E}from"../../../core/human/scan.js";import{readPageTicket as h,readTicketResult as k,selectedPageDir as x,validatePageTicketResponses as R,writePageProgress as S}from"../../../core/human/tickets.js";import{describePageAnswer as O}from"../../../core/human/answer.js";import{cancelHumanTicket as N,resolvePageTicket as C}from"../../human/finish.js";import{filterAsync as v}from"../../../core/async-array.js";const D="Canceled from the inbox.",j=1e3,G=/^[a-f0-9]{64}$/;async function c(e){const i=await p(e);return i===null?null:{ticketId:i.request_id,dir:i.request_dir,kind:i.kind}}o(c,"resolveTicket");function l(e){const i=e.ticket_id;if(i===void 0||!G.test(i))throw new t(400,"invalid_request","invalid ticket id");return i}o(l,"requireTicketId");function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(u,"isPlainObject");function f(e,i){for(const n of Object.keys(e))if(!i.includes(n))throw new t(400,"invalid_request",`unexpected field: ${n}`)}o(f,"requireNoExtraKeys");function L(e){if(!u(e))throw new t(400,"invalid_request","respond body is required");if(f(e,["responses"]),!u(e.responses))throw new t(400,"invalid_request","`responses` must be an object");return{responses:e.responses}}o(L,"validateRespondRequest");function H(e){if(!u(e))throw new t(400,"invalid_request","progress body is required");if(f(e,["responses"]),!u(e.responses))throw new t(400,"invalid_request","`responses` must be an object");return{responses:e.responses}}o(H,"validateProgressRequest");function K(e){if(e===void 0)return{};if(!u(e))throw new t(400,"invalid_request","cancel body must be an object");if(f(e,["reason"]),e.reason===void 0)return{};const i=e.reason;if(typeof i!="string")throw new t(400,"invalid_request","`reason` must be a string");if(i.trim()===""||i.length>j)throw new t(400,"invalid_request","`reason` must be nonempty after trim and at most 1000 characters");return{reason:i}}o(K,"validateCancelRequest");const $=[/^slot ".*?" /,/^response names unknown or non-response-bearing slot id/,/^final page response is missing response-bearing slot id/];function _(e){return e instanceof Error&&$.some(i=>i.test(e.message))}o(_,"isSlotValidationError");function q(e){const i={request_id:e.id,request_dir:e.dir,ticket_id:e.inboxTicketId,kind:"page",title:e.title,placement:e.placement,dialect:e.dialect,steps:e.steps,emitted_at:e.emittedAt,source:e.source,slot_kinds:e.slotKinds,inbox:e.inbox,awaits_response:e.awaitsResponse,state:e.state};return e.subtitle!==""&&(i.subtitle=e.subtitle),e.answerDigest!==void 0&&(i.answer_digest=e.answerDigest),e.recommendedOptions.length>0&&(i.recommended_options=e.recommendedOptions.map(n=>({slot_id:n.slotId,option_id:n.optionId,label:n.label}))),e.fastAction!==void 0&&(i.fast_action={kind:e.fastAction.kind,responses:e.fastAction.responses}),i}o(q,"pageSummaryToDTO");async function V(e){return{status:200,body:{tickets:(await v(await P(),async n=>{if(g(e.principal))return!0;const s=await p(n.inboxTicketId),r=s?.requester_node_id?await b(s.requester_node_id):null;return r!==null&&await y(e.principal,r.grantee??"app:terminal",r.node_id)})).map(n=>{if(n.kind==="page")return q(n);if(n.kind==="review")return{request_id:n.id,request_dir:n.dir,ticket_id:n.inboxTicketId,kind:"review",title:n.title,subtitle:n.subtitle,blocked_since:n.blockedSince,source:n.source};throw new Error(`unknown ticket kind: ${n.kind}`)}).sort((n,s)=>{const r=o(d=>d.kind==="page"?d.emitted_at:d.blocked_since,"pageTime"),a=Date.parse(r(s))-Date.parse(r(n));return a!==0?a:n.ticket_id.localeCompare(s.ticket_id)})}}}o(V,"handleList");const z=new Set(["pending","resolved","canceled","passive"]);async function B(e){const i=e.query.get("node_id");if(i==="")throw new t(400,"invalid_request","node_id must be nonempty when present");const n=e.query.get("state");if(n!==null&&!z.has(n))throw new t(400,"invalid_request","state must be one of pending, resolved, canceled, passive");const s=(await E(i??void 0)).filter(d=>n===null||d.state===n);return{status:200,body:{tickets:(await v(s,async d=>{if(g(e.principal))return!0;const m=await p(d.inboxTicketId),w=m?.requester_node_id?await b(m.requester_node_id):null;return w!==null&&await y(e.principal,w.grantee??"app:terminal",w.node_id)})).map(q)}}}o(B,"handleHistory");async function F(e){const i=l(e.params),n=await c(i);if(n===null)throw new t(404,"ticket_not_found","no matching ticket");if(n.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets have no page read operation");const s=await p(i);if(s===null||s.kind!=="page")throw new t(404,"ticket_not_found","no matching ticket");try{return{status:200,body:await A(s)}}catch{throw new t(500,"internal","the ticket could not be read")}}o(F,"handleGetPage");async function M(e){const i=l(e.params),n=L(e.body),s=await c(i);if(s===null)throw new t(404,"ticket_not_found","no matching ticket");if(s.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets submit through their own path");if((await h(s.dir)).state==="passive")throw new t(409,"page_has_no_response_lifecycle","this page has no response lifecycle");const r=await k(s.dir);if(r!==null&&r.kind!=="canceled")throw new t(409,"ticket_already_resolved","ticket was already resolved");if(r?.kind==="canceled")throw new t(409,"ticket_canceled","canceled tickets cannot be answered");try{await R(s.dir,n.responses)}catch(a){throw _(a)?new t(400,"invalid_ticket_response",a.message):new t(500,"internal","validation failed")}try{const a=await C(s.ticketId,n.responses);if(a.kind!=="page")throw new t(409,"ticket_kind_mismatch","unexpected result kind");return{status:200,body:a}}catch(a){throw a instanceof t?a:_(a)?new t(400,"invalid_ticket_response",a.message):new t(500,"internal","the ticket could not be finalized")}}o(M,"handleRespond");async function U(e){const i=l(e.params),n=H(e.body),s=await c(i);if(s===null)throw new t(404,"ticket_not_found","no matching ticket");if(s.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets do not support progress autosave");if((await h(s.dir)).state==="passive")throw new t(409,"page_has_no_response_lifecycle","this page has no response lifecycle");const r=await k(s.dir);if(r!==null&&r.kind!=="canceled")throw new t(409,"ticket_already_resolved","ticket was already resolved");try{return await S(s.dir,n.responses),{status:200,body:{}}}catch(a){throw _(a)?new t(400,"invalid_ticket_response",a.message):new t(500,"internal","progress could not be saved")}}o(U,"handleProgress");async function X(e){const i=l(e.params),n=K(e.body),s=await c(i);if(s===null)throw new t(404,"ticket_not_found","no matching ticket");if(s.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets have their own cancel path");if((await h(s.dir)).state==="passive")throw new t(409,"page_has_no_response_lifecycle","this page has no response lifecycle");try{const r=await N(s.ticketId,{reason:n.reason??D,actor:"human",disposition:"dismissed"});if(r.outcome==="already_settled"||r.result.kind!=="canceled")throw new t(409,"ticket_already_resolved","ticket was already resolved");return{status:200,body:r.result}}catch(r){throw r instanceof t?r:new t(500,"internal","the ticket could not be canceled")}}o(X,"handleCancel");async function J(e){const i=l(e.params),n=await c(i);if(n===null)throw new t(404,"ticket_not_found","no matching ticket");if(n.kind==="review")throw new t(409,"ticket_kind_unsupported","review tickets fetch responses through their own path");const s=await k(n.dir);if(s===null)throw new t(404,"ticket_pending","ticket has no response yet");if(s.kind==="canceled")throw new t(404,"ticket_canceled","canceled tickets have no response");if(s.kind!=="page")throw new t(409,"ticket_kind_mismatch","unexpected result kind");try{const r=I(await x(n.dir));return{status:200,body:{...s,answer:O(r,s.responses,{completedAt:s.completedAt})}}}catch{throw new t(500,"internal","the ticket answer could not be read")}}o(J,"handleGetResponse");const de=[{method:"GET",pattern:"/v1/human/inbox",handler:V},{method:"GET",pattern:"/v1/human/inbox/history",handler:B},{method:"GET",pattern:"/v1/human/inbox/:ticket_id",handler:F},{method:"GET",pattern:"/v1/human/inbox/:ticket_id/response",handler:J},{method:"POST",pattern:"/v1/human/inbox/:ticket_id/respond",handler:M},{method:"POST",pattern:"/v1/human/inbox/:ticket_id/progress",handler:U},{method:"POST",pattern:"/v1/human/inbox/:ticket_id/cancel",handler:X}];export{de as inboxRoutes,l as requireTicketId,c as resolveTicket};
@@ -1,2 +1,2 @@
1
1
  var ce=Object.defineProperty;var u=(t,e)=>ce(t,"name",{value:e,configurable:!0});import{randomBytes as ue}from"node:crypto";import{claimNodeMail as le,acknowledgeNodeMail as fe}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as me}from"../../../core/feed/inbox.js";import{enqueueNodeMail as D,cancelPendingNodeMail as pe}from"../../../core/feed/messages.js";import{reviveNode as L}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as U}from"../../../core/runtime/broker-request.js";import{isBrokerLive as R}from"../../../core/runtime/model-swap.js";import{deliverLive as ye,interruptLive as he}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as we}from"../../../core/profiles/manifest.js";import{getNode as O,withFreshTerminalGuard as be}from"../../../core/canvas/canvas.js";import{getById as G,nodeObject as F,ownerForGrantee as ge}from"../../../core/graph/objects.js";import{recordActedOn as ve}from"../../../core/graph/edges.js";import{recordWatch as H}from"../../../core/graph/watches.js";import{publish as V}from"../../../core/graph/events.js";import{readerFor as K}from"../reader.js";import{canRead as _e}from"../../../core/graph/access.js";import{withCanvasWrite as k}from"../../../core/canvas/db.js";import{getPendingStructuredRequestForNode as Q}from"../../../core/canvas/structured-requests.js";import{consumeDeadlineOnWake as X}from"../../../core/feed/messages.js";import{assertNotFinalized as M,assertFinalizedForReopen as ke,commitReopenResident as P}from"../../../core/runtime/reopen.js";import{admitLegacyStructuredOutput as Se}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as $e}from"../../../core/runtime/structured-output.js";import{appendSituationalContext as E,formatSituationalProse as Ne}from"../../../core/runtime/situational-context.js";import{formatDataCard as Y}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as je}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as Ae}from"../../park-pending.js";import{wantsExecution as qe}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as Oe}from"../../../core/runtime/revive.js";import{CrtrError as Ce,notFound as C,usage as c}from"../../../core/errors.js";import{isStartRefusal as xe}from"../../../core/runtime/start-check.js";import{emitEvent as Re}from"../../../core/events/emit.js";import{assertScope as Fe}from"../../../core/scopes.js";import{InputError as I}from"../../../core/io.js";import{ApiError as Me}from"../../../api/index.js";import{describeObject as Pe,stubOf as Ee}from"../../../core/peer/stubs.js";import{machineNameOf as Z}from"../../../core/peer/names.js";import{callerNode as Ie,callerStub as Te,forwardVerb as ee,relayError as te,remoteStub as Be,unknownError as re,withMachine as ne}from"../../peer/forward.js";import{ownerOnly as ze}from"../router.js";import{personId as We}from"../../../core/canvas/person.js";const Je=["critical","urgent","normal","deferred"];function oe(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw c(`${e} must be an object { kind, facts?, body? }`);const a=t,n=a.kind;if(typeof n!="string"||n.trim()==="")throw c(`${e}.kind is required`);if(!n.includes(":"))throw c(`${e}.kind must be namespaced (contain ':'): ${n}`);const r={kind:n},o=a.facts;if(o!==void 0){if(typeof o!="object"||o===null||Array.isArray(o))throw c(`${e}.facts must be an object of string or number values`);const d={};for(const[l,m]of Object.entries(o)){if(typeof m!="string"&&typeof m!="number")throw c(`${e}.facts.${l} must be a string or number`);d[l]=m}r.facts=d}const s=a.body;if(s!==void 0){if(typeof s!="string")throw c(`${e}.body must be a string`);r.body=s}return r}u(oe,"parseCardRequest");function ae(t,e){try{return Y(t.kind,t.facts??{},t.body??"")}catch(a){throw c(`${e}: ${a instanceof Error?a.message:String(a)}`)}}u(ae,"renderCard");function De(t){if(typeof t!="object"||t===null)throw c("a message requires a JSON body { body, tier?, fresh? }");const e=t,a=e.body,n=e.fresh===!0,r=e.tier,o=e.situational_context,s=e.output_schema,d=typeof a=="string"&&a.trim()!=="",l=typeof o=="string"&&o.trim()!=="",m=typeof s=="string"&&s.trim()!=="",v=e.situational_card,S=e.context_cards,b=v===void 0?void 0:oe(v,"situational_card");if(S!==void 0&&!Array.isArray(S))throw c("context_cards must be an array of { kind, facts?, body? }");const p=S?.map((N,$)=>oe(N,`context_cards[${$}]`));if(b!==void 0&&typeof o=="string"&&o!=="")throw c("situational_card and situational_context are mutually exclusive");const w=b!==void 0||p!==void 0&&p.length>0;if(!n&&!d&&!l&&!m&&!w)throw c("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(n&&p!==void 0&&p.length>0)throw c("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(r!==void 0&&!Je.includes(r))throw c(`invalid tier: ${String(r)} (expected critical|urgent|normal|deferred)`);const f={body:typeof a=="string"?a:""};r!==void 0&&(f.tier=r),n&&(f.fresh=!0),e.reopen===!0&&(f.reopen=!0),typeof o=="string"&&(f.situational_context=o),b!==void 0&&(f.situational_card=b),p!==void 0&&(f.context_cards=p),typeof s=="string"&&(f.output_schema=s),typeof e.from=="string"&&(f.from=e.from);const y=e.delivery;if(y!==void 0&&y!=="interactive")throw c(`invalid delivery: ${String(y)} (expected interactive)`);if(y==="interactive"){if(n||f.situational_context!==void 0||f.output_schema!==void 0)throw c("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!d)throw c("interactive delivery requires a non-empty body");if(f.tier==="deferred")throw c("interactive delivery cannot be deferred");f.delivery="interactive"}return f}u(De,"parseSendBody");function Le(t){let e;try{e=JSON.parse(t)}catch{throw c("output_schema must be a JSON schema string")}if(typeof e!="object"||e===null||Array.isArray(e))throw c("output_schema must be a JSON schema object");return e}u(Le,"parseSchema");function Ue(t){return t.split(`
2
- `)[0].slice(0,120)}u(Ue,"label");function ie(t,e){return e===null?"":Y("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}u(ie,"previousFinalReportCard");async function Ge(t,e,a){if(a!==null&&a!=="human"&&(await G(t,a))?.type==="node"){const o=await F(t,a);return{actor:o,senderNode:o}}if(a==="human")return{actor:await ge(t,We()),senderNode:null};const n=await K(t,e);return{actor:n.class==="person"?n.person:n.class==="app"?n.app:n.node,senderNode:n.class==="node"?n.node:null}}u(Ge,"messageActor");async function se(t,e,a,n,r,o){const s=await F(t,a),{actor:d,senderNode:l}=await Ge(t,e,n),m=r===null?{}:{pointer:r};await ve(t,d,s),l!==null&&l.id!==s.id&&await H(t,l,s,"message",{endsOn:o&&r!==null?`result:${r}`:"final"}),await V(t,{event:"messaged",object:s,actor:d,attrs:{},...m}),l!==null&&await V(t,{event:"sent",object:l,actor:l,attrs:{to:s.id},...m})}u(se,"recordMessage");function He(t,e){return new I({error:"deferred_no_natural_cycle",message:`${t} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}u(He,"deferredNoNaturalCycle");async function Ve(t){if(!await Oe(t))throw new Me(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}u(Ve,"assertRecoverableForFresh");function Ke(t,e){return t instanceof I?{error:t.payload.error,message:t.payload.message,next:t.payload.next,message_id:e}:t instanceof Ce?{error:t.code,message:t.message,message_id:e}:xe(t)?{error:t.code,message:t.message,message_id:e}:{error:"wake_failed",message:"the target could not be woken; see the daemon log",message_id:e}}u(Ke,"wakeFailure");async function Qe(t,e){const a=typeof t.body=="object"&&t.body!==null&&!Array.isArray(t.body)?{...t.body}:t.body;typeof a=="object"&&a!==null&&delete a.from;const n=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/messages`,body:a});if(n.kind==="local")return null;if(n.kind==="unknown")throw re(e,n.unreachable);if(n.status>=400)throw te(n.status,n.body);return await k(async r=>{const o=await Ie(r,t);if(o===null)return;const s=n.body?.object,d=await Be(r,e,"node",n.machine.id,s);await H(r,o,d,"message",{endsOn:"final"})}),{status:n.status,body:ne(n.body,n.machine)}}u(Qe,"forwardMessage");async function Xe(t){const e=await Ye(t);if(t.principal.class!=="forwarded"||typeof e.body!="object"||e.body===null)return e;const a=await k(async n=>{const r=await F(n,t.params.id);return await _e(n,await K(n,t),r)?await Pe(n,r):{id:r.id,type:r.type,kind:null,name:r.id,owner:null}});return{...e,body:{...e.body,object:a}}}u(Xe,"handleMessage");async function Ye(t){const e=t.params.id,a=await Qe(t,e);if(a!==null)return a;const n=await O(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=De(t.body),o=r.tier??"normal",s=we(n.profile_id),d=t.principal.class==="forwarded"?await k(async i=>(await Te(i,t))?.id??null):r.from??null;if(d!==null){const i=await O(d);i!==null&&Fe(i,"crtr:act")}const l=d===null?null:await k(async i=>{const h=await G(i,d);return h===null?null:(await Ee(i,h))?.home_machine??null}),m=l===null?void 0:`${d} on ${Z(l)}`,v=t.principal.class==="broker"?t.principal.node:null,S=l===null?{}:{from_machine:Z(l)},b=r.body.trim()!=="",p=r.situational_card!==void 0?ae(r.situational_card,"situational_card"):r.situational_context!==void 0?Ne(r.situational_context.trim()):"",w=p!=="",f=(r.context_cards??[]).map((i,h)=>ae(i,`context_cards[${h}]`)),y=r.output_schema!==void 0&&r.output_schema.trim()!==""?Le(r.output_schema):null;y!==null&&await $e(y);let N=!1;const $=u(async i=>{if(!(y===null||N)){if(await Q(e)!==null)throw new I({error:"structured_request_conflict",message:`node ${e} already has a pending structured request`,next:"Wait for the current request to settle before requesting another structured result."});await Se(e,"oneoff",y,i),N=!0}},"ensureSchema");if(r.fresh){const i=r.reopen?await ke(e):null;r.reopen||await M(e),await Ve(e),await $(),w&&E(e,p),r.reopen&&await P(e,i,v);const h=await L(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:h.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&await M(e);let T=!1,_="";if(r.delivery==="interactive"&&r.reopen&&(_=ie(e,await P(e,void 0,v)),T=!0),r.delivery==="interactive"&&await $(),r.delivery==="interactive"&&!s&&!n.run_id&&R(n))try{return w&&E(e,p),await ye(e,r.body,{cards:[..._===""?[]:[_],...w?[p]:[],...f],origin:d==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...d===null?{}:{from:d},...m===void 0?{}:{fromName:m},kind:"message",tier:o}]}}),await k(async h=>await se(h,t,e,d,null,!1)),await X(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(i){if(!(i instanceof U))throw i}const B=u(async()=>{r.reopen||await M(e);const i=ue(16).toString("hex"),h=u(async q=>await se(q,t,e,d,i,y!==null),"withinEnqueue");await $(i),w&&E(e,p),r.reopen&&!T&&(_=ie(e,await P(e,void 0,v)));const x=[..._===""?[]:[_],...f],J=x.length>0?{cards:x}:{};if(b||y!==null){const q=b?r.body:`A one-off structured-output request has been granted. Submit a result matching the requested schema with the \`submit_result\` tool (\`request_id: "${(await Q(e))?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:h,label:Ue(q),bodyJson:{body:q,...S,...w?{situational:!0}:{},...J}})}return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:h,label:w?"(ambient context updated)":"(context delivered)",bodyJson:{...w?{situational:!0}:{},situationalOnly:!0,...J}})},"deliverImmediate"),g=await u(async()=>{if(o==="deferred"){const i=await be(e,je,B);if(i.kind==="missing")throw C(`unknown node: ${e}`,{received:e});if(i.kind==="terminal")throw He(e,i.status);return i.result}return await B()},"deliver")();g.urgency!=="deferred"&&await k(async()=>Ae(e));const j=await O(e);if(j===null)throw C(`unknown node: ${e}`,{received:e});n.frozen_at!==null&&await X(e);let z=!1,W=!1,A;if((r.reopen||j.lifecycle==="terminal"||!await qe(j))&&g.urgency!=="deferred"&&!s&&!R(j))try{const i=await L(e,{resume:!0,capacity:"freeze"});z=i.launch!==void 0,W=i.outcome==="frozen"}catch(i){A=Ke(i,g.messageId),Re({level:"error",event:"message.wake_failed",node_id:e,error:i,fields:{message_id:g.messageId,error_code:A.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:z,...W?{not_revived_reason:"capacity_frozen"}:{},...A===void 0?{}:{wake_failed:A},delivered_at:g.createdAt,...g.urgency===o?{}:{delivered_tier:g.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}u(Ye,"handleMessageHere");async function Ze(t){const e=t.params.id,a=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/interrupt`,body:t.body});if(a.kind==="unknown")throw re(e,a.unreachable);if(a.kind==="remote"){if(a.status>=400)throw te(a.status,a.body);return{status:a.status,body:ne(a.body,a.machine)}}const n=await O(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=await pe(e,{senderNodeId:"human",kind:"message"});let o=!1;if(R(n))try{o=await he(e)!=="idle"}catch(d){if(!(d instanceof U))throw d}return{status:200,body:{node_id:e,outcome:o?"aborted_turn":r.length>0?"canceled_pending":"idle",aborted_turn:o,canceled_pending:r.length}}}u(Ze,"handleInterrupt");function de(t){if(typeof t.body!="object"||t.body===null||Array.isArray(t.body))throw c("mail requires an object body");const e=t.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw c("execution_id is required");return e}u(de,"mailBody");async function et(t){const e=de(t),a=e.channel;if(a!=="wake"&&a!=="passive"&&a!=="deferred_run")throw c("channel must be wake, passive, or deferred_run");const n=await le(t.params.id,e.execution_id,a);return{status:200,body:{action:n.action,deliveries:n.deliveries.map(o=>({delivery_id:o.deliveryId,attempts:o.attempts,handoff:o.handoff,entry:{...me(o),seq:o.message.seq}}))}}}u(et,"handleMailClaim");async function tt(t){const e=de(t);if(!Array.isArray(e.deliveries))throw c("deliveries must be an array");const a=e.deliveries.map(o=>{if(typeof o!="object"||o===null||Array.isArray(o))throw c("each delivery must be an object");const s=o;if(typeof s.delivery_id!="string"||s.delivery_id==="")throw c("delivery_id is required");if(!Number.isSafeInteger(s.attempts)||s.attempts<1)throw c("attempts must be a positive integer");if(s.disposition!=="acknowledged"&&s.disposition!=="released")throw c("disposition must be acknowledged or released");return{delivery_id:s.delivery_id,attempts:s.attempts,disposition:s.disposition}}),n=await fe(t.params.id,e.execution_id,a.map(o=>({deliveryId:o.delivery_id,attempts:o.attempts,disposition:o.disposition})));return{status:200,body:{action:n.action,results:n.results.map(o=>({delivery_id:o.deliveryId,outcome:o.outcome}))}}}u(tt,"handleMailAcknowledge");const Ut=ze([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:et},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:tt}]),Gt=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:Xe},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Ze}];export{Ut as brokerMailRoutes,Xe as handleMessage,Gt as messageRoutes};
2
+ `)[0].slice(0,120)}u(Ue,"label");function ie(t,e){return e===null?"":Y("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}u(ie,"previousFinalReportCard");async function Ge(t,e,a){if(a!==null&&a!=="human"&&(await G(t,a))?.type==="node"){const o=await F(t,a);return{actor:o,senderNode:o}}if(a==="human")return{actor:await ge(t,We()),senderNode:null};const n=await K(t,e);return{actor:n.class==="person"?n.person:n.class==="app"?n.app:n.node,senderNode:n.class==="node"?n.node:null}}u(Ge,"messageActor");async function se(t,e,a,n,r,o){const s=await F(t,a),{actor:d,senderNode:l}=await Ge(t,e,n),m=r===null?{}:{pointer:r};await ve(t,d,s),l!==null&&l.id!==s.id&&await H(t,l,s,"message",{endsOn:o&&r!==null?`result:${r}`:"final"}),await V(t,{event:"messaged",object:s,actor:d,attrs:{},...m}),l!==null&&await V(t,{event:"sent",object:l,actor:l,attrs:{to:s.id},...m})}u(se,"recordMessage");function He(t,e){return new I({error:"deferred_no_natural_cycle",message:`${t} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}u(He,"deferredNoNaturalCycle");async function Ve(t){if(!await Oe(t))throw new Me(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}u(Ve,"assertRecoverableForFresh");function Ke(t,e){return t instanceof I?{error:t.payload.error,message:t.payload.message,next:t.payload.next,message_id:e}:t instanceof Ce?{error:t.code,message:t.message,message_id:e}:xe(t)?{error:t.code,message:t.message,message_id:e}:{error:"wake_failed",message:"the target could not be woken; see the daemon log",message_id:e}}u(Ke,"wakeFailure");async function Qe(t,e){const a=typeof t.body=="object"&&t.body!==null&&!Array.isArray(t.body)?{...t.body}:t.body;typeof a=="object"&&a!==null&&delete a.from;const n=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/messages`,body:a});if(n.kind==="local")return null;if(n.kind==="unknown")throw re(e,n.unreachable);if(n.status>=400)throw te(n.status,n.body);return await k(async r=>{const o=await Ie(r,t);if(o===null)return;const s=n.body?.object,d=await Be(r,e,"node",n.machine.id,s);await H(r,o,d,"message",{endsOn:"final"})}),{status:n.status,body:ne(n.body,n.machine)}}u(Qe,"forwardMessage");async function Xe(t){const e=await Ye(t);if(t.principal.class!=="forwarded"||typeof e.body!="object"||e.body===null)return e;const a=await k(async n=>{const r=await F(n,t.params.id);return await _e(n,await K(n,t),r)?await Pe(n,r):{id:r.id,type:r.type,kind:null,name:r.id,owner:null}});return{...e,body:{...e.body,object:a}}}u(Xe,"handleMessage");async function Ye(t){const e=t.params.id,a=await Qe(t,e);if(a!==null)return a;const n=await O(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=De(t.body),o=r.tier??"normal",s=we(n.profile_id),d=t.principal.class==="forwarded"?await k(async i=>(await Te(i,t))?.id??null):r.from??null;if(d!==null){const i=await O(d);i!==null&&Fe(i,"crtr:act")}const l=d===null?null:await k(async i=>{const h=await G(i,d);return h===null?null:(await Ee(i,h))?.home_machine??null}),m=l===null?void 0:`${d} on ${Z(l)}`,v=t.principal.class==="broker"?t.principal.node:null,S=l===null?{}:{from_machine:Z(l)},b=r.body.trim()!=="",p=r.situational_card!==void 0?ae(r.situational_card,"situational_card"):r.situational_context!==void 0?Ne(r.situational_context.trim()):"",w=p!=="",f=(r.context_cards??[]).map((i,h)=>ae(i,`context_cards[${h}]`)),y=r.output_schema!==void 0&&r.output_schema.trim()!==""?Le(r.output_schema):null;y!==null&&await $e(y);let N=!1;const $=u(async i=>{if(!(y===null||N)){if(await Q(e)!==null)throw new I({error:"structured_request_conflict",message:`node ${e} already has a pending structured request`,next:"Wait for the current request to settle before requesting another structured result."});await Se(e,"oneoff",y,i),N=!0}},"ensureSchema");if(r.fresh){const i=r.reopen?await ke(e):null;r.reopen||await M(e),await Ve(e),await $(),w&&await E(e,p),r.reopen&&await P(e,i,v);const h=await L(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:h.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&await M(e);let T=!1,_="";if(r.delivery==="interactive"&&r.reopen&&(_=ie(e,await P(e,void 0,v)),T=!0),r.delivery==="interactive"&&await $(),r.delivery==="interactive"&&!s&&!n.run_id&&R(n))try{return w&&await E(e,p),await ye(e,r.body,{cards:[..._===""?[]:[_],...w?[p]:[],...f],origin:d==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...d===null?{}:{from:d},...m===void 0?{}:{fromName:m},kind:"message",tier:o}]}}),await k(async h=>await se(h,t,e,d,null,!1)),await X(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(i){if(!(i instanceof U))throw i}const B=u(async()=>{r.reopen||await M(e);const i=ue(16).toString("hex"),h=u(async q=>await se(q,t,e,d,i,y!==null),"withinEnqueue");await $(i),w&&await E(e,p),r.reopen&&!T&&(_=ie(e,await P(e,void 0,v)));const x=[..._===""?[]:[_],...f],J=x.length>0?{cards:x}:{};if(b||y!==null){const q=b?r.body:`A one-off structured-output request has been granted. Submit a result matching the requested schema with the \`submit_result\` tool (\`request_id: "${(await Q(e))?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:h,label:Ue(q),bodyJson:{body:q,...S,...w?{situational:!0}:{},...J}})}return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:h,label:w?"(ambient context updated)":"(context delivered)",bodyJson:{...w?{situational:!0}:{},situationalOnly:!0,...J}})},"deliverImmediate"),g=await u(async()=>{if(o==="deferred"){const i=await be(e,je,B);if(i.kind==="missing")throw C(`unknown node: ${e}`,{received:e});if(i.kind==="terminal")throw He(e,i.status);return i.result}return await B()},"deliver")();g.urgency!=="deferred"&&await k(async()=>Ae(e));const j=await O(e);if(j===null)throw C(`unknown node: ${e}`,{received:e});n.frozen_at!==null&&await X(e);let z=!1,W=!1,A;if((r.reopen||j.lifecycle==="terminal"||!await qe(j))&&g.urgency!=="deferred"&&!s&&!R(j))try{const i=await L(e,{resume:!0,capacity:"freeze"});z=i.launch!==void 0,W=i.outcome==="frozen"}catch(i){A=Ke(i,g.messageId),Re({level:"error",event:"message.wake_failed",node_id:e,error:i,fields:{message_id:g.messageId,error_code:A.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:z,...W?{not_revived_reason:"capacity_frozen"}:{},...A===void 0?{}:{wake_failed:A},delivered_at:g.createdAt,...g.urgency===o?{}:{delivered_tier:g.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}u(Ye,"handleMessageHere");async function Ze(t){const e=t.params.id,a=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/interrupt`,body:t.body});if(a.kind==="unknown")throw re(e,a.unreachable);if(a.kind==="remote"){if(a.status>=400)throw te(a.status,a.body);return{status:a.status,body:ne(a.body,a.machine)}}const n=await O(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=await pe(e,{senderNodeId:"human",kind:"message"});let o=!1;if(R(n))try{o=await he(e)!=="idle"}catch(d){if(!(d instanceof U))throw d}return{status:200,body:{node_id:e,outcome:o?"aborted_turn":r.length>0?"canceled_pending":"idle",aborted_turn:o,canceled_pending:r.length}}}u(Ze,"handleInterrupt");function de(t){if(typeof t.body!="object"||t.body===null||Array.isArray(t.body))throw c("mail requires an object body");const e=t.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw c("execution_id is required");return e}u(de,"mailBody");async function et(t){const e=de(t),a=e.channel;if(a!=="wake"&&a!=="passive"&&a!=="deferred_run")throw c("channel must be wake, passive, or deferred_run");const n=await le(t.params.id,e.execution_id,a);return{status:200,body:{action:n.action,deliveries:n.deliveries.map(o=>({delivery_id:o.deliveryId,attempts:o.attempts,handoff:o.handoff,entry:{...me(o),seq:o.message.seq}}))}}}u(et,"handleMailClaim");async function tt(t){const e=de(t);if(!Array.isArray(e.deliveries))throw c("deliveries must be an array");const a=e.deliveries.map(o=>{if(typeof o!="object"||o===null||Array.isArray(o))throw c("each delivery must be an object");const s=o;if(typeof s.delivery_id!="string"||s.delivery_id==="")throw c("delivery_id is required");if(!Number.isSafeInteger(s.attempts)||s.attempts<1)throw c("attempts must be a positive integer");if(s.disposition!=="acknowledged"&&s.disposition!=="released")throw c("disposition must be acknowledged or released");return{delivery_id:s.delivery_id,attempts:s.attempts,disposition:s.disposition}}),n=await fe(t.params.id,e.execution_id,a.map(o=>({deliveryId:o.delivery_id,attempts:o.attempts,disposition:o.disposition})));return{status:200,body:{action:n.action,results:n.results.map(o=>({delivery_id:o.deliveryId,outcome:o.outcome}))}}}u(tt,"handleMailAcknowledge");const Ut=ze([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:et},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:tt}]),Gt=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:Xe},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Ze}];export{Ut as brokerMailRoutes,Xe as handleMessage,Gt as messageRoutes};
@@ -1 +1 @@
1
- var f=Object.defineProperty;var i=(e,o)=>f(e,"name",{value:o,configurable:!0});import{ApiError as t}from"../../../api/errors.js";import{validateCoreModelConfig as a,replaceCoreModelConfig as c}from"../../../core/model-config.js";import{parseModelSpec as d}from"../../../core/model-routes.js";import{openModelRegistry as l}from"../../../core/runtime/model-registry.js";import{ownerOnly as m}from"../router.js";function g(e){if(e===null||typeof e!="object"||Array.isArray(e))throw new t(400,"invalid_request","model config must be an object");const o=e;if(typeof o.config_version!="string"||o.config_version.trim()==="")throw new t(400,"invalid_request","config_version must be a non-empty string");try{return{configVersion:o.config_version,config:a(o)}}catch(r){throw new t(400,"invalid_request",r instanceof Error?r.message:String(r))}}i(g,"parseRequest");async function u(e){const o=await l();for(const r of Object.values(e.modelRoutes))for(const n of Object.values(r.models)){const s=d(n);if(s===void 0||o.find(s.providerId,s.modelId)===void 0)throw new t(422,"unprocessable",`route ref ${n} is absent from the baked model registry`)}}i(u,"validateCatalog");async function p(e){const{configVersion:o,config:r}=g(e.body);await u(r);try{c(r)}catch(n){throw new t(500,"model_config_write_failed",n instanceof Error?n.message:String(n))}return{status:200,body:{config_version:o,delivered:!0}}}i(p,"handlePut");const C=m([{method:"PUT",pattern:"/v1/model-config",handler:p}]);export{C as modelConfigRoutes};
1
+ var a=Object.defineProperty;var i=(e,o)=>a(e,"name",{value:o,configurable:!0});import{ApiError as t}from"../../../api/errors.js";import{validateCoreModelConfig as f,replaceCoreModelConfig as c}from"../../../core/model-config.js";import{parseModelSpec as d}from"../../../core/model-routes.js";import{openModelRegistry as l}from"../../../core/runtime/model-registry.js";import{ownerOnly as m}from"../router.js";function g(e){if(e===null||typeof e!="object"||Array.isArray(e))throw new t(400,"invalid_request","model config must be an object");const o=e;if(typeof o.config_version!="string"||o.config_version.trim()==="")throw new t(400,"invalid_request","config_version must be a non-empty string");try{return{configVersion:o.config_version,config:f(o)}}catch(r){throw new t(400,"invalid_request",r instanceof Error?r.message:String(r))}}i(g,"parseRequest");async function u(e){const o=await l();for(const r of Object.values(e.modelRoutes))for(const n of Object.values(r.models)){const s=d(n);if(s===void 0||o.find(s.providerId,s.modelId)===void 0)throw new t(422,"unprocessable",`route ref ${n} is absent from the baked model registry`)}}i(u,"validateCatalog");async function p(e){const{configVersion:o,config:r}=g(e.body);await u(r);try{await c(r)}catch(n){throw new t(500,"model_config_write_failed",n instanceof Error?n.message:String(n))}return{status:200,body:{config_version:o,delivered:!0}}}i(p,"handlePut");const C=m([{method:"PUT",pattern:"/v1/model-config",handler:p}]);export{C as modelConfigRoutes};
@@ -1,5 +1,5 @@
1
1
  import type { ModelAuthProviderStatusDTO } from '../../../api/index.js';
2
2
  import { type ManagedProviderId } from '../../../core/subscription-state.js';
3
3
  import type { RouteTable } from '../router.js';
4
- export declare function managedStatus(provider: ManagedProviderId): ModelAuthProviderStatusDTO;
4
+ export declare function managedStatus(provider: ManagedProviderId): Promise<ModelAuthProviderStatusDTO>;
5
5
  export declare const modelAuthRoutes: RouteTable;
@@ -1 +1 @@
1
- var q=Object.defineProperty;var r=(n,e)=>q(n,"name",{value:e,configurable:!0});import{join as O}from"node:path";import{deleteAuthCredential as _,readAuthCredentials as S,setAuthCredential as y}from"../../../core/auth-file.js";import{secretsDir as D}from"../../../core/layout.js";import{ApiError as s}from"../../../api/index.js";import{RunError as b}from"../../../core/runs/operations.js";import{usage as u}from"../../../core/errors.js";import{modelAuthReadiness as E}from"../../../core/model-auth/readiness.js";import{MANAGED_PROVIDER_IDS as I,OPENAI_CHATGPT_PROVIDER_ID as j,commitManagedLogin as F,isManagedProvider as p,readSubscriptionPool as h,removeAllManagedAccounts as P}from"../../../core/subscription-state.js";import{cancelModelAuthFlow as M,completeModelAuthFlow as R,startModelAuthFlow as T,waitModelAuthFlow as $}from"../../../core/model-auth/flows.js";import{waitSeconds as C}from"../long-poll-wait.js";function l(){return O(D(),"auth.json")}r(l,"authPath");function g(n,e){if(typeof e!="string"||e==="")throw new s(400,"invalid_request",`oauth credential requires \`${n}\``);const t=Date.parse(e);if(Number.isNaN(t))throw new s(400,"invalid_request",`\`${n}\` is not a valid ISO timestamp`);return t}r(g,"parseExpiry");function c(n,e,t){if(typeof t!="string"||t==="")throw new s(400,"invalid_request",`${n} credential requires \`${e}\``);return t}r(c,"requireField");function L(n,e=Date.now()){const t=Object.entries(n.modelCooldowns??{}).filter(([,o])=>o>e).map(([o,a])=>({family:o,rate_limited_until:new Date(a).toISOString()}));return{label:n.label,expires_at:new Date(n.expires).toISOString(),rate_limited_until:new Date(n.rateLimitedUntil).toISOString(),...t.length?{model_cooldowns:t}:{},...n.authFailure?{auth_failure:n.authFailure}:{},...n.accountId?{account_id:n.accountId}:{}}}r(L,"toManagedAccountStatus");function G(n){const e=h(n).map(t=>L(t));return{provider:n,managed:!0,configured:e.length>0,accounts:e}}r(G,"managedStatus");function f(n,e){const t=n.query.getAll(e);if(t.length>1)throw u(`${e} must appear at most once`);return t[0]}r(f,"singleQueryValue");async function N(){const n=await S(l()),e=r(o=>o===j&&n[o]!==void 0&&h(o).length===0,"legacyApiKey"),t=I.filter(o=>!e(o)).map(G);for(const[o,a]of Object.entries(n))p(o)&&!e(o)||a.type!=="api_key"&&a.type!=="oauth"||t.push({provider:o,managed:!1,configured:!0,kind:a.type});return{status:200,body:{providers:t}}}r(N,"handleList");async function x(n){for(const[i]of n.query)if(i!=="profile"&&i!=="cwd"&&i!=="kind"&&i!=="model")throw u(`unknown model-auth readiness query parameter: ${i}`);const e=f(n,"profile"),t=f(n,"cwd"),o=f(n,"kind"),a=f(n,"model");if(o!==void 0&&o.trim()==="")throw u("kind must be a non-empty string when provided");if(a!==void 0&&a.trim()==="")throw u("model must be a non-empty string when provided");return{status:200,body:await E({...e!==void 0?{profile:e}:{},...t!==void 0?{cwd:t}:{},...o!==void 0?{kind:o}:{},...a!==void 0?{model:a}:{}})}}r(x,"handleReadiness");async function V(n){const e=n.params.provider,t=n.body;if(t===void 0||typeof t!="object"||typeof t.kind!="string")throw new s(400,"invalid_request","a credential `kind` is required");switch(t.kind){case"api_key":{const o=c("api_key","api_key",t.api_key);return await y(e,{type:"api_key",key:o},l()),{status:200,body:{provider:e,installed:!0,managed:!1}}}case"oauth":{if(p(e))throw new s(422,"unprocessable",`provider ${e} stores oauth credentials as managed accounts \u2014 use kind \`managed_account\``);const o=c("oauth","access_token",t.access_token),a=c("oauth","refresh_token",t.refresh_token),i=g("expires_at",t.expires_at),d=t.extra??{};await y(e,{type:"oauth",...d,access:o,refresh:a,expires:i},l());const m={provider:e,installed:!0,managed:!1};return typeof t.account_id=="string"&&t.account_id!==""&&(m.account_id=t.account_id),{status:200,body:m}}case"managed_account":{if(!p(e))throw new s(422,"unprocessable",`provider ${e} does not support managed accounts`);const o=typeof t.label=="string"&&t.label.trim()?t.label.trim():void 0;if(!o&&t.auto_label!==!0)throw new s(400,"invalid_request","managed_account credential requires `label` or `auto_label`");const a=typeof t.account_id=="string"&&t.account_id!==""?t.account_id:void 0,i=c("managed_account","access_token",t.access_token),d=c("managed_account","refresh_token",t.refresh_token),m=g("expires_at",t.expires_at),k=typeof t.last_rate_limited_at=="number"?t.last_rate_limited_at:Math.max(0,...h(e).map(A=>A.lastRateLimitedAt));await F(e,o,{refresh:d,access:i,expires:m,...a?{accountId:a}:{},lastRateLimitedAt:k,autoLabel:t.auto_label===!0});const w={provider:e,installed:!0,managed:!0};return a&&(w.account_id=a),{status:200,body:w}}default:throw new s(400,"invalid_request",`unknown credential kind: ${String(t.kind)}`)}}r(V,"handleInstall");async function K(n){const e=n.params.provider;if(p(e)){const o=await P(e),a=await _(e,l());return{status:200,body:{provider:e,removed_accounts:o+(a?1:0)}}}const t=await _(e,l())?1:0;return{status:200,body:{provider:e,removed_accounts:t}}}r(K,"handleDelete");function v(n){const e=n.body;if(e===void 0)return{};if(typeof e!="object"||e===null||Array.isArray(e))throw new s(400,"invalid_request","request body must be a JSON object");return e}r(v,"bodyObject");async function U(n){const e=v(n);return{status:200,body:await T({provider:e.provider,...e.redirect!==void 0?{redirect:e.redirect}:{},...e.label!==void 0?{label:e.label}:{}})}}r(U,"handleFlowStart");async function H(n){const e=v(n);return{status:200,body:await R(n.params.flow_id,e.input)}}r(H,"handleFlowComplete");async function J(n){const e=M(n.params.flow_id);if(!e)throw new b(400,"invalid_request","no sign-in has this flow_id","flow_id");const{jti:t,...o}=e;return{status:200,body:o}}r(J,"handleFlowCancel");async function Q(n){for(const[d]of n.query)if(d!=="wait")throw u(`unknown model-auth flow query parameter: ${d}`);f(n,"wait");const e=C("model_auth.get",n.query),t=new AbortController;n.res.once("close",()=>t.abort());const o=await $(n.params.flow_id,e*1e3,t.signal);if(!o)throw new b(404,"not_found","no sign-in has this flow_id","flow_id");const{jti:a,...i}=o;return{status:200,body:i}}r(Q,"handleFlowGet");const re=[{method:"POST",pattern:"/v1/model-auth/flows",ownerOnly:!0,handler:U},{method:"POST",pattern:"/v1/model-auth/flows/:flow_id/complete",ownerOnly:!0,handler:H},{method:"POST",pattern:"/v1/model-auth/flows/:flow_id/cancel",ownerOnly:!0,handler:J},{method:"GET",pattern:"/v1/model-auth/flows/:flow_id",ownerOnly:!0,handler:Q},{method:"GET",pattern:"/v1/model-auth",handler:N},{method:"GET",pattern:"/v1/model-auth/readiness",handler:x},{method:"PUT",pattern:"/v1/model-auth/:provider",ownerOnly:!0,handler:V},{method:"DELETE",pattern:"/v1/model-auth/:provider",ownerOnly:!0,handler:K}];export{G as managedStatus,re as modelAuthRoutes};
1
+ var O=Object.defineProperty;var a=(n,e)=>O(n,"name",{value:e,configurable:!0});import{deleteAuthCredential as y,readAuthCredentials as S,setAuthCredential as b}from"../../../core/auth-file.js";import{ApiError as i}from"../../../api/index.js";import{RunError as g}from"../../../core/runs/operations.js";import{usage as u}from"../../../core/errors.js";import{modelAuthReadiness as E}from"../../../core/model-auth/readiness.js";import{MANAGED_PROVIDER_IDS as v,OPENAI_CHATGPT_PROVIDER_ID as D,DuplicateSubscriptionError as I,commitManagedLogin as P,isManagedProvider as l,promoteSubscription as $,readSubscriptionPool as m,removeAllManagedAccounts as T,removeManagedAccount as j,renameSubscription as F}from"../../../core/subscription-state.js";import{cancelModelAuthFlow as M,completeModelAuthFlow as C,startModelAuthFlow as R,waitModelAuthFlow as L}from"../../../core/model-auth/flows.js";import{waitSeconds as G}from"../long-poll-wait.js";function k(n,e){if(typeof e!="string"||e==="")throw new i(400,"invalid_request",`oauth credential requires \`${n}\``);const t=Date.parse(e);if(Number.isNaN(t))throw new i(400,"invalid_request",`\`${n}\` is not a valid ISO timestamp`);return t}a(k,"parseExpiry");function c(n,e,t){if(typeof t!="string"||t==="")throw new i(400,"invalid_request",`${n} credential requires \`${e}\``);return t}a(c,"requireField");function N(n,e=Date.now()){const t=Object.entries(n.modelCooldowns??{}).filter(([,o])=>o>e).map(([o,r])=>({family:o,rate_limited_until:new Date(r).toISOString()}));return{label:n.label,expires_at:new Date(n.expires).toISOString(),rate_limited_until:new Date(n.rateLimitedUntil).toISOString(),...t.length?{model_cooldowns:t}:{},...n.authFailure?{auth_failure:n.authFailure}:{},...n.accountId?{account_id:n.accountId}:{}}}a(N,"toManagedAccountStatus");async function p(n){const e=(await m(n)).map(t=>N(t));return{provider:n,managed:!0,configured:e.length>0,accounts:e}}a(p,"managedStatus");function f(n,e){const t=n.query.getAll(e);if(t.length>1)throw u(`${e} must appear at most once`);return t[0]}a(f,"singleQueryValue");async function U(){const n=await S(),e=new Set;for(const r of v)r===D&&n[r]!==void 0&&(await m(r)).length===0&&e.add(r);const t=a(r=>e.has(r),"legacyApiKey"),o=await Promise.all(v.filter(r=>!t(r)).map(p));for(const[r,s]of Object.entries(n))l(r)&&!t(r)||s.type!=="api_key"&&s.type!=="oauth"||o.push({provider:r,managed:!1,configured:!0,kind:s.type});return{status:200,body:{providers:o}}}a(U,"handleList");async function K(n){for(const[s]of n.query)if(s!=="profile"&&s!=="cwd"&&s!=="kind"&&s!=="model")throw u(`unknown model-auth readiness query parameter: ${s}`);const e=f(n,"profile"),t=f(n,"cwd"),o=f(n,"kind"),r=f(n,"model");if(o!==void 0&&o.trim()==="")throw u("kind must be a non-empty string when provided");if(r!==void 0&&r.trim()==="")throw u("model must be a non-empty string when provided");return{status:200,body:await E({...e!==void 0?{profile:e}:{},...t!==void 0?{cwd:t}:{},...o!==void 0?{kind:o}:{},...r!==void 0?{model:r}:{}})}}a(K,"handleReadiness");async function V(n){const e=n.params.provider,t=n.body;if(t===void 0||typeof t!="object"||typeof t.kind!="string")throw new i(400,"invalid_request","a credential `kind` is required");switch(t.kind){case"api_key":{const o=c("api_key","api_key",t.api_key);return await b(e,{type:"api_key",key:o}),{status:200,body:{provider:e,installed:!0,managed:!1}}}case"oauth":{if(l(e))throw new i(422,"unprocessable",`provider ${e} stores oauth credentials as managed accounts \u2014 use kind \`managed_account\``);const o=c("oauth","access_token",t.access_token),r=c("oauth","refresh_token",t.refresh_token),s=k("expires_at",t.expires_at),d=t.extra??{};await b(e,{type:"oauth",...d,access:o,refresh:r,expires:s});const w={provider:e,installed:!0,managed:!1};return typeof t.account_id=="string"&&t.account_id!==""&&(w.account_id=t.account_id),{status:200,body:w}}case"managed_account":{if(!l(e))throw new i(422,"unprocessable",`provider ${e} does not support managed accounts`);const o=typeof t.label=="string"&&t.label.trim()?t.label.trim():void 0;if(!o&&t.auto_label!==!0)throw new i(400,"invalid_request","managed_account credential requires `label` or `auto_label`");const r=typeof t.account_id=="string"&&t.account_id!==""?t.account_id:void 0,s=c("managed_account","access_token",t.access_token),d=c("managed_account","refresh_token",t.refresh_token),w=k("expires_at",t.expires_at),A=typeof t.last_rate_limited_at=="number"?t.last_rate_limited_at:Math.max(0,...(await m(e)).map(q=>q.lastRateLimitedAt));await P(e,o,{refresh:d,access:s,expires:w,...r?{accountId:r}:{},lastRateLimitedAt:A,autoLabel:t.auto_label===!0});const _={provider:e,installed:!0,managed:!0};return r&&(_.account_id=r),{status:200,body:_}}default:throw new i(400,"invalid_request",`unknown credential kind: ${String(t.kind)}`)}}a(V,"handleInstall");async function H(n){const e=n.params.provider;if(l(e)){const o=await T(e),r=await y(e);return{status:200,body:{provider:e,removed_accounts:o+(r?1:0)}}}const t=await y(e)?1:0;return{status:200,body:{provider:e,removed_accounts:t}}}a(H,"handleDelete");async function x(n){const e=n.params.provider;if(!l(e))throw new i(400,"invalid_request",`${e} has no managed accounts`);const t=h(n);for(const r of Object.keys(t))if(r!=="label"&&r!=="preferred")throw new i(400,"invalid_request",`unknown account field: ${r}`);if(t.label!==void 0&&typeof t.label!="string")throw new i(400,"invalid_request","`label` must be a string");if(t.preferred!==void 0&&t.preferred!==!0)throw new i(400,"invalid_request","`preferred` can only be true");if(t.label===void 0&&t.preferred===void 0)throw new i(400,"invalid_request","send `label` and/or `preferred`");let o=n.params.label;try{t.label!==void 0&&(await F(e,o,t.label),o=t.label.trim()),t.preferred&&await $(e,o)}catch(r){throw r instanceof Error&&/^Unknown .* subscription:/.test(r.message)?new i(404,"not_found",r.message):r instanceof I?new i(409,"conflict",r.message):r}return{status:200,body:await p(e)}}a(x,"handlePatchAccount");async function J(n){const e=n.params.provider;if(!l(e))throw new i(400,"invalid_request",`${e} has no managed accounts`);try{await j(e,n.params.label)}catch(t){throw t instanceof Error&&/^Unknown .* subscription:/.test(t.message)?new i(404,"not_found",t.message):t}return{status:200,body:await p(e)}}a(J,"handleDeleteAccount");function h(n){const e=n.body;if(e===void 0)return{};if(typeof e!="object"||e===null||Array.isArray(e))throw new i(400,"invalid_request","request body must be a JSON object");return e}a(h,"bodyObject");async function Q(n){const e=h(n);return{status:200,body:await R({provider:e.provider,...e.redirect!==void 0?{redirect:e.redirect}:{},...e.label!==void 0?{label:e.label}:{}})}}a(Q,"handleFlowStart");async function z(n){const e=h(n);return{status:200,body:await C(n.params.flow_id,e.input)}}a(z,"handleFlowComplete");async function B(n){const e=await M(n.params.flow_id);if(!e)throw new g(400,"invalid_request","no sign-in has this flow_id","flow_id");const{jti:t,...o}=e;return{status:200,body:o}}a(B,"handleFlowCancel");async function W(n){for(const[d]of n.query)if(d!=="wait")throw u(`unknown model-auth flow query parameter: ${d}`);f(n,"wait");const e=G("model_auth.get",n.query),t=new AbortController;n.res.once("close",()=>t.abort());const o=await L(n.params.flow_id,e*1e3,t.signal);if(!o)throw new g(404,"not_found","no sign-in has this flow_id","flow_id");const{jti:r,...s}=o;return{status:200,body:s}}a(W,"handleFlowGet");const ie=[{method:"POST",pattern:"/v1/model-auth/flows",ownerOnly:!0,handler:Q},{method:"POST",pattern:"/v1/model-auth/flows/:flow_id/complete",ownerOnly:!0,handler:z},{method:"POST",pattern:"/v1/model-auth/flows/:flow_id/cancel",ownerOnly:!0,handler:B},{method:"GET",pattern:"/v1/model-auth/flows/:flow_id",ownerOnly:!0,handler:W},{method:"GET",pattern:"/v1/model-auth",handler:U},{method:"GET",pattern:"/v1/model-auth/readiness",handler:K},{method:"PUT",pattern:"/v1/model-auth/:provider",ownerOnly:!0,handler:V},{method:"DELETE",pattern:"/v1/model-auth/:provider",ownerOnly:!0,handler:H},{method:"DELETE",pattern:"/v1/model-auth/:provider/accounts/:label",ownerOnly:!0,handler:J},{method:"PATCH",pattern:"/v1/model-auth/:provider/accounts/:label",ownerOnly:!0,handler:x}];export{p as managedStatus,ie as modelAuthRoutes};
@@ -33,10 +33,16 @@ export declare class NodeEventTranslationState {
33
33
  export declare function translateBrokerFrame(nodeId: string, frame: BrokerToClient, state?: NodeEventTranslationState): StreamEventPayload[];
34
34
  declare class NodeEventStreams {
35
35
  private readonly hubs;
36
+ private unsubscribeBus;
37
+ private refresh;
38
+ /** One bus subscription per process while any hub is held. Signals sent while the LISTEN connection was down are lost, so a restart refreshes every hub. */
39
+ private listen;
40
+ private remove;
36
41
  subscribe(nodeId: string, after: number | undefined, subscriber: Subscriber): Promise<{
37
42
  unsubscribe: () => void;
38
43
  terminal: boolean;
39
44
  }>;
45
+ /** Publishes the report to this process's stream now and signals every other process's stream on the node (kind `report`). */
40
46
  report(nodeId: string, report: ReportDTO): void;
41
47
  }
42
48
  export declare const nodeEventStreams: NodeEventStreams;
@@ -1,6 +1,6 @@
1
- var O=Object.defineProperty;var o=(n,e)=>O(n,"name",{value:e,configurable:!0});import{randomUUID as q}from"node:crypto";import{ApiError as E}from"../../../api/errors.js";import{BrokerClient as C}from"../../../core/broker-client/client.js";import{getNode as m}from"../../../core/canvas/canvas.js";import{emitEvent as k}from"../../../core/events/emit.js";import{isPidAlive as B}from"../../../core/canvas/pid.js";import{BROKER_VIEW_SOCKET_WAIT_MS as M}from"../../../core/runtime/view-socket.js";import{toNodeOutcomeDTO as D}from"../map.js";import{reportsForNode as L}from"./reports.js";const $=15e3,P=6e4,I=250,j=512,x=256*1024,G=1e3,V=32*1024*1024;class H{static{o(this,"NodeEventRing")}events=[];bytes=0;nextSequence=1;earliestAvailable=1;append(e){const t={...e,sequence_number:this.nextSequence++},s=Buffer.byteLength(JSON.stringify(t),"utf8");if(s>x)return this.events=[],this.bytes=0,this.earliestAvailable=this.nextSequence,t;for(this.events.push(t),this.bytes+=s;this.events.length>j||this.bytes>x;){const r=this.events.shift();if(r===void 0)break;this.bytes-=Buffer.byteLength(JSON.stringify(r),"utf8"),this.earliestAvailable=r.sequence_number+1}return t}replay(e){if(e===void 0)return{gap:null,events:this.events};const t=e<this.earliestAvailable-1||e>=this.nextSequence?T(this.earliestAvailable):null;return{gap:t,events:t===null?this.events.filter(s=>s.sequence_number>e):this.events}}get empty(){return this.events.length===0}}function T(n){return{type:"error",error:{code:"stream_gap",message:"the requested event cursor is older than this daemon can resume",details:{earliest_sequence:n}}}}o(T,"streamGap");function z(n){return n===null?"arguments: null":Array.isArray(n)?`arguments: array (${n.length} items)`:typeof n=="object"?`arguments: object (${Object.keys(n).length} fields)`:`arguments: ${typeof n}`}o(z,"toolSummary");function b(n){if(typeof n!="object"||n===null)return"";const e=n.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>typeof t=="object"&&t!==null).filter(t=>t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}o(b,"assistantText");class A{static{o(this,"NodeEventTranslationState")}toolSummaries=new Map;emittedAssistantText="";resetAssistantText(){this.emittedAssistantText=""}emitAssistantTextDelta(e){const t=b(e),s=t.startsWith(this.emittedAssistantText)?t.slice(this.emittedAssistantText.length):t;return this.emittedAssistantText=t,s}seedAssistantText(e){const t=b(e);return this.emittedAssistantText=t,t}}function J(n,e,t=new A){switch(e.type){case"message_start":return e.message.role==="assistant"&&t.resetAssistantText(),[];case"message_update":{if(e.message.role!=="assistant")return[];const s=t.emitAssistantTextDelta(e.message);return s===""?[]:[{type:"node.output_text.delta",node_id:n,delta:s}]}case"message_end":{if(e.message.role!=="assistant")return[];const s=b(e.message);return t.resetAssistantText(),[{type:"node.output_text.done",node_id:n,text:s}]}case"tool_execution_start":{const s=z(e.args);return t.toolSummaries.set(e.toolCallId,s),[{type:"node.tool_call.started",node_id:n,tool_call_id:e.toolCallId,tool:e.toolName,summary:s}]}case"tool_execution_end":{const s=t.toolSummaries.get(e.toolCallId)??"[arguments unavailable]";return t.toolSummaries.delete(e.toolCallId),[{type:"node.tool_call.completed",node_id:n,tool_call_id:e.toolCallId,tool:e.toolName,status:e.isError?"error":"ok",summary:s}]}case"turn_start":return[{type:"node.turn.started",node_id:n}];case"turn_end":return[{type:"node.turn.completed",node_id:n}];default:return[]}}o(J,"translateBrokerFrame");class W{static{o(this,"NodeEventHub")}nodeId;remove;ring=new H;subscribers=new Set;observer;observerErrorAt;poll;reconnect;idleClose;status;settledRevision;settledOutcome;settledSequence;snapshotSeeded=!1;reportsSeeded=!1;translationState=new A;fresh=!0;constructor(e,t){this.nodeId=e,this.remove=t}async subscribe(e,t){const s=this.fresh&&e!==void 0;this.fresh=!1,await this.start();const r=this.settledOutcome!==void 0,a=s?{gap:T(1),events:this.ring.replay(void 0).events}:this.ring.replay(e);r||(this.subscribers.add(t),this.status!=="dormant"&&await this.openObserver());let c=!1;return queueMicrotask(()=>{if(!c){a.gap!==null&&t(a.gap);for(const u of a.events)t(u)}}),r&&this.scheduleIdleClose(),{unsubscribe:o(()=>{c=!0,r||this.unsubscribe(t)},"unsubscribe"),terminal:r}}report(e){this.settledRevision===void 0&&this.publish({type:"node.report.pushed",node_id:this.nodeId,report:e})}async start(){this.idleClose!==void 0&&(clearTimeout(this.idleClose),this.idleClose=void 0),this.poll===void 0&&(await this.check(),this.settledRevision===void 0&&(await this.seedReports(),this.poll=setInterval(()=>this.checkDetached(),I)))}async seedReports(){if(!this.reportsSeeded){this.reportsSeeded=!0;for(const e of(await L(this.nodeId)).reverse())this.report(e)}}async check(){const e=await m(this.nodeId);if(e===null){this.fail("stream_error",`node ${this.nodeId} no longer exists`);return}const t=D(e);if(t!==null){this.settledRevision!==t.revision&&(this.settledRevision=t.revision,this.settledOutcome=t,this.settledSequence=this.publish({type:"node.settled",node_id:this.nodeId,outcome:t}).sequence_number,this.stopObserver(),this.stopPoll());return}const s=e.pi_pid===null?"dormant":e.status;if(s==="dormant"){this.observerErrorAt=void 0,this.status!=="dormant"&&(this.status=s,this.publish({type:"node.status.changed",node_id:this.nodeId,status:s}));return}this.status===void 0?this.status=s:this.status!=="dormant"&&this.status!==s&&(this.status=s,this.publish({type:"node.status.changed",node_id:this.nodeId,status:s})),await this.openObserver()}async openObserver(){if(this.observer!==void 0||this.subscribers.size===0)return;const e=new C(this.nodeId);this.observer=e,e.on("connect",()=>{(async()=>{this.observerErrorAt=void 0;const t=await m(this.nodeId);this.status==="dormant"&&t!==null&&t.pi_pid!==null&&(this.status=t.status,this.publish({type:"node.status.changed",node_id:this.nodeId,status:t.status})),e.send({type:"hello",role:"observer",client_id:q(),attends:!1})})().catch(t=>this.fail("stream_error",t instanceof Error?t.message:String(t)))}),e.on("frame",t=>{try{t.type==="welcome"&&this.seedSnapshot(t.snapshot);for(const s of J(this.nodeId,t,this.translationState))this.publish(s)}catch(s){this.fail("stream_error",s instanceof Error?s.message:String(s))}}),e.on("error",()=>{(async()=>{const t=await m(this.nodeId),s=Date.now();if(t!==null&&t.pi_pid!==null&&B(t.pi_pid)){if(this.observerErrorAt??=s,s-this.observerErrorAt<M)return;this.fail("stream_error","observer connection failed");return}this.observerErrorAt=void 0})().catch(t=>this.fail("stream_error",t instanceof Error?t.message:String(t)))}),e.on("close",()=>{this.observer===e&&(this.observer=void 0,!(this.subscribers.size===0||this.settledRevision!==void 0)&&(this.status!=="dormant"&&(this.publish({type:"node.status.changed",node_id:this.nodeId,status:"dormant"}),this.status="dormant"),this.scheduleReconnect()))}),e.connect()}seedSnapshot(e){if(this.snapshotSeeded)return;this.snapshotSeeded=!0;const t=e.messages.filter(r=>r.role==="assistant"),s=e.state.isStreaming?t.pop():void 0;for(const r of t)this.publish({type:"node.output_text.done",node_id:this.nodeId,text:b(r)});s!==void 0&&this.publish({type:"node.output_text.delta",node_id:this.nodeId,delta:this.translationState.seedAssistantText(s)})}scheduleReconnect(){this.reconnect===void 0&&(this.reconnect=setTimeout(()=>{this.reconnect=void 0,this.checkDetached()},I))}checkDetached(){this.check().catch(e=>k({level:"error",event:"api.node_events.check_failed",node_id:this.nodeId,error:e}))}publish(e){const t=this.ring.append(e);for(const s of[...this.subscribers])s(t);return t}fail(e,t){const s={type:"error",error:{code:e,message:t}};for(const r of[...this.subscribers])r(s);this.stopObserver(),this.stopPoll()}unsubscribe(e){this.subscribers.delete(e),this.subscribers.size===0&&this.scheduleIdleClose()}scheduleIdleClose(){this.idleClose===void 0&&(this.idleClose=setTimeout(()=>{this.stopObserver(),this.stopPoll(),this.remove()},P))}stopObserver(){this.reconnect!==void 0&&(clearTimeout(this.reconnect),this.reconnect=void 0);const e=this.observer;this.observer=void 0,e?.close()}stopPoll(){this.poll!==void 0&&(clearInterval(this.poll),this.poll=void 0)}}class F{static{o(this,"NodeEventStreams")}hubs=new Map;async subscribe(e,t,s){let r=this.hubs.get(e);return r===void 0&&(r=new W(e,()=>this.hubs.delete(e)),this.hubs.set(e,r)),await r.subscribe(t,s)}report(e,t){this.hubs.get(e)?.report(t)}}const K=new F;function U(n){const e=n.get("after");if(e===null||e==="")return{};if(!/^(?:0|[1-9]\d*)$/.test(e))throw new E(400,"invalid_request","`after` must be a non-negative integer");const t=Number(e);if(!Number.isSafeInteger(t))throw new E(400,"invalid_request","`after` must be a safe integer");return{after:t}}o(U,"parseQuery");function w(n){const{type:e,...t}=n;return`event: ${e}
1
+ var C=Object.defineProperty;var o=(r,e)=>C(r,"name",{value:e,configurable:!0});import{randomUUID as k}from"node:crypto";import{ApiError as E}from"../../../api/errors.js";import{BrokerClient as B}from"../../../core/broker-client/client.js";import{getNode as p}from"../../../core/canvas/canvas.js";import{emitEvent as w}from"../../../core/events/emit.js";import{isPidAlive as L}from"../../../core/canvas/pid.js";import{BROKER_VIEW_SOCKET_WAIT_MS as D}from"../../../core/runtime/view-socket.js";import{openDb as M}from"../../../core/canvas/db.js";import{brokerSignalBus as $}from"../../broker-signals/bus.js";import{toNodeOutcomeDTO as P}from"../map.js";import{reportsForNode as x}from"./reports.js";import{runAsPerson as j}from"../../../core/canvas/person.js";const G=15e3,V=6e4,T=250,z=512,A=256*1024,H=1e3,J=32*1024*1024;class W{static{o(this,"NodeEventRing")}events=[];bytes=0;nextSequence=1;earliestAvailable=1;append(e){const t={...e,sequence_number:this.nextSequence++},s=Buffer.byteLength(JSON.stringify(t),"utf8");if(s>A)return this.events=[],this.bytes=0,this.earliestAvailable=this.nextSequence,t;for(this.events.push(t),this.bytes+=s;this.events.length>z||this.bytes>A;){const n=this.events.shift();if(n===void 0)break;this.bytes-=Buffer.byteLength(JSON.stringify(n),"utf8"),this.earliestAvailable=n.sequence_number+1}return t}replay(e){if(e===void 0)return{gap:null,events:this.events};const t=e<this.earliestAvailable-1||e>=this.nextSequence?R(this.earliestAvailable):null;return{gap:t,events:t===null?this.events.filter(s=>s.sequence_number>e):this.events}}get empty(){return this.events.length===0}}function R(r){return{type:"error",error:{code:"stream_gap",message:"the requested event cursor is older than this daemon can resume",details:{earliest_sequence:r}}}}o(R,"streamGap");function F(r){return r===null?"arguments: null":Array.isArray(r)?`arguments: array (${r.length} items)`:typeof r=="object"?`arguments: object (${Object.keys(r).length} fields)`:`arguments: ${typeof r}`}o(F,"toolSummary");function m(r){if(typeof r!="object"||r===null)return"";const e=r.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>typeof t=="object"&&t!==null).filter(t=>t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}o(m,"assistantText");class N{static{o(this,"NodeEventTranslationState")}toolSummaries=new Map;emittedAssistantText="";resetAssistantText(){this.emittedAssistantText=""}emitAssistantTextDelta(e){const t=m(e),s=t.startsWith(this.emittedAssistantText)?t.slice(this.emittedAssistantText.length):t;return this.emittedAssistantText=t,s}seedAssistantText(e){const t=m(e);return this.emittedAssistantText=t,t}}function K(r,e,t=new N){switch(e.type){case"message_start":return e.message.role==="assistant"&&t.resetAssistantText(),[];case"message_update":{if(e.message.role!=="assistant")return[];const s=t.emitAssistantTextDelta(e.message);return s===""?[]:[{type:"node.output_text.delta",node_id:r,delta:s}]}case"message_end":{if(e.message.role!=="assistant")return[];const s=m(e.message);return t.resetAssistantText(),[{type:"node.output_text.done",node_id:r,text:s}]}case"tool_execution_start":{const s=F(e.args);return t.toolSummaries.set(e.toolCallId,s),[{type:"node.tool_call.started",node_id:r,tool_call_id:e.toolCallId,tool:e.toolName,summary:s}]}case"tool_execution_end":{const s=t.toolSummaries.get(e.toolCallId)??"[arguments unavailable]";return t.toolSummaries.delete(e.toolCallId),[{type:"node.tool_call.completed",node_id:r,tool_call_id:e.toolCallId,tool:e.toolName,status:e.isError?"error":"ok",summary:s}]}case"turn_start":return[{type:"node.turn.started",node_id:r}];case"turn_end":return[{type:"node.turn.completed",node_id:r}];default:return[]}}o(K,"translateBrokerFrame");class U{static{o(this,"NodeEventHub")}nodeId;remove;ring=new W;subscribers=new Set;observer;observerErrorAt;poll;reconnect;idleClose;status;settledRevision;settledOutcome;settledSequence;snapshotSeeded=!1;reportsSeeded=!1;publishedReports=new Set;translationState=new N;fresh=!0;constructor(e,t){this.nodeId=e,this.remove=t}async subscribe(e,t){const s=this.fresh&&e!==void 0;this.fresh=!1,await this.start();const n=this.settledOutcome!==void 0,a=s?{gap:R(1),events:this.ring.replay(void 0).events}:this.ring.replay(e);n||(this.subscribers.add(t),this.status!=="dormant"&&await this.openObserver());let h=!1;return queueMicrotask(()=>{if(!h){a.gap!==null&&t(a.gap);for(const u of a.events)t(u)}}),n&&this.scheduleIdleClose(),{unsubscribe:o(()=>{h=!0,n||this.unsubscribe(t)},"unsubscribe"),terminal:n}}report(e){this.settledRevision!==void 0||this.publishedReports.has(e.id)||(this.publishedReports.add(e.id),this.publish({type:"node.report.pushed",node_id:this.nodeId,report:e}))}async start(){this.idleClose!==void 0&&(clearTimeout(this.idleClose),this.idleClose=void 0),this.poll===void 0&&(await this.check(),this.settledRevision===void 0&&(await this.seedReports(),this.poll=setInterval(()=>this.checkDetached(),T)))}async seedReports(){if(!this.reportsSeeded){this.reportsSeeded=!0;for(const e of(await this.storedReports()).reverse())this.report(e)}}async storedReports(){const e=(await p(this.nodeId))?.sub;return e?await j(e,()=>x(this.nodeId)):await x(this.nodeId)}async refreshReports(){if(!(!this.reportsSeeded||this.settledRevision!==void 0))for(const e of(await this.storedReports()).reverse())this.report(e)}async check(){const e=await p(this.nodeId);if(e===null){this.fail("stream_error",`node ${this.nodeId} no longer exists`);return}const t=await P(e);if(t!==null){this.settledRevision!==t.revision&&(this.settledRevision=t.revision,this.settledOutcome=t,this.settledSequence=this.publish({type:"node.settled",node_id:this.nodeId,outcome:t}).sequence_number,this.stopObserver(),this.stopPoll());return}const s=e.pi_pid===null?"dormant":e.status;if(s==="dormant"){this.observerErrorAt=void 0,this.status!=="dormant"&&(this.status=s,this.publish({type:"node.status.changed",node_id:this.nodeId,status:s}));return}this.status===void 0?this.status=s:this.status!=="dormant"&&this.status!==s&&(this.status=s,this.publish({type:"node.status.changed",node_id:this.nodeId,status:s})),await this.openObserver()}async openObserver(){if(this.observer!==void 0||this.subscribers.size===0)return;const e=new B(this.nodeId);this.observer=e,e.on("connect",()=>{(async()=>{this.observerErrorAt=void 0;const t=await p(this.nodeId);this.status==="dormant"&&t!==null&&t.pi_pid!==null&&(this.status=t.status,this.publish({type:"node.status.changed",node_id:this.nodeId,status:t.status})),e.send({type:"hello",role:"observer",client_id:k(),attends:!1})})().catch(t=>this.fail("stream_error",t instanceof Error?t.message:String(t)))}),e.on("frame",t=>{try{t.type==="welcome"&&this.seedSnapshot(t.snapshot);for(const s of K(this.nodeId,t,this.translationState))this.publish(s)}catch(s){this.fail("stream_error",s instanceof Error?s.message:String(s))}}),e.on("error",()=>{(async()=>{const t=await p(this.nodeId),s=Date.now();if(t!==null&&t.pi_pid!==null&&L(t.pi_pid)){if(this.observerErrorAt??=s,s-this.observerErrorAt<D)return;this.fail("stream_error","observer connection failed");return}this.observerErrorAt=void 0})().catch(t=>this.fail("stream_error",t instanceof Error?t.message:String(t)))}),e.on("close",()=>{this.observer===e&&(this.observer=void 0,!(this.subscribers.size===0||this.settledRevision!==void 0)&&(this.status!=="dormant"&&(this.publish({type:"node.status.changed",node_id:this.nodeId,status:"dormant"}),this.status="dormant"),this.scheduleReconnect()))}),e.connect()}seedSnapshot(e){if(this.snapshotSeeded)return;this.snapshotSeeded=!0;const t=e.messages.filter(n=>n.role==="assistant"),s=e.state.isStreaming?t.pop():void 0;for(const n of t)this.publish({type:"node.output_text.done",node_id:this.nodeId,text:m(n)});s!==void 0&&this.publish({type:"node.output_text.delta",node_id:this.nodeId,delta:this.translationState.seedAssistantText(s)})}scheduleReconnect(){this.reconnect===void 0&&(this.reconnect=setTimeout(()=>{this.reconnect=void 0,this.checkDetached()},T))}checkDetached(){this.check().catch(e=>w({level:"error",event:"api.node_events.check_failed",node_id:this.nodeId,error:e}))}publish(e){const t=this.ring.append(e);for(const s of[...this.subscribers])s(t);return t}fail(e,t){const s={type:"error",error:{code:e,message:t}};for(const n of[...this.subscribers])n(s);this.stopObserver(),this.stopPoll()}unsubscribe(e){this.subscribers.delete(e),this.subscribers.size===0&&this.scheduleIdleClose()}scheduleIdleClose(){this.idleClose===void 0&&(this.idleClose=setTimeout(()=>{this.stopObserver(),this.stopPoll(),this.remove()},V))}stopObserver(){this.reconnect!==void 0&&(clearTimeout(this.reconnect),this.reconnect=void 0);const e=this.observer;this.observer=void 0,e?.close()}stopPoll(){this.poll!==void 0&&(clearInterval(this.poll),this.poll=void 0)}}class Y{static{o(this,"NodeEventStreams")}hubs=new Map;unsubscribeBus;refresh(e){this.hubs.get(e)?.refreshReports().catch(t=>w({level:"error",event:"api.node_events.report_refresh_failed",node_id:e,error:t}))}listen(){this.unsubscribeBus??=$.subscribe(e=>this.refresh(e),{kinds:["report"],onListenStart:o(()=>{for(const e of[...this.hubs.keys()])this.refresh(e)},"onListenStart")})}remove(e){if(this.hubs.delete(e),this.hubs.size===0){const t=this.unsubscribeBus;this.unsubscribeBus=void 0,t?.then(s=>s())}}async subscribe(e,t,s){let n=this.hubs.get(e);return n===void 0&&(n=new U(e,()=>this.remove(e)),this.hubs.set(e,n),this.listen()),await n.subscribe(t,s)}report(e,t){this.hubs.get(e)?.report(t),M().then(s=>s.prepare("SELECT pg_notify(?, ?)").get("crtr_signal",`report:${e}`)).catch(s=>w({level:"error",event:"api.node_events.report_signal_failed",node_id:e,error:s}))}}const Q=new Y;function X(r){const e=r.get("after");if(e===null||e==="")return{};if(!/^(?:0|[1-9]\d*)$/.test(e))throw new E(400,"invalid_request","`after` must be a non-negative integer");const t=Number(e);if(!Number.isSafeInteger(t))throw new E(400,"invalid_request","`after` must be a safe integer");return{after:t}}o(X,"parseQuery");function I(r){const{type:e,...t}=r;return`event: ${e}
2
2
  data: ${JSON.stringify(t)}
3
3
 
4
- `}o(w,"sseRecord");async function Y(n){const e=n.params.id??"";if(await m(e)===null)throw new E(404,"node_not_found",`no node ${e}`);const{after:t}=U(n.query),{req:s,res:r}=n;r.writeHead(200,{"content-type":"text/event-stream; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});let a=!1,c=!1,u=!1,h=0;const d=[];let v,f;const _=o(()=>{r.writableEnded||r.end()},"finish"),p=o(()=>{if(!a){if(a=!0,f!==void 0&&clearInterval(f),v?.(),r.destroyed){d.length=0,h=0,_();return}if(u||d.length>0){c=!0;return}_()}},"close"),y=o(()=>{for(u=!1;d.length>0;){const i=d.shift();if(h-=Buffer.byteLength(i,"utf8"),!r.write(i)){u=!0,r.once("drain",y);return}}c&&_()},"flush"),N=o(()=>{if(a)return;d.length=0,h=0;const i=w({type:"error",error:{code:"stream_dropped",message:"stream reader is too slow"}});d.push(i),h=Buffer.byteLength(i,"utf8"),a=!0,c=!0,f!==void 0&&clearInterval(f),v?.(),u||y()},"dropSlowReader"),g=o(i=>{if(a)return!1;if(u||d.length>0){const l=Buffer.byteLength(i,"utf8");return d.length>=G||h+l>V?(N(),!1):(d.push(i),h+=l,!0)}return r.write(i)||(u=!0,r.once("drain",y)),!0},"write"),S=o((i,l)=>{a||g(w({type:"error",error:{code:i,message:l}})),p()},"fail"),R=o(i=>{try{if(!g(w(i)))return;(i.type==="node.settled"||i.type==="error"&&i.error.code!=="stream_gap")&&p()}catch(l){S("stream_error",l instanceof Error?l.message:String(l))}},"onEvent");f=setInterval(()=>{try{a||g(`: keepalive
4
+ `}o(I,"sseRecord");async function Z(r){const e=r.params.id??"";if(await p(e)===null)throw new E(404,"node_not_found",`no node ${e}`);const{after:t}=X(r.query),{req:s,res:n}=r;n.writeHead(200,{"content-type":"text/event-stream; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});let a=!1,h=!1,u=!1,c=0;const d=[];let v,f;const _=o(()=>{n.writableEnded||n.end()},"finish"),b=o(()=>{if(!a){if(a=!0,f!==void 0&&clearInterval(f),v?.(),n.destroyed){d.length=0,c=0,_();return}if(u||d.length>0){h=!0;return}_()}},"close"),y=o(()=>{for(u=!1;d.length>0;){const i=d.shift();if(c-=Buffer.byteLength(i,"utf8"),!n.write(i)){u=!0,n.once("drain",y);return}}h&&_()},"flush"),O=o(()=>{if(a)return;d.length=0,c=0;const i=I({type:"error",error:{code:"stream_dropped",message:"stream reader is too slow"}});d.push(i),c=Buffer.byteLength(i,"utf8"),a=!0,h=!0,f!==void 0&&clearInterval(f),v?.(),u||y()},"dropSlowReader"),g=o(i=>{if(a)return!1;if(u||d.length>0){const l=Buffer.byteLength(i,"utf8");return d.length>=H||c+l>J?(O(),!1):(d.push(i),c+=l,!0)}return n.write(i)||(u=!0,n.once("drain",y)),!0},"write"),S=o((i,l)=>{a||g(I({type:"error",error:{code:i,message:l}})),b()},"fail"),q=o(i=>{try{if(!g(I(i)))return;(i.type==="node.settled"||i.type==="error"&&i.error.code!=="stream_gap")&&b()}catch(l){S("stream_error",l instanceof Error?l.message:String(l))}},"onEvent");f=setInterval(()=>{try{a||g(`: keepalive
5
5
 
6
- `)}catch(i){S("stream_error",i instanceof Error?i.message:String(i))}},$),s.once("close",p);try{const i=await K.subscribe(e,t,R);v=i.unsubscribe,i.terminal&&queueMicrotask(p)}catch(i){S("stream_error",i instanceof Error?i.message:String(i))}return{status:200}}o(Y,"handleEvents");const ae=[{method:"GET",pattern:"/v1/nodes/:id/events",handler:Y}];export{H as NodeEventRing,A as NodeEventTranslationState,ae as nodeEventRoutes,K as nodeEventStreams,J as translateBrokerFrame};
6
+ `)}catch(i){S("stream_error",i instanceof Error?i.message:String(i))}},G),s.once("close",b);try{const i=await Q.subscribe(e,t,q);v=i.unsubscribe,i.terminal&&queueMicrotask(b)}catch(i){S("stream_error",i instanceof Error?i.message:String(i))}return{status:200}}o(Z,"handleEvents");const fe=[{method:"GET",pattern:"/v1/nodes/:id/events",handler:Z}];export{W as NodeEventRing,N as NodeEventTranslationState,fe as nodeEventRoutes,Q as nodeEventStreams,K as translateBrokerFrame};
@@ -1 +1 @@
1
- var _=Object.defineProperty;var a=(t,e)=>_(t,"name",{value:e,configurable:!0});import{setTimeout as h}from"node:timers/promises";import{ApiError as r}from"../../../api/errors.js";import{getNode as v}from"../../../core/canvas/canvas.js";import{withCanvasWrite as m,openDb as A}from"../../../core/canvas/db.js";import{enqueueLateOutcomeAction as O,readOutcomeAction as l,registerOutcomeAction as g,unregisterOutcomeAction as D}from"../../../core/canvas/outcome-actions.js";import{OUTCOME_PAYLOAD_MAX_BYTES as f}from"../../../core/canvas/types.js";import{composeNodeOutcomeDocument as N}from"../../../core/runtime/outcome-document.js";import{HUMAN_ACTION_NAME_PATTERN as k}from"../../../core/human/action-binding.js";import{resolveHumanAction as b}from"../../../core/human-actions.js";import{toNodeOutcomeDTO as p,toOutcomeDeliveryDTO as E}from"../map.js";import{waitSeconds as T}from"../long-poll-wait.js";const q=250;async function s(t){const e=await v(t);if(e===null)throw new r(404,"node_not_found",`no node ${t}`);return e}a(s,"requireNode");async function $(t){const e=p(t);return{node_id:t.node_id,state:e===null?"pending":"settled",outcome:e,node_status:t.status,deadline_at:t.deadline_at??null}}a($,"responseFor");async function L(t){const e=t.params.id??"",o=Date.now()+T("node-outcomes.get.119",t.query)*1e3;let n=await s(e);for(;p(n)===null&&Date.now()<o;)await h(Math.min(q,o-Date.now())),n=await s(e);return{status:200,body:await $(n)}}a(L,"handleGetOutcome");function j(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}a(j,"isPlainObject");function M(t){let e;try{e=JSON.stringify(t)}catch{throw new r(400,"invalid_request","`payload` must be JSON-serializable")}if(e===void 0)throw new r(400,"invalid_request","`payload` must be JSON-serializable");return Buffer.byteLength(e,"utf8")}a(M,"payloadBytes");function P(t){if(!j(t))throw new r(400,"invalid_request","request body must be an object");for(const o of Object.keys(t))if(o!=="action"&&o!=="payload")throw new r(400,"invalid_request",`unexpected field in request body: ${o}`);const e=t.action;if(typeof e!="string"||!k.test(e))throw new r(400,"invalid_request","`action` must be a declared action name");if(t.payload!==void 0&&M(t.payload)>f)throw new r(413,"payload_too_large",`serialized payload exceeds ${f} bytes`);return t.payload===void 0?{action:e}:{action:e,payload:t.payload}}a(P,"parseRegistration");function w(t,e){const o=e.delivery,n=Date.parse(e.object.created_at);return E({nodeId:t,actionName:e.actionName,state:o===null?"armed":o.state==="handed_off"?"running":o.state==="acknowledged"?"accepted":o.state,attempt:o?.attempts??0,nextAttemptAt:o?.nextAttemptAt??0,acceptedAt:o?.acknowledgedAt??null,permanentFailedAt:o?.failedAt??null,lastFailure:o?.lastFailure??null,createdAt:n,updatedAt:o?.updatedAt??e.updatedAt})}a(w,"outcomeView");function S(t){const e=t.outcome_reason;let o,n;return t.outcome_kind==="result"||e==="finished"||e==="declined"?(o="done",n="done"):e==="parked"?(o="done",n="parked"):e==="closed"||e==="retired"||e==="stranded"||e==="deadline_exceeded"?(o="canceled",n=null):(o="dead",n=null),{...t,status:o,intent:n,terminal_reason:e}}a(S,"nodeAtOutcome");function R(t,e){const o=b(t,e);if(!("kind"in o))return o;throw o.kind==="unknown_action"?new r(422,"unknown_action",`no action named ${t} is declared from ${e}`):new r(422,"invalid_action",`${t} is declared in ${o.configOrigin} but unusable: ${o.reason}`,{reason:o.reason,configOrigin:o.configOrigin})}a(R,"resolveAction");async function x(t){const e=t.params.id??"",o=await s(e),n=P(t.body),y=R(n.action,o.cwd);return await m(async d=>{const u=await l(d,e);if(u&&u.delivery!==null)throw new r(409,"outcome_delivery_settled","outcome delivery has already started or settled");const i=await s(e);if(await g(d,e,{actionName:n.action,...y,payload:n.payload}),i.outcome_at!==null){if(i.outcome_kind==null||i.outcome_reason==null||i.outcome_revision==null||i.outcome_at==null)throw new Error(`outcome latch is incomplete for node ${e}`);await O(d,e,await N({node:S(i),outcome:{kind:i.outcome_kind,reason:i.outcome_reason,at:i.outcome_at,revision:i.outcome_revision,detailJson:i.outcome_detail_json??null},finalReport:i.final_report}))}const c=await l(d,e);if(c===null)throw new Error(`outcome action was not registered for ${e}`);return{status:200,body:w(e,c)}})}a(x,"handlePutDelivery");async function z(t){const e=t.params.id??"",o=await l(await A(),e);if(o===null)throw new r(404,"outcome_delivery_not_found",`no outcome delivery for node ${e}`);return{status:200,body:w(e,o)}}a(z,"handleGetDelivery");async function F(t){const e=t.params.id??"";return await m(async o=>{if(!await D(o,e))throw new r(409,"outcome_delivery_settled","outcome delivery has already started or settled");return{status:204}})}a(F,"handleDeleteDelivery");const Q=[{method:"GET",pattern:"/v1/nodes/:id/outcome",handler:L},{method:"PUT",pattern:"/v1/nodes/:id/outcome-delivery",handler:x},{method:"GET",pattern:"/v1/nodes/:id/outcome-delivery",handler:z},{method:"DELETE",pattern:"/v1/nodes/:id/outcome-delivery",handler:F}];export{Q as nodeOutcomeRoutes};
1
+ var _=Object.defineProperty;var a=(t,e)=>_(t,"name",{value:e,configurable:!0});import{setTimeout as h}from"node:timers/promises";import{ApiError as r}from"../../../api/errors.js";import{getNode as v}from"../../../core/canvas/canvas.js";import{withCanvasWrite as m,openDb as A}from"../../../core/canvas/db.js";import{enqueueLateOutcomeAction as O,readOutcomeAction as l,registerOutcomeAction as g,unregisterOutcomeAction as D}from"../../../core/canvas/outcome-actions.js";import{OUTCOME_PAYLOAD_MAX_BYTES as f}from"../../../core/canvas/types.js";import{composeNodeOutcomeDocument as N}from"../../../core/runtime/outcome-document.js";import{HUMAN_ACTION_NAME_PATTERN as k}from"../../../core/human/action-binding.js";import{resolveHumanAction as b}from"../../../core/human-actions.js";import{toNodeOutcomeDTO as p,toOutcomeDeliveryDTO as E}from"../map.js";import{waitSeconds as T}from"../long-poll-wait.js";const q=250;async function s(t){const e=await v(t);if(e===null)throw new r(404,"node_not_found",`no node ${t}`);return e}a(s,"requireNode");async function $(t){const e=await p(t);return{node_id:t.node_id,state:e===null?"pending":"settled",outcome:e,node_status:t.status,deadline_at:t.deadline_at??null}}a($,"responseFor");async function L(t){const e=t.params.id??"",o=Date.now()+T("node-outcomes.get.119",t.query)*1e3;let n=await s(e);for(;await p(n)===null&&Date.now()<o;)await h(Math.min(q,o-Date.now())),n=await s(e);return{status:200,body:await $(n)}}a(L,"handleGetOutcome");function j(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}a(j,"isPlainObject");function M(t){let e;try{e=JSON.stringify(t)}catch{throw new r(400,"invalid_request","`payload` must be JSON-serializable")}if(e===void 0)throw new r(400,"invalid_request","`payload` must be JSON-serializable");return Buffer.byteLength(e,"utf8")}a(M,"payloadBytes");function P(t){if(!j(t))throw new r(400,"invalid_request","request body must be an object");for(const o of Object.keys(t))if(o!=="action"&&o!=="payload")throw new r(400,"invalid_request",`unexpected field in request body: ${o}`);const e=t.action;if(typeof e!="string"||!k.test(e))throw new r(400,"invalid_request","`action` must be a declared action name");if(t.payload!==void 0&&M(t.payload)>f)throw new r(413,"payload_too_large",`serialized payload exceeds ${f} bytes`);return t.payload===void 0?{action:e}:{action:e,payload:t.payload}}a(P,"parseRegistration");function w(t,e){const o=e.delivery,n=Date.parse(e.object.created_at);return E({nodeId:t,actionName:e.actionName,state:o===null?"armed":o.state==="handed_off"?"running":o.state==="acknowledged"?"accepted":o.state,attempt:o?.attempts??0,nextAttemptAt:o?.nextAttemptAt??0,acceptedAt:o?.acknowledgedAt??null,permanentFailedAt:o?.failedAt??null,lastFailure:o?.lastFailure??null,createdAt:n,updatedAt:o?.updatedAt??e.updatedAt})}a(w,"outcomeView");function S(t){const e=t.outcome_reason;let o,n;return t.outcome_kind==="result"||e==="finished"||e==="declined"?(o="done",n="done"):e==="parked"?(o="done",n="parked"):e==="closed"||e==="retired"||e==="stranded"||e==="deadline_exceeded"?(o="canceled",n=null):(o="dead",n=null),{...t,status:o,intent:n,terminal_reason:e}}a(S,"nodeAtOutcome");function R(t,e){const o=b(t,e);if(!("kind"in o))return o;throw o.kind==="unknown_action"?new r(422,"unknown_action",`no action named ${t} is declared from ${e}`):new r(422,"invalid_action",`${t} is declared in ${o.configOrigin} but unusable: ${o.reason}`,{reason:o.reason,configOrigin:o.configOrigin})}a(R,"resolveAction");async function x(t){const e=t.params.id??"",o=await s(e),n=P(t.body),y=R(n.action,o.cwd);return await m(async d=>{const u=await l(d,e);if(u&&u.delivery!==null)throw new r(409,"outcome_delivery_settled","outcome delivery has already started or settled");const i=await s(e);if(await g(d,e,{actionName:n.action,...y,payload:n.payload}),i.outcome_at!==null){if(i.outcome_kind==null||i.outcome_reason==null||i.outcome_revision==null||i.outcome_at==null)throw new Error(`outcome latch is incomplete for node ${e}`);await O(d,e,await N({node:S(i),outcome:{kind:i.outcome_kind,reason:i.outcome_reason,at:i.outcome_at,revision:i.outcome_revision,detailJson:i.outcome_detail_json??null},finalReport:i.final_report}))}const c=await l(d,e);if(c===null)throw new Error(`outcome action was not registered for ${e}`);return{status:200,body:w(e,c)}})}a(x,"handlePutDelivery");async function z(t){const e=t.params.id??"",o=await l(await A(),e);if(o===null)throw new r(404,"outcome_delivery_not_found",`no outcome delivery for node ${e}`);return{status:200,body:w(e,o)}}a(z,"handleGetDelivery");async function F(t){const e=t.params.id??"";return await m(async o=>{if(!await D(o,e))throw new r(409,"outcome_delivery_settled","outcome delivery has already started or settled");return{status:204}})}a(F,"handleDeleteDelivery");const Q=[{method:"GET",pattern:"/v1/nodes/:id/outcome",handler:L},{method:"PUT",pattern:"/v1/nodes/:id/outcome-delivery",handler:x},{method:"GET",pattern:"/v1/nodes/:id/outcome-delivery",handler:z},{method:"DELETE",pattern:"/v1/nodes/:id/outcome-delivery",handler:F}];export{Q as nodeOutcomeRoutes};
@@ -1,3 +1,4 @@
1
- var p=Object.defineProperty;var o=(e,r)=>p(e,"name",{value:r,configurable:!0});import{dirname as c,isAbsolute as l,join as f,resolve as h}from"node:path";import{appendRotatingRecord as y}from"../../../core/log.js";import{jobDir as b,messagesDir as g}from"../../../core/canvas/paths.js";import{parseNodeTelemetryRecord as w,writeNodeTelemetryRecord as _}from"./telemetry-record.js";import{openDb as v}from"../../../core/canvas/db.js";import{reportDocumentBody as N}from"../../../core/feed/inbox.js";import{reportRefNodeId as S}from"../../../shared/inbox-entry-body.js";import{writeNodeRecap as R}from"../../../core/canvas/node-recap.js";import{markStopSignal as T,consumeStopSignals as E,clearStopSignals as j}from"../../../core/runtime/stop-signals.js";import{notFound as s,usage as n}from"../../../core/errors.js";import{isBeneathRefusal as D,readFileBeneath as A}from"../../../core/spaces/open-beneath.js";import{requireCurrentExecution as u}from"./broker-recovery.js";async function i(e){if(e.body===null||typeof e.body!="object"||Array.isArray(e.body))throw n("node record requires a JSON object");const r=e.body;return await u(e.params.id,r.expected_execution_id),r}o(i,"body");function a(e,r){if(typeof e!="string")throw n(`${r} must be a string`);return e}o(a,"text");const M=[{method:"POST",pattern:"/v1/nodes/:id/records/log",handler:o(async e=>{const r=a((await i(e)).record,"record");return{status:200,body:{appended:y(f(b(e.params.id),"log.jsonl"),r)}}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/telemetry",handler:o(async e=>(_(e.params.id,w(await i(e))),{status:204}),"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/recap",handler:o(async e=>(R(e.params.id,a((await i(e)).briefing,"briefing")),{status:204}),"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/inbox",handler:o(async e=>{const r=e.params.id,d=e.query.get("ref");if(await u(r,e.query.get("execution_id")),d===null||S(d)===void 0)throw n("ref must be a report handle");const t=await(await v()).prepare(`SELECT m.object_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
1
+ var f=Object.defineProperty;var r=(e,t)=>f(e,"name",{value:t,configurable:!0});import{join as y}from"node:path";import{appendRotatingRecord as h}from"../../../core/log.js";import{jobDir as b}from"../../../core/canvas/paths.js";import{parseNodeTelemetryRecord as _,writeNodeTelemetryRecord as w}from"./telemetry-record.js";import{openDb as m}from"../../../core/canvas/db.js";import{reportDocumentBody as g}from"../../../core/feed/inbox.js";import{reportRefNodeId as E}from"../../../shared/inbox-entry-body.js";import{writeNodeRecap as T}from"../../../core/canvas/node-recap.js";import{markStopSignal as N,consumeStopSignals as R,clearStopSignals as S}from"../../../core/runtime/stop-signals.js";import{notFound as d,usage as s}from"../../../core/errors.js";import{blobStore as v}from"../../../core/blobs/index.js";import{requireCurrentExecution as c}from"./broker-recovery.js";async function u(e){if(e.body===null||typeof e.body!="object"||Array.isArray(e.body))throw s("node record requires a JSON object");const t=e.body;return await c(e.params.id,t.expected_execution_id),t}r(u,"body");function p(e,t){if(typeof e!="string")throw s(`${t} must be a string`);return e}r(p,"text");async function l(e){const t=await m(),o=await t.prepare("SELECT run_id FROM nodes WHERE node_id = ?").get(e);if(o===void 0)throw d("node not found");return o.run_id===null?[]:(await t.prepare("SELECT path, blob_key FROM upload_uses WHERE run_id = ? AND blob_key IS NOT NULL ORDER BY path").all(o.run_id)).map(n=>({...n,sha256:n.blob_key.slice(n.blob_key.lastIndexOf("/")+1)}))}r(l,"runAttachments");const H=[{method:"POST",pattern:"/v1/nodes/:id/records/log",handler:r(async e=>{const t=p((await u(e)).record,"record");return{status:200,body:{appended:h(y(b(e.params.id),"log.jsonl"),t)}}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/telemetry",handler:r(async e=>(w(e.params.id,_(await u(e))),{status:204}),"handler")},{method:"GET",pattern:"/v1/nodes/:id/attachments",handler:r(async e=>({status:200,body:{attachments:(await l(e.params.id)).map(({path:t,sha256:o})=>({path:t,sha256:o}))}}),"handler")},{method:"GET",pattern:"/v1/nodes/:id/attachments/:sha256",handler:r(async e=>{const t=e.params.sha256,o=(await l(e.params.id)).find(n=>n.sha256===t);if(o===void 0)throw d("attachment not found");const a=await(await v()).get(o.blob_key);if(a===null)throw d("attachment not found");return{status:200,rawBody:a,headers:{"content-type":"application/octet-stream"}}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/summaries",handler:r(async e=>{const t=await u(e),o=await m();for(const[a,n]of[["tool_summaries","tool_summaries_json"],["turn_replies","turn_replies_json"]]){const i=t[a];if(i!==void 0){if(i===null||typeof i!="object"||Array.isArray(i))throw s(`${a} must be an object`);await o.prepare(`UPDATE nodes SET ${n} = ? WHERE node_id = ?`).run(JSON.stringify(i),e.params.id)}}return{status:204}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/recap",handler:r(async e=>(T(e.params.id,p((await u(e)).briefing,"briefing")),{status:204}),"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/inbox",handler:r(async e=>{const t=e.params.id,o=e.query.get("ref");if(await c(t,e.query.get("execution_id")),o===null||E(o)===void 0)throw s("ref must be a report handle");const a=await(await m()).prepare(`SELECT m.object_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
2
2
  WHERE d.destination_id = ? AND d.state = 'handed_off'
3
- AND d.claim_owner = ? AND d.canceled_at IS NULL AND m.body_ref = ? LIMIT 1`).get(r,e.query.get("execution_id"),d);if(t===void 0)throw s("report was not delivered to this node");const m=t.object_id===null?null:await N(t.object_id);if(m===null)throw s("report not found");return{status:200,body:{content:m}}},"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/passive",handler:o(e=>{const r=e.query.get("ref"),d=g(e.params.id);if(r===null||!l(r)||c(h(r))!==d||!r.endsWith(".md"))throw n("ref must be a direct-message spill path for this node");try{return{status:200,body:{content:A(d,r).toString("utf8")}}}catch(t){throw t.code==="ENOENT"?s("passive message not found"):D(t)?n("ref meets a symlink or is not a regular file; only the node's own message files are served"):t}},"handler")},{method:"POST",pattern:"/v1/nodes/:id/records/pushed-final",handler:o(async e=>{const r=await i(e);if(r.action==="mark")T(e.params.id,"pushedFinal",a(r.expected_execution_id,"expected_execution_id"));else if(r.action==="clear")j(e.params.id);else{if(r.action==="consume")return{status:200,body:E(e.params.id,a(r.expected_execution_id,"expected_execution_id"))};throw n("action must be mark, clear or consume")}return{status:200,body:{pushedFinal:!1}}},"handler")}];export{M as nodeRecordRoutes};
3
+ AND d.claim_owner = ? AND d.canceled_at IS NULL AND m.body_ref = ? LIMIT 1`).get(t,e.query.get("execution_id"),o);if(a===void 0)throw d("report was not delivered to this node");const n=a.object_id===null?null:await g(a.object_id);if(n===null)throw d("report not found");return{status:200,body:{content:n}}},"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/passive",handler:r(async e=>{const t=e.query.get("ref");if(t===null||t==="")throw s("ref must be a direct-message spill path for this node");const o=await(await m()).prepare(`SELECT m.body_json ->> 'body_full' AS body FROM messages m JOIN deliveries d ON d.message_id = m.message_id
4
+ WHERE d.destination_id = ? AND m.body_ref = ? LIMIT 1`).get(e.params.id,t);if(o===void 0||o.body===null)throw d("passive message not found");return{status:200,body:{content:o.body}}},"handler")},{method:"POST",pattern:"/v1/nodes/:id/records/pushed-final",handler:r(async e=>{const t=await u(e);if(t.action==="mark")N(e.params.id,"pushedFinal",p(t.expected_execution_id,"expected_execution_id"));else if(t.action==="clear")S(e.params.id);else{if(t.action==="consume")return{status:200,body:R(e.params.id,p(t.expected_execution_id,"expected_execution_id"))};throw s("action must be mark, clear or consume")}return{status:200,body:{pushedFinal:!1}}},"handler")}];export{H as nodeRecordRoutes};