@elie-laloum/outpost 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (381) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +3 -1
  3. package/SECURITY.md +3 -1
  4. package/dist/adapters/agents/gemini-adapter.d.ts +3 -0
  5. package/dist/adapters/agents/gemini-adapter.js +15 -0
  6. package/dist/adapters/agents/gemini-adapter.js.map +1 -0
  7. package/dist/adapters/agents/gemini-diagnostics.d.ts +2 -0
  8. package/dist/adapters/agents/gemini-diagnostics.js +15 -0
  9. package/dist/adapters/agents/gemini-diagnostics.js.map +1 -0
  10. package/dist/adapters/agents/gemini-events.d.ts +2 -0
  11. package/dist/adapters/agents/gemini-events.js +50 -0
  12. package/dist/adapters/agents/gemini-events.js.map +1 -0
  13. package/dist/adapters/agents/gemini-request.d.ts +4 -0
  14. package/dist/adapters/agents/gemini-request.js +21 -0
  15. package/dist/adapters/agents/gemini-request.js.map +1 -0
  16. package/dist/adapters/agents/gemini.types.d.ts +6 -0
  17. package/dist/adapters/agents/gemini.types.js +2 -0
  18. package/dist/adapters/agents/gemini.types.js.map +1 -0
  19. package/dist/adapters/agents/protocol-fixtures.constants.d.ts +1 -1
  20. package/dist/adapters/agents/protocol-fixtures.constants.js +37 -0
  21. package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
  22. package/dist/application/agent-bootstrap.constants.d.ts +1 -0
  23. package/dist/application/agent-bootstrap.constants.js +1 -0
  24. package/dist/application/agent-bootstrap.constants.js.map +1 -1
  25. package/dist/application/agent-bootstrap.js +6 -2
  26. package/dist/application/agent-bootstrap.js.map +1 -1
  27. package/dist/application/agent-output.js +9 -2
  28. package/dist/application/agent-output.js.map +1 -1
  29. package/dist/application/artifact-tasks.d.ts +5 -0
  30. package/dist/application/artifact-tasks.js +31 -0
  31. package/dist/application/artifact-tasks.js.map +1 -0
  32. package/dist/application/artifact-tasks.types.d.ts +8 -0
  33. package/dist/application/artifact-tasks.types.js +2 -0
  34. package/dist/application/artifact-tasks.types.js.map +1 -0
  35. package/dist/application/dispatch-validation.js +2 -0
  36. package/dist/application/dispatch-validation.js.map +1 -1
  37. package/dist/application/doctor-agent.constants.d.ts +2 -0
  38. package/dist/application/doctor-agent.constants.js +2 -0
  39. package/dist/application/doctor-agent.constants.js.map +1 -1
  40. package/dist/application/doctor-agent.js +1 -1
  41. package/dist/application/doctor-agent.js.map +1 -1
  42. package/dist/application/doctor-protocol.js +2 -1
  43. package/dist/application/doctor-protocol.js.map +1 -1
  44. package/dist/application/doctor.constants.js +1 -1
  45. package/dist/application/doctor.constants.js.map +1 -1
  46. package/dist/application/doctor.types.d.ts +1 -1
  47. package/dist/application/doctor.types.js.map +1 -1
  48. package/dist/application/outpost.types.d.ts +2 -0
  49. package/dist/application/outpost.types.js.map +1 -1
  50. package/dist/application/queue-worker.d.ts +2 -0
  51. package/dist/application/queue-worker.js +75 -0
  52. package/dist/application/queue-worker.js.map +1 -0
  53. package/dist/application/queue-worker.types.d.ts +15 -0
  54. package/dist/application/queue-worker.types.js +2 -0
  55. package/dist/application/queue-worker.types.js.map +1 -0
  56. package/dist/application/queued-task.d.ts +3 -0
  57. package/dist/application/queued-task.js +56 -0
  58. package/dist/application/queued-task.js.map +1 -0
  59. package/dist/application/queued-task.types.d.ts +11 -0
  60. package/dist/application/queued-task.types.js +2 -0
  61. package/dist/application/queued-task.types.js.map +1 -0
  62. package/dist/application/recovery-inspection.js +5 -0
  63. package/dist/application/recovery-inspection.js.map +1 -1
  64. package/dist/application/recovery-inspection.types.d.ts +3 -0
  65. package/dist/application/recovery-inspection.types.js.map +1 -1
  66. package/dist/application/recovery-restore-snapshot.d.ts +2 -0
  67. package/dist/application/recovery-restore-snapshot.js +57 -0
  68. package/dist/application/recovery-restore-snapshot.js.map +1 -0
  69. package/dist/application/recovery-restore.d.ts +3 -0
  70. package/dist/application/recovery-restore.js +161 -0
  71. package/dist/application/recovery-restore.js.map +1 -0
  72. package/dist/application/recovery-restore.types.d.ts +28 -0
  73. package/dist/application/recovery-restore.types.js +2 -0
  74. package/dist/application/recovery-restore.types.js.map +1 -0
  75. package/dist/application/recovery-retention.js +5 -0
  76. package/dist/application/recovery-retention.js.map +1 -1
  77. package/dist/application/recovery-verification.d.ts +2 -1
  78. package/dist/application/recovery-verification.js +1 -1
  79. package/dist/application/recovery-verification.js.map +1 -1
  80. package/dist/application/remote-apply.js +6 -0
  81. package/dist/application/remote-apply.js.map +1 -1
  82. package/dist/application/remote-download.js +2 -2
  83. package/dist/application/remote-download.js.map +1 -1
  84. package/dist/application/remote-history.d.ts +6 -0
  85. package/dist/application/remote-history.js +114 -0
  86. package/dist/application/remote-history.js.map +1 -0
  87. package/dist/application/remote-upload.d.ts +2 -0
  88. package/dist/application/remote-upload.js +17 -0
  89. package/dist/application/remote-upload.js.map +1 -0
  90. package/dist/application/remote-validation.js +20 -28
  91. package/dist/application/remote-validation.js.map +1 -1
  92. package/dist/application/remote-workspace.js +4 -10
  93. package/dist/application/remote-workspace.js.map +1 -1
  94. package/dist/application/sandbox-activity.d.ts +3 -0
  95. package/dist/application/sandbox-activity.js +25 -0
  96. package/dist/application/sandbox-activity.js.map +1 -0
  97. package/dist/application/sandbox-provision.js +55 -10
  98. package/dist/application/sandbox-provision.js.map +1 -1
  99. package/dist/application/sandbox-session.types.d.ts +2 -0
  100. package/dist/application/sandbox-session.types.js.map +1 -1
  101. package/dist/application/sandbox.js +23 -11
  102. package/dist/application/sandbox.js.map +1 -1
  103. package/dist/application/speculation-host.d.ts +2 -0
  104. package/dist/application/speculation-host.js +30 -0
  105. package/dist/application/speculation-host.js.map +1 -0
  106. package/dist/application/speculation.constants.d.ts +4 -0
  107. package/dist/application/speculation.constants.js +2 -0
  108. package/dist/application/speculation.constants.js.map +1 -0
  109. package/dist/application/speculation.d.ts +2 -0
  110. package/dist/application/speculation.js +166 -0
  111. package/dist/application/speculation.js.map +1 -0
  112. package/dist/application/speculation.types.d.ts +56 -0
  113. package/dist/application/speculation.types.js +2 -0
  114. package/dist/application/speculation.types.js.map +1 -0
  115. package/dist/application/storage-reservation.d.ts +3 -0
  116. package/dist/application/storage-reservation.js +10 -0
  117. package/dist/application/storage-reservation.js.map +1 -0
  118. package/dist/application/storage-reservation.types.d.ts +4 -0
  119. package/dist/application/storage-reservation.types.js +2 -0
  120. package/dist/application/storage-reservation.types.js.map +1 -0
  121. package/dist/application/task-usage.d.ts +1 -1
  122. package/dist/application/task-usage.js.map +1 -1
  123. package/dist/application/tasks.js +1 -1
  124. package/dist/application/tasks.js.map +1 -1
  125. package/dist/application/tasks.types.d.ts +4 -3
  126. package/dist/application/tasks.types.js.map +1 -1
  127. package/dist/application/workspace-allocation.d.ts +3 -0
  128. package/dist/application/workspace-allocation.js +34 -0
  129. package/dist/application/workspace-allocation.js.map +1 -0
  130. package/dist/application/workspace.js +2 -2
  131. package/dist/application/workspace.js.map +1 -1
  132. package/dist/cli/doctor-command.js +1 -1
  133. package/dist/cli/doctor-command.js.map +1 -1
  134. package/dist/cli/main.constants.d.ts +11 -2
  135. package/dist/cli/main.constants.js +8 -4
  136. package/dist/cli/main.constants.js.map +1 -1
  137. package/dist/cli/recovery-command.js +28 -4
  138. package/dist/cli/recovery-command.js.map +1 -1
  139. package/dist/cli/recovery-restore-command.d.ts +2 -0
  140. package/dist/cli/recovery-restore-command.js +34 -0
  141. package/dist/cli/recovery-restore-command.js.map +1 -0
  142. package/dist/cli/scaffold-files.js +2 -2
  143. package/dist/cli/scaffold-files.js.map +1 -1
  144. package/dist/cli/scaffold-validation.js +1 -1
  145. package/dist/cli/scaffold-validation.js.map +1 -1
  146. package/dist/cli/scaffold.constants.d.ts +5 -0
  147. package/dist/cli/scaffold.constants.js +7 -2
  148. package/dist/cli/scaffold.constants.js.map +1 -1
  149. package/dist/cli/scaffold.types.d.ts +1 -1
  150. package/dist/cli/scaffold.types.js.map +1 -1
  151. package/dist/domain/agent.types.d.ts +2 -0
  152. package/dist/domain/agent.types.js.map +1 -1
  153. package/dist/domain/artifact-reference.d.ts +4 -0
  154. package/dist/domain/artifact-reference.js +90 -0
  155. package/dist/domain/artifact-reference.js.map +1 -0
  156. package/dist/domain/artifact.constants.d.ts +2 -0
  157. package/dist/domain/artifact.constants.js +3 -0
  158. package/dist/domain/artifact.constants.js.map +1 -0
  159. package/dist/domain/artifact.d.ts +7 -0
  160. package/dist/domain/artifact.js +104 -0
  161. package/dist/domain/artifact.js.map +1 -0
  162. package/dist/domain/artifact.types.d.ts +44 -0
  163. package/dist/domain/artifact.types.js +2 -0
  164. package/dist/domain/artifact.types.js.map +1 -0
  165. package/dist/domain/egress.constants.d.ts +1 -0
  166. package/dist/domain/egress.constants.js +7 -0
  167. package/dist/domain/egress.constants.js.map +1 -0
  168. package/dist/domain/egress.d.ts +2 -0
  169. package/dist/domain/egress.js +48 -0
  170. package/dist/domain/egress.js.map +1 -0
  171. package/dist/domain/egress.types.d.ts +8 -0
  172. package/dist/domain/egress.types.js +2 -0
  173. package/dist/domain/egress.types.js.map +1 -0
  174. package/dist/domain/sandbox.types.d.ts +1 -0
  175. package/dist/domain/sandbox.types.js.map +1 -1
  176. package/dist/domain/task-queue.constants.d.ts +8 -0
  177. package/dist/domain/task-queue.constants.js +9 -0
  178. package/dist/domain/task-queue.constants.js.map +1 -0
  179. package/dist/domain/task-queue.d.ts +11 -0
  180. package/dist/domain/task-queue.js +105 -0
  181. package/dist/domain/task-queue.js.map +1 -0
  182. package/dist/domain/task-queue.types.d.ts +41 -0
  183. package/dist/domain/task-queue.types.js +2 -0
  184. package/dist/domain/task-queue.types.js.map +1 -0
  185. package/dist/domain/workflow/budget.d.ts +2 -2
  186. package/dist/domain/workflow/budget.js +5 -3
  187. package/dist/domain/workflow/budget.js.map +1 -1
  188. package/dist/domain/workflow/checkpoint-validation.d.ts +3 -0
  189. package/dist/domain/workflow/checkpoint-validation.js +81 -0
  190. package/dist/domain/workflow/checkpoint-validation.js.map +1 -0
  191. package/dist/domain/workflow/checkpoint-value.d.ts +2 -0
  192. package/dist/domain/workflow/checkpoint-value.js +49 -0
  193. package/dist/domain/workflow/checkpoint-value.js.map +1 -0
  194. package/dist/domain/workflow/checkpoint.d.ts +3 -0
  195. package/dist/domain/workflow/checkpoint.js +70 -0
  196. package/dist/domain/workflow/checkpoint.js.map +1 -0
  197. package/dist/domain/workflow/checkpoint.types.d.ts +40 -0
  198. package/dist/domain/workflow/checkpoint.types.js +2 -0
  199. package/dist/domain/workflow/checkpoint.types.js.map +1 -0
  200. package/dist/domain/workflow/gate-validation.d.ts +4 -0
  201. package/dist/domain/workflow/gate-validation.js +71 -0
  202. package/dist/domain/workflow/gate-validation.js.map +1 -0
  203. package/dist/domain/workflow/gates.constants.d.ts +4 -0
  204. package/dist/domain/workflow/gates.constants.js +5 -0
  205. package/dist/domain/workflow/gates.constants.js.map +1 -0
  206. package/dist/domain/workflow/gates.d.ts +7 -0
  207. package/dist/domain/workflow/gates.js +85 -0
  208. package/dist/domain/workflow/gates.js.map +1 -0
  209. package/dist/domain/workflow/gates.types.d.ts +27 -0
  210. package/dist/domain/workflow/gates.types.js +2 -0
  211. package/dist/domain/workflow/gates.types.js.map +1 -0
  212. package/dist/domain/workflow/task-runner.js +14 -2
  213. package/dist/domain/workflow/task-runner.js.map +1 -1
  214. package/dist/domain/workflow/usage-receipt.constants.d.ts +2 -0
  215. package/dist/domain/workflow/usage-receipt.constants.js +3 -0
  216. package/dist/domain/workflow/usage-receipt.constants.js.map +1 -0
  217. package/dist/domain/workflow/usage-receipt.d.ts +2 -0
  218. package/dist/domain/workflow/usage-receipt.js +18 -0
  219. package/dist/domain/workflow/usage-receipt.js.map +1 -0
  220. package/dist/domain/workflow/validation.js +6 -0
  221. package/dist/domain/workflow/validation.js.map +1 -1
  222. package/dist/domain/workflow/workflow-scheduler.js +65 -32
  223. package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
  224. package/dist/domain/workflow/workflow-state.d.ts +2 -1
  225. package/dist/domain/workflow/workflow-state.js +91 -16
  226. package/dist/domain/workflow/workflow-state.js.map +1 -1
  227. package/dist/domain/workflow.types.d.ts +13 -2
  228. package/dist/domain/workflow.types.js.map +1 -1
  229. package/dist/index.d.ts +32 -2
  230. package/dist/index.js +14 -1
  231. package/dist/index.js.map +1 -1
  232. package/dist/infrastructure/artifact-store.constants.d.ts +1 -0
  233. package/dist/infrastructure/artifact-store.constants.js +2 -0
  234. package/dist/infrastructure/artifact-store.constants.js.map +1 -0
  235. package/dist/infrastructure/artifact-store.d.ts +3 -0
  236. package/dist/infrastructure/artifact-store.js +100 -0
  237. package/dist/infrastructure/artifact-store.js.map +1 -0
  238. package/dist/infrastructure/artifact-store.types.d.ts +4 -0
  239. package/dist/infrastructure/artifact-store.types.js +2 -0
  240. package/dist/infrastructure/artifact-store.types.js.map +1 -0
  241. package/dist/infrastructure/file-manifest.d.ts +1 -1
  242. package/dist/infrastructure/file-manifest.js +3 -2
  243. package/dist/infrastructure/file-manifest.js.map +1 -1
  244. package/dist/infrastructure/git/verification-command.d.ts +1 -1
  245. package/dist/infrastructure/git/verification-command.js +3 -2
  246. package/dist/infrastructure/git/verification-command.js.map +1 -1
  247. package/dist/infrastructure/opentelemetry.js +1 -1
  248. package/dist/infrastructure/opentelemetry.js.map +1 -1
  249. package/dist/infrastructure/resource-activity-inspection.d.ts +2 -0
  250. package/dist/infrastructure/resource-activity-inspection.js +152 -0
  251. package/dist/infrastructure/resource-activity-inspection.js.map +1 -0
  252. package/dist/infrastructure/resource-activity.constants.d.ts +8 -0
  253. package/dist/infrastructure/resource-activity.constants.js +26 -0
  254. package/dist/infrastructure/resource-activity.constants.js.map +1 -0
  255. package/dist/infrastructure/resource-activity.d.ts +2 -0
  256. package/dist/infrastructure/resource-activity.js +166 -0
  257. package/dist/infrastructure/resource-activity.js.map +1 -0
  258. package/dist/infrastructure/resource-activity.types.d.ts +53 -0
  259. package/dist/infrastructure/resource-activity.types.js +2 -0
  260. package/dist/infrastructure/resource-activity.types.js.map +1 -0
  261. package/dist/infrastructure/storage-mutation-lock.constants.d.ts +5 -0
  262. package/dist/infrastructure/storage-mutation-lock.constants.js +6 -0
  263. package/dist/infrastructure/storage-mutation-lock.constants.js.map +1 -0
  264. package/dist/infrastructure/storage-mutation-lock.d.ts +1 -0
  265. package/dist/infrastructure/storage-mutation-lock.js +21 -0
  266. package/dist/infrastructure/storage-mutation-lock.js.map +1 -0
  267. package/dist/infrastructure/storage-reservations.constants.d.ts +4 -0
  268. package/dist/infrastructure/storage-reservations.constants.js +5 -0
  269. package/dist/infrastructure/storage-reservations.constants.js.map +1 -0
  270. package/dist/infrastructure/storage-reservations.d.ts +2 -0
  271. package/dist/infrastructure/storage-reservations.js +150 -0
  272. package/dist/infrastructure/storage-reservations.js.map +1 -0
  273. package/dist/infrastructure/storage-reservations.types.d.ts +21 -0
  274. package/dist/infrastructure/storage-reservations.types.js +2 -0
  275. package/dist/infrastructure/storage-reservations.types.js.map +1 -0
  276. package/dist/infrastructure/task-queue-http.constants.d.ts +2 -0
  277. package/dist/infrastructure/task-queue-http.constants.js +3 -0
  278. package/dist/infrastructure/task-queue-http.constants.js.map +1 -0
  279. package/dist/infrastructure/task-queue-http.d.ts +4 -0
  280. package/dist/infrastructure/task-queue-http.js +158 -0
  281. package/dist/infrastructure/task-queue-http.js.map +1 -0
  282. package/dist/infrastructure/task-queue-http.types.d.ts +16 -0
  283. package/dist/infrastructure/task-queue-http.types.js +2 -0
  284. package/dist/infrastructure/task-queue-http.types.js.map +1 -0
  285. package/dist/infrastructure/task-queue.d.ts +2 -0
  286. package/dist/infrastructure/task-queue.js +134 -0
  287. package/dist/infrastructure/task-queue.js.map +1 -0
  288. package/dist/infrastructure/transfer.js +5 -0
  289. package/dist/infrastructure/transfer.js.map +1 -1
  290. package/dist/infrastructure/workflow-checkpoint.constants.d.ts +1 -0
  291. package/dist/infrastructure/workflow-checkpoint.constants.js +2 -0
  292. package/dist/infrastructure/workflow-checkpoint.constants.js.map +1 -0
  293. package/dist/infrastructure/workflow-checkpoint.d.ts +3 -0
  294. package/dist/infrastructure/workflow-checkpoint.js +77 -0
  295. package/dist/infrastructure/workflow-checkpoint.js.map +1 -0
  296. package/dist/infrastructure/workflow-checkpoint.types.d.ts +4 -0
  297. package/dist/infrastructure/workflow-checkpoint.types.js +2 -0
  298. package/dist/infrastructure/workflow-checkpoint.types.js.map +1 -0
  299. package/dist/providers/agents.d.ts +2 -0
  300. package/dist/providers/agents.js +1 -0
  301. package/dist/providers/agents.js.map +1 -1
  302. package/dist/providers/container-isolation.d.ts +2 -0
  303. package/dist/providers/container-isolation.js +29 -0
  304. package/dist/providers/container-isolation.js.map +1 -0
  305. package/dist/providers/container-mounts.js +7 -2
  306. package/dist/providers/container-mounts.js.map +1 -1
  307. package/dist/providers/container-network.d.ts +2 -0
  308. package/dist/providers/container-network.js +14 -0
  309. package/dist/providers/container-network.js.map +1 -0
  310. package/dist/providers/container-plan.js +4 -2
  311. package/dist/providers/container-plan.js.map +1 -1
  312. package/dist/providers/container.constants.d.ts +1 -0
  313. package/dist/providers/container.constants.js +1 -0
  314. package/dist/providers/container.constants.js.map +1 -1
  315. package/dist/providers/container.js +19 -2
  316. package/dist/providers/container.js.map +1 -1
  317. package/dist/providers/container.types.d.ts +3 -0
  318. package/dist/providers/container.types.js.map +1 -1
  319. package/dist/providers/daytona-command.js +3 -2
  320. package/dist/providers/daytona-command.js.map +1 -1
  321. package/dist/providers/daytona-terminal.d.ts +3 -0
  322. package/dist/providers/daytona-terminal.js +128 -0
  323. package/dist/providers/daytona-terminal.js.map +1 -0
  324. package/dist/providers/daytona.js +2 -0
  325. package/dist/providers/daytona.js.map +1 -1
  326. package/dist/providers/docker.d.ts +1 -0
  327. package/dist/providers/docker.js.map +1 -1
  328. package/dist/providers/file-batches.d.ts +1 -1
  329. package/dist/providers/file-batches.js +9 -0
  330. package/dist/providers/file-batches.js.map +1 -1
  331. package/dist/providers/file-upload.constants.d.ts +1 -0
  332. package/dist/providers/file-upload.constants.js +68 -0
  333. package/dist/providers/file-upload.constants.js.map +1 -0
  334. package/dist/providers/file-upload.d.ts +2 -0
  335. package/dist/providers/file-upload.js +146 -0
  336. package/dist/providers/file-upload.js.map +1 -0
  337. package/dist/providers/firecracker-command.d.ts +5 -0
  338. package/dist/providers/firecracker-command.js +114 -0
  339. package/dist/providers/firecracker-command.js.map +1 -0
  340. package/dist/providers/firecracker-files.constants.d.ts +1 -0
  341. package/dist/providers/firecracker-files.constants.js +21 -0
  342. package/dist/providers/firecracker-files.constants.js.map +1 -0
  343. package/dist/providers/firecracker-files.d.ts +3 -0
  344. package/dist/providers/firecracker-files.js +110 -0
  345. package/dist/providers/firecracker-files.js.map +1 -0
  346. package/dist/providers/firecracker-machine.d.ts +3 -0
  347. package/dist/providers/firecracker-machine.js +155 -0
  348. package/dist/providers/firecracker-machine.js.map +1 -0
  349. package/dist/providers/firecracker.constants.d.ts +10 -0
  350. package/dist/providers/firecracker.constants.js +11 -0
  351. package/dist/providers/firecracker.constants.js.map +1 -0
  352. package/dist/providers/firecracker.d.ts +4 -0
  353. package/dist/providers/firecracker.js +103 -0
  354. package/dist/providers/firecracker.js.map +1 -0
  355. package/dist/providers/firecracker.types.d.ts +36 -0
  356. package/dist/providers/firecracker.types.js +2 -0
  357. package/dist/providers/firecracker.types.js.map +1 -0
  358. package/dist/providers/local.js +2 -1
  359. package/dist/providers/local.js.map +1 -1
  360. package/dist/providers/podman.d.ts +1 -0
  361. package/dist/providers/podman.js.map +1 -1
  362. package/dist/providers/terminal-bridge.d.ts +14 -0
  363. package/dist/providers/terminal-bridge.js +100 -0
  364. package/dist/providers/terminal-bridge.js.map +1 -0
  365. package/dist/providers/vercel-directory.d.ts +2 -0
  366. package/dist/providers/vercel-directory.js +7 -0
  367. package/dist/providers/vercel-directory.js.map +1 -0
  368. package/dist/providers/vercel-files.js +3 -2
  369. package/dist/providers/vercel-files.js.map +1 -1
  370. package/dist/providers/vercel-network.d.ts +2 -0
  371. package/dist/providers/vercel-network.js +18 -0
  372. package/dist/providers/vercel-network.js.map +1 -0
  373. package/dist/providers/vercel.d.ts +1 -0
  374. package/dist/providers/vercel.js +5 -1
  375. package/dist/providers/vercel.js.map +1 -1
  376. package/dist/providers/vercel.types.d.ts +2 -0
  377. package/dist/providers/vercel.types.js.map +1 -1
  378. package/dist/providers/versions.constants.d.ts +1 -0
  379. package/dist/providers/versions.constants.js +1 -0
  380. package/dist/providers/versions.constants.js.map +1 -1
  381. package/package.json +5 -1
@@ -0,0 +1,41 @@
1
+ import type { Usage } from "./agent.types.ts";
2
+ import type { WorkflowJson } from "./workflow/checkpoint.types.ts";
3
+ export interface QueueRequest {
4
+ readonly id: string;
5
+ readonly handler: string;
6
+ readonly input: WorkflowJson;
7
+ readonly deadline?: number;
8
+ }
9
+ export interface QueueResult {
10
+ readonly value: WorkflowJson;
11
+ readonly usage?: Usage;
12
+ readonly error?: string;
13
+ }
14
+ export interface QueueJob extends QueueRequest {
15
+ readonly status: "pending" | "active" | "done" | "failed" | "cancelled";
16
+ readonly fence: number;
17
+ readonly worker?: string;
18
+ readonly expires?: number;
19
+ readonly result?: QueueResult;
20
+ }
21
+ export interface QueueClaim {
22
+ readonly worker: string;
23
+ readonly handlers: readonly string[];
24
+ readonly leaseMs: number;
25
+ }
26
+ export interface QueueLease {
27
+ readonly id: string;
28
+ readonly worker: string;
29
+ readonly fence: number;
30
+ }
31
+ export interface TaskQueue {
32
+ enqueue(request: QueueRequest): Promise<QueueJob>;
33
+ get(id: string): Promise<QueueJob | undefined>;
34
+ claim(request: QueueClaim): Promise<QueueJob | undefined>;
35
+ renew(lease: QueueLease, leaseMs: number): Promise<QueueJob>;
36
+ complete(lease: QueueLease, result: QueueResult): Promise<QueueJob>;
37
+ cancel(id: string, fence: number): Promise<QueueJob>;
38
+ }
39
+ export interface DurableTaskQueue extends TaskQueue {
40
+ close(): void;
41
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=task-queue.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-queue.types.js","sourceRoot":"","sources":["../../src/domain/task-queue.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Usage } from \"./agent.types.ts\";\nimport type { WorkflowJson } from \"./workflow/checkpoint.types.ts\";\n\nexport interface QueueRequest {\n readonly id: string;\n readonly handler: string;\n readonly input: WorkflowJson;\n readonly deadline?: number;\n}\nexport interface QueueResult {\n readonly value: WorkflowJson;\n readonly usage?: Usage;\n readonly error?: string;\n}\nexport interface QueueJob extends QueueRequest {\n readonly status: \"pending\" | \"active\" | \"done\" | \"failed\" | \"cancelled\";\n readonly fence: number;\n readonly worker?: string;\n readonly expires?: number;\n readonly result?: QueueResult;\n}\nexport interface QueueClaim {\n readonly worker: string;\n readonly handlers: readonly string[];\n readonly leaseMs: number;\n}\nexport interface QueueLease {\n readonly id: string;\n readonly worker: string;\n readonly fence: number;\n}\nexport interface TaskQueue {\n enqueue(request: QueueRequest): Promise<QueueJob>;\n get(id: string): Promise<QueueJob | undefined>;\n claim(request: QueueClaim): Promise<QueueJob | undefined>;\n renew(lease: QueueLease, leaseMs: number): Promise<QueueJob>;\n complete(lease: QueueLease, result: QueueResult): Promise<QueueJob>;\n cancel(id: string, fence: number): Promise<QueueJob>;\n}\nexport interface DurableTaskQueue extends TaskQueue {\n close(): void;\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  import type { Usage } from "../agent.types.ts";
2
- import type { WorkflowAccounting, WorkflowBudget } from "./budget.types.ts";
2
+ import type { WorkflowAccounting, WorkflowBudget, WorkflowUsage } from "./budget.types.ts";
3
3
  export declare class WorkflowBudgetExceeded extends Error {
4
4
  readonly dimension: "attempts" | keyof Usage;
5
5
  readonly limit: number;
6
6
  readonly observed: number;
7
7
  constructor(dimension: "attempts" | keyof Usage, limit: number, observed: number);
8
8
  }
9
- export declare function workflowAccounting(budget: WorkflowBudget | undefined, exhaust: (error: WorkflowBudgetExceeded) => void): WorkflowAccounting;
9
+ export declare function workflowAccounting(budget: WorkflowBudget | undefined, exhaust: (error: WorkflowBudgetExceeded) => void, initial?: WorkflowUsage): WorkflowAccounting;
@@ -12,7 +12,7 @@ export class WorkflowBudgetExceeded extends Error {
12
12
  this.observed = observed;
13
13
  }
14
14
  }
15
- export function workflowAccounting(budget, exhaust) {
15
+ export function workflowAccounting(budget, exhaust, initial) {
16
16
  for (const [key, value] of Object.entries({
17
17
  attempts: budget?.attempts,
18
18
  ...budget?.usage,
@@ -20,8 +20,10 @@ export function workflowAccounting(budget, exhaust) {
20
20
  if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))
21
21
  throw new Error(`Workflow budget ${key} must be a nonnegative safe integer`);
22
22
  }
23
- let attempts = 0;
24
- let tokens = { input: 0, cached: 0, output: 0 };
23
+ let attempts = initial?.attempts ?? 0;
24
+ let tokens = initial
25
+ ? { ...initial.tokens }
26
+ : { input: 0, cached: 0, output: 0 };
25
27
  let exhausted = false;
26
28
  let usageExhausted = false;
27
29
  function fail(dimension, limit, observed) {
@@ -1 +1 @@
1
- {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/domain/workflow/budget.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"../agent.types.ts\";\nimport { addUsage } from \"../usage.ts\";\nimport { usageDimensions } from \"./budget.constants.ts\";\nimport type { WorkflowAccounting, WorkflowBudget } from \"./budget.types.ts\";\n\nexport class WorkflowBudgetExceeded extends Error {\n readonly dimension: \"attempts\" | keyof Usage;\n readonly limit: number;\n readonly observed: number;\n constructor(\n dimension: \"attempts\" | keyof Usage,\n limit: number,\n observed: number,\n ) {\n super(\n `Workflow budget exhausted: ${dimension} limit ${limit}, observed ${observed}`,\n );\n this.name = \"WorkflowBudgetExceeded\";\n this.dimension = dimension;\n this.limit = limit;\n this.observed = observed;\n }\n}\n\nexport function workflowAccounting(\n budget: WorkflowBudget | undefined,\n exhaust: (error: WorkflowBudgetExceeded) => void,\n): WorkflowAccounting {\n for (const [key, value] of Object.entries({\n attempts: budget?.attempts,\n ...budget?.usage,\n })) {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))\n throw new Error(\n `Workflow budget ${key} must be a nonnegative safe integer`,\n );\n }\n let attempts = 0;\n let tokens: Usage = { input: 0, cached: 0, output: 0 };\n let exhausted = false;\n let usageExhausted = false;\n function fail(\n dimension: \"attempts\" | keyof Usage,\n limit: number,\n observed: number,\n ): WorkflowBudgetExceeded {\n const error = new WorkflowBudgetExceeded(dimension, limit, observed);\n if (!exhausted || (dimension !== \"attempts\" && !usageExhausted)) {\n exhausted = true;\n if (dimension !== \"attempts\") usageExhausted = true;\n exhaust(error);\n }\n return error;\n }\n return {\n get exhausted() {\n return exhausted;\n },\n admit() {\n if (budget?.attempts !== undefined && attempts >= budget.attempts)\n throw fail(\"attempts\", budget.attempts, attempts);\n for (const dimension of usageDimensions) {\n const limit = budget?.usage?.[dimension];\n if (limit !== undefined && (tokens[dimension] ?? 0) >= limit)\n throw fail(dimension, limit, tokens[dimension] ?? 0);\n }\n attempts++;\n },\n report(usage) {\n for (const dimension of usageDimensions) {\n const value = usage[dimension] ?? 0;\n if (!Number.isSafeInteger(value) || value < 0)\n throw new Error(\n `Reported usage ${dimension} must be a nonnegative safe integer`,\n );\n }\n tokens = addUsage(tokens, usage);\n for (const dimension of usageDimensions) {\n const limit = budget?.usage?.[dimension];\n if (limit !== undefined && (tokens[dimension] ?? 0) >= limit)\n fail(dimension, limit, tokens[dimension] ?? 0);\n }\n },\n snapshot: () =>\n Object.freeze({ attempts, tokens: Object.freeze({ ...tokens }) }),\n };\n}\n"]}
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/domain/workflow/budget.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"../agent.types.ts\";\nimport { addUsage } from \"../usage.ts\";\nimport { usageDimensions } from \"./budget.constants.ts\";\nimport type {\n WorkflowAccounting,\n WorkflowBudget,\n WorkflowUsage,\n} from \"./budget.types.ts\";\n\nexport class WorkflowBudgetExceeded extends Error {\n readonly dimension: \"attempts\" | keyof Usage;\n readonly limit: number;\n readonly observed: number;\n constructor(\n dimension: \"attempts\" | keyof Usage,\n limit: number,\n observed: number,\n ) {\n super(\n `Workflow budget exhausted: ${dimension} limit ${limit}, observed ${observed}`,\n );\n this.name = \"WorkflowBudgetExceeded\";\n this.dimension = dimension;\n this.limit = limit;\n this.observed = observed;\n }\n}\n\nexport function workflowAccounting(\n budget: WorkflowBudget | undefined,\n exhaust: (error: WorkflowBudgetExceeded) => void,\n initial?: WorkflowUsage,\n): WorkflowAccounting {\n for (const [key, value] of Object.entries({\n attempts: budget?.attempts,\n ...budget?.usage,\n })) {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))\n throw new Error(\n `Workflow budget ${key} must be a nonnegative safe integer`,\n );\n }\n let attempts = initial?.attempts ?? 0;\n let tokens: Usage = initial\n ? { ...initial.tokens }\n : { input: 0, cached: 0, output: 0 };\n let exhausted = false;\n let usageExhausted = false;\n function fail(\n dimension: \"attempts\" | keyof Usage,\n limit: number,\n observed: number,\n ): WorkflowBudgetExceeded {\n const error = new WorkflowBudgetExceeded(dimension, limit, observed);\n if (!exhausted || (dimension !== \"attempts\" && !usageExhausted)) {\n exhausted = true;\n if (dimension !== \"attempts\") usageExhausted = true;\n exhaust(error);\n }\n return error;\n }\n return {\n get exhausted() {\n return exhausted;\n },\n admit() {\n if (budget?.attempts !== undefined && attempts >= budget.attempts)\n throw fail(\"attempts\", budget.attempts, attempts);\n for (const dimension of usageDimensions) {\n const limit = budget?.usage?.[dimension];\n if (limit !== undefined && (tokens[dimension] ?? 0) >= limit)\n throw fail(dimension, limit, tokens[dimension] ?? 0);\n }\n attempts++;\n },\n report(usage) {\n for (const dimension of usageDimensions) {\n const value = usage[dimension] ?? 0;\n if (!Number.isSafeInteger(value) || value < 0)\n throw new Error(\n `Reported usage ${dimension} must be a nonnegative safe integer`,\n );\n }\n tokens = addUsage(tokens, usage);\n for (const dimension of usageDimensions) {\n const limit = budget?.usage?.[dimension];\n if (limit !== undefined && (tokens[dimension] ?? 0) >= limit)\n fail(dimension, limit, tokens[dimension] ?? 0);\n }\n },\n snapshot: () =>\n Object.freeze({ attempts, tokens: Object.freeze({ ...tokens }) }),\n };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { WorkflowCheckpoint } from "./checkpoint.types.ts";
2
+ import type { Task } from "../workflow.types.ts";
3
+ export declare function validateCheckpoint(value: unknown, identity: string, tasks: readonly Task[]): asserts value is WorkflowCheckpoint;
@@ -0,0 +1,81 @@
1
+ import { validateUsageReceipts } from "./usage-receipt.js";
2
+ import { validateGateRecord } from "./gate-validation.js";
3
+ import { checkpointValue } from "./checkpoint-value.js";
4
+ function object(value) {
5
+ return value !== null && typeof value === "object" && !Array.isArray(value);
6
+ }
7
+ function integer(value) {
8
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
9
+ }
10
+ export function validateCheckpoint(value, identity, tasks) {
11
+ const invalid = () => new Error("Invalid or incompatible workflow checkpoint");
12
+ if (!object(value) ||
13
+ value.format !== 1 ||
14
+ value.identity !== identity ||
15
+ typeof value.executionId !== "string" ||
16
+ !value.executionId ||
17
+ !Array.isArray(value.records) ||
18
+ !object(value.values) ||
19
+ !object(value.usage))
20
+ throw invalid();
21
+ if (!integer(value.usage.attempts) || !object(value.usage.tokens))
22
+ throw invalid();
23
+ for (const dimension of ["input", "cached", "output"])
24
+ if (!integer(value.usage.tokens[dimension]))
25
+ throw invalid();
26
+ for (const count of Object.values(value.usage.tokens))
27
+ if (!integer(count))
28
+ throw invalid();
29
+ if (value.records.length !== tasks.length)
30
+ throw invalid();
31
+ const keys = new Set(tasks.map((item) => item.key));
32
+ let attempts = 0;
33
+ for (const record of value.records) {
34
+ if (!object(record) ||
35
+ typeof record.key !== "string" ||
36
+ !keys.delete(record.key) ||
37
+ !integer(record.attempts) ||
38
+ ![
39
+ "waiting",
40
+ "active",
41
+ "done",
42
+ "failed",
43
+ "skipped",
44
+ "cancelled",
45
+ "paused",
46
+ "rejected",
47
+ ].includes(String(record.status)))
48
+ throw invalid();
49
+ for (const field of ["startedAt", "finishedAt", "error"])
50
+ if (record[field] !== undefined && typeof record[field] !== "string")
51
+ throw invalid();
52
+ validateUsageReceipts(record.usageReceipts);
53
+ attempts += record.attempts;
54
+ const output = Object.hasOwn(value.values, record.key)
55
+ ? value.values[record.key]
56
+ : undefined;
57
+ validateGateRecord(record, tasks.find((item) => item.key === record.key), value.executionId, output);
58
+ if (record.status !== "done") {
59
+ if (output !== undefined)
60
+ throw invalid();
61
+ continue;
62
+ }
63
+ if (!object(output) || !["undefined", "json"].includes(String(output.kind)))
64
+ throw invalid();
65
+ if (output.kind === "json") {
66
+ if (!Object.hasOwn(output, "value") || output.value === undefined)
67
+ throw invalid();
68
+ checkpointValue(output.value);
69
+ }
70
+ }
71
+ if (attempts !== value.usage.attempts)
72
+ throw invalid();
73
+ if (Object.keys(value.values).some((key) => !tasks.some((item) => item.key === key)))
74
+ throw invalid();
75
+ const records = new Map(value.records.map((entry) => [entry.key, entry]));
76
+ for (const item of tasks)
77
+ if (["done", "paused", "rejected"].includes(String(records.get(item.key)?.status)) &&
78
+ item.after.some((dependency) => records.get(dependency.key)?.status !== "done"))
79
+ throw invalid();
80
+ }
81
+ //# sourceMappingURL=checkpoint-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-validation.js","sourceRoot":"","sources":["../../../src/domain/workflow/checkpoint-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AACD,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,KAAc,EACd,QAAgB,EAChB,KAAsB;IAEtB,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC3D,IACE,CAAC,MAAM,CAAC,KAAK,CAAC;QACd,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAC3B,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;QACrC,CAAC,KAAK,CAAC,WAAW;QAClB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAC7B,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QACrB,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;QAEpB,MAAM,OAAO,EAAE,CAAC;IAClB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAC/D,MAAM,OAAO,EAAE,CAAC;IAClB,KAAK,MAAM,SAAS,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAAE,MAAM,OAAO,EAAE,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,MAAM,OAAO,EAAE,CAAC;IACvC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAAE,MAAM,OAAO,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,IACE,CAAC,MAAM,CAAC,MAAM,CAAC;YACf,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;YAC9B,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;YACxB,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;YACzB,CAAC;gBACC,SAAS;gBACT,QAAQ;gBACR,MAAM;gBACN,QAAQ;gBACR,SAAS;gBACT,WAAW;gBACX,QAAQ;gBACR,UAAU;aACX,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEjC,MAAM,OAAO,EAAE,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC;YACtD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ;gBAClE,MAAM,OAAO,EAAE,CAAC;QACpB,qBAAqB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC5C,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;YACpD,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;YAC1B,CAAC,CAAC,SAAS,CAAC;QACd,kBAAkB,CAChB,MAAM,EACN,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAE,EAC9C,KAAK,CAAC,WAAW,EACjB,MAAM,CACP,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,OAAO,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACzE,MAAM,OAAO,EAAE,CAAC;QAClB,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;gBAC/D,MAAM,OAAO,EAAE,CAAC;YAClB,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,QAAQ;QAAE,MAAM,OAAO,EAAE,CAAC;IACvD,IACE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAC5B,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CACjD;QAED,MAAM,OAAO,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1E,KAAK,MAAM,IAAI,IAAI,KAAK;QACtB,IACE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,QAAQ,CACrC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CACtC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CACb,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,MAAM,CAC/D;YAED,MAAM,OAAO,EAAE,CAAC;AACtB,CAAC","sourcesContent":["import { validateUsageReceipts } from \"./usage-receipt.ts\";\nimport { validateGateRecord } from \"./gate-validation.ts\";\nimport type { WorkflowCheckpoint } from \"./checkpoint.types.ts\";\nimport type { Task } from \"../workflow.types.ts\";\nimport { checkpointValue } from \"./checkpoint-value.ts\";\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction integer(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nexport function validateCheckpoint(\n value: unknown,\n identity: string,\n tasks: readonly Task[],\n): asserts value is WorkflowCheckpoint {\n const invalid = () =>\n new Error(\"Invalid or incompatible workflow checkpoint\");\n if (\n !object(value) ||\n value.format !== 1 ||\n value.identity !== identity ||\n typeof value.executionId !== \"string\" ||\n !value.executionId ||\n !Array.isArray(value.records) ||\n !object(value.values) ||\n !object(value.usage)\n )\n throw invalid();\n if (!integer(value.usage.attempts) || !object(value.usage.tokens))\n throw invalid();\n for (const dimension of [\"input\", \"cached\", \"output\"])\n if (!integer(value.usage.tokens[dimension])) throw invalid();\n for (const count of Object.values(value.usage.tokens))\n if (!integer(count)) throw invalid();\n if (value.records.length !== tasks.length) throw invalid();\n const keys = new Set(tasks.map((item) => item.key));\n let attempts = 0;\n for (const record of value.records) {\n if (\n !object(record) ||\n typeof record.key !== \"string\" ||\n !keys.delete(record.key) ||\n !integer(record.attempts) ||\n ![\n \"waiting\",\n \"active\",\n \"done\",\n \"failed\",\n \"skipped\",\n \"cancelled\",\n \"paused\",\n \"rejected\",\n ].includes(String(record.status))\n )\n throw invalid();\n for (const field of [\"startedAt\", \"finishedAt\", \"error\"])\n if (record[field] !== undefined && typeof record[field] !== \"string\")\n throw invalid();\n validateUsageReceipts(record.usageReceipts);\n attempts += record.attempts;\n const output = Object.hasOwn(value.values, record.key)\n ? value.values[record.key]\n : undefined;\n validateGateRecord(\n record,\n tasks.find((item) => item.key === record.key)!,\n value.executionId,\n output,\n );\n if (record.status !== \"done\") {\n if (output !== undefined) throw invalid();\n continue;\n }\n if (!object(output) || ![\"undefined\", \"json\"].includes(String(output.kind)))\n throw invalid();\n if (output.kind === \"json\") {\n if (!Object.hasOwn(output, \"value\") || output.value === undefined)\n throw invalid();\n checkpointValue(output.value);\n }\n }\n if (attempts !== value.usage.attempts) throw invalid();\n if (\n Object.keys(value.values).some(\n (key) => !tasks.some((item) => item.key === key),\n )\n )\n throw invalid();\n const records = new Map(value.records.map((entry) => [entry.key, entry]));\n for (const item of tasks)\n if (\n [\"done\", \"paused\", \"rejected\"].includes(\n String(records.get(item.key)?.status),\n ) &&\n item.after.some(\n (dependency) => records.get(dependency.key)?.status !== \"done\",\n )\n )\n throw invalid();\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { WorkflowCheckpointValue } from "./checkpoint.types.ts";
2
+ export declare function checkpointValue(value: unknown): WorkflowCheckpointValue;
@@ -0,0 +1,49 @@
1
+ export function checkpointValue(value) {
2
+ if (value === undefined)
3
+ return { kind: "undefined" };
4
+ return { kind: "json", value: jsonValue(value, new Set()) };
5
+ }
6
+ function jsonValue(value, ancestors) {
7
+ if (value === null || typeof value === "boolean" || typeof value === "string")
8
+ return value;
9
+ if (typeof value === "number" &&
10
+ Number.isFinite(value) &&
11
+ !Object.is(value, -0))
12
+ return value;
13
+ if (typeof value !== "object" || value === null || ancestors.has(value))
14
+ throw new Error("Checkpoint outputs must be lossless JSON values or top-level undefined");
15
+ const prototype = Object.getPrototypeOf(value);
16
+ if (!Array.isArray(value) &&
17
+ prototype !== Object.prototype &&
18
+ prototype !== null)
19
+ throw new Error("Checkpoint outputs must contain plain JSON objects");
20
+ ancestors.add(value);
21
+ try {
22
+ if (Array.isArray(value)) {
23
+ if (prototype !== Array.prototype)
24
+ throw new Error("Checkpoint arrays must have the standard prototype");
25
+ if (Reflect.ownKeys(value).length !== value.length + 1)
26
+ throw new Error("Checkpoint arrays must be dense and have no extra properties");
27
+ return Array.from({ length: value.length }, (_, index) => {
28
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
29
+ if (!descriptor || !("value" in descriptor) || !descriptor.enumerable)
30
+ throw new Error("Checkpoint arrays must have enumerable data properties");
31
+ return jsonValue(descriptor.value, ancestors);
32
+ });
33
+ }
34
+ const result = Object.create(null);
35
+ for (const key of Reflect.ownKeys(value)) {
36
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
37
+ if (typeof key !== "string" ||
38
+ !descriptor.enumerable ||
39
+ !("value" in descriptor))
40
+ throw new Error("Checkpoint objects must have enumerable string data properties");
41
+ result[key] = jsonValue(descriptor.value, ancestors);
42
+ }
43
+ return result;
44
+ }
45
+ finally {
46
+ ancestors.delete(value);
47
+ }
48
+ }
49
+ //# sourceMappingURL=checkpoint-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-value.js","sourceRoot":"","sources":["../../../src/domain/workflow/checkpoint-value.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n WorkflowCheckpointValue,\n WorkflowJson,\n} from \"./checkpoint.types.ts\";\n\nexport function checkpointValue(value: unknown): WorkflowCheckpointValue {\n if (value === undefined) return { kind: \"undefined\" };\n return { kind: \"json\", value: jsonValue(value, new Set()) };\n}\n\nfunction jsonValue(value: unknown, ancestors: Set<object>): WorkflowJson {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\")\n return value;\n if (\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n !Object.is(value, -0)\n )\n return value;\n if (typeof value !== \"object\" || value === null || ancestors.has(value))\n throw new Error(\n \"Checkpoint outputs must be lossless JSON values or top-level undefined\",\n );\n const prototype: unknown = Object.getPrototypeOf(value);\n if (\n !Array.isArray(value) &&\n prototype !== Object.prototype &&\n prototype !== null\n )\n throw new Error(\"Checkpoint outputs must contain plain JSON objects\");\n ancestors.add(value);\n try {\n if (Array.isArray(value)) {\n if (prototype !== Array.prototype)\n throw new Error(\"Checkpoint arrays must have the standard prototype\");\n if (Reflect.ownKeys(value).length !== value.length + 1)\n throw new Error(\n \"Checkpoint arrays must be dense and have no extra properties\",\n );\n return Array.from({ length: value.length }, (_, index) => {\n const descriptor = Object.getOwnPropertyDescriptor(\n value,\n String(index),\n );\n if (!descriptor || !(\"value\" in descriptor) || !descriptor.enumerable)\n throw new Error(\n \"Checkpoint arrays must have enumerable data properties\",\n );\n return jsonValue(descriptor.value, ancestors);\n });\n }\n const result: Record<string, WorkflowJson> = Object.create(null);\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key)!;\n if (\n typeof key !== \"string\" ||\n !descriptor.enumerable ||\n !(\"value\" in descriptor)\n )\n throw new Error(\n \"Checkpoint objects must have enumerable string data properties\",\n );\n result[key] = jsonValue(descriptor.value, ancestors);\n }\n return result;\n } finally {\n ancestors.delete(value);\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { Task } from "../workflow.types.ts";
2
+ import type { WorkflowCheckpointOptions, WorkflowCheckpointSession } from "./checkpoint.types.ts";
3
+ export declare function openCheckpoint(name: string, tasks: readonly Task[], options: WorkflowCheckpointOptions): Promise<WorkflowCheckpointSession>;
@@ -0,0 +1,70 @@
1
+ import { createHash } from "node:crypto";
2
+ import { checkpointValue } from "./checkpoint-value.js";
3
+ import { validateCheckpoint } from "./checkpoint-validation.js";
4
+ export async function openCheckpoint(name, tasks, options) {
5
+ if (!options.runId.trim() || !options.version.trim())
6
+ throw new Error("Checkpoint runId and version must not be empty");
7
+ const graph = tasks
8
+ .map((item) => ({
9
+ key: item.key,
10
+ ...(item.gate ? { gate: item.gate } : {}),
11
+ after: item.after.map((dependency) => dependency.key).sort(),
12
+ timeoutMs: item.timeoutMs,
13
+ retry: item.retry?.attempts,
14
+ delayMs: item.retry?.delayMs,
15
+ condition: !!item.condition,
16
+ accepts: !!item.retry?.accepts,
17
+ }))
18
+ .sort((a, b) => {
19
+ if (a.key === b.key)
20
+ return 0;
21
+ return a.key < b.key ? -1 : 1;
22
+ });
23
+ const identity = createHash("sha256")
24
+ .update(JSON.stringify({ name, version: options.version, graph }))
25
+ .digest("hex");
26
+ const lease = await options.store.acquire(options.runId);
27
+ try {
28
+ const saved = await lease.read();
29
+ let initial;
30
+ if (saved !== undefined) {
31
+ validateCheckpoint(saved, identity, tasks);
32
+ initial = saved;
33
+ const settledGate = saved.records.some((record) => ["paused", "rejected"].includes(record.status));
34
+ if (saved.records.some((record) => !["done", "skipped", "paused", "rejected"].includes(record.status) &&
35
+ !(settledGate &&
36
+ record.status === "waiting" &&
37
+ record.attempts === 0)) &&
38
+ options.resume !== "retry-incomplete")
39
+ throw new Error("Incomplete workflow checkpoint: resume retry-incomplete must explicitly authorize replay");
40
+ }
41
+ let writes = Promise.resolve();
42
+ return {
43
+ initial,
44
+ save(state) {
45
+ const snapshot = {
46
+ format: 1,
47
+ identity,
48
+ executionId: state.executionId,
49
+ records: [...state.records.values()].map((record) => ({ ...record })),
50
+ values: Object.fromEntries([...state.values].map(([item, value]) => [
51
+ item.key,
52
+ checkpointValue(value),
53
+ ])),
54
+ usage: state.accounting.snapshot(),
55
+ };
56
+ writes = writes.then(() => lease.write(snapshot));
57
+ return writes;
58
+ },
59
+ async release() {
60
+ await writes.catch(() => { });
61
+ await lease.release();
62
+ },
63
+ };
64
+ }
65
+ catch (error) {
66
+ await lease.release();
67
+ throw error;
68
+ }
69
+ }
70
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../../src/domain/workflow/checkpoint.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { Task, WorkflowExecutionState } from \"../workflow.types.ts\";\nimport type {\n WorkflowCheckpoint,\n WorkflowCheckpointOptions,\n WorkflowCheckpointSession,\n} from \"./checkpoint.types.ts\";\nimport { checkpointValue } from \"./checkpoint-value.ts\";\nimport { validateCheckpoint } from \"./checkpoint-validation.ts\";\n\nexport async function openCheckpoint(\n name: string,\n tasks: readonly Task[],\n options: WorkflowCheckpointOptions,\n): Promise<WorkflowCheckpointSession> {\n if (!options.runId.trim() || !options.version.trim())\n throw new Error(\"Checkpoint runId and version must not be empty\");\n const graph = tasks\n .map((item) => ({\n key: item.key,\n ...(item.gate ? { gate: item.gate } : {}),\n after: item.after.map((dependency) => dependency.key).sort(),\n timeoutMs: item.timeoutMs,\n retry: item.retry?.attempts,\n delayMs: item.retry?.delayMs,\n condition: !!item.condition,\n accepts: !!item.retry?.accepts,\n }))\n .sort((a, b) => {\n if (a.key === b.key) return 0;\n return a.key < b.key ? -1 : 1;\n });\n const identity = createHash(\"sha256\")\n .update(JSON.stringify({ name, version: options.version, graph }))\n .digest(\"hex\");\n const lease = await options.store.acquire(options.runId);\n try {\n const saved = await lease.read();\n let initial: WorkflowCheckpoint | undefined;\n if (saved !== undefined) {\n validateCheckpoint(saved, identity, tasks);\n initial = saved;\n const settledGate = saved.records.some((record) =>\n [\"paused\", \"rejected\"].includes(record.status),\n );\n if (\n saved.records.some(\n (record) =>\n ![\"done\", \"skipped\", \"paused\", \"rejected\"].includes(\n record.status,\n ) &&\n !(\n settledGate &&\n record.status === \"waiting\" &&\n record.attempts === 0\n ),\n ) &&\n options.resume !== \"retry-incomplete\"\n )\n throw new Error(\n \"Incomplete workflow checkpoint: resume retry-incomplete must explicitly authorize replay\",\n );\n }\n let writes = Promise.resolve();\n return {\n initial,\n save(state: WorkflowExecutionState) {\n const snapshot: WorkflowCheckpoint = {\n format: 1,\n identity,\n executionId: state.executionId,\n records: [...state.records.values()].map((record) => ({ ...record })),\n values: Object.fromEntries(\n [...state.values].map(([item, value]) => [\n item.key,\n checkpointValue(value),\n ]),\n ),\n usage: state.accounting.snapshot(),\n };\n writes = writes.then(() => lease.write(snapshot));\n return writes;\n },\n async release() {\n await writes.catch(() => {});\n await lease.release();\n },\n };\n } catch (error) {\n await lease.release();\n throw error;\n }\n}\n"]}
@@ -0,0 +1,40 @@
1
+ import type { TaskRecord, WorkflowExecutionState } from "../workflow.types.ts";
2
+ import type { WorkflowUsage } from "./budget.types.ts";
3
+ export type WorkflowJson = null | boolean | number | string | readonly WorkflowJson[] | {
4
+ readonly [key: string]: WorkflowJson;
5
+ };
6
+ export type WorkflowCheckpointValue = {
7
+ readonly kind: "undefined";
8
+ } | {
9
+ readonly kind: "json";
10
+ readonly value: WorkflowJson;
11
+ };
12
+ export interface WorkflowCheckpoint {
13
+ readonly format: 1;
14
+ readonly identity: string;
15
+ readonly executionId: string;
16
+ readonly records: readonly Readonly<TaskRecord>[];
17
+ readonly values: Readonly<Record<string, WorkflowCheckpointValue>>;
18
+ readonly usage: WorkflowUsage;
19
+ }
20
+ export interface WorkflowCheckpointLease {
21
+ read(): Promise<unknown>;
22
+ write(checkpoint: WorkflowCheckpoint): Promise<void>;
23
+ release(): Promise<void>;
24
+ }
25
+ export interface WorkflowCheckpointStore {
26
+ acquire(runId: string): Promise<WorkflowCheckpointLease>;
27
+ }
28
+ export interface WorkflowCheckpointOptions {
29
+ readonly store: WorkflowCheckpointStore;
30
+ readonly runId: string;
31
+ /** Change when task implementations or workflow inputs change. */
32
+ readonly version: string;
33
+ /** Explicitly authorize replay of incomplete tasks and their side effects. */
34
+ readonly resume?: "retry-incomplete";
35
+ }
36
+ export interface WorkflowCheckpointSession {
37
+ readonly initial: WorkflowCheckpoint | undefined;
38
+ save(state: WorkflowExecutionState): Promise<void>;
39
+ release(): Promise<void>;
40
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=checkpoint.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.types.js","sourceRoot":"","sources":["../../../src/domain/workflow/checkpoint.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { TaskRecord, WorkflowExecutionState } from \"../workflow.types.ts\";\nimport type { WorkflowUsage } from \"./budget.types.ts\";\n\nexport type WorkflowJson =\n | null\n | boolean\n | number\n | string\n | readonly WorkflowJson[]\n | { readonly [key: string]: WorkflowJson };\nexport type WorkflowCheckpointValue =\n | { readonly kind: \"undefined\" }\n | { readonly kind: \"json\"; readonly value: WorkflowJson };\n\nexport interface WorkflowCheckpoint {\n readonly format: 1;\n readonly identity: string;\n readonly executionId: string;\n readonly records: readonly Readonly<TaskRecord>[];\n readonly values: Readonly<Record<string, WorkflowCheckpointValue>>;\n readonly usage: WorkflowUsage;\n}\n\nexport interface WorkflowCheckpointLease {\n read(): Promise<unknown>;\n write(checkpoint: WorkflowCheckpoint): Promise<void>;\n release(): Promise<void>;\n}\n\nexport interface WorkflowCheckpointStore {\n acquire(runId: string): Promise<WorkflowCheckpointLease>;\n}\n\nexport interface WorkflowCheckpointOptions {\n readonly store: WorkflowCheckpointStore;\n readonly runId: string;\n /** Change when task implementations or workflow inputs change. */\n readonly version: string;\n /** Explicitly authorize replay of incomplete tasks and their side effects. */\n readonly resume?: \"retry-incomplete\";\n}\n\nexport interface WorkflowCheckpointSession {\n readonly initial: WorkflowCheckpoint | undefined;\n save(state: WorkflowExecutionState): Promise<void>;\n release(): Promise<void>;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { Task } from "../workflow.types.ts";
2
+ import type { WorkflowGate } from "./gates.types.ts";
3
+ export declare function validateGate(gate: WorkflowGate): void;
4
+ export declare function validateGateRecord(record: Record<string, unknown>, item: Task, executionId: string, output: unknown): void;
@@ -0,0 +1,71 @@
1
+ import { gateActions } from "./gates.constants.js";
2
+ function object(value) {
3
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4
+ }
5
+ export function validateGate(gate) {
6
+ if (!["approval", "pause"].includes(gate.kind))
7
+ throw new Error("Invalid workflow gate kind");
8
+ if (!gate.prompt.trim())
9
+ throw new Error("Gate prompt cannot be empty");
10
+ if (!gate.actors.length ||
11
+ gate.actors.some((actor) => !actor.trim()) ||
12
+ new Set(gate.actors).size !== gate.actors.length)
13
+ throw new Error("Gate actors must be nonempty and unique");
14
+ }
15
+ export function validateGateRecord(record, item, executionId, output) {
16
+ const invalid = () => new Error("Invalid workflow checkpoint gate record");
17
+ const gate = item.gate;
18
+ const request = record.pause;
19
+ const decision = record.decision;
20
+ if (!gate) {
21
+ if (request !== undefined ||
22
+ decision !== undefined ||
23
+ ["paused", "rejected"].includes(String(record.status)))
24
+ throw invalid();
25
+ return;
26
+ }
27
+ if (record.attempts !== 0)
28
+ throw invalid();
29
+ if (!["paused", "done", "rejected"].includes(String(record.status))) {
30
+ if (!["waiting", "skipped", "cancelled"].includes(String(record.status)) ||
31
+ request !== undefined ||
32
+ decision !== undefined)
33
+ throw invalid();
34
+ return;
35
+ }
36
+ if (!object(request) ||
37
+ typeof request.id !== "string" ||
38
+ !request.id.trim() ||
39
+ typeof request.requestedAt !== "string" ||
40
+ !Number.isFinite(Date.parse(request.requestedAt)) ||
41
+ request.kind !== gate.kind ||
42
+ request.prompt !== gate.prompt ||
43
+ JSON.stringify(request.actors) !== JSON.stringify(gate.actors))
44
+ throw invalid();
45
+ if (record.status === "paused") {
46
+ if (decision !== undefined)
47
+ throw invalid();
48
+ return;
49
+ }
50
+ const action = record.status === "rejected" ? "reject" : gateActions[gate.kind];
51
+ if (!object(decision) ||
52
+ decision.executionId !== executionId ||
53
+ decision.key !== item.key ||
54
+ decision.requestId !== request.id ||
55
+ decision.action !== action ||
56
+ typeof decision.actor !== "string" ||
57
+ !gate.actors.includes(decision.actor) ||
58
+ typeof decision.reason !== "string" ||
59
+ !decision.reason.trim() ||
60
+ typeof decision.decidedAt !== "string" ||
61
+ !Number.isFinite(Date.parse(decision.decidedAt)))
62
+ throw invalid();
63
+ if (record.status === "done" &&
64
+ (!object(output) ||
65
+ output.kind !== "json" ||
66
+ !object(output.value) ||
67
+ Object.keys(output.value).length !== Object.keys(decision).length ||
68
+ !Object.entries(decision).every(([key, value]) => object(output.value) && output.value[key] === value)))
69
+ throw invalid();
70
+ }
71
+ //# sourceMappingURL=gate-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-validation.js","sourceRoot":"","sources":["../../../src/domain/workflow/gate-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { gateActions } from \"./gates.constants.ts\";\nimport type { Task } from \"../workflow.types.ts\";\nimport type { WorkflowGate } from \"./gates.types.ts\";\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function validateGate(gate: WorkflowGate): void {\n if (![\"approval\", \"pause\"].includes(gate.kind))\n throw new Error(\"Invalid workflow gate kind\");\n if (!gate.prompt.trim()) throw new Error(\"Gate prompt cannot be empty\");\n if (\n !gate.actors.length ||\n gate.actors.some((actor) => !actor.trim()) ||\n new Set(gate.actors).size !== gate.actors.length\n )\n throw new Error(\"Gate actors must be nonempty and unique\");\n}\n\nexport function validateGateRecord(\n record: Record<string, unknown>,\n item: Task,\n executionId: string,\n output: unknown,\n): void {\n const invalid = () => new Error(\"Invalid workflow checkpoint gate record\");\n const gate = item.gate;\n const request = record.pause;\n const decision = record.decision;\n if (!gate) {\n if (\n request !== undefined ||\n decision !== undefined ||\n [\"paused\", \"rejected\"].includes(String(record.status))\n )\n throw invalid();\n return;\n }\n if (record.attempts !== 0) throw invalid();\n if (![\"paused\", \"done\", \"rejected\"].includes(String(record.status))) {\n if (\n ![\"waiting\", \"skipped\", \"cancelled\"].includes(String(record.status)) ||\n request !== undefined ||\n decision !== undefined\n )\n throw invalid();\n return;\n }\n if (\n !object(request) ||\n typeof request.id !== \"string\" ||\n !request.id.trim() ||\n typeof request.requestedAt !== \"string\" ||\n !Number.isFinite(Date.parse(request.requestedAt)) ||\n request.kind !== gate.kind ||\n request.prompt !== gate.prompt ||\n JSON.stringify(request.actors) !== JSON.stringify(gate.actors)\n )\n throw invalid();\n if (record.status === \"paused\") {\n if (decision !== undefined) throw invalid();\n return;\n }\n const action =\n record.status === \"rejected\" ? \"reject\" : gateActions[gate.kind];\n if (\n !object(decision) ||\n decision.executionId !== executionId ||\n decision.key !== item.key ||\n decision.requestId !== request.id ||\n decision.action !== action ||\n typeof decision.actor !== \"string\" ||\n !gate.actors.includes(decision.actor) ||\n typeof decision.reason !== \"string\" ||\n !decision.reason.trim() ||\n typeof decision.decidedAt !== \"string\" ||\n !Number.isFinite(Date.parse(decision.decidedAt))\n )\n throw invalid();\n if (\n record.status === \"done\" &&\n (!object(output) ||\n output.kind !== \"json\" ||\n !object(output.value) ||\n Object.keys(output.value).length !== Object.keys(decision).length ||\n !Object.entries(decision).every(\n ([key, value]) => object(output.value) && output.value[key] === value,\n ))\n )\n throw invalid();\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const gateActions: {
2
+ readonly approval: "approve";
3
+ readonly pause: "resume";
4
+ };
@@ -0,0 +1,5 @@
1
+ export const gateActions = {
2
+ approval: "approve",
3
+ pause: "resume",
4
+ };
5
+ //# sourceMappingURL=gates.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gates.constants.js","sourceRoot":"","sources":["../../../src/domain/workflow/gates.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,QAAQ;CACP,CAAC","sourcesContent":["export const gateActions = {\n approval: \"approve\",\n pause: \"resume\",\n} as const;\n"]}
@@ -0,0 +1,7 @@
1
+ import type { Task, WorkflowExecutionState } from "../workflow.types.ts";
2
+ import type { WorkflowDecisionRecord, WorkflowGateOptions } from "./gates.types.ts";
3
+ export declare function approvalTask(options: WorkflowGateOptions): Task<WorkflowDecisionRecord>;
4
+ export declare function pauseTask(options: WorkflowGateOptions): Task<WorkflowDecisionRecord>;
5
+ export declare function pauseGate(item: Task, runtime: WorkflowExecutionState): Promise<void>;
6
+ export declare function prepareDecisions(runtime: WorkflowExecutionState): readonly WorkflowDecisionRecord[];
7
+ export declare function applyDecisions(runtime: WorkflowExecutionState, decisions: readonly WorkflowDecisionRecord[]): void;