@elie-laloum/outpost 6.0.1 → 7.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 (463) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +3 -3
  3. package/SECURITY.md +9 -1
  4. package/dist/adapters/agents/antigravity-adapter.js +4 -2
  5. package/dist/adapters/agents/antigravity-adapter.js.map +1 -1
  6. package/dist/adapters/agents/antigravity-diagnostics.js +1 -1
  7. package/dist/adapters/agents/antigravity-diagnostics.js.map +1 -1
  8. package/dist/adapters/agents/antigravity-events.js +19 -10
  9. package/dist/adapters/agents/antigravity-events.js.map +1 -1
  10. package/dist/adapters/agents/antigravity-request.js +9 -1
  11. package/dist/adapters/agents/antigravity-request.js.map +1 -1
  12. package/dist/adapters/agents/antigravity.constants.d.ts +3 -0
  13. package/dist/adapters/agents/antigravity.constants.js +4 -0
  14. package/dist/adapters/agents/antigravity.constants.js.map +1 -0
  15. package/dist/adapters/agents/claude-events.js +52 -9
  16. package/dist/adapters/agents/claude-events.js.map +1 -1
  17. package/dist/adapters/agents/claude-request.js +2 -0
  18. package/dist/adapters/agents/claude-request.js.map +1 -1
  19. package/dist/adapters/agents/cli-diagnostics.d.ts +1 -1
  20. package/dist/adapters/agents/cli-diagnostics.js +15 -8
  21. package/dist/adapters/agents/cli-diagnostics.js.map +1 -1
  22. package/dist/adapters/agents/codex-events.js +28 -2
  23. package/dist/adapters/agents/codex-events.js.map +1 -1
  24. package/dist/adapters/agents/copilot-adapter.js +8 -2
  25. package/dist/adapters/agents/copilot-adapter.js.map +1 -1
  26. package/dist/adapters/agents/copilot-authentication.js +2 -1
  27. package/dist/adapters/agents/copilot-authentication.js.map +1 -1
  28. package/dist/adapters/agents/copilot-diagnostics.js +1 -1
  29. package/dist/adapters/agents/copilot-diagnostics.js.map +1 -1
  30. package/dist/adapters/agents/copilot-events.js +16 -0
  31. package/dist/adapters/agents/copilot-events.js.map +1 -1
  32. package/dist/adapters/agents/copilot-request.js +6 -1
  33. package/dist/adapters/agents/copilot-request.js.map +1 -1
  34. package/dist/adapters/agents/copilot-usage.d.ts +3 -0
  35. package/dist/adapters/agents/copilot-usage.js +19 -0
  36. package/dist/adapters/agents/copilot-usage.js.map +1 -0
  37. package/dist/adapters/agents/kimi-adapter.js +19 -3
  38. package/dist/adapters/agents/kimi-adapter.js.map +1 -1
  39. package/dist/adapters/agents/kimi-authentication.d.ts +2 -1
  40. package/dist/adapters/agents/kimi-authentication.js +41 -26
  41. package/dist/adapters/agents/kimi-authentication.js.map +1 -1
  42. package/dist/adapters/agents/kimi-diagnostics.d.ts +2 -1
  43. package/dist/adapters/agents/kimi-diagnostics.js +9 -1
  44. package/dist/adapters/agents/kimi-diagnostics.js.map +1 -1
  45. package/dist/adapters/agents/kimi-events.js +4 -0
  46. package/dist/adapters/agents/kimi-events.js.map +1 -1
  47. package/dist/adapters/agents/kimi-fork.d.ts +2 -0
  48. package/dist/adapters/agents/kimi-fork.js +11 -0
  49. package/dist/adapters/agents/kimi-fork.js.map +1 -0
  50. package/dist/adapters/agents/kimi-request.js +6 -1
  51. package/dist/adapters/agents/kimi-request.js.map +1 -1
  52. package/dist/adapters/agents/kimi-usage.d.ts +2 -0
  53. package/dist/adapters/agents/kimi-usage.js +7 -0
  54. package/dist/adapters/agents/kimi-usage.js.map +1 -0
  55. package/dist/adapters/agents/kimi.constants.d.ts +13 -0
  56. package/dist/adapters/agents/kimi.constants.js +14 -0
  57. package/dist/adapters/agents/kimi.constants.js.map +1 -0
  58. package/dist/adapters/agents/kimi.types.d.ts +1 -0
  59. package/dist/adapters/agents/kimi.types.js.map +1 -1
  60. package/dist/adapters/agents/protocol-fixtures.constants.js +15 -19
  61. package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
  62. package/dist/adapters/agents/session-usage.constants.d.ts +10 -0
  63. package/dist/adapters/agents/session-usage.constants.js +110 -0
  64. package/dist/adapters/agents/session-usage.constants.js.map +1 -0
  65. package/dist/adapters/agents/session-usage.d.ts +5 -0
  66. package/dist/adapters/agents/session-usage.js +45 -0
  67. package/dist/adapters/agents/session-usage.js.map +1 -0
  68. package/dist/adapters/agents/settings.types.d.ts +1 -0
  69. package/dist/adapters/agents/settings.types.js.map +1 -1
  70. package/dist/adapters/agents/tool-result.d.ts +2 -0
  71. package/dist/adapters/agents/tool-result.js +17 -0
  72. package/dist/adapters/agents/tool-result.js.map +1 -0
  73. package/dist/adapters/models/anthropic-response.js +3 -0
  74. package/dist/adapters/models/anthropic-response.js.map +1 -1
  75. package/dist/adapters/models/http-provider.js +6 -1
  76. package/dist/adapters/models/http-provider.js.map +1 -1
  77. package/dist/adapters/models/openai-responses.js +10 -0
  78. package/dist/adapters/models/openai-responses.js.map +1 -1
  79. package/dist/adapters/models/retry-after.d.ts +1 -0
  80. package/dist/adapters/models/retry-after.js +16 -0
  81. package/dist/adapters/models/retry-after.js.map +1 -0
  82. package/dist/application/activity-watchdog.js +1 -2
  83. package/dist/application/activity-watchdog.js.map +1 -1
  84. package/dist/application/agent-bootstrap.constants.js +1 -3
  85. package/dist/application/agent-bootstrap.constants.js.map +1 -1
  86. package/dist/application/agent-bootstrap.js +9 -3
  87. package/dist/application/agent-bootstrap.js.map +1 -1
  88. package/dist/application/agent-bootstrap.types.d.ts +1 -2
  89. package/dist/application/agent-bootstrap.types.js.map +1 -1
  90. package/dist/application/agent-output.js +74 -8
  91. package/dist/application/agent-output.js.map +1 -1
  92. package/dist/application/agent-request.d.ts +3 -0
  93. package/dist/application/agent-request.js +11 -0
  94. package/dist/application/agent-request.js.map +1 -0
  95. package/dist/application/agent-turn.js +74 -6
  96. package/dist/application/agent-turn.js.map +1 -1
  97. package/dist/application/agent-usage.d.ts +6 -0
  98. package/dist/application/agent-usage.js +57 -0
  99. package/dist/application/agent-usage.js.map +1 -0
  100. package/dist/application/attach.js +2 -0
  101. package/dist/application/attach.js.map +1 -1
  102. package/dist/application/custom-turn.js +44 -49
  103. package/dist/application/custom-turn.js.map +1 -1
  104. package/dist/application/dispatch-observation.d.ts +1 -1
  105. package/dist/application/dispatch-observation.js +141 -21
  106. package/dist/application/dispatch-observation.js.map +1 -1
  107. package/dist/application/dispatch-observation.types.d.ts +2 -0
  108. package/dist/application/dispatch-observation.types.js.map +1 -1
  109. package/dist/application/dispatch-validation.js +2 -0
  110. package/dist/application/dispatch-validation.js.map +1 -1
  111. package/dist/application/dispatch.js +1 -1
  112. package/dist/application/dispatch.js.map +1 -1
  113. package/dist/application/doctor-agent.constants.js +3 -0
  114. package/dist/application/doctor-agent.constants.js.map +1 -1
  115. package/dist/application/doctor-agent.js +6 -2
  116. package/dist/application/doctor-agent.js.map +1 -1
  117. package/dist/application/doctor.js +26 -6
  118. package/dist/application/doctor.js.map +1 -1
  119. package/dist/application/doctor.types.d.ts +1 -0
  120. package/dist/application/doctor.types.js.map +1 -1
  121. package/dist/application/execution.constants.d.ts +2 -0
  122. package/dist/application/execution.constants.js +2 -0
  123. package/dist/application/execution.constants.js.map +1 -1
  124. package/dist/application/execution.types.d.ts +8 -0
  125. package/dist/application/execution.types.js.map +1 -1
  126. package/dist/application/harness-budget.d.ts +3 -0
  127. package/dist/application/harness-budget.js +42 -0
  128. package/dist/application/harness-budget.js.map +1 -0
  129. package/dist/application/harness-budget.types.d.ts +5 -0
  130. package/dist/application/harness-budget.types.js +2 -0
  131. package/dist/application/harness-budget.types.js.map +1 -0
  132. package/dist/application/harness-hooks.js +34 -3
  133. package/dist/application/harness-hooks.js.map +1 -1
  134. package/dist/application/harness-loop.js +52 -24
  135. package/dist/application/harness-loop.js.map +1 -1
  136. package/dist/application/harness-model-provider.d.ts +3 -0
  137. package/dist/application/harness-model-provider.js +49 -0
  138. package/dist/application/harness-model-provider.js.map +1 -0
  139. package/dist/application/harness-model-provider.types.d.ts +10 -0
  140. package/dist/application/harness-model-provider.types.js +2 -0
  141. package/dist/application/harness-model-provider.types.js.map +1 -0
  142. package/dist/application/harness-subagent.d.ts +4 -0
  143. package/dist/application/harness-subagent.js +110 -0
  144. package/dist/application/harness-subagent.js.map +1 -0
  145. package/dist/application/harness.types.d.ts +11 -0
  146. package/dist/application/harness.types.js.map +1 -1
  147. package/dist/application/lifecycle-hooks.d.ts +1 -1
  148. package/dist/application/lifecycle-hooks.js +5 -4
  149. package/dist/application/lifecycle-hooks.js.map +1 -1
  150. package/dist/application/observed-lease.d.ts +3 -0
  151. package/dist/application/observed-lease.js +26 -0
  152. package/dist/application/observed-lease.js.map +1 -0
  153. package/dist/application/outpost.types.d.ts +3 -0
  154. package/dist/application/outpost.types.js.map +1 -1
  155. package/dist/application/output-lines.d.ts +4 -0
  156. package/dist/application/output-lines.js +28 -0
  157. package/dist/application/output-lines.js.map +1 -0
  158. package/dist/application/queue-worker.js +1 -1
  159. package/dist/application/queue-worker.js.map +1 -1
  160. package/dist/application/queue-worker.types.d.ts +1 -0
  161. package/dist/application/queue-worker.types.js.map +1 -1
  162. package/dist/application/queued-task.js +24 -5
  163. package/dist/application/queued-task.js.map +1 -1
  164. package/dist/application/recovery-archive.d.ts +3 -2
  165. package/dist/application/recovery-archive.js +9 -2
  166. package/dist/application/recovery-archive.js.map +1 -1
  167. package/dist/application/recovery-restore.d.ts +3 -2
  168. package/dist/application/recovery-restore.js +9 -2
  169. package/dist/application/recovery-restore.js.map +1 -1
  170. package/dist/application/recovery-retention.d.ts +3 -2
  171. package/dist/application/recovery-retention.js +9 -2
  172. package/dist/application/recovery-retention.js.map +1 -1
  173. package/dist/application/remote-workspace.js +5 -4
  174. package/dist/application/remote-workspace.js.map +1 -1
  175. package/dist/application/remote-workspace.types.d.ts +1 -0
  176. package/dist/application/remote-workspace.types.js.map +1 -1
  177. package/dist/application/sandbox-agents.js +11 -12
  178. package/dist/application/sandbox-agents.js.map +1 -1
  179. package/dist/application/sandbox-attach.js +12 -3
  180. package/dist/application/sandbox-attach.js.map +1 -1
  181. package/dist/application/sandbox-dispatch.js +13 -25
  182. package/dist/application/sandbox-dispatch.js.map +1 -1
  183. package/dist/application/sandbox-provision.js +15 -9
  184. package/dist/application/sandbox-provision.js.map +1 -1
  185. package/dist/application/sandbox-session.types.d.ts +2 -2
  186. package/dist/application/sandbox-session.types.js.map +1 -1
  187. package/dist/application/sandbox.js +13 -6
  188. package/dist/application/sandbox.js.map +1 -1
  189. package/dist/application/speculation-checkpoint.d.ts +6 -0
  190. package/dist/application/speculation-checkpoint.js +206 -0
  191. package/dist/application/speculation-checkpoint.js.map +1 -0
  192. package/dist/application/speculation-checkpoint.types.d.ts +24 -0
  193. package/dist/application/speculation-checkpoint.types.js +2 -0
  194. package/dist/application/speculation-checkpoint.types.js.map +1 -0
  195. package/dist/application/speculation-integration.constants.d.ts +4 -0
  196. package/dist/application/speculation-integration.constants.js +5 -0
  197. package/dist/application/speculation-integration.constants.js.map +1 -0
  198. package/dist/application/speculation-integration.d.ts +2 -0
  199. package/dist/application/speculation-integration.js +67 -0
  200. package/dist/application/speculation-integration.js.map +1 -0
  201. package/dist/application/speculation-resume.d.ts +4 -0
  202. package/dist/application/speculation-resume.js +71 -0
  203. package/dist/application/speculation-resume.js.map +1 -0
  204. package/dist/application/speculation-run.d.ts +4 -0
  205. package/dist/application/speculation-run.js +320 -0
  206. package/dist/application/speculation-run.js.map +1 -0
  207. package/dist/application/speculation-timeout.d.ts +1 -0
  208. package/dist/application/speculation-timeout.js +15 -0
  209. package/dist/application/speculation-timeout.js.map +1 -0
  210. package/dist/application/speculation.constants.d.ts +1 -0
  211. package/dist/application/speculation.constants.js +5 -1
  212. package/dist/application/speculation.constants.js.map +1 -1
  213. package/dist/application/speculation.js +41 -149
  214. package/dist/application/speculation.js.map +1 -1
  215. package/dist/application/speculation.types.d.ts +23 -0
  216. package/dist/application/speculation.types.js.map +1 -1
  217. package/dist/application/startup-recovery.js +13 -0
  218. package/dist/application/startup-recovery.js.map +1 -1
  219. package/dist/application/startup-recovery.types.d.ts +1 -0
  220. package/dist/application/startup-recovery.types.js.map +1 -1
  221. package/dist/application/stop-reason.d.ts +2 -0
  222. package/dist/application/stop-reason.js +21 -0
  223. package/dist/application/stop-reason.js.map +1 -0
  224. package/dist/application/stop-reason.types.d.ts +4 -0
  225. package/dist/application/stop-reason.types.js +2 -0
  226. package/dist/application/stop-reason.types.js.map +1 -0
  227. package/dist/application/task-observation.d.ts +3 -0
  228. package/dist/application/task-observation.js +22 -0
  229. package/dist/application/task-observation.js.map +1 -0
  230. package/dist/application/task-usage.js +5 -12
  231. package/dist/application/task-usage.js.map +1 -1
  232. package/dist/application/tasks.js +41 -16
  233. package/dist/application/tasks.js.map +1 -1
  234. package/dist/application/tool-execution.js +42 -19
  235. package/dist/application/tool-execution.js.map +1 -1
  236. package/dist/application/workspace.js +6 -4
  237. package/dist/application/workspace.js.map +1 -1
  238. package/dist/cli/doctor-command.js +1 -1
  239. package/dist/cli/doctor-command.js.map +1 -1
  240. package/dist/cli/main.js +2 -1
  241. package/dist/cli/main.js.map +1 -1
  242. package/dist/cli/scaffold.constants.js +3 -2
  243. package/dist/cli/scaffold.constants.js.map +1 -1
  244. package/dist/domain/agent-observation.d.ts +4 -0
  245. package/dist/domain/agent-observation.js +27 -0
  246. package/dist/domain/agent-observation.js.map +1 -0
  247. package/dist/domain/agent.types.d.ts +75 -3
  248. package/dist/domain/agent.types.js.map +1 -1
  249. package/dist/domain/harness.js +6 -0
  250. package/dist/domain/harness.js.map +1 -1
  251. package/dist/domain/harness.types.d.ts +2 -1
  252. package/dist/domain/harness.types.js.map +1 -1
  253. package/dist/domain/model.types.d.ts +8 -0
  254. package/dist/domain/model.types.js.map +1 -1
  255. package/dist/domain/observation.constants.d.ts +8 -0
  256. package/dist/domain/observation.constants.js +9 -0
  257. package/dist/domain/observation.constants.js.map +1 -0
  258. package/dist/domain/observation.d.ts +2 -0
  259. package/dist/domain/observation.js +190 -0
  260. package/dist/domain/observation.js.map +1 -0
  261. package/dist/domain/observation.types.d.ts +84 -0
  262. package/dist/domain/observation.types.js +2 -0
  263. package/dist/domain/observation.types.js.map +1 -0
  264. package/dist/domain/observed-operation.d.ts +2 -0
  265. package/dist/domain/observed-operation.js +30 -0
  266. package/dist/domain/observed-operation.js.map +1 -0
  267. package/dist/domain/sandbox.types.d.ts +2 -0
  268. package/dist/domain/sandbox.types.js.map +1 -1
  269. package/dist/domain/subagent.constants.d.ts +13 -0
  270. package/dist/domain/subagent.constants.js +9 -0
  271. package/dist/domain/subagent.constants.js.map +1 -0
  272. package/dist/domain/subagent.d.ts +4 -0
  273. package/dist/domain/subagent.js +28 -0
  274. package/dist/domain/subagent.js.map +1 -0
  275. package/dist/domain/subagent.types.d.ts +13 -0
  276. package/dist/domain/subagent.types.js +2 -0
  277. package/dist/domain/subagent.types.js.map +1 -0
  278. package/dist/domain/transcript.types.d.ts +2 -0
  279. package/dist/domain/transcript.types.js.map +1 -1
  280. package/dist/domain/usage.d.ts +1 -0
  281. package/dist/domain/usage.js +16 -0
  282. package/dist/domain/usage.js.map +1 -1
  283. package/dist/domain/workflow/budget.d.ts +7 -3
  284. package/dist/domain/workflow/budget.js +26 -0
  285. package/dist/domain/workflow/budget.js.map +1 -1
  286. package/dist/domain/workflow/budget.types.d.ts +1 -1
  287. package/dist/domain/workflow/budget.types.js.map +1 -1
  288. package/dist/domain/workflow/checkpoint-validation.js +7 -1
  289. package/dist/domain/workflow/checkpoint-validation.js.map +1 -1
  290. package/dist/domain/workflow/checkpoint.js +3 -0
  291. package/dist/domain/workflow/checkpoint.js.map +1 -1
  292. package/dist/domain/workflow/gate-validation.js +14 -1
  293. package/dist/domain/workflow/gate-validation.js.map +1 -1
  294. package/dist/domain/workflow/gates.d.ts +1 -1
  295. package/dist/domain/workflow/gates.js +52 -4
  296. package/dist/domain/workflow/gates.js.map +1 -1
  297. package/dist/domain/workflow/gates.types.d.ts +15 -1
  298. package/dist/domain/workflow/gates.types.js.map +1 -1
  299. package/dist/domain/workflow/idempotency.d.ts +1 -0
  300. package/dist/domain/workflow/idempotency.js +7 -0
  301. package/dist/domain/workflow/idempotency.js.map +1 -0
  302. package/dist/domain/workflow/retry.constants.d.ts +2 -0
  303. package/dist/domain/workflow/retry.constants.js +3 -0
  304. package/dist/domain/workflow/retry.constants.js.map +1 -0
  305. package/dist/domain/workflow/retry.d.ts +4 -0
  306. package/dist/domain/workflow/retry.js +49 -0
  307. package/dist/domain/workflow/retry.js.map +1 -0
  308. package/dist/domain/workflow/task-runner.js +9 -5
  309. package/dist/domain/workflow/task-runner.js.map +1 -1
  310. package/dist/domain/workflow/task.js +6 -6
  311. package/dist/domain/workflow/task.js.map +1 -1
  312. package/dist/domain/workflow/workflow-scheduler.js +110 -72
  313. package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
  314. package/dist/domain/workflow/workflow-state.js +28 -12
  315. package/dist/domain/workflow/workflow-state.js.map +1 -1
  316. package/dist/domain/workflow.d.ts +1 -1
  317. package/dist/domain/workflow.js +1 -1
  318. package/dist/domain/workflow.js.map +1 -1
  319. package/dist/domain/workflow.types.d.ts +13 -2
  320. package/dist/domain/workflow.types.js.map +1 -1
  321. package/dist/index.d.ts +12 -3
  322. package/dist/index.js +6 -1
  323. package/dist/index.js.map +1 -1
  324. package/dist/infrastructure/conversations/capture.js +10 -0
  325. package/dist/infrastructure/conversations/capture.js.map +1 -1
  326. package/dist/infrastructure/conversations/harness-transcript.js +6 -0
  327. package/dist/infrastructure/conversations/harness-transcript.js.map +1 -1
  328. package/dist/infrastructure/conversations/harness-transcript.types.d.ts +2 -0
  329. package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -1
  330. package/dist/infrastructure/conversations/layout.js +2 -0
  331. package/dist/infrastructure/conversations/layout.js.map +1 -1
  332. package/dist/infrastructure/conversations/locate.js +7 -1
  333. package/dist/infrastructure/conversations/locate.js.map +1 -1
  334. package/dist/infrastructure/conversations/native-store.js +8 -1
  335. package/dist/infrastructure/conversations/native-store.js.map +1 -1
  336. package/dist/infrastructure/conversations/paths.js +3 -0
  337. package/dist/infrastructure/conversations/paths.js.map +1 -1
  338. package/dist/infrastructure/conversations/restore.js +7 -0
  339. package/dist/infrastructure/conversations/restore.js.map +1 -1
  340. package/dist/infrastructure/conversations/session-bundle.constants.d.ts +5 -0
  341. package/dist/infrastructure/conversations/session-bundle.constants.js +173 -0
  342. package/dist/infrastructure/conversations/session-bundle.constants.js.map +1 -0
  343. package/dist/infrastructure/conversations/session-bundle.d.ts +6 -0
  344. package/dist/infrastructure/conversations/session-bundle.js +98 -0
  345. package/dist/infrastructure/conversations/session-bundle.js.map +1 -0
  346. package/dist/infrastructure/conversations/session-bundle.types.d.ts +1 -0
  347. package/dist/infrastructure/conversations/session-bundle.types.js +2 -0
  348. package/dist/infrastructure/conversations/session-bundle.types.js.map +1 -0
  349. package/dist/infrastructure/conversations.js +4 -2
  350. package/dist/infrastructure/conversations.js.map +1 -1
  351. package/dist/infrastructure/conversations.types.d.ts +1 -1
  352. package/dist/infrastructure/conversations.types.js.map +1 -1
  353. package/dist/infrastructure/custom-reporter.js +32 -24
  354. package/dist/infrastructure/custom-reporter.js.map +1 -1
  355. package/dist/infrastructure/custom-reporter.types.d.ts +2 -0
  356. package/dist/infrastructure/custom-reporter.types.js.map +1 -1
  357. package/dist/infrastructure/git/workspace-lease.js +4 -3
  358. package/dist/infrastructure/git/workspace-lease.js.map +1 -1
  359. package/dist/infrastructure/git/workspace.js +7 -6
  360. package/dist/infrastructure/git/workspace.js.map +1 -1
  361. package/dist/infrastructure/git/workspace.types.d.ts +1 -0
  362. package/dist/infrastructure/git/workspace.types.js.map +1 -1
  363. package/dist/infrastructure/journal.constants.js +10 -1
  364. package/dist/infrastructure/journal.constants.js.map +1 -1
  365. package/dist/infrastructure/journal.d.ts +1 -1
  366. package/dist/infrastructure/journal.js +2 -2
  367. package/dist/infrastructure/journal.js.map +1 -1
  368. package/dist/infrastructure/journal.types.d.ts +2 -2
  369. package/dist/infrastructure/journal.types.js.map +1 -1
  370. package/dist/infrastructure/opentelemetry-dispatch.d.ts +3 -3
  371. package/dist/infrastructure/opentelemetry-dispatch.js +5 -4
  372. package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -1
  373. package/dist/infrastructure/opentelemetry-observation.d.ts +5 -0
  374. package/dist/infrastructure/opentelemetry-observation.js +59 -0
  375. package/dist/infrastructure/opentelemetry-observation.js.map +1 -0
  376. package/dist/infrastructure/opentelemetry.js +15 -1
  377. package/dist/infrastructure/opentelemetry.js.map +1 -1
  378. package/dist/infrastructure/opentelemetry.types.d.ts +9 -1
  379. package/dist/infrastructure/opentelemetry.types.js.map +1 -1
  380. package/dist/infrastructure/reporter.d.ts +2 -2
  381. package/dist/infrastructure/reporter.js +5 -1
  382. package/dist/infrastructure/reporter.js.map +1 -1
  383. package/dist/infrastructure/s3-transport.constants.d.ts +2 -0
  384. package/dist/infrastructure/s3-transport.constants.js +3 -0
  385. package/dist/infrastructure/s3-transport.constants.js.map +1 -0
  386. package/dist/infrastructure/s3-transport.js +57 -3
  387. package/dist/infrastructure/s3-transport.js.map +1 -1
  388. package/dist/infrastructure/s3-transport.types.d.ts +1 -0
  389. package/dist/infrastructure/s3-transport.types.js.map +1 -1
  390. package/dist/infrastructure/speculation-store.constants.d.ts +3 -0
  391. package/dist/infrastructure/speculation-store.constants.js +2 -0
  392. package/dist/infrastructure/speculation-store.constants.js.map +1 -0
  393. package/dist/infrastructure/speculation-store.d.ts +4 -0
  394. package/dist/infrastructure/speculation-store.js +73 -0
  395. package/dist/infrastructure/speculation-store.js.map +1 -0
  396. package/dist/infrastructure/speculation-store.types.d.ts +12 -0
  397. package/dist/infrastructure/speculation-store.types.js +2 -0
  398. package/dist/infrastructure/speculation-store.types.js.map +1 -0
  399. package/dist/infrastructure/task-queue-bullmq-resources.js +3 -0
  400. package/dist/infrastructure/task-queue-bullmq-resources.js.map +1 -1
  401. package/dist/infrastructure/task-queue-http.js +29 -4
  402. package/dist/infrastructure/task-queue-http.js.map +1 -1
  403. package/dist/infrastructure/task-queue-http.types.d.ts +2 -2
  404. package/dist/infrastructure/task-queue-http.types.js.map +1 -1
  405. package/dist/infrastructure/transport-conversations.js +2 -0
  406. package/dist/infrastructure/transport-conversations.js.map +1 -1
  407. package/dist/infrastructure/transport-journal.d.ts +1 -1
  408. package/dist/infrastructure/transport-journal.js +8 -2
  409. package/dist/infrastructure/transport-journal.js.map +1 -1
  410. package/dist/infrastructure/workflow-decision-signature.constants.d.ts +4 -0
  411. package/dist/infrastructure/workflow-decision-signature.constants.js +5 -0
  412. package/dist/infrastructure/workflow-decision-signature.constants.js.map +1 -0
  413. package/dist/infrastructure/workflow-decision-signature.d.ts +4 -0
  414. package/dist/infrastructure/workflow-decision-signature.js +83 -0
  415. package/dist/infrastructure/workflow-decision-signature.js.map +1 -0
  416. package/dist/infrastructure/workflow-decision-signature.types.d.ts +16 -0
  417. package/dist/infrastructure/workflow-decision-signature.types.js +2 -0
  418. package/dist/infrastructure/workflow-decision-signature.types.js.map +1 -0
  419. package/dist/providers/antigravity-install.constants.d.ts +2 -0
  420. package/dist/providers/antigravity-install.constants.js +28 -0
  421. package/dist/providers/antigravity-install.constants.js.map +1 -0
  422. package/dist/providers/antigravity-install.d.ts +2 -0
  423. package/dist/providers/antigravity-install.js +29 -0
  424. package/dist/providers/antigravity-install.js.map +1 -0
  425. package/dist/providers/antigravity-install.types.d.ts +4 -0
  426. package/dist/providers/antigravity-install.types.js +2 -0
  427. package/dist/providers/antigravity-install.types.js.map +1 -0
  428. package/dist/providers/container-recovery.d.ts +4 -0
  429. package/dist/providers/container-recovery.js +28 -0
  430. package/dist/providers/container-recovery.js.map +1 -0
  431. package/dist/providers/container.js +8 -0
  432. package/dist/providers/container.js.map +1 -1
  433. package/dist/providers/daytona-network.constants.d.ts +5 -0
  434. package/dist/providers/daytona-network.constants.js +8 -0
  435. package/dist/providers/daytona-network.constants.js.map +1 -0
  436. package/dist/providers/daytona-network.d.ts +4 -0
  437. package/dist/providers/daytona-network.js +33 -0
  438. package/dist/providers/daytona-network.js.map +1 -0
  439. package/dist/providers/daytona.d.ts +1 -0
  440. package/dist/providers/daytona.js +9 -3
  441. package/dist/providers/daytona.js.map +1 -1
  442. package/dist/providers/daytona.types.d.ts +2 -0
  443. package/dist/providers/daytona.types.js.map +1 -1
  444. package/dist/providers/firecracker-command.js +1 -1
  445. package/dist/providers/firecracker-command.js.map +1 -1
  446. package/dist/providers/firecracker-jailer.constants.d.ts +9 -0
  447. package/dist/providers/firecracker-jailer.constants.js +10 -0
  448. package/dist/providers/firecracker-jailer.constants.js.map +1 -0
  449. package/dist/providers/firecracker-jailer.d.ts +4 -0
  450. package/dist/providers/firecracker-jailer.js +171 -0
  451. package/dist/providers/firecracker-jailer.js.map +1 -0
  452. package/dist/providers/firecracker-machine.js +30 -8
  453. package/dist/providers/firecracker-machine.js.map +1 -1
  454. package/dist/providers/firecracker.types.d.ts +16 -0
  455. package/dist/providers/firecracker.types.js.map +1 -1
  456. package/dist/providers/vercel-network.js +1 -1
  457. package/dist/providers/vercel-network.js.map +1 -1
  458. package/dist/providers/vercel.js +6 -3
  459. package/dist/providers/vercel.js.map +1 -1
  460. package/dist/providers/versions.constants.d.ts +1 -1
  461. package/dist/providers/versions.constants.js +1 -1
  462. package/dist/providers/versions.constants.js.map +1 -1
  463. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"harness-loop.js","sourceRoot":"","sources":["../../src/application/harness-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport type {\n ModelContentBlock,\n ModelRequest,\n ModelResult,\n ModelStopReason,\n ModelToolCallBlock,\n ModelToolSpec,\n} from \"../domain/model.types.ts\";\nimport { loadedSkills } from \"../domain/skill.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport type {\n HarnessHistory,\n HarnessRuntime,\n LoopState,\n StopHandler,\n} from \"./harness.types.ts\";\nimport { compact } from \"./harness-context.ts\";\nimport {\n afterModel,\n beforeModel,\n sessionInstructions,\n stopRequest,\n} from \"./harness-hooks.ts\";\nimport { executeToolCalls } from \"./tool-execution.ts\";\n\nconst stopHandlers: Readonly<Record<ModelStopReason, StopHandler>> = {\n end: async (runtime, state, result, content) => {\n const message = await stopRequest(runtime, result.text, state.step);\n await state.history.append({ role: \"assistant\", content });\n if (message === undefined) return result.text;\n runtime.emit({ kind: \"stop-prevented\", message });\n await state.history.append({\n role: \"user\",\n content: [{ type: \"text\", text: message }],\n });\n return undefined;\n },\n \"max-tokens\": async (_runtime, state) => {\n throw new OutpostError(\n \"limit\",\n `Model output reached maxOutputTokens during step ${state.step}`,\n { limit: \"maxOutputTokens\", step: state.step },\n );\n },\n refusal: async (_runtime, state) => {\n throw new OutpostError(\"response\", \"The model refused to continue\", {\n step: state.step,\n });\n },\n \"tool-calls\": async (runtime, state, _result, content) => {\n const calls = content.filter(\n (block): block is ModelToolCallBlock => block.type === \"tool-call\",\n );\n state.toolCalls += calls.length;\n const { maxToolCalls } = runtime.agent.harness.limits;\n if (maxToolCalls !== undefined && state.toolCalls > maxToolCalls)\n throw limit(\n \"maxToolCalls\",\n `Harness exceeded ${maxToolCalls} tool calls`,\n );\n await state.history.append({ role: \"assistant\", content });\n await state.history.append({\n role: \"user\",\n content: await executeToolCalls(\n runtime,\n calls,\n state.step,\n loadedSkills(state.history.messages),\n ),\n });\n return undefined;\n },\n};\n\nexport async function harnessLoop(\n runtime: HarnessRuntime,\n prompt: string,\n history: HarnessHistory,\n): Promise<string> {\n const { harness, model } = runtime.agent;\n const system = [\n await instructions(runtime),\n ...(await sessionInstructions(runtime, prompt)),\n ]\n .filter((text) => text.trim())\n .join(\"\\n\\n\");\n const tools: ModelToolSpec[] = runtime.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }));\n await history.append({\n role: \"user\",\n content: [{ type: \"text\", text: prompt }],\n });\n let usage: Usage = { input: 0, cached: 0, output: 0 };\n let toolCalls = 0;\n for (let step = 1; ; step++) {\n runtime.signal.throwIfAborted();\n if (step > harness.limits.maxSteps)\n throw limit(\n \"maxSteps\",\n `Harness reached ${harness.limits.maxSteps} steps without a final answer`,\n );\n const exceeded = exceededUsage(usage, harness.limits.usage);\n if (exceeded)\n throw limit(\"usage\", `Harness exceeded its ${exceeded} token budget`);\n runtime.emit({ kind: \"step\", index: step });\n await compact(runtime, history, step);\n await beforeModel(runtime, history.messages, step);\n const result = await requestModel(runtime, {\n model: model.name,\n messages: history.messages,\n ...(system ? { system } : {}),\n ...(tools.length ? { tools } : {}),\n ...(harness.cache ? { cache: true } : {}),\n });\n if (harness.limits.usage && !result.usage)\n throw new OutpostError(\n \"configuration\",\n \"Harness usage limits require a model provider that reports usage\",\n );\n if (result.usage) usage = addUsage(usage, result.usage);\n await afterModel(runtime, result, step);\n const content: readonly ModelContentBlock[] = result.content ?? [\n { type: \"text\", text: result.text },\n ];\n for (const block of content)\n if (block.type === \"text\" && block.text)\n runtime.emit({ kind: \"text\", text: block.text });\n const state: LoopState = { history, step, toolCalls };\n const reason = result.stopReason ?? inferredStop(content);\n const answer = await stopHandlers[reason](runtime, state, result, content);\n toolCalls = state.toolCalls;\n if (answer !== undefined) return answer;\n }\n}\n\nasync function instructions(runtime: HarnessRuntime): Promise<string> {\n const texts = await Promise.all(\n runtime.agent.harness.instructions.map((entry) =>\n entry.resolve({\n sandbox: runtime.sandbox,\n signal: runtime.signal,\n model: runtime.agent.model,\n }),\n ),\n );\n runtime.signal.throwIfAborted();\n return texts.filter((text) => text.trim()).join(\"\\n\\n\");\n}\n\nfunction inferredStop(content: readonly ModelContentBlock[]): ModelStopReason {\n return content.some((block) => block.type === \"tool-call\")\n ? \"tool-calls\"\n : \"end\";\n}\n\nfunction exceededUsage(\n usage: Usage,\n limits: Partial<Usage> | undefined,\n): string | undefined {\n return Object.entries(limits ?? {}).find(\n ([key, value]) => (usage[key as keyof Usage] ?? 0) > (value ?? Infinity),\n )?.[0];\n}\n\nfunction limit(name: string, message: string): OutpostError {\n return new OutpostError(\"limit\", message, { limit: name });\n}\n\nasync function requestModel(\n runtime: HarnessRuntime,\n request: ModelRequest,\n): Promise<ModelResult> {\n const provider = runtime.modelProvider;\n if (!provider.stream) return provider.request(request);\n let result: ModelResult | undefined;\n for await (const event of provider.stream(request)) {\n if (event.type === \"text-delta\")\n runtime.emit({ kind: \"text-delta\", text: event.text });\n if (event.type === \"result\") result = event.result;\n }\n if (!result)\n throw new OutpostError(\"response\", \"Model stream ended without a result\");\n return result;\n}\n"]}
1
+ {"version":3,"file":"harness-loop.js","sourceRoot":"","sources":["../../src/application/harness-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOlD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,YAAY,GAAmD;IACnE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC7C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;SAC3C,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QACtC,MAAM,IAAI,YAAY,CACpB,OAAO,EACP,oDAAoD,KAAK,CAAC,IAAI,EAAE,EAChE,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAC/C,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QACjC,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,+BAA+B,EAAE;YAClE,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IACD,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QACvD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAC1B,CAAC,KAAK,EAA+B,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CACnE,CAAC;QACF,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;QAChC,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACtD,IAAI,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,YAAY;YAC9D,MAAM,KAAK,CACT,cAAc,EACd,oBAAoB,YAAY,aAAa,CAC9C,CAAC;QACJ,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,MAAM,gBAAgB,CAC7B,OAAO,EACP,KAAK,EACL,KAAK,CAAC,IAAI,EACV,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CACrC;SACF,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAuB,EACvB,MAAc,EACd,OAAuB;IAEvB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IACzC,MAAM,MAAM,GAAG;QACb,MAAM,YAAY,CAAC,OAAO,CAAC;QAC3B,GAAG,CAAC,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;KAChD;SACE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC7B,IAAI,CAAC,MAAM,CAAC,CAAC;IAChB,MAAM,KAAK,GAAoB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC,CAAC,CAAC;IACJ,MAAM,OAAO,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;KAC1C,CAAC,CAAC;IACH,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,KAAK,IAAI,IAAI,GAAG,CAAC,GAAI,IAAI,EAAE,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAChC,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ;YAChC,MAAM,KAAK,CACT,UAAU,EACV,mBAAmB,OAAO,CAAC,MAAM,CAAC,QAAQ,+BAA+B,CAC1E,CAAC;QACJ,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAC5D,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CACrC,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,WAAW,CAAC,MAAM;YACpB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE;YACzC,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,OAAO,GAAiC,MAAM,CAAC,OAAO,IAAI;YAC9D,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;SACpC,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI;gBACrC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI;gBAC1C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,KAAK,GAAc,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3E,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAuB;IACjD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/C,KAAK,CAAC,OAAO,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK;KAC3B,CAAC,CACH,CACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;KAClD,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,YAAY,CAAC,OAAqC;IACzD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;QACxD,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AAED,SAAS,KAAK,CAAC,IAAY,EAAE,OAAe;IAC1C,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAuB,EACvB,OAAqB;IAErB,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IACvC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,OAAO;YACjB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;IACD,KAAK,UAAU,OAAO;QACpB,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,OAAO,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,MAA+B,CAAC;QACpC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACzD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;gBAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;gBACxB,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrD,CAAC,CAAC;YACL,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,qCAAqC,CAAC,CAAC;QAC5E,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC","sourcesContent":["import { OutpostError } from \"../domain/errors.ts\";\nimport type {\n ModelContentBlock,\n ModelRequest,\n ModelResult,\n ModelStopReason,\n ModelToolCallBlock,\n ModelToolSpec,\n} from \"../domain/model.types.ts\";\nimport { loadedSkills } from \"../domain/skill.ts\";\nimport type {\n HarnessHistory,\n HarnessRuntime,\n LoopState,\n StopHandler,\n} from \"./harness.types.ts\";\nimport { compact } from \"./harness-context.ts\";\nimport {\n afterModel,\n beforeModel,\n sessionInstructions,\n stopRequest,\n} from \"./harness-hooks.ts\";\nimport { executeToolCalls } from \"./tool-execution.ts\";\n\nconst stopHandlers: Readonly<Record<ModelStopReason, StopHandler>> = {\n end: async (runtime, state, result, content) => {\n const message = await stopRequest(runtime, result.text, state.step);\n await state.history.append({ role: \"assistant\", content });\n if (message === undefined) return result.text;\n runtime.emit({ kind: \"stop-prevented\", message });\n await state.history.append({\n role: \"user\",\n content: [{ type: \"text\", text: message }],\n });\n return undefined;\n },\n \"max-tokens\": async (_runtime, state) => {\n throw new OutpostError(\n \"limit\",\n `Model output reached maxOutputTokens during step ${state.step}`,\n { limit: \"maxOutputTokens\", step: state.step },\n );\n },\n refusal: async (_runtime, state) => {\n throw new OutpostError(\"response\", \"The model refused to continue\", {\n step: state.step,\n });\n },\n \"tool-calls\": async (runtime, state, _result, content) => {\n const calls = content.filter(\n (block): block is ModelToolCallBlock => block.type === \"tool-call\",\n );\n state.toolCalls += calls.length;\n const { maxToolCalls } = runtime.agent.harness.limits;\n if (maxToolCalls !== undefined && state.toolCalls > maxToolCalls)\n throw limit(\n \"maxToolCalls\",\n `Harness exceeded ${maxToolCalls} tool calls`,\n );\n await state.history.append({ role: \"assistant\", content });\n await state.history.append({\n role: \"user\",\n content: await executeToolCalls(\n runtime,\n calls,\n state.step,\n loadedSkills(state.history.messages),\n ),\n });\n return undefined;\n },\n};\n\nexport async function harnessLoop(\n runtime: HarnessRuntime,\n prompt: string,\n history: HarnessHistory,\n): Promise<string> {\n const { harness, model } = runtime.agent;\n const system = [\n await instructions(runtime),\n ...(await sessionInstructions(runtime, prompt)),\n ]\n .filter((text) => text.trim())\n .join(\"\\n\\n\");\n const tools: ModelToolSpec[] = runtime.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }));\n await history.append({\n role: \"user\",\n content: [{ type: \"text\", text: prompt }],\n });\n let toolCalls = 0;\n const announcedSkills = new Set<string>();\n for (let step = 1; ; step++) {\n runtime.signal.throwIfAborted();\n if (step > harness.limits.maxSteps)\n throw limit(\n \"maxSteps\",\n `Harness reached ${harness.limits.maxSteps} steps without a final answer`,\n );\n runtime.budget.check();\n const newlyLoaded = [...loadedSkills(history.messages)].filter(\n (name) => !announcedSkills.has(name),\n );\n for (const name of newlyLoaded) announcedSkills.add(name);\n if (newlyLoaded.length)\n runtime.emit({ kind: \"skills-loaded\", names: newlyLoaded });\n runtime.emit({ kind: \"step\", index: step });\n await compact(runtime, history, step);\n await beforeModel(runtime, history.messages, step);\n const result = await requestModel(runtime, {\n model: model.name,\n messages: history.messages,\n ...(system ? { system } : {}),\n ...(tools.length ? { tools } : {}),\n ...(harness.cache ? { cache: true } : {}),\n });\n await afterModel(runtime, result, step);\n const content: readonly ModelContentBlock[] = result.content ?? [\n { type: \"text\", text: result.text },\n ];\n for (const block of content) {\n if (block.type === \"text\" && block.text)\n runtime.emit({ kind: \"text\", text: block.text });\n if (block.type === \"reasoning\" && block.text)\n runtime.emit({ kind: \"reasoning\", text: block.text });\n }\n const state: LoopState = { history, step, toolCalls };\n const reason = result.stopReason ?? inferredStop(content);\n const answer = await stopHandlers[reason](runtime, state, result, content);\n toolCalls = state.toolCalls;\n runtime.budget.check();\n if (answer !== undefined) return answer;\n }\n}\n\nasync function instructions(runtime: HarnessRuntime): Promise<string> {\n const texts = await Promise.all(\n runtime.agent.harness.instructions.map((entry) =>\n entry.resolve({\n sandbox: runtime.sandbox,\n signal: runtime.signal,\n model: runtime.agent.model,\n }),\n ),\n );\n runtime.signal.throwIfAborted();\n runtime.emit({\n kind: \"instructions-loaded\",\n count: texts.filter((text) => text.trim()).length,\n });\n return texts.filter((text) => text.trim()).join(\"\\n\\n\");\n}\n\nfunction inferredStop(content: readonly ModelContentBlock[]): ModelStopReason {\n return content.some((block) => block.type === \"tool-call\")\n ? \"tool-calls\"\n : \"end\";\n}\n\nfunction limit(name: string, message: string): OutpostError {\n return new OutpostError(\"limit\", message, { limit: name });\n}\n\nasync function requestModel(\n runtime: HarnessRuntime,\n request: ModelRequest,\n): Promise<ModelResult> {\n const provider = runtime.modelProvider;\n if (runtime.verbose) runtime.emit({ kind: \"model-request\", request });\n try {\n const result = await receive();\n if (runtime.verbose)\n runtime.emit({ kind: \"model-response\", response: result });\n return result;\n } catch (error) {\n runtime.emit({\n kind: \"model-error\",\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n async function receive(): Promise<ModelResult> {\n if (!provider.stream) return provider.request(request);\n let result: ModelResult | undefined;\n for await (const event of provider.stream(request)) {\n if (event.type === \"text-delta\")\n runtime.emit({ kind: \"text-delta\", text: event.text });\n if (event.type === \"reasoning\")\n runtime.emit({ kind: \"reasoning\", text: event.text });\n if (event.type === \"retry\")\n runtime.emit({\n kind: \"model-retry\",\n attempt: event.attempt,\n ...(event.message ? { message: event.message } : {}),\n });\n if (event.type === \"result\") result = event.result;\n }\n if (!result)\n throw new OutpostError(\"response\", \"Model stream ended without a result\");\n return result;\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ModelProvider } from "../domain/model.types.ts";
2
+ import type { HarnessModelScope } from "./harness-model-provider.types.ts";
3
+ export declare function harnessModelProvider(scope: HarnessModelScope): ModelProvider;
@@ -0,0 +1,49 @@
1
+ import { invariant } from "../domain/errors.js";
2
+ export function harnessModelProvider(scope) {
3
+ const { agent, signal, budget, track } = scope;
4
+ const provider = agent.harness.modelProvider;
5
+ const scoped = (request) => {
6
+ signal.throwIfAborted();
7
+ budget.check();
8
+ const { reasoning, maxOutputTokens } = agent.model;
9
+ return {
10
+ ...(reasoning === undefined ? {} : { reasoning }),
11
+ ...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),
12
+ ...request,
13
+ signal,
14
+ };
15
+ };
16
+ const account = (result) => {
17
+ signal.throwIfAborted();
18
+ invariant(result && typeof result.text === "string", "Model provider must return text");
19
+ scope.account(result);
20
+ budget.account(result);
21
+ return result;
22
+ };
23
+ async function* stream(request) {
24
+ let finish;
25
+ track(new Promise((resolve) => (finish = resolve)));
26
+ try {
27
+ let received = false;
28
+ for await (const event of provider.stream(scoped(request))) {
29
+ signal.throwIfAborted();
30
+ if (event.type === "result") {
31
+ invariant(!received, "Model stream returned more than one result");
32
+ received = true;
33
+ yield { type: "result", result: account(event.result) };
34
+ continue;
35
+ }
36
+ yield event;
37
+ }
38
+ }
39
+ finally {
40
+ finish();
41
+ }
42
+ }
43
+ return {
44
+ name: provider.name,
45
+ ...(provider.stream ? { stream } : {}),
46
+ request: (request) => track(Promise.resolve().then(async () => account(await provider.request(scoped(request))))),
47
+ };
48
+ }
49
+ //# sourceMappingURL=harness-model-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-model-provider.js","sourceRoot":"","sources":["../../src/application/harness-model-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAShD,MAAM,UAAU,oBAAoB,CAAC,KAAwB;IAC3D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;IAC7C,MAAM,MAAM,GAAG,CAAC,OAAqB,EAAgB,EAAE;QACrD,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC;QACnD,OAAO;YACL,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;YACjD,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;YAC7D,GAAG,OAAO;YACV,MAAM;SACP,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,MAAmB,EAAe,EAAE;QACnD,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,SAAS,CACP,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EACzC,iCAAiC,CAClC,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IACF,KAAK,SAAS,CAAC,CAAC,MAAM,CACpB,OAAqB;QAErB,IAAI,MAAmB,CAAC;QACxB,KAAK,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBAC5D,MAAM,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5B,SAAS,CAAC,CAAC,QAAQ,EAAE,4CAA4C,CAAC,CAAC;oBACnE,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxD,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CACnB,KAAK,CACH,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAChC,OAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CACjD,CACF;KACJ,CAAC;AACJ,CAAC","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport type {\n ModelProvider,\n ModelRequest,\n ModelResult,\n ModelStreamEvent,\n} from \"../domain/model.types.ts\";\nimport type { HarnessModelScope } from \"./harness-model-provider.types.ts\";\n\nexport function harnessModelProvider(scope: HarnessModelScope): ModelProvider {\n const { agent, signal, budget, track } = scope;\n const provider = agent.harness.modelProvider;\n const scoped = (request: ModelRequest): ModelRequest => {\n signal.throwIfAborted();\n budget.check();\n const { reasoning, maxOutputTokens } = agent.model;\n return {\n ...(reasoning === undefined ? {} : { reasoning }),\n ...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),\n ...request,\n signal,\n };\n };\n const account = (result: ModelResult): ModelResult => {\n signal.throwIfAborted();\n invariant(\n result && typeof result.text === \"string\",\n \"Model provider must return text\",\n );\n scope.account(result);\n budget.account(result);\n return result;\n };\n async function* stream(\n request: ModelRequest,\n ): AsyncGenerator<ModelStreamEvent> {\n let finish!: () => void;\n track(new Promise<void>((resolve) => (finish = resolve)));\n try {\n let received = false;\n for await (const event of provider.stream!(scoped(request))) {\n signal.throwIfAborted();\n if (event.type === \"result\") {\n invariant(!received, \"Model stream returned more than one result\");\n received = true;\n yield { type: \"result\", result: account(event.result) };\n continue;\n }\n yield event;\n }\n } finally {\n finish();\n }\n }\n return {\n name: provider.name,\n ...(provider.stream ? { stream } : {}),\n request: (request) =>\n track(\n Promise.resolve().then(async () =>\n account(await provider.request(scoped(request))),\n ),\n ),\n };\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { CustomAgent } from "../domain/agent.types.ts";
2
+ import type { ModelResult } from "../domain/model.types.ts";
3
+ import type { HarnessBudget } from "./harness-budget.types.ts";
4
+ export interface HarnessModelScope {
5
+ readonly agent: CustomAgent;
6
+ readonly signal: AbortSignal;
7
+ readonly budget: HarnessBudget;
8
+ track<T>(operation: Promise<T>): Promise<T>;
9
+ account(result: ModelResult, subagentId?: string): void;
10
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=harness-model-provider.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-model-provider.types.js","sourceRoot":"","sources":["../../src/application/harness-model-provider.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CustomAgent } from \"../domain/agent.types.ts\";\nimport type { ModelResult } from \"../domain/model.types.ts\";\nimport type { HarnessBudget } from \"./harness-budget.types.ts\";\n\nexport interface HarnessModelScope {\n readonly agent: CustomAgent;\n readonly signal: AbortSignal;\n readonly budget: HarnessBudget;\n track<T>(operation: Promise<T>): Promise<T>;\n account(result: ModelResult, subagentId?: string): void;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { HarnessSubagent } from "../domain/subagent.types.ts";
2
+ import type { HarnessToolContext } from "../domain/tool.types.ts";
3
+ import type { HarnessRuntime } from "./harness.types.ts";
4
+ export declare function runSubagent(runtime: HarnessRuntime, tool: HarnessSubagent, input: unknown, context: HarnessToolContext): Promise<string>;
@@ -0,0 +1,110 @@
1
+ import { join } from "node:path";
2
+ import { randomUUID } from "node:crypto";
3
+ import { OutpostError, recordRecovery } from "../domain/errors.js";
4
+ import { MAX_DELEGATION_DEPTH } from "../domain/subagent.constants.js";
5
+ import { openTranscript } from "../infrastructure/conversations/harness-transcript.js";
6
+ import { storageFor } from "./agent-storage.js";
7
+ import { harnessBudget } from "./harness-budget.js";
8
+ import { harnessHistory } from "./harness-history.js";
9
+ import { harnessLoop } from "./harness-loop.js";
10
+ import { harnessModelProvider } from "./harness-model-provider.js";
11
+ export async function runSubagent(runtime, tool, input, context) {
12
+ const validated = await tool.validate(input);
13
+ if ("issues" in validated)
14
+ throw new OutpostError("configuration", validated.issues);
15
+ if (runtime.depth >= runtime.maxDepth)
16
+ throw new OutpostError("limit", "Harness reached its delegation depth limit", { limit: "maxDelegationDepth" });
17
+ runtime.budget.check();
18
+ const agent = tool.subagent;
19
+ const budget = harnessBudget(agent.harness.limits, runtime.budget);
20
+ const id = randomUUID();
21
+ const depth = runtime.depth + 1;
22
+ const store = storageFor(agent);
23
+ let transcript;
24
+ let failure;
25
+ let text = "";
26
+ const lifecycle = (status) => runtime.emit({
27
+ kind: "subagent",
28
+ id,
29
+ callId: context.callId,
30
+ name: tool.name,
31
+ status,
32
+ ...(transcript ? { conversation: transcript.id } : {}),
33
+ });
34
+ try {
35
+ transcript = store
36
+ ? await openTranscript({
37
+ repository: runtime.repository,
38
+ store,
39
+ model: agent.model.name,
40
+ ...(runtime.conversation
41
+ ? { parentConversation: runtime.conversation }
42
+ : {}),
43
+ parentCallId: context.callId,
44
+ })
45
+ : undefined;
46
+ lifecycle("started");
47
+ text = await harnessLoop({
48
+ ...runtime,
49
+ agent,
50
+ budget,
51
+ depth,
52
+ maxDepth: Math.min(runtime.maxDepth, depth +
53
+ (agent.harness.limits.maxDelegationDepth ?? MAX_DELEGATION_DEPTH)),
54
+ conversation: transcript?.id,
55
+ tools: agent.harness.tools,
56
+ permissions: [
57
+ ...runtime.permissions,
58
+ ...(agent.harness.permissions ? [agent.harness.permissions] : []),
59
+ ],
60
+ sandbox: context.sandbox,
61
+ signal: context.signal,
62
+ modelProvider: harnessModelProvider({
63
+ agent,
64
+ signal: context.signal,
65
+ budget,
66
+ ...runtime.modelScope,
67
+ account: (result) => runtime.modelScope.account(result, id),
68
+ }),
69
+ emit: (event) => {
70
+ context.signal.throwIfAborted();
71
+ runtime.emit({ ...event, subagentId: event.subagentId ?? id });
72
+ },
73
+ }, validated.value.prompt, harnessHistory(transcript));
74
+ context.signal.throwIfAborted();
75
+ }
76
+ catch (error) {
77
+ failure = error;
78
+ }
79
+ try {
80
+ if (transcript && store)
81
+ await store.capture(transcript.id, {
82
+ repository: runtime.repository,
83
+ sandbox: context.sandbox,
84
+ staging: join(runtime.repository, ".outpost", "conversations", "harness"),
85
+ });
86
+ }
87
+ catch (error) {
88
+ if (failure)
89
+ recordRecovery(failure, {
90
+ subagentCaptureError: error,
91
+ conversation: transcript?.id,
92
+ });
93
+ failure ??= error;
94
+ }
95
+ finally {
96
+ await transcript?.close();
97
+ }
98
+ if (failure) {
99
+ if (!runtime.signal.aborted)
100
+ lifecycle("failed");
101
+ throw failure;
102
+ }
103
+ context.signal.throwIfAborted();
104
+ lifecycle("finished");
105
+ return JSON.stringify({
106
+ text,
107
+ ...(transcript ? { conversation: transcript.id } : {}),
108
+ });
109
+ }
110
+ //# sourceMappingURL=harness-subagent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-subagent.js","sourceRoot":"","sources":["../../src/application/harness-subagent.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { OutpostError, recordRecovery } from \"../domain/errors.ts\";\nimport { MAX_DELEGATION_DEPTH } from \"../domain/subagent.constants.ts\";\nimport type { HarnessSubagent } from \"../domain/subagent.types.ts\";\nimport type { HarnessToolContext } from \"../domain/tool.types.ts\";\nimport { openTranscript } from \"../infrastructure/conversations/harness-transcript.ts\";\nimport type { TranscriptHandle } from \"../infrastructure/conversations/harness-transcript.types.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport { harnessBudget } from \"./harness-budget.ts\";\nimport { harnessHistory } from \"./harness-history.ts\";\nimport { harnessLoop } from \"./harness-loop.ts\";\nimport { harnessModelProvider } from \"./harness-model-provider.ts\";\nimport type { HarnessRuntime } from \"./harness.types.ts\";\n\nexport async function runSubagent(\n runtime: HarnessRuntime,\n tool: HarnessSubagent,\n input: unknown,\n context: HarnessToolContext,\n): Promise<string> {\n const validated = await tool.validate(input);\n if (\"issues\" in validated)\n throw new OutpostError(\"configuration\", validated.issues);\n if (runtime.depth >= runtime.maxDepth)\n throw new OutpostError(\n \"limit\",\n \"Harness reached its delegation depth limit\",\n { limit: \"maxDelegationDepth\" },\n );\n runtime.budget.check();\n const agent = tool.subagent;\n const budget = harnessBudget(agent.harness.limits, runtime.budget);\n const id = randomUUID();\n const depth = runtime.depth + 1;\n const store = storageFor(agent);\n let transcript: TranscriptHandle | undefined;\n let failure: unknown;\n let text = \"\";\n const lifecycle = (status: \"started\" | \"finished\" | \"failed\") =>\n runtime.emit({\n kind: \"subagent\",\n id,\n callId: context.callId,\n name: tool.name,\n status,\n ...(transcript ? { conversation: transcript.id } : {}),\n });\n try {\n transcript = store\n ? await openTranscript({\n repository: runtime.repository,\n store,\n model: agent.model.name,\n ...(runtime.conversation\n ? { parentConversation: runtime.conversation }\n : {}),\n parentCallId: context.callId,\n })\n : undefined;\n lifecycle(\"started\");\n text = await harnessLoop(\n {\n ...runtime,\n agent,\n budget,\n depth,\n maxDepth: Math.min(\n runtime.maxDepth,\n depth +\n (agent.harness.limits.maxDelegationDepth ?? MAX_DELEGATION_DEPTH),\n ),\n conversation: transcript?.id,\n tools: agent.harness.tools,\n permissions: [\n ...runtime.permissions,\n ...(agent.harness.permissions ? [agent.harness.permissions] : []),\n ],\n sandbox: context.sandbox,\n signal: context.signal,\n modelProvider: harnessModelProvider({\n agent,\n signal: context.signal,\n budget,\n ...runtime.modelScope,\n account: (result) => runtime.modelScope.account(result, id),\n }),\n emit: (event) => {\n context.signal.throwIfAborted();\n runtime.emit({ ...event, subagentId: event.subagentId ?? id });\n },\n },\n validated.value.prompt,\n harnessHistory(transcript),\n );\n context.signal.throwIfAborted();\n } catch (error) {\n failure = error;\n }\n try {\n if (transcript && store)\n await store.capture(transcript.id, {\n repository: runtime.repository,\n sandbox: context.sandbox,\n staging: join(\n runtime.repository,\n \".outpost\",\n \"conversations\",\n \"harness\",\n ),\n });\n } catch (error) {\n if (failure)\n recordRecovery(failure, {\n subagentCaptureError: error,\n conversation: transcript?.id,\n });\n failure ??= error;\n } finally {\n await transcript?.close();\n }\n if (failure) {\n if (!runtime.signal.aborted) lifecycle(\"failed\");\n throw failure;\n }\n context.signal.throwIfAborted();\n lifecycle(\"finished\");\n return JSON.stringify({\n text,\n ...(transcript ? { conversation: transcript.id } : {}),\n });\n}\n"]}
@@ -1,9 +1,20 @@
1
+ import type { HarnessBudget } from "./harness-budget.types.ts";
2
+ import type { HarnessPermissions } from "../domain/permissions.types.ts";
3
+ import type { HarnessModelScope } from "./harness-model-provider.types.ts";
1
4
  import type { AgentEvent, CustomAgent } from "../domain/agent.types.ts";
2
5
  import type { ModelContentBlock, ModelMessage, ModelProvider, ModelResult, ModelToolCallBlock } from "../domain/model.types.ts";
3
6
  import type { SandboxLease } from "../domain/sandbox.types.ts";
4
7
  import type { HarnessTool } from "../domain/tool.types.ts";
5
8
  import type { DispatchOptions, TurnContext } from "./execution.types.ts";
6
9
  export interface HarnessRuntime {
10
+ readonly verbose?: boolean;
11
+ readonly repository: string;
12
+ readonly conversation?: string | undefined;
13
+ readonly budget: HarnessBudget;
14
+ readonly permissions: readonly HarnessPermissions[];
15
+ readonly depth: number;
16
+ readonly maxDepth: number;
17
+ readonly modelScope: Pick<HarnessModelScope, "track" | "account">;
7
18
  readonly agent: CustomAgent;
8
19
  readonly tools: readonly HarnessTool[];
9
20
  readonly modelProvider: ModelProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"harness.types.js","sourceRoot":"","sources":["../../src/application/harness.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentEvent, CustomAgent } from \"../domain/agent.types.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelProvider,\n ModelResult,\n ModelToolCallBlock,\n} from \"../domain/model.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport type { HarnessTool } from \"../domain/tool.types.ts\";\nimport type { DispatchOptions, TurnContext } from \"./execution.types.ts\";\n\nexport interface HarnessRuntime {\n readonly agent: CustomAgent;\n readonly tools: readonly HarnessTool[];\n readonly modelProvider: ModelProvider;\n readonly sandbox: SandboxLease;\n readonly signal: AbortSignal;\n emit(event: AgentEvent): void;\n hold(): () => void;\n}\n\nexport interface ToolCallBatch {\n readonly concurrent: boolean;\n readonly calls: readonly PreparedCall[];\n}\n\nexport type ValidatedInput =\n { readonly value: unknown } | { readonly outcome: ToolOutcome };\n\nexport interface ToolOutcome {\n readonly content: string;\n readonly isError: boolean;\n}\n\nexport interface HarnessHistory {\n readonly messages: readonly ModelMessage[];\n append(message: ModelMessage): Promise<void>;\n replace(messages: readonly ModelMessage[]): Promise<void>;\n}\n\nexport interface CustomTurnContext extends TurnContext {\n readonly continuation?: DispatchOptions[\"continuation\"];\n}\n\nexport interface LoopState {\n readonly history: HarnessHistory;\n readonly step: number;\n toolCalls: number;\n}\n\nexport type StopHandler = (\n runtime: HarnessRuntime,\n state: LoopState,\n result: ModelResult,\n content: readonly ModelContentBlock[],\n) => Promise<string | undefined>;\n\nexport interface PreparedCall {\n readonly call: ModelToolCallBlock;\n readonly tool?: HarnessTool;\n readonly input?: unknown;\n readonly outcome?: ToolOutcome;\n}\n\nexport interface ToolDenial {\n readonly deny: string;\n}\n\nexport type BlockRenderers = {\n readonly [Type in ModelContentBlock[\"type\"]]: (\n block: Extract<ModelContentBlock, { type: Type }>,\n ) => string;\n};\n"]}
1
+ {"version":3,"file":"harness.types.js","sourceRoot":"","sources":["../../src/application/harness.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { HarnessBudget } from \"./harness-budget.types.ts\";\nimport type { HarnessPermissions } from \"../domain/permissions.types.ts\";\nimport type { HarnessModelScope } from \"./harness-model-provider.types.ts\";\nimport type { AgentEvent, CustomAgent } from \"../domain/agent.types.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelProvider,\n ModelResult,\n ModelToolCallBlock,\n} from \"../domain/model.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport type { HarnessTool } from \"../domain/tool.types.ts\";\nimport type { DispatchOptions, TurnContext } from \"./execution.types.ts\";\n\nexport interface HarnessRuntime {\n readonly verbose?: boolean;\n readonly repository: string;\n readonly conversation?: string | undefined;\n readonly budget: HarnessBudget;\n readonly permissions: readonly HarnessPermissions[];\n readonly depth: number;\n readonly maxDepth: number;\n readonly modelScope: Pick<HarnessModelScope, \"track\" | \"account\">;\n readonly agent: CustomAgent;\n readonly tools: readonly HarnessTool[];\n readonly modelProvider: ModelProvider;\n readonly sandbox: SandboxLease;\n readonly signal: AbortSignal;\n emit(event: AgentEvent): void;\n hold(): () => void;\n}\n\nexport interface ToolCallBatch {\n readonly concurrent: boolean;\n readonly calls: readonly PreparedCall[];\n}\n\nexport type ValidatedInput =\n { readonly value: unknown } | { readonly outcome: ToolOutcome };\n\nexport interface ToolOutcome {\n readonly content: string;\n readonly isError: boolean;\n}\n\nexport interface HarnessHistory {\n readonly messages: readonly ModelMessage[];\n append(message: ModelMessage): Promise<void>;\n replace(messages: readonly ModelMessage[]): Promise<void>;\n}\n\nexport interface CustomTurnContext extends TurnContext {\n readonly continuation?: DispatchOptions[\"continuation\"];\n}\n\nexport interface LoopState {\n readonly history: HarnessHistory;\n readonly step: number;\n toolCalls: number;\n}\n\nexport type StopHandler = (\n runtime: HarnessRuntime,\n state: LoopState,\n result: ModelResult,\n content: readonly ModelContentBlock[],\n) => Promise<string | undefined>;\n\nexport interface PreparedCall {\n readonly call: ModelToolCallBlock;\n readonly tool?: HarnessTool;\n readonly input?: unknown;\n readonly outcome?: ToolOutcome;\n}\n\nexport interface ToolDenial {\n readonly deny: string;\n}\n\nexport type BlockRenderers = {\n readonly [Type in ModelContentBlock[\"type\"]]: (\n block: Extract<ModelContentBlock, { type: Type }>,\n ) => string;\n};\n"]}
@@ -1,3 +1,3 @@
1
1
  import type { Command } from "../domain/command.types.ts";
2
2
  import type { SandboxLease } from "../domain/sandbox.types.ts";
3
- export declare function hooks(commands: readonly Command[], directory: string, invoke: SandboxLease["invoke"], signal?: AbortSignal, parallel?: boolean): Promise<void>;
3
+ export declare function hooks(commands: readonly Command[], directory: string, invoke: SandboxLease["invoke"], signal?: AbortSignal, parallel?: boolean, observation?: import("../domain/observation.types.ts").ObservationHub): Promise<void>;
@@ -1,12 +1,13 @@
1
+ import { observedOperation } from "../domain/observed-operation.js";
1
2
  import { requireSuccess } from "../infrastructure/process.js";
2
3
  import { hookDeadlineMs } from "./lifecycle.constants.js";
3
- export async function hooks(commands, directory, invoke, signal, parallel = false) {
4
+ export async function hooks(commands, directory, invoke, signal, parallel = false, observation) {
4
5
  if (parallel) {
5
6
  const controller = new AbortController();
6
7
  const combined = signal
7
8
  ? AbortSignal.any([signal, controller.signal])
8
9
  : controller.signal;
9
- const outcomes = await Promise.allSettled(commands.map((command) => hooks([command], directory, invoke, combined).catch((cause) => {
10
+ const outcomes = await Promise.allSettled(commands.map((command) => hooks([command], directory, invoke, combined, false, observation).catch((cause) => {
10
11
  controller.abort(cause);
11
12
  throw cause;
12
13
  })));
@@ -16,11 +17,11 @@ export async function hooks(commands, directory, invoke, signal, parallel = fals
16
17
  return;
17
18
  }
18
19
  for (const command of commands)
19
- await requireSuccess({
20
+ await observedOperation(observation, "hooks", "lifecycle.command", async () => requireSuccess({
20
21
  ...command,
21
22
  directory: command.directory ?? directory,
22
23
  deadlineMs: command.deadlineMs ?? hookDeadlineMs,
23
24
  ...(signal ? { signal } : {}),
24
- }, invoke);
25
+ }, invoke));
25
26
  }
26
27
  //# sourceMappingURL=lifecycle-hooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-hooks.js","sourceRoot":"","sources":["../../src/application/lifecycle-hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,QAA4B,EAC5B,SAAiB,EACjB,MAA8B,EAC9B,MAAoB,EACpB,QAAQ,GAAG,KAAK;IAEhB,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,MAAM;YACrB,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAU,CACvC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACvB,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5D,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CACH,CACF,CAAC;QACF,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;QAC1E,IAAI,OAAO,EAAE,MAAM,KAAK,UAAU;YAAE,MAAM,OAAO,CAAC,MAAM,CAAC;QACzD,OAAO;IACT,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ;QAC5B,MAAM,cAAc,CAClB;YACE,GAAG,OAAO;YACV,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;YACzC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,cAAc;YAChD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,EACD,MAAM,CACP,CAAC;AACN,CAAC","sourcesContent":["import type { Command } from \"../domain/command.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { requireSuccess } from \"../infrastructure/process.ts\";\nimport { hookDeadlineMs } from \"./lifecycle.constants.ts\";\n\nexport async function hooks(\n commands: readonly Command[],\n directory: string,\n invoke: SandboxLease[\"invoke\"],\n signal?: AbortSignal,\n parallel = false,\n): Promise<void> {\n if (parallel) {\n const controller = new AbortController();\n const combined = signal\n ? AbortSignal.any([signal, controller.signal])\n : controller.signal;\n const outcomes = await Promise.allSettled(\n commands.map((command) =>\n hooks([command], directory, invoke, combined).catch((cause) => {\n controller.abort(cause);\n throw cause;\n }),\n ),\n );\n const failure = outcomes.find((outcome) => outcome.status === \"rejected\");\n if (failure?.status === \"rejected\") throw failure.reason;\n return;\n }\n for (const command of commands)\n await requireSuccess(\n {\n ...command,\n directory: command.directory ?? directory,\n deadlineMs: command.deadlineMs ?? hookDeadlineMs,\n ...(signal ? { signal } : {}),\n },\n invoke,\n );\n}\n"]}
1
+ {"version":3,"file":"lifecycle-hooks.js","sourceRoot":"","sources":["../../src/application/lifecycle-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,QAA4B,EAC5B,SAAiB,EACjB,MAA8B,EAC9B,MAAoB,EACpB,QAAQ,GAAG,KAAK,EAChB,WAAqE;IAErE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,MAAM;YACrB,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAU,CACvC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACvB,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,KAAK,CACrE,CAAC,KAAK,EAAE,EAAE;YACR,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC,CACF,CACF,CACF,CAAC;QACF,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;QAC1E,IAAI,OAAO,EAAE,MAAM,KAAK,UAAU;YAAE,MAAM,OAAO,CAAC,MAAM,CAAC;QACzD,OAAO;IACT,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ;QAC5B,MAAM,iBAAiB,CACrB,WAAW,EACX,OAAO,EACP,mBAAmB,EACnB,KAAK,IAAI,EAAE,CACT,cAAc,CACZ;YACE,GAAG,OAAO;YACV,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;YACzC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,cAAc;YAChD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,EACD,MAAM,CACP,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { observedOperation } from \"../domain/observed-operation.ts\";\nimport type { Command } from \"../domain/command.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { requireSuccess } from \"../infrastructure/process.ts\";\nimport { hookDeadlineMs } from \"./lifecycle.constants.ts\";\n\nexport async function hooks(\n commands: readonly Command[],\n directory: string,\n invoke: SandboxLease[\"invoke\"],\n signal?: AbortSignal,\n parallel = false,\n observation?: import(\"../domain/observation.types.ts\").ObservationHub,\n): Promise<void> {\n if (parallel) {\n const controller = new AbortController();\n const combined = signal\n ? AbortSignal.any([signal, controller.signal])\n : controller.signal;\n const outcomes = await Promise.allSettled(\n commands.map((command) =>\n hooks([command], directory, invoke, combined, false, observation).catch(\n (cause) => {\n controller.abort(cause);\n throw cause;\n },\n ),\n ),\n );\n const failure = outcomes.find((outcome) => outcome.status === \"rejected\");\n if (failure?.status === \"rejected\") throw failure.reason;\n return;\n }\n for (const command of commands)\n await observedOperation(\n observation,\n \"hooks\",\n \"lifecycle.command\",\n async () =>\n requireSuccess(\n {\n ...command,\n directory: command.directory ?? directory,\n deadlineMs: command.deadlineMs ?? hookDeadlineMs,\n ...(signal ? { signal } : {}),\n },\n invoke,\n ),\n );\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ObservationHub } from "../domain/observation.types.ts";
2
+ import type { SandboxLease } from "../domain/sandbox.types.ts";
3
+ export declare function observedLease(lease: SandboxLease, observation?: ObservationHub): SandboxLease;
@@ -0,0 +1,26 @@
1
+ import { observedOperation } from "../domain/observed-operation.js";
2
+ export function observedLease(lease, observation) {
3
+ if (!observation)
4
+ return lease;
5
+ return {
6
+ ...lease,
7
+ invoke: lease.invoke.bind(lease),
8
+ ...(lease.fileTransfers
9
+ ? {
10
+ fileTransfers: {
11
+ manifest: (source, paths, options) => observedOperation(observation, "transfer", "files.manifest", () => lease.fileTransfers.manifest(source, paths, options)),
12
+ downloadBatch: (source, entries, destination, options) => observedOperation(observation, "transfer", "files.download", () => lease.fileTransfers.downloadBatch(source, entries, destination, options)),
13
+ ...(lease.fileTransfers.uploadBatch
14
+ ? {
15
+ uploadBatch: (source, entries, destination, options) => observedOperation(observation, "transfer", "files.upload", () => lease.fileTransfers.uploadBatch(source, entries, destination, options)),
16
+ }
17
+ : {}),
18
+ },
19
+ }
20
+ : {}),
21
+ upload: (source, destination, settings) => observedOperation(observation, "transfer", "file.upload", () => lease.upload(source, destination, settings)),
22
+ download: (source, destination, settings) => observedOperation(observation, "transfer", "file.download", () => lease.download(source, destination, settings)),
23
+ release: () => observedOperation(observation, "sandbox", "sandbox.release", () => lease.release()),
24
+ };
25
+ }
26
+ //# sourceMappingURL=observed-lease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observed-lease.js","sourceRoot":"","sources":["../../src/application/observed-lease.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,MAAM,UAAU,aAAa,CAC3B,KAAmB,EACnB,WAA4B;IAE5B,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO;QACL,GAAG,KAAK;QACR,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,GAAG,CAAC,KAAK,CAAC,aAAa;YACrB,CAAC,CAAC;gBACE,aAAa,EAAE;oBACb,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CACnC,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAChE,KAAK,CAAC,aAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CACtD;oBACH,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CACvD,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAChE,KAAK,CAAC,aAAc,CAAC,aAAa,CAChC,MAAM,EACN,OAAO,EACP,WAAW,EACX,OAAO,CACR,CACF;oBACH,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW;wBACjC,CAAC,CAAC;4BACE,WAAW,EAAE,CACX,MAAc,EACd,OAA0E,EAC1E,WAAmB,EACnB,OAA8D,EAC9D,EAAE,CACF,iBAAiB,CACf,WAAW,EACX,UAAU,EACV,cAAc,EACd,GAAG,EAAE,CACH,KAAK,CAAC,aAAc,CAAC,WAAY,CAC/B,MAAM,EACN,OAAO,EACP,WAAW,EACX,OAAO,CACR,CACJ;yBACJ;wBACH,CAAC,CAAC,EAAE,CAAC;iBACR;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,CACxC,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,CAC7D,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAC5C;QACH,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,CAC1C,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE,CAC/D,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAC9C;QACH,OAAO,EAAE,GAAG,EAAE,CACZ,iBAAiB,CAAC,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAChE,KAAK,CAAC,OAAO,EAAE,CAChB;KACJ,CAAC;AACJ,CAAC","sourcesContent":["import type { ObservationHub } from \"../domain/observation.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { observedOperation } from \"../domain/observed-operation.ts\";\n\nexport function observedLease(\n lease: SandboxLease,\n observation?: ObservationHub,\n): SandboxLease {\n if (!observation) return lease;\n return {\n ...lease,\n invoke: lease.invoke.bind(lease),\n ...(lease.fileTransfers\n ? {\n fileTransfers: {\n manifest: (source, paths, options) =>\n observedOperation(observation, \"transfer\", \"files.manifest\", () =>\n lease.fileTransfers!.manifest(source, paths, options),\n ),\n downloadBatch: (source, entries, destination, options) =>\n observedOperation(observation, \"transfer\", \"files.download\", () =>\n lease.fileTransfers!.downloadBatch(\n source,\n entries,\n destination,\n options,\n ),\n ),\n ...(lease.fileTransfers.uploadBatch\n ? {\n uploadBatch: (\n source: string,\n entries: readonly import(\"../domain/sandbox.types.ts\").FileManifestEntry[],\n destination: string,\n options?: import(\"../domain/sandbox.types.ts\").TransferOptions,\n ) =>\n observedOperation(\n observation,\n \"transfer\",\n \"files.upload\",\n () =>\n lease.fileTransfers!.uploadBatch!(\n source,\n entries,\n destination,\n options,\n ),\n ),\n }\n : {}),\n },\n }\n : {}),\n upload: (source, destination, settings) =>\n observedOperation(observation, \"transfer\", \"file.upload\", () =>\n lease.upload(source, destination, settings),\n ),\n download: (source, destination, settings) =>\n observedOperation(observation, \"transfer\", \"file.download\", () =>\n lease.download(source, destination, settings),\n ),\n release: () =>\n observedOperation(observation, \"sandbox\", \"sandbox.release\", () =>\n lease.release(),\n ),\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import type { ObservationHub } from "../domain/observation.types.ts";
1
2
  import type { Transport, TransportReference } from "../domain/transport.types.ts";
2
3
  import type { Agent } from "../domain/agent.types.ts";
3
4
  import type { Command, CommandResult } from "../domain/command.types.ts";
@@ -10,6 +11,7 @@ import type { SandboxDiagnosticOptions, SandboxDiagnosticReport } from "./doctor
10
11
  import type { DispatchOptions, Execution } from "./execution.types.ts";
11
12
  import type { VariableQuestion } from "./interactive-brief.types.ts";
12
13
  export interface WorkspaceOptions {
14
+ readonly observation?: ObservationHub;
13
15
  readonly storageQuota?: Omit<StorageReservationOptions, "signal">;
14
16
  readonly signal?: AbortSignal;
15
17
  readonly repository?: string;
@@ -63,6 +65,7 @@ export interface AttachResult extends CommandResult, Disposal {
63
65
  readonly directory: string;
64
66
  }
65
67
  export interface DispatchResult<T> extends Execution<T> {
68
+ readonly observerErrors?: readonly unknown[];
66
69
  readonly branch: string;
67
70
  readonly directory: string;
68
71
  readonly commits: readonly Commit[];
@@ -1 +1 @@
1
- {"version":3,"file":"outpost.types.js","sourceRoot":"","sources":["../../src/application/outpost.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n Transport,\n TransportReference,\n} from \"../domain/transport.types.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport type { Command, CommandResult } from \"../domain/command.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type {\n BranchPolicy,\n Commit,\n Disposal,\n LifecycleHooks,\n StageLimits,\n WorkspaceRecord,\n} from \"../domain/workspace.types.ts\";\nimport type { StorageReservationOptions } from \"../infrastructure/storage-reservations.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\nimport type {\n SandboxDiagnosticOptions,\n SandboxDiagnosticReport,\n} from \"./doctor-sandbox.types.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport type { VariableQuestion } from \"./interactive-brief.types.ts\";\n\nexport interface WorkspaceOptions {\n readonly storageQuota?: Omit<StorageReservationOptions, \"signal\">;\n readonly signal?: AbortSignal;\n readonly repository?: string;\n readonly branch?: BranchPolicy;\n readonly copies?: readonly string[];\n readonly limits?: StageLimits;\n readonly label?: string;\n readonly hooks?: LifecycleHooks;\n}\n\nexport interface Workspace extends WorkspaceRecord {\n dispatch<T = undefined>(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n DispatchOptions<T> & { readonly agent: Agent },\n ): Promise<DispatchResult<T>>;\n sandbox(\n options?: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n >,\n ): Promise<Sandbox>;\n attach(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n AttachOptions & { readonly agent: Agent },\n ): Promise<AttachResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n integrate(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SandboxOptions extends WorkspaceOptions {\n readonly includeUncommitted?: boolean;\n readonly agent?: Agent;\n readonly sandboxProvider?: SandboxProvider;\n readonly workspace?: Workspace;\n readonly hooks?: LifecycleHooks;\n readonly signal?: AbortSignal;\n readonly logging?: Logging;\n readonly bootstrap?: boolean;\n readonly conversationHome?: string;\n readonly recoveryTransport?: Transport;\n readonly activityTransport?: Transport;\n}\n\nexport interface AttachOptions {\n readonly ask?: VariableQuestion;\n readonly agent?: Agent;\n readonly brief?: Brief;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly signal?: AbortSignal;\n readonly terminal?: Command[\"terminal\"];\n}\n\nexport interface AttachResult extends CommandResult, Disposal {\n readonly commits: readonly Commit[];\n readonly branch: string;\n readonly directory: string;\n}\n\nexport interface DispatchResult<T> extends Execution<T> {\n readonly branch: string;\n readonly directory: string;\n readonly commits: readonly Commit[];\n readonly transcript?: string;\n readonly transcriptReference?: TransportReference;\n readonly logReference?: TransportReference;\n readonly retainedDirectory?: string;\n resume<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n fork<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n}\n\nexport type ContinuationOptions<T = undefined> = DispatchOptions<T> &\n Omit<SandboxOptions, \"agent\">;\n\nexport interface WarmDispatchResult<T> extends Omit<\n DispatchResult<T>,\n \"resume\" | \"fork\"\n> {\n resume<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n fork<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n}\n\nexport interface Sandbox {\n diagnose(\n options?: SandboxDiagnosticOptions,\n ): Promise<SandboxDiagnosticReport>;\n readonly workspace: Workspace;\n readonly root: string;\n dispatch<T = undefined>(\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n resume<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n fork<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n attach(options?: AttachOptions): Promise<AttachResult>;\n command(command: Command): Promise<CommandResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"outpost.types.js","sourceRoot":"","sources":["../../src/application/outpost.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ObservationHub } from \"../domain/observation.types.ts\";\nimport type {\n Transport,\n TransportReference,\n} from \"../domain/transport.types.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport type { Command, CommandResult } from \"../domain/command.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type {\n BranchPolicy,\n Commit,\n Disposal,\n LifecycleHooks,\n StageLimits,\n WorkspaceRecord,\n} from \"../domain/workspace.types.ts\";\nimport type { StorageReservationOptions } from \"../infrastructure/storage-reservations.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\nimport type {\n SandboxDiagnosticOptions,\n SandboxDiagnosticReport,\n} from \"./doctor-sandbox.types.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport type { VariableQuestion } from \"./interactive-brief.types.ts\";\n\nexport interface WorkspaceOptions {\n readonly observation?: ObservationHub;\n readonly storageQuota?: Omit<StorageReservationOptions, \"signal\">;\n readonly signal?: AbortSignal;\n readonly repository?: string;\n readonly branch?: BranchPolicy;\n readonly copies?: readonly string[];\n readonly limits?: StageLimits;\n readonly label?: string;\n readonly hooks?: LifecycleHooks;\n}\n\nexport interface Workspace extends WorkspaceRecord {\n dispatch<T = undefined>(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n DispatchOptions<T> & { readonly agent: Agent },\n ): Promise<DispatchResult<T>>;\n sandbox(\n options?: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n >,\n ): Promise<Sandbox>;\n attach(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n AttachOptions & { readonly agent: Agent },\n ): Promise<AttachResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n integrate(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SandboxOptions extends WorkspaceOptions {\n readonly includeUncommitted?: boolean;\n readonly agent?: Agent;\n readonly sandboxProvider?: SandboxProvider;\n readonly workspace?: Workspace;\n readonly hooks?: LifecycleHooks;\n readonly signal?: AbortSignal;\n readonly logging?: Logging;\n readonly bootstrap?: boolean;\n readonly conversationHome?: string;\n readonly recoveryTransport?: Transport;\n readonly activityTransport?: Transport;\n}\n\nexport interface AttachOptions {\n readonly ask?: VariableQuestion;\n readonly agent?: Agent;\n readonly brief?: Brief;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly signal?: AbortSignal;\n readonly terminal?: Command[\"terminal\"];\n}\n\nexport interface AttachResult extends CommandResult, Disposal {\n readonly commits: readonly Commit[];\n readonly branch: string;\n readonly directory: string;\n}\n\nexport interface DispatchResult<T> extends Execution<T> {\n readonly observerErrors?: readonly unknown[];\n readonly branch: string;\n readonly directory: string;\n readonly commits: readonly Commit[];\n readonly transcript?: string;\n readonly transcriptReference?: TransportReference;\n readonly logReference?: TransportReference;\n readonly retainedDirectory?: string;\n resume<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n fork<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n}\n\nexport type ContinuationOptions<T = undefined> = DispatchOptions<T> &\n Omit<SandboxOptions, \"agent\">;\n\nexport interface WarmDispatchResult<T> extends Omit<\n DispatchResult<T>,\n \"resume\" | \"fork\"\n> {\n resume<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n fork<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n}\n\nexport interface Sandbox {\n diagnose(\n options?: SandboxDiagnosticOptions,\n ): Promise<SandboxDiagnosticReport>;\n readonly workspace: Workspace;\n readonly root: string;\n dispatch<T = undefined>(\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n resume<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n fork<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n attach(options?: AttachOptions): Promise<AttachResult>;\n command(command: Command): Promise<CommandResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare function boundedLines(emit: (text: string, truncated: boolean) => void): {
2
+ append(chunk: string): void;
3
+ flush(): void;
4
+ };
@@ -0,0 +1,28 @@
1
+ import { observationDefaults } from "../domain/observation.constants.js";
2
+ export function boundedLines(emit) {
3
+ let pending = "";
4
+ const limit = observationDefaults.outputCharacters;
5
+ return {
6
+ append(chunk) {
7
+ for (let offset = 0; offset < chunk.length; offset += limit) {
8
+ pending += chunk.slice(offset, offset + limit);
9
+ let end;
10
+ while ((end = pending.indexOf("\n")) >= 0) {
11
+ const line = pending.slice(0, end);
12
+ emit(line.slice(0, limit), line.length > limit);
13
+ pending = pending.slice(end + 1);
14
+ }
15
+ if (pending.length >= limit) {
16
+ emit(pending.slice(0, limit), true);
17
+ pending = pending.slice(limit);
18
+ }
19
+ }
20
+ },
21
+ flush() {
22
+ if (pending)
23
+ emit(pending, false);
24
+ pending = "";
25
+ },
26
+ };
27
+ }
28
+ //# sourceMappingURL=output-lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-lines.js","sourceRoot":"","sources":["../../src/application/output-lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,UAAU,YAAY,CAAC,IAAgD;IAC3E,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,mBAAmB,CAAC,gBAAgB,CAAC;IACnD,OAAO;QACL,MAAM,CAAC,KAAa;YAClB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC;gBAC5D,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;gBAC/C,IAAI,GAAW,CAAC;gBAChB,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;oBACnC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;oBAChD,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBACnC,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;oBACpC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK;YACH,IAAI,OAAO;gBAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAClC,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { observationDefaults } from \"../domain/observation.constants.ts\";\n\nexport function boundedLines(emit: (text: string, truncated: boolean) => void) {\n let pending = \"\";\n const limit = observationDefaults.outputCharacters;\n return {\n append(chunk: string) {\n for (let offset = 0; offset < chunk.length; offset += limit) {\n pending += chunk.slice(offset, offset + limit);\n let end: number;\n while ((end = pending.indexOf(\"\\n\")) >= 0) {\n const line = pending.slice(0, end);\n emit(line.slice(0, limit), line.length > limit);\n pending = pending.slice(end + 1);\n }\n if (pending.length >= limit) {\n emit(pending.slice(0, limit), true);\n pending = pending.slice(limit);\n }\n }\n },\n flush() {\n if (pending) emit(pending, false);\n pending = \"\";\n },\n };\n}\n"]}
@@ -37,7 +37,7 @@ export async function runQueueWorker(options) {
37
37
  throw new Error("Worker handler unavailable");
38
38
  let result;
39
39
  try {
40
- result = queueResult(await handler(job.input, { signal, job }));
40
+ result = queueResult(await handler(job.input, { signal, job, idempotencyKey: job.id }));
41
41
  }
42
42
  catch (error) {
43
43
  result = {
@@ -1 +1 @@
1
- {"version":3,"file":"queue-worker.js","sourceRoot":"","sources":["../../src/application/queue-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { setTimeout as delay } from \"node:timers/promises\";\nimport {\n queueMaxStringLength,\n queueDefaultLeaseMs,\n queueDefaultPollMs,\n} from \"../domain/task-queue.constants.ts\";\nimport {\n queueLeaseMs,\n queueNumber,\n queueString,\n queueResult,\n} from \"../domain/task-queue.ts\";\nimport type { QueueWorkerOptions } from \"./queue-worker.types.ts\";\nimport type { QueueJob, QueueResult } from \"../domain/task-queue.types.ts\";\n\nexport async function runQueueWorker(\n options: QueueWorkerOptions,\n): Promise<void> {\n const leaseMs = queueLeaseMs(options.leaseMs ?? queueDefaultLeaseMs);\n const pollMs = queueNumber(options.pollMs ?? queueDefaultPollMs);\n if (!pollMs) throw new Error(\"Worker poll interval must be positive\");\n const handlers = new Map(Object.entries(options.handlers));\n if (\n !handlers.size ||\n [...handlers.values()].some((handler) => typeof handler !== \"function\")\n )\n throw new Error(\"Worker requires trusted handlers\");\n const worker = queueString(options.worker);\n async function execute(job: QueueJob) {\n if (options.signal.aborted) return;\n const stop = new AbortController();\n const signal = AbortSignal.any([options.signal, stop.signal]);\n const lease = { id: job.id, worker, fence: job.fence };\n const heartbeat = (async () => {\n try {\n while (!signal.aborted) {\n await delay(Math.max(10, Math.floor(leaseMs / 3)), undefined, {\n signal,\n });\n await options.queue.renew(lease, leaseMs);\n }\n } catch (error) {\n if (!signal.aborted) stop.abort(error);\n }\n })();\n try {\n const handler = handlers.get(job.handler);\n if (!handler) throw new Error(\"Worker handler unavailable\");\n let result: QueueResult;\n try {\n result = queueResult(await handler(job.input, { signal, job }));\n } catch (error) {\n result = {\n value: null,\n error:\n (error instanceof Error ? error.message : String(error)).slice(\n 0,\n queueMaxStringLength,\n ) || \"Queue handler failed\",\n };\n }\n if (!signal.aborted) await options.queue.complete(lease, result);\n } finally {\n stop.abort();\n await heartbeat;\n }\n }\n try {\n while (!options.signal.aborted) {\n const job = await options.queue.claim({\n worker,\n handlers: [...handlers.keys()],\n leaseMs,\n });\n if (job) {\n await execute(job);\n continue;\n }\n await delay(pollMs, undefined, { signal: options.signal });\n }\n } catch (error) {\n if (!options.signal.aborted) throw error;\n }\n}\n"]}
1
+ {"version":3,"file":"queue-worker.js","sourceRoot":"","sources":["../../src/application/queue-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { setTimeout as delay } from \"node:timers/promises\";\nimport {\n queueMaxStringLength,\n queueDefaultLeaseMs,\n queueDefaultPollMs,\n} from \"../domain/task-queue.constants.ts\";\nimport {\n queueLeaseMs,\n queueNumber,\n queueString,\n queueResult,\n} from \"../domain/task-queue.ts\";\nimport type { QueueWorkerOptions } from \"./queue-worker.types.ts\";\nimport type { QueueJob, QueueResult } from \"../domain/task-queue.types.ts\";\n\nexport async function runQueueWorker(\n options: QueueWorkerOptions,\n): Promise<void> {\n const leaseMs = queueLeaseMs(options.leaseMs ?? queueDefaultLeaseMs);\n const pollMs = queueNumber(options.pollMs ?? queueDefaultPollMs);\n if (!pollMs) throw new Error(\"Worker poll interval must be positive\");\n const handlers = new Map(Object.entries(options.handlers));\n if (\n !handlers.size ||\n [...handlers.values()].some((handler) => typeof handler !== \"function\")\n )\n throw new Error(\"Worker requires trusted handlers\");\n const worker = queueString(options.worker);\n async function execute(job: QueueJob) {\n if (options.signal.aborted) return;\n const stop = new AbortController();\n const signal = AbortSignal.any([options.signal, stop.signal]);\n const lease = { id: job.id, worker, fence: job.fence };\n const heartbeat = (async () => {\n try {\n while (!signal.aborted) {\n await delay(Math.max(10, Math.floor(leaseMs / 3)), undefined, {\n signal,\n });\n await options.queue.renew(lease, leaseMs);\n }\n } catch (error) {\n if (!signal.aborted) stop.abort(error);\n }\n })();\n try {\n const handler = handlers.get(job.handler);\n if (!handler) throw new Error(\"Worker handler unavailable\");\n let result: QueueResult;\n try {\n result = queueResult(\n await handler(job.input, { signal, job, idempotencyKey: job.id }),\n );\n } catch (error) {\n result = {\n value: null,\n error:\n (error instanceof Error ? error.message : String(error)).slice(\n 0,\n queueMaxStringLength,\n ) || \"Queue handler failed\",\n };\n }\n if (!signal.aborted) await options.queue.complete(lease, result);\n } finally {\n stop.abort();\n await heartbeat;\n }\n }\n try {\n while (!options.signal.aborted) {\n const job = await options.queue.claim({\n worker,\n handlers: [...handlers.keys()],\n leaseMs,\n });\n if (job) {\n await execute(job);\n continue;\n }\n await delay(pollMs, undefined, { signal: options.signal });\n }\n } catch (error) {\n if (!options.signal.aborted) throw error;\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import type { QueueJob, QueueResult, TaskQueue } from "../domain/task-queue.types.ts";
2
2
  import type { WorkflowJson } from "../domain/workflow/checkpoint.types.ts";
3
3
  export interface QueueHandlerContext {
4
+ readonly idempotencyKey: string;
4
5
  readonly signal: AbortSignal;
5
6
  readonly job: QueueJob;
6
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"queue-worker.types.js","sourceRoot":"","sources":["../../src/application/queue-worker.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n QueueJob,\n QueueResult,\n TaskQueue,\n} from \"../domain/task-queue.types.ts\";\nimport type { WorkflowJson } from \"../domain/workflow/checkpoint.types.ts\";\nexport interface QueueHandlerContext {\n readonly signal: AbortSignal;\n readonly job: QueueJob;\n}\nexport type QueueHandler = (\n input: WorkflowJson,\n context: QueueHandlerContext,\n) => Promise<QueueResult> | QueueResult;\nexport interface QueueWorkerOptions {\n readonly queue: TaskQueue;\n readonly worker: string;\n readonly handlers: Readonly<Record<string, QueueHandler>>;\n readonly signal: AbortSignal;\n readonly leaseMs?: number;\n readonly pollMs?: number;\n}\n"]}
1
+ {"version":3,"file":"queue-worker.types.js","sourceRoot":"","sources":["../../src/application/queue-worker.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n QueueJob,\n QueueResult,\n TaskQueue,\n} from \"../domain/task-queue.types.ts\";\nimport type { WorkflowJson } from \"../domain/workflow/checkpoint.types.ts\";\nexport interface QueueHandlerContext {\n readonly idempotencyKey: string;\n readonly signal: AbortSignal;\n readonly job: QueueJob;\n}\nexport type QueueHandler = (\n input: WorkflowJson,\n context: QueueHandlerContext,\n) => Promise<QueueResult> | QueueResult;\nexport interface QueueWorkerOptions {\n readonly queue: TaskQueue;\n readonly worker: string;\n readonly handlers: Readonly<Record<string, QueueHandler>>;\n readonly signal: AbortSignal;\n readonly leaseMs?: number;\n readonly pollMs?: number;\n}\n"]}