@elie-laloum/outpost 4.2.0 → 5.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 (450) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +5 -3
  3. package/dist/{cli/init-authentication.constants.js → adapters/agents/authentication.constants.js} +1 -1
  4. package/dist/adapters/agents/authentication.constants.js.map +1 -0
  5. package/dist/adapters/agents/authentication.d.ts +2 -0
  6. package/dist/adapters/agents/authentication.js +52 -0
  7. package/dist/adapters/agents/authentication.js.map +1 -0
  8. package/dist/adapters/agents/claude-adapter.d.ts +2 -2
  9. package/dist/adapters/agents/claude-adapter.js +30 -2
  10. package/dist/adapters/agents/claude-adapter.js.map +1 -1
  11. package/dist/adapters/agents/claude-request.d.ts +2 -2
  12. package/dist/adapters/agents/claude-request.js +3 -3
  13. package/dist/adapters/agents/claude-request.js.map +1 -1
  14. package/dist/adapters/agents/codex-adapter.d.ts +2 -2
  15. package/dist/adapters/agents/codex-adapter.js +17 -1
  16. package/dist/adapters/agents/codex-adapter.js.map +1 -1
  17. package/dist/adapters/agents/codex-provider.d.ts +2 -2
  18. package/dist/adapters/agents/codex-provider.js +1 -1
  19. package/dist/adapters/agents/codex-provider.js.map +1 -1
  20. package/dist/adapters/agents/codex-request.d.ts +2 -2
  21. package/dist/adapters/agents/codex-request.js +3 -3
  22. package/dist/adapters/agents/codex-request.js.map +1 -1
  23. package/dist/adapters/agents/gemini-adapter.d.ts +2 -2
  24. package/dist/adapters/agents/gemini-adapter.js +20 -1
  25. package/dist/adapters/agents/gemini-adapter.js.map +1 -1
  26. package/dist/adapters/agents/gemini-request.d.ts +2 -1
  27. package/dist/adapters/agents/gemini-request.js +1 -1
  28. package/dist/adapters/agents/gemini-request.js.map +1 -1
  29. package/dist/adapters/agents/gemini.types.d.ts +2 -1
  30. package/dist/adapters/agents/gemini.types.js.map +1 -1
  31. package/dist/adapters/agents/model-support.constants.d.ts +6 -0
  32. package/dist/adapters/agents/model-support.constants.js +18 -0
  33. package/dist/adapters/agents/model-support.constants.js.map +1 -0
  34. package/dist/adapters/agents/model-support.d.ts +4 -0
  35. package/dist/adapters/agents/model-support.js +11 -0
  36. package/dist/adapters/agents/model-support.js.map +1 -0
  37. package/dist/adapters/agents/settings.types.d.ts +11 -3
  38. package/dist/adapters/agents/settings.types.js.map +1 -1
  39. package/dist/adapters/models/anthropic-model-provider.constants.d.ts +3 -0
  40. package/dist/adapters/models/anthropic-model-provider.constants.js +17 -0
  41. package/dist/adapters/models/anthropic-model-provider.constants.js.map +1 -0
  42. package/dist/adapters/models/anthropic-model-provider.d.ts +3 -0
  43. package/dist/adapters/models/anthropic-model-provider.js +31 -0
  44. package/dist/adapters/models/anthropic-model-provider.js.map +1 -0
  45. package/dist/adapters/models/anthropic-model-provider.types.d.ts +7 -0
  46. package/dist/adapters/models/anthropic-model-provider.types.js +2 -0
  47. package/dist/adapters/models/anthropic-model-provider.types.js.map +1 -0
  48. package/dist/adapters/models/anthropic-request.d.ts +4 -0
  49. package/dist/adapters/models/anthropic-request.js +81 -0
  50. package/dist/adapters/models/anthropic-request.js.map +1 -0
  51. package/dist/adapters/models/anthropic-response.d.ts +3 -0
  52. package/dist/adapters/models/anthropic-response.js +55 -0
  53. package/dist/adapters/models/anthropic-response.js.map +1 -0
  54. package/dist/adapters/models/anthropic-stream.d.ts +2 -0
  55. package/dist/adapters/models/anthropic-stream.js +96 -0
  56. package/dist/adapters/models/anthropic-stream.js.map +1 -0
  57. package/dist/adapters/models/http-provider.d.ts +3 -0
  58. package/dist/adapters/models/http-provider.js +113 -0
  59. package/dist/adapters/models/http-provider.js.map +1 -0
  60. package/dist/adapters/models/{openai-http.js → model-http.js} +1 -1
  61. package/dist/adapters/models/model-http.js.map +1 -0
  62. package/dist/adapters/models/model-protocol.types.d.ts +41 -0
  63. package/dist/adapters/models/model-protocol.types.js +2 -0
  64. package/dist/adapters/models/model-protocol.types.js.map +1 -0
  65. package/dist/adapters/models/model-request.d.ts +2 -0
  66. package/dist/adapters/models/model-request.js +18 -0
  67. package/dist/adapters/models/model-request.js.map +1 -0
  68. package/dist/adapters/models/model-response.d.ts +7 -0
  69. package/dist/adapters/models/model-response.js +41 -0
  70. package/dist/adapters/models/model-response.js.map +1 -0
  71. package/dist/adapters/models/{openai-compatible.constants.js → model.constants.js} +6 -1
  72. package/dist/adapters/models/model.constants.js.map +1 -0
  73. package/dist/adapters/models/openai-chat-stream.d.ts +2 -0
  74. package/dist/adapters/models/openai-chat-stream.js +66 -0
  75. package/dist/adapters/models/openai-chat-stream.js.map +1 -0
  76. package/dist/adapters/models/openai-chat.d.ts +4 -0
  77. package/dist/adapters/models/openai-chat.js +108 -0
  78. package/dist/adapters/models/openai-chat.js.map +1 -0
  79. package/dist/adapters/models/openai-model-provider.d.ts +3 -0
  80. package/dist/adapters/models/openai-model-provider.js +13 -0
  81. package/dist/adapters/models/openai-model-provider.js.map +1 -0
  82. package/dist/adapters/models/openai-model-provider.types.d.ts +4 -0
  83. package/dist/adapters/models/openai-model-provider.types.js +2 -0
  84. package/dist/adapters/models/openai-model-provider.types.js.map +1 -0
  85. package/dist/adapters/models/openai-protocols.d.ts +2 -0
  86. package/dist/adapters/models/openai-protocols.js +22 -0
  87. package/dist/adapters/models/openai-protocols.js.map +1 -0
  88. package/dist/adapters/models/openai-responses-stream.d.ts +2 -0
  89. package/dist/adapters/models/openai-responses-stream.js +35 -0
  90. package/dist/adapters/models/openai-responses-stream.js.map +1 -0
  91. package/dist/adapters/models/openai-responses.d.ts +4 -0
  92. package/dist/adapters/models/openai-responses.js +107 -0
  93. package/dist/adapters/models/openai-responses.js.map +1 -0
  94. package/dist/adapters/models/openai-usage.d.ts +3 -0
  95. package/dist/adapters/models/openai-usage.js +20 -0
  96. package/dist/adapters/models/openai-usage.js.map +1 -0
  97. package/dist/adapters/models/stop-reasons.constants.d.ts +4 -0
  98. package/dist/adapters/models/stop-reasons.constants.js +19 -0
  99. package/dist/adapters/models/stop-reasons.constants.js.map +1 -0
  100. package/dist/adapters/models/stream-events.d.ts +3 -0
  101. package/dist/adapters/models/stream-events.js +22 -0
  102. package/dist/adapters/models/stream-events.js.map +1 -0
  103. package/dist/adapters/tools/edit-tools.d.ts +2 -0
  104. package/dist/adapters/tools/edit-tools.js +84 -0
  105. package/dist/adapters/tools/edit-tools.js.map +1 -0
  106. package/dist/adapters/tools/file-tools.d.ts +2 -0
  107. package/dist/adapters/tools/file-tools.js +97 -0
  108. package/dist/adapters/tools/file-tools.js.map +1 -0
  109. package/dist/adapters/tools/git-tools.d.ts +2 -0
  110. package/dist/adapters/tools/git-tools.js +54 -0
  111. package/dist/adapters/tools/git-tools.js.map +1 -0
  112. package/dist/adapters/tools/sandbox-files.d.ts +10 -0
  113. package/dist/adapters/tools/sandbox-files.js +60 -0
  114. package/dist/adapters/tools/sandbox-files.js.map +1 -0
  115. package/dist/adapters/tools/search-tools.d.ts +2 -0
  116. package/dist/adapters/tools/search-tools.js +65 -0
  117. package/dist/adapters/tools/search-tools.js.map +1 -0
  118. package/dist/adapters/tools/shell-tools.d.ts +3 -0
  119. package/dist/adapters/tools/shell-tools.js +38 -0
  120. package/dist/adapters/tools/shell-tools.js.map +1 -0
  121. package/dist/adapters/tools/tools.constants.d.ts +11 -0
  122. package/dist/adapters/tools/tools.constants.js +17 -0
  123. package/dist/adapters/tools/tools.constants.js.map +1 -0
  124. package/dist/adapters/tools/tools.types.d.ts +41 -0
  125. package/dist/adapters/tools/tools.types.js +2 -0
  126. package/dist/adapters/tools/tools.types.js.map +1 -0
  127. package/dist/application/activity-watchdog.js +15 -2
  128. package/dist/application/activity-watchdog.js.map +1 -1
  129. package/dist/application/agent-bootstrap.d.ts +2 -2
  130. package/dist/application/agent-bootstrap.js +2 -0
  131. package/dist/application/agent-bootstrap.js.map +1 -1
  132. package/dist/application/agent-storage.d.ts +3 -2
  133. package/dist/application/agent-storage.js +9 -2
  134. package/dist/application/agent-storage.js.map +1 -1
  135. package/dist/application/agent-turn.d.ts +3 -3
  136. package/dist/application/agent-turn.js +7 -1
  137. package/dist/application/agent-turn.js.map +1 -1
  138. package/dist/application/attach.js +1 -0
  139. package/dist/application/attach.js.map +1 -1
  140. package/dist/application/custom-turn.d.ts +5 -0
  141. package/dist/application/custom-turn.js +190 -0
  142. package/dist/application/custom-turn.js.map +1 -0
  143. package/dist/application/dispatch-observation.d.ts +3 -0
  144. package/dist/application/dispatch-observation.js +51 -0
  145. package/dist/application/dispatch-observation.js.map +1 -0
  146. package/dist/application/dispatch-observation.types.d.ts +5 -0
  147. package/dist/application/dispatch-observation.types.js +2 -0
  148. package/dist/application/dispatch-observation.types.js.map +1 -0
  149. package/dist/application/dispatch-validation.d.ts +2 -2
  150. package/dist/application/dispatch-validation.js.map +1 -1
  151. package/dist/application/dispatch.js +8 -3
  152. package/dist/application/dispatch.js.map +1 -1
  153. package/dist/application/doctor-image.js +3 -3
  154. package/dist/application/doctor-image.js.map +1 -1
  155. package/dist/application/doctor-protocol.js +9 -4
  156. package/dist/application/doctor-protocol.js.map +1 -1
  157. package/dist/application/doctor-sandbox.js +4 -4
  158. package/dist/application/doctor-sandbox.js.map +1 -1
  159. package/dist/application/doctor-sandbox.types.d.ts +2 -2
  160. package/dist/application/doctor-sandbox.types.js.map +1 -1
  161. package/dist/application/doctor.constants.d.ts +1 -1
  162. package/dist/application/doctor.constants.js +1 -1
  163. package/dist/application/doctor.constants.js.map +1 -1
  164. package/dist/application/doctor.js +10 -9
  165. package/dist/application/doctor.js.map +1 -1
  166. package/dist/application/doctor.types.d.ts +3 -3
  167. package/dist/application/doctor.types.js.map +1 -1
  168. package/dist/application/execution.d.ts +2 -2
  169. package/dist/application/execution.js +1 -1
  170. package/dist/application/execution.js.map +1 -1
  171. package/dist/application/execution.types.d.ts +9 -2
  172. package/dist/application/execution.types.js.map +1 -1
  173. package/dist/application/harness-context.d.ts +2 -0
  174. package/dist/application/harness-context.js +54 -0
  175. package/dist/application/harness-context.js.map +1 -0
  176. package/dist/application/harness-history.d.ts +3 -0
  177. package/dist/application/harness-history.js +17 -0
  178. package/dist/application/harness-history.js.map +1 -0
  179. package/dist/application/harness-hooks.d.ts +9 -0
  180. package/dist/application/harness-hooks.js +90 -0
  181. package/dist/application/harness-hooks.js.map +1 -0
  182. package/dist/application/harness-loop.d.ts +2 -0
  183. package/dist/application/harness-loop.js +132 -0
  184. package/dist/application/harness-loop.js.map +1 -0
  185. package/dist/application/harness.types.d.ts +55 -0
  186. package/dist/application/harness.types.js +2 -0
  187. package/dist/application/harness.types.js.map +1 -0
  188. package/dist/application/lifecycle.constants.d.ts +1 -1
  189. package/dist/application/lifecycle.constants.js +1 -1
  190. package/dist/application/lifecycle.constants.js.map +1 -1
  191. package/dist/application/outpost.types.d.ts +6 -6
  192. package/dist/application/outpost.types.js.map +1 -1
  193. package/dist/application/remote-download.js +1 -1
  194. package/dist/application/remote-download.js.map +1 -1
  195. package/dist/application/sandbox-agents.js +12 -4
  196. package/dist/application/sandbox-agents.js.map +1 -1
  197. package/dist/application/sandbox-attach.js +5 -2
  198. package/dist/application/sandbox-attach.js.map +1 -1
  199. package/dist/application/sandbox-dispatch.js +3 -3
  200. package/dist/application/sandbox-dispatch.js.map +1 -1
  201. package/dist/application/sandbox-provision.js +13 -10
  202. package/dist/application/sandbox-provision.js.map +1 -1
  203. package/dist/application/sandbox-session.types.d.ts +8 -8
  204. package/dist/application/sandbox-session.types.js.map +1 -1
  205. package/dist/application/sandbox.js +6 -3
  206. package/dist/application/sandbox.js.map +1 -1
  207. package/dist/application/speculation.js +1 -1
  208. package/dist/application/speculation.js.map +1 -1
  209. package/dist/application/speculation.types.d.ts +3 -3
  210. package/dist/application/speculation.types.js.map +1 -1
  211. package/dist/application/tasks.types.d.ts +2 -2
  212. package/dist/application/tasks.types.js.map +1 -1
  213. package/dist/application/tool-execution.d.ts +3 -0
  214. package/dist/application/tool-execution.js +211 -0
  215. package/dist/application/tool-execution.js.map +1 -0
  216. package/dist/cli/commands.js +4 -2
  217. package/dist/cli/commands.js.map +1 -1
  218. package/dist/cli/doctor-command.js +6 -6
  219. package/dist/cli/doctor-command.js.map +1 -1
  220. package/dist/cli/init-authentication.js +6 -7
  221. package/dist/cli/init-authentication.js.map +1 -1
  222. package/dist/cli/init-command.js +3 -3
  223. package/dist/cli/init-command.js.map +1 -1
  224. package/dist/cli/main.constants.d.ts +4 -4
  225. package/dist/cli/main.constants.js +4 -4
  226. package/dist/cli/main.constants.js.map +1 -1
  227. package/dist/cli/recovery-command.js +1 -1
  228. package/dist/cli/recovery-command.js.map +1 -1
  229. package/dist/cli/scaffold-files.js +5 -4
  230. package/dist/cli/scaffold-files.js.map +1 -1
  231. package/dist/cli/scaffold-validation.js +13 -10
  232. package/dist/cli/scaffold-validation.js.map +1 -1
  233. package/dist/cli/scaffold.js +8 -4
  234. package/dist/cli/scaffold.js.map +1 -1
  235. package/dist/cli/scaffold.types.d.ts +1 -1
  236. package/dist/cli/scaffold.types.js.map +1 -1
  237. package/dist/cli/starters.js +8 -8
  238. package/dist/cli/starters.js.map +1 -1
  239. package/dist/domain/agent-model.d.ts +3 -0
  240. package/dist/domain/agent-model.js +22 -0
  241. package/dist/domain/agent-model.js.map +1 -0
  242. package/dist/domain/agent.d.ts +4 -0
  243. package/dist/domain/agent.js +32 -0
  244. package/dist/domain/agent.js.map +1 -0
  245. package/dist/domain/agent.types.d.ts +69 -2
  246. package/dist/domain/agent.types.js.map +1 -1
  247. package/dist/domain/context.constants.d.ts +7 -0
  248. package/dist/domain/context.constants.js +8 -0
  249. package/dist/domain/context.constants.js.map +1 -0
  250. package/dist/domain/context.d.ts +4 -0
  251. package/dist/domain/context.js +81 -0
  252. package/dist/domain/context.js.map +1 -0
  253. package/dist/domain/context.types.d.ts +26 -0
  254. package/dist/domain/context.types.js +2 -0
  255. package/dist/domain/context.types.js.map +1 -0
  256. package/dist/domain/dispatch-telemetry.types.d.ts +12 -0
  257. package/dist/domain/dispatch-telemetry.types.js +2 -0
  258. package/dist/domain/dispatch-telemetry.types.js.map +1 -0
  259. package/dist/domain/errors.types.d.ts +1 -1
  260. package/dist/domain/errors.types.js.map +1 -1
  261. package/dist/domain/glob.d.ts +2 -0
  262. package/dist/domain/glob.js +25 -0
  263. package/dist/domain/glob.js.map +1 -0
  264. package/dist/domain/glob.types.d.ts +1 -0
  265. package/dist/domain/glob.types.js +2 -0
  266. package/dist/domain/glob.types.js.map +1 -0
  267. package/dist/domain/harness.constants.d.ts +11 -0
  268. package/dist/domain/harness.constants.js +24 -0
  269. package/dist/domain/harness.constants.js.map +1 -0
  270. package/dist/domain/harness.d.ts +2 -0
  271. package/dist/domain/harness.js +89 -0
  272. package/dist/domain/harness.js.map +1 -0
  273. package/dist/domain/harness.types.d.ts +60 -0
  274. package/dist/domain/harness.types.js +2 -0
  275. package/dist/domain/harness.types.js.map +1 -0
  276. package/dist/domain/hook.constants.d.ts +3 -0
  277. package/dist/domain/hook.constants.js +10 -0
  278. package/dist/domain/hook.constants.js.map +1 -0
  279. package/dist/domain/hook.d.ts +3 -0
  280. package/dist/domain/hook.js +25 -0
  281. package/dist/domain/hook.js.map +1 -0
  282. package/dist/domain/hook.types.d.ts +66 -0
  283. package/dist/domain/hook.types.js +2 -0
  284. package/dist/domain/hook.types.js.map +1 -0
  285. package/dist/domain/instructions.d.ts +3 -0
  286. package/dist/domain/instructions.js +25 -0
  287. package/dist/domain/instructions.js.map +1 -0
  288. package/dist/domain/model-messages.d.ts +5 -0
  289. package/dist/domain/model-messages.js +81 -0
  290. package/dist/domain/model-messages.js.map +1 -0
  291. package/dist/domain/model-messages.types.d.ts +6 -0
  292. package/dist/domain/model-messages.types.js +2 -0
  293. package/dist/domain/model-messages.types.js.map +1 -0
  294. package/dist/domain/model.constants.d.ts +4 -0
  295. package/dist/domain/model.constants.js +16 -0
  296. package/dist/domain/model.constants.js.map +1 -0
  297. package/dist/domain/model.types.d.ts +59 -2
  298. package/dist/domain/model.types.js.map +1 -1
  299. package/dist/domain/permissions.d.ts +3 -0
  300. package/dist/domain/permissions.js +92 -0
  301. package/dist/domain/permissions.js.map +1 -0
  302. package/dist/domain/permissions.types.d.ts +34 -0
  303. package/dist/domain/permissions.types.js +2 -0
  304. package/dist/domain/permissions.types.js.map +1 -0
  305. package/dist/domain/response.js +3 -2
  306. package/dist/domain/response.js.map +1 -1
  307. package/dist/domain/response.types.d.ts +12 -0
  308. package/dist/domain/response.types.js.map +1 -1
  309. package/dist/domain/skill.constants.d.ts +2 -0
  310. package/dist/domain/skill.constants.js +8 -0
  311. package/dist/domain/skill.constants.js.map +1 -0
  312. package/dist/domain/skill.d.ts +8 -0
  313. package/dist/domain/skill.js +79 -0
  314. package/dist/domain/skill.js.map +1 -0
  315. package/dist/domain/skill.types.d.ts +18 -0
  316. package/dist/domain/skill.types.js +2 -0
  317. package/dist/domain/skill.types.js.map +1 -0
  318. package/dist/domain/standard-schema.d.ts +6 -0
  319. package/dist/domain/standard-schema.js +45 -0
  320. package/dist/domain/standard-schema.js.map +1 -0
  321. package/dist/domain/tool-schema.d.ts +3 -0
  322. package/dist/domain/tool-schema.js +109 -0
  323. package/dist/domain/tool-schema.js.map +1 -0
  324. package/dist/domain/tool.constants.d.ts +4 -0
  325. package/dist/domain/tool.constants.js +36 -0
  326. package/dist/domain/tool.constants.js.map +1 -0
  327. package/dist/domain/tool.d.ts +4 -0
  328. package/dist/domain/tool.js +66 -0
  329. package/dist/domain/tool.js.map +1 -0
  330. package/dist/domain/tool.types.d.ts +62 -0
  331. package/dist/domain/tool.types.js +2 -0
  332. package/dist/domain/tool.types.js.map +1 -0
  333. package/dist/domain/transcript.d.ts +4 -0
  334. package/dist/domain/transcript.js +48 -0
  335. package/dist/domain/transcript.js.map +1 -0
  336. package/dist/domain/transcript.types.d.ts +15 -0
  337. package/dist/domain/transcript.types.js +2 -0
  338. package/dist/domain/transcript.types.js.map +1 -0
  339. package/dist/domain/workflow/workflow-state.js +13 -6
  340. package/dist/domain/workflow/workflow-state.js.map +1 -1
  341. package/dist/domain/workflow.d.ts +1 -1
  342. package/dist/domain/workflow.js.map +1 -1
  343. package/dist/domain/workflow.types.d.ts +4 -0
  344. package/dist/domain/workflow.types.js.map +1 -1
  345. package/dist/index.d.ts +34 -8
  346. package/dist/index.js +19 -4
  347. package/dist/index.js.map +1 -1
  348. package/dist/infrastructure/conversations/harness-store.d.ts +3 -0
  349. package/dist/infrastructure/conversations/harness-store.js +27 -0
  350. package/dist/infrastructure/conversations/harness-store.js.map +1 -0
  351. package/dist/infrastructure/conversations/harness-transcript.d.ts +2 -0
  352. package/dist/infrastructure/conversations/harness-transcript.js +50 -0
  353. package/dist/infrastructure/conversations/harness-transcript.js.map +1 -0
  354. package/dist/infrastructure/conversations/harness-transcript.types.d.ts +18 -0
  355. package/dist/infrastructure/conversations/harness-transcript.types.js +2 -0
  356. package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -0
  357. package/dist/infrastructure/conversations.d.ts +4 -1
  358. package/dist/infrastructure/conversations.js +3 -0
  359. package/dist/infrastructure/conversations.js.map +1 -1
  360. package/dist/infrastructure/conversations.types.d.ts +1 -0
  361. package/dist/infrastructure/conversations.types.js.map +1 -1
  362. package/dist/infrastructure/custom-reporter.d.ts +2 -0
  363. package/dist/infrastructure/custom-reporter.js +33 -0
  364. package/dist/infrastructure/custom-reporter.js.map +1 -0
  365. package/dist/infrastructure/custom-reporter.types.d.ts +13 -0
  366. package/dist/infrastructure/custom-reporter.types.js +2 -0
  367. package/dist/infrastructure/custom-reporter.types.js.map +1 -0
  368. package/dist/infrastructure/git/git.constants.d.ts +1 -1
  369. package/dist/infrastructure/git/git.constants.js +1 -0
  370. package/dist/infrastructure/git/git.constants.js.map +1 -1
  371. package/dist/infrastructure/journal.constants.d.ts +1 -0
  372. package/dist/infrastructure/journal.constants.js +2 -0
  373. package/dist/infrastructure/journal.constants.js.map +1 -0
  374. package/dist/infrastructure/journal.js +4 -1
  375. package/dist/infrastructure/journal.js.map +1 -1
  376. package/dist/infrastructure/opentelemetry-dispatch.d.ts +6 -0
  377. package/dist/infrastructure/opentelemetry-dispatch.js +70 -0
  378. package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -0
  379. package/dist/infrastructure/opentelemetry.constants.d.ts +3 -0
  380. package/dist/infrastructure/opentelemetry.constants.js +3 -0
  381. package/dist/infrastructure/opentelemetry.constants.js.map +1 -1
  382. package/dist/infrastructure/opentelemetry.js +4 -0
  383. package/dist/infrastructure/opentelemetry.js.map +1 -1
  384. package/dist/infrastructure/opentelemetry.types.d.ts +3 -3
  385. package/dist/infrastructure/opentelemetry.types.js.map +1 -1
  386. package/dist/infrastructure/reporter.js +27 -2
  387. package/dist/infrastructure/reporter.js.map +1 -1
  388. package/dist/infrastructure/resource-activity-inspection.js +3 -2
  389. package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
  390. package/dist/infrastructure/resource-activity.js +2 -2
  391. package/dist/infrastructure/resource-activity.js.map +1 -1
  392. package/dist/infrastructure/resource-activity.types.d.ts +2 -2
  393. package/dist/infrastructure/resource-activity.types.js.map +1 -1
  394. package/dist/infrastructure/settings.d.ts +1 -1
  395. package/dist/infrastructure/settings.js +3 -3
  396. package/dist/infrastructure/settings.js.map +1 -1
  397. package/dist/infrastructure/sse.d.ts +2 -0
  398. package/dist/infrastructure/sse.js +64 -0
  399. package/dist/infrastructure/sse.js.map +1 -0
  400. package/dist/infrastructure/sse.types.d.ts +4 -0
  401. package/dist/infrastructure/sse.types.js +2 -0
  402. package/dist/infrastructure/sse.types.js.map +1 -0
  403. package/dist/infrastructure/transport-conversations.d.ts +2 -2
  404. package/dist/infrastructure/transport-conversations.js +8 -1
  405. package/dist/infrastructure/transport-conversations.js.map +1 -1
  406. package/dist/infrastructure/transport-journal.js +2 -1
  407. package/dist/infrastructure/transport-journal.js.map +1 -1
  408. package/dist/providers/agents.d.ts +3 -3
  409. package/dist/providers/agents.js +3 -3
  410. package/dist/providers/agents.js.map +1 -1
  411. package/dist/providers/daytona.d.ts +1 -1
  412. package/dist/providers/daytona.js +1 -1
  413. package/dist/providers/daytona.js.map +1 -1
  414. package/dist/providers/docker.d.ts +1 -1
  415. package/dist/providers/docker.js +1 -1
  416. package/dist/providers/docker.js.map +1 -1
  417. package/dist/providers/factories.d.ts +2 -2
  418. package/dist/providers/factories.js +3 -3
  419. package/dist/providers/factories.js.map +1 -1
  420. package/dist/providers/firecracker.d.ts +1 -1
  421. package/dist/providers/firecracker.js +1 -1
  422. package/dist/providers/firecracker.js.map +1 -1
  423. package/dist/providers/local.d.ts +1 -1
  424. package/dist/providers/local.js +1 -1
  425. package/dist/providers/local.js.map +1 -1
  426. package/dist/providers/podman.d.ts +1 -1
  427. package/dist/providers/podman.js +1 -1
  428. package/dist/providers/podman.js.map +1 -1
  429. package/dist/providers/vercel.d.ts +1 -1
  430. package/dist/providers/vercel.js +1 -1
  431. package/dist/providers/vercel.js.map +1 -1
  432. package/package.json +1 -1
  433. package/dist/adapters/models/openai-compatible.constants.js.map +0 -1
  434. package/dist/adapters/models/openai-compatible.d.ts +0 -3
  435. package/dist/adapters/models/openai-compatible.js +0 -78
  436. package/dist/adapters/models/openai-compatible.js.map +0 -1
  437. package/dist/adapters/models/openai-compatible.types.d.ts +0 -14
  438. package/dist/adapters/models/openai-compatible.types.js +0 -2
  439. package/dist/adapters/models/openai-compatible.types.js.map +0 -1
  440. package/dist/adapters/models/openai-http.js.map +0 -1
  441. package/dist/adapters/models/openai-request.d.ts +0 -4
  442. package/dist/adapters/models/openai-request.js +0 -46
  443. package/dist/adapters/models/openai-request.js.map +0 -1
  444. package/dist/adapters/models/openai-response.d.ts +0 -3
  445. package/dist/adapters/models/openai-response.js +0 -65
  446. package/dist/adapters/models/openai-response.js.map +0 -1
  447. package/dist/cli/init-authentication.constants.js.map +0 -1
  448. /package/dist/{cli/init-authentication.constants.d.ts → adapters/agents/authentication.constants.d.ts} +0 -0
  449. /package/dist/adapters/models/{openai-http.d.ts → model-http.d.ts} +0 -0
  450. /package/dist/adapters/models/{openai-compatible.constants.d.ts → model.constants.d.ts} +0 -0
@@ -1,18 +1,26 @@
1
+ import { requireSuccess } from "../infrastructure/process.js";
1
2
  import { invariant } from "../domain/errors.js";
2
3
  import { resolveVariables } from "../infrastructure/settings.js";
3
4
  import { prepareAdapter } from "./agent-bootstrap.js";
4
5
  import { storageFor } from "./agent-storage.js";
5
6
  export function sandboxAgents(context) {
6
- const { options, provider, workspace, runtime, prepared, staging } = context;
7
+ const { options, sandboxProvider, workspace, runtime, prepared, staging } = context;
7
8
  const known = new Set();
9
+ const authenticated = new Map();
8
10
  const selectAgent = async (selected, signal) => {
9
11
  invariant(selected, "Provide an agent on the sandbox or this operation");
10
12
  if (!prepared.has(selected))
11
- prepared.set(selected, provider.placement === "remote" && options.bootstrap !== false
13
+ prepared.set(selected, sandboxProvider.placement === "remote" && options.bootstrap !== false
12
14
  ? await prepareAdapter(selected, runtime, signal)
13
15
  : selected);
14
- const variables = await resolveVariables(workspace.repository, selected.variables, provider.variables);
16
+ const variables = await resolveVariables(workspace.repository, selected.variables, sandboxProvider.variables);
15
17
  const adapter = prepared.get(selected);
18
+ if (adapter.kind === "cli" && authenticated.get(adapter.name) !== adapter) {
19
+ const command = adapter.authenticate?.(variables);
20
+ if (command)
21
+ await requireSuccess({ ...command, variables, signal }, runtime.invoke.bind(runtime));
22
+ authenticated.set(adapter.name, adapter);
23
+ }
16
24
  return {
17
25
  selected,
18
26
  adapter,
@@ -35,7 +43,7 @@ export function sandboxAgents(context) {
35
43
  invariant(storage, "This adapter does not support native conversations");
36
44
  const found = await storage.locate(id, workspace.repository, options.conversationHome);
37
45
  if (found.reference !== undefined ||
38
- provider.placement !== "host" ||
46
+ sandboxProvider.placement !== "host" ||
39
47
  workspace.directory !== workspace.repository)
40
48
  await storage.restore(found, {
41
49
  repository: workspace.repository,
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-agents.js","sourceRoot":"","sources":["../../src/application/sandbox-agents.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { Command } from \"../domain/command.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport function sandboxAgents(context: ProvisionedSandbox): SandboxAgents {\n const { options, provider, workspace, runtime, prepared, staging } = context;\n const known = new Set<string>();\n const selectAgent = async (\n selected: AgentAdapter | undefined,\n signal: AbortSignal,\n ) => {\n invariant(selected, \"Provide an agent on the sandbox or this operation\");\n if (!prepared.has(selected))\n prepared.set(\n selected,\n provider.placement === \"remote\" && options.bootstrap !== false\n ? await prepareAdapter(selected, runtime, signal)\n : selected,\n );\n const variables = await resolveVariables(\n workspace.repository,\n selected.variables,\n provider.variables,\n );\n const adapter = prepared.get(selected)!;\n return {\n selected,\n adapter,\n executionLease: {\n ...runtime,\n invoke(command: Command) {\n return runtime.invoke({\n ...command,\n variables: { ...variables, ...command.variables },\n });\n },\n },\n };\n };\n const conversationKey = (agent: AgentAdapter, id: string) =>\n `${agent.storage?.name ?? agent.conversations ?? agent.name}:${id}`;\n const restore = async (id: string, agent: AgentAdapter) => {\n if (known.has(conversationKey(agent, id))) return;\n const storage = storageFor(agent);\n invariant(storage, \"This adapter does not support native conversations\");\n const found = await storage.locate(\n id,\n workspace.repository,\n options.conversationHome,\n );\n if (\n found.reference !== undefined ||\n provider.placement !== \"host\" ||\n workspace.directory !== workspace.repository\n )\n await storage.restore(found, {\n repository: workspace.repository,\n sandbox: runtime,\n staging,\n });\n known.add(conversationKey(agent, id));\n };\n\n return {\n selectAgent,\n restore,\n remember: (agent, id) => {\n known.add(conversationKey(agent, id));\n },\n };\n}\n"]}
1
+ {"version":3,"file":"sandbox-agents.js","sourceRoot":"","sources":["../../src/application/sandbox-agents.ts"],"names":[],"mappings":"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","sourcesContent":["import { requireSuccess } from \"../infrastructure/process.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport type { Command } from \"../domain/command.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport function sandboxAgents(context: ProvisionedSandbox): SandboxAgents {\n const { options, sandboxProvider, workspace, runtime, prepared, staging } =\n context;\n const known = new Set<string>();\n const authenticated = new Map<string, Agent>();\n const selectAgent = async (\n selected: Agent | undefined,\n signal: AbortSignal,\n ) => {\n invariant(selected, \"Provide an agent on the sandbox or this operation\");\n if (!prepared.has(selected))\n prepared.set(\n selected,\n sandboxProvider.placement === \"remote\" && options.bootstrap !== false\n ? await prepareAdapter(selected, runtime, signal)\n : selected,\n );\n const variables = await resolveVariables(\n workspace.repository,\n selected.variables,\n sandboxProvider.variables,\n );\n const adapter = prepared.get(selected)!;\n if (adapter.kind === \"cli\" && authenticated.get(adapter.name) !== adapter) {\n const command = adapter.authenticate?.(variables);\n if (command)\n await requireSuccess(\n { ...command, variables, signal },\n runtime.invoke.bind(runtime),\n );\n authenticated.set(adapter.name, adapter);\n }\n return {\n selected,\n adapter,\n executionLease: {\n ...runtime,\n invoke(command: Command) {\n return runtime.invoke({\n ...command,\n variables: { ...variables, ...command.variables },\n });\n },\n },\n };\n };\n const conversationKey = (agent: Agent, id: string) =>\n `${agent.storage?.name ?? agent.conversations ?? agent.name}:${id}`;\n const restore = async (id: string, agent: Agent) => {\n if (known.has(conversationKey(agent, id))) return;\n const storage = storageFor(agent);\n invariant(storage, \"This adapter does not support native conversations\");\n const found = await storage.locate(\n id,\n workspace.repository,\n options.conversationHome,\n );\n if (\n found.reference !== undefined ||\n sandboxProvider.placement !== \"host\" ||\n workspace.directory !== workspace.repository\n )\n await storage.restore(found, {\n repository: workspace.repository,\n sandbox: runtime,\n staging,\n });\n known.add(conversationKey(agent, id));\n };\n\n return {\n selectAgent,\n restore,\n remember: (agent, id) => {\n known.add(conversationKey(agent, id));\n },\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { invariant } from "../domain/errors.js";
1
2
  import { git } from "../infrastructure/git/command.js";
2
3
  import { commits } from "../infrastructure/git/history.js";
3
4
  import { restoreTerminal } from "../infrastructure/terminal.js";
@@ -5,7 +6,8 @@ import { renderBrief } from "./brief-renderer.js";
5
6
  import { executionDefaults } from "./execution.constants.js";
6
7
  import { completeBrief } from "./interactive-brief.js";
7
8
  export async function attachInSandbox(context, agents, settings) {
8
- const { options, provider, workspace, sync, stop } = context;
9
+ const { options, sandboxProvider, workspace, sync, stop } = context;
10
+ invariant((settings.agent ?? options.agent)?.kind === "cli", "This harness does not support interactive attachment");
9
11
  const { selectAgent, restore } = agents;
10
12
  const signal = settings.signal
11
13
  ? AbortSignal.any([settings.signal, stop.signal])
@@ -15,8 +17,9 @@ export async function attachInSandbox(context, agents, settings) {
15
17
  await restore(settings.continuation.id, selected);
16
18
  const brief = await completeBrief(settings.brief, signal, settings.ask);
17
19
  const text = brief
18
- ? await renderBrief(brief, workspace, executionLease, provider.placement === "host", settings)
20
+ ? await renderBrief(brief, workspace, executionLease, sandboxProvider.placement === "host", settings)
19
21
  : undefined;
22
+ invariant(adapter.kind === "cli", "This harness does not support interactive attachment");
20
23
  const command = adapter.request({
21
24
  interactive: true,
22
25
  ...(text === undefined ? {} : { text }),
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-attach.js","sourceRoot":"","sources":["../../src/application/sandbox-attach.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandResult } from \"../domain/command.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { commits } from \"../infrastructure/git/history.ts\";\nimport { restoreTerminal } from \"../infrastructure/terminal.ts\";\nimport { renderBrief } from \"./brief-renderer.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport { completeBrief } from \"./interactive-brief.ts\";\nimport type { AttachOptions, AttachResult } from \"./outpost.types.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport async function attachInSandbox(\n context: ProvisionedSandbox,\n agents: SandboxAgents,\n settings: AttachOptions,\n): Promise<AttachResult> {\n const { options, provider, workspace, sync, stop } = context;\n const { selectAgent, restore } = agents;\n const signal = settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal;\n const { selected, adapter, executionLease } = await selectAgent(\n settings.agent ?? options.agent,\n signal,\n );\n if (settings.continuation) await restore(settings.continuation.id, selected);\n const brief = await completeBrief(settings.brief, signal, settings.ask);\n const text = brief\n ? await renderBrief(\n brief,\n workspace,\n executionLease,\n provider.placement === \"host\",\n settings,\n )\n : undefined;\n const command = adapter.request({\n interactive: true,\n ...(text === undefined ? {} : { text }),\n ...(settings.continuation ? { continuation: settings.continuation } : {}),\n });\n const baseline = (\n await git(workspace.directory, [\"rev-parse\", \"HEAD\"])\n ).trim();\n let output: CommandResult;\n try {\n output = await executionLease.invoke({\n ...command,\n ...(settings.terminal ? { terminal: settings.terminal } : {}),\n deadlineMs: executionDefaults.attachMs,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n restoreTerminal();\n await sync?.pull();\n }\n return {\n ...output,\n branch: workspace.branch,\n directory: workspace.directory,\n commits: await commits(\n workspace.directory,\n baseline,\n options.limits?.collectMs,\n ),\n };\n}\n"]}
1
+ {"version":3,"file":"sandbox-attach.js","sourceRoot":"","sources":["../../src/application/sandbox-attach.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport type { CommandResult } from \"../domain/command.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { commits } from \"../infrastructure/git/history.ts\";\nimport { restoreTerminal } from \"../infrastructure/terminal.ts\";\nimport { renderBrief } from \"./brief-renderer.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport { completeBrief } from \"./interactive-brief.ts\";\nimport type { AttachOptions, AttachResult } from \"./outpost.types.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport async function attachInSandbox(\n context: ProvisionedSandbox,\n agents: SandboxAgents,\n settings: AttachOptions,\n): Promise<AttachResult> {\n const { options, sandboxProvider, workspace, sync, stop } = context;\n invariant(\n (settings.agent ?? options.agent)?.kind === \"cli\",\n \"This harness does not support interactive attachment\",\n );\n const { selectAgent, restore } = agents;\n const signal = settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal;\n const { selected, adapter, executionLease } = await selectAgent(\n settings.agent ?? options.agent,\n signal,\n );\n if (settings.continuation) await restore(settings.continuation.id, selected);\n const brief = await completeBrief(settings.brief, signal, settings.ask);\n const text = brief\n ? await renderBrief(\n brief,\n workspace,\n executionLease,\n sandboxProvider.placement === \"host\",\n settings,\n )\n : undefined;\n invariant(\n adapter.kind === \"cli\",\n \"This harness does not support interactive attachment\",\n );\n const command = adapter.request({\n interactive: true,\n ...(text === undefined ? {} : { text }),\n ...(settings.continuation ? { continuation: settings.continuation } : {}),\n });\n const baseline = (\n await git(workspace.directory, [\"rev-parse\", \"HEAD\"])\n ).trim();\n let output: CommandResult;\n try {\n output = await executionLease.invoke({\n ...command,\n ...(settings.terminal ? { terminal: settings.terminal } : {}),\n deadlineMs: executionDefaults.attachMs,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n restoreTerminal();\n await sync?.pull();\n }\n return {\n ...output,\n branch: workspace.branch,\n directory: workspace.directory,\n commits: await commits(\n workspace.directory,\n baseline,\n options.limits?.collectMs,\n ),\n };\n}\n"]}
@@ -9,7 +9,7 @@ import { preflightDispatch } from "./dispatch-validation.js";
9
9
  import { execute } from "./execution.js";
10
10
  import { notify } from "./observation.js";
11
11
  export async function dispatchInSandbox(context, agents, result, dispatch) {
12
- const { options, provider, workspace, runtime, sync, stop, staging } = context;
12
+ const { options, sandboxProvider, workspace, runtime, sync, stop, staging } = context;
13
13
  const { selectAgent, restore } = agents;
14
14
  await preflightDispatch(dispatch, workspace.repository, dispatch.agent ?? options.agent);
15
15
  const signal = dispatch.signal
@@ -34,14 +34,14 @@ export async function dispatchInSandbox(context, agents, result, dispatch) {
34
34
  staging,
35
35
  ...(options.conversationHome ? { home: options.conversationHome } : {}),
36
36
  ...(dispatch.warn ? { warn: dispatch.warn } : {}),
37
- local: provider.placement === "host",
37
+ local: sandboxProvider.placement === "host",
38
38
  });
39
39
  captured.set(id, location);
40
40
  transcript = location;
41
41
  return location;
42
42
  };
43
43
  try {
44
- execution = await execute(workspace, executionLease, adapter, provider.placement === "host", {
44
+ execution = await execute(workspace, executionLease, adapter, sandboxProvider.placement === "host", {
45
45
  ...dispatch,
46
46
  signal,
47
47
  observe(event) {
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-dispatch.js","sourceRoot":"","sources":["../../src/application/sandbox-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAO1C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA2B,EAC3B,MAAqB,EACrB,MAAe,EACf,QAA4B;IAE5B,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAClE,OAAO,CAAC;IACV,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IACxC,MAAM,iBAAiB,CACrB,QAAQ,EACR,SAAS,CAAC,UAAU,EACpB,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAChC,CAAC;IACF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM;QAC5B,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,WAAW,CAC7D,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAC/B,MAAM,CACP,CAAC;IACF,IAAI,QAAQ,CAAC,YAAY;QAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,CACf,MAAM,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CACtD,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,GAAG,GAAG,MAAM,OAAO,CACvB,SAAS,CAAC,UAAU,EACpB,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,EACnC,QAAQ,CAAC,KAAK,CACf,CAAC;IACF,IAAI,SAAmC,EACrC,UAA0C,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,OAAgB,CAAC;IACrB,IAAI,YAAY,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAS,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,KAAK,EAAE,EAAU,EAAE,EAAE;QAChC,SAAS,CAAC,OAAO,EAAE,qCAAqC,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE;YACzC,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,OAAO,EAAE,OAAO;YAChB,OAAO;YACP,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,KAAK,EAAE,QAAQ,CAAC,SAAS,KAAK,MAAM;SACrC,CAAC,CAAC;QACH,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC3B,UAAU,GAAG,QAAQ,CAAC;QACtB,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IACF,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,OAAO,CACvB,SAAS,EACT,cAAc,EACd,OAAO,EACP,QAAQ,CAAC,SAAS,KAAK,MAAM,EAC7B;YACE,GAAG,QAAQ;YACX,MAAM;YACN,OAAO,CAAC,KAAK;gBACX,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAClC,YAAY,GAAG,KAAK,CAAC,EAAE,CAAC;oBACxB,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC5B,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtC,CAAC;gBACD,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAClC,CAAC;SACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK;gBAC9D,OAAO,IAAI,CAAC;YACd,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,EAAE,CACtC,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CACtC,CAAC;YACF,OAAO;gBACL,GAAG,IAAI;gBACP,UAAU,EAAE,QAAQ,CAAC,IAAI;gBACzB,GAAG,CAAC,QAAQ,CAAC,SAAS;oBACpB,CAAC,CAAC,EAAE,mBAAmB,EAAE,QAAQ,CAAC,SAAS,EAAE;oBAC7C,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5B,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,KAAK,CAAC;QAChB,GAAG,CAAC,MAAM,CAAC;YACT,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC;QACnB,IAAI,OAAO,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK;YACvC,KAAK,MAAM,EAAE,IAAI,aAAa;gBAC5B,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,OAAO;YACf,CAAC,CAAC,IAAI,cAAc,CAChB,CAAC,OAAO,EAAE,KAAK,CAAC,EAChB,oCAAoC,CACrC;YACH,CAAC,CAAC,KAAK,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,KAAK,CAAC;IACpB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAC3B,SAAS,CAAC,SAAS,EACnB,QAAQ,EACR,OAAO,CAAC,MAAM,EAAE,SAAS,CAC1B,CAAC;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,cAAc,CAAC,OAAO,EAAE;YACtB,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,OAAO,EAAE,OAAO;YAChB,UAAU,EAAE,UAAU,EAAE,IAAI;YAC5B,GAAG,EAAE,GAAG,CAAC,IAAI;YACb,YAAY,EAAE,GAAG,CAAC,SAAS;YAC3B,mBAAmB,EAAE,UAAU,EAAE,SAAS;SAC3C,CAAC,CAAC;QACH,MAAM,OAAO,CAAC;IAChB,CAAC;IACD,SAAS,CAAC,SAAS,EAAE,oCAAoC,CAAC,CAAC;IAC3D,OAAO;QACL,GAAG,SAAS;QACZ,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,OAAO,EAAE,OAAO;QAChB,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,UAAU,EAAE,SAAS;YACvB,CAAC,CAAC,EAAE,mBAAmB,EAAE,UAAU,CAAC,SAAS,EAAE;YAC/C,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,CAAI,IAAwB;YAChC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;YACvD,OAAO,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAI,IAAwB;YAC9B,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;YACvD,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport type { ConversationRecord } from \"../domain/conversation.types.ts\";\nimport { invariant, recordRecovery } from \"../domain/errors.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { commits } from \"../infrastructure/git/history.ts\";\nimport { journal } from \"../infrastructure/journal.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport { warmContinuation } from \"./continuation.ts\";\nimport { preflightDispatch } from \"./dispatch-validation.ts\";\nimport { execute } from \"./execution.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\nimport type { Sandbox, WarmDispatchResult } from \"./outpost.types.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport async function dispatchInSandbox<T>(\n context: ProvisionedSandbox,\n agents: SandboxAgents,\n result: Sandbox,\n dispatch: DispatchOptions<T>,\n): Promise<WarmDispatchResult<T>> {\n const { options, provider, workspace, runtime, sync, stop, staging } =\n context;\n const { selectAgent, restore } = agents;\n await preflightDispatch(\n dispatch,\n workspace.repository,\n dispatch.agent ?? options.agent,\n );\n const signal = dispatch.signal\n ? AbortSignal.any([dispatch.signal, stop.signal])\n : stop.signal;\n const { selected, adapter, executionLease } = await selectAgent(\n dispatch.agent ?? options.agent,\n signal,\n );\n if (dispatch.continuation) await restore(dispatch.continuation.id, selected);\n const baseline = (\n await git(workspace.directory, [\"rev-parse\", \"HEAD\"])\n ).trim();\n const log = await journal(\n workspace.repository,\n dispatch.logging ?? options.logging,\n dispatch.label,\n );\n let execution: Execution<T> | undefined,\n transcript: ConversationRecord | undefined;\n const captured = new Map<string, ConversationRecord>();\n const storage = storageFor(selected);\n let failure: unknown;\n let conversation = dispatch.continuation?.id;\n const conversations = new Set<string>(conversation ? [conversation] : []);\n const save = async (id: string) => {\n invariant(storage, \"Conversation storage is unavailable\");\n const location = await storage.capture(id, {\n repository: workspace.repository,\n sandbox: runtime,\n staging,\n ...(options.conversationHome ? { home: options.conversationHome } : {}),\n ...(dispatch.warn ? { warn: dispatch.warn } : {}),\n local: provider.placement === \"host\",\n });\n captured.set(id, location);\n transcript = location;\n return location;\n };\n try {\n execution = await execute(\n workspace,\n executionLease,\n adapter,\n provider.placement === \"host\",\n {\n ...dispatch,\n signal,\n observe(event) {\n if (event.kind === \"conversation\") {\n conversation = event.id;\n conversations.add(event.id);\n agents.remember(selected, event.id);\n }\n log.record(event);\n notify(dispatch.observe, event);\n },\n },\n async (turn) => {\n if (!turn.conversation || !storage || selected.capture === false)\n return turn;\n const location = await save(turn.conversation);\n const usage = selected.transcriptUsage?.(\n await readFile(location.file, \"utf8\"),\n );\n return {\n ...turn,\n transcript: location.file,\n ...(location.reference\n ? { transcriptReference: location.reference }\n : {}),\n ...(usage ? { usage } : {}),\n };\n },\n );\n } catch (cause) {\n failure = cause;\n log.record({\n kind: \"failure\",\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n try {\n await sync?.pull();\n if (storage && selected.capture !== false)\n for (const id of conversations)\n if (failure || !captured.has(id)) await save(id);\n } catch (cause) {\n failure = failure\n ? new AggregateError(\n [failure, cause],\n \"Execution and recovery both failed\",\n )\n : cause;\n }\n try {\n await log.close();\n } catch (cause) {\n failure ??= cause;\n }\n const changes = await commits(\n workspace.directory,\n baseline,\n options.limits?.collectMs,\n );\n if (failure) {\n recordRecovery(failure, {\n branch: workspace.branch,\n directory: workspace.directory,\n commits: changes,\n transcript: transcript?.file,\n log: log.file,\n logReference: log.reference,\n transcriptReference: transcript?.reference,\n });\n throw failure;\n }\n invariant(execution, \"Execution did not produce a result\");\n return {\n ...execution,\n branch: workspace.branch,\n directory: workspace.directory,\n commits: changes,\n ...(transcript ? { transcript: transcript.file } : {}),\n ...(log.file ? { log: log.file } : {}),\n ...(log.reference ? { logReference: log.reference } : {}),\n ...(transcript?.reference\n ? { transcriptReference: transcript.reference }\n : {}),\n resume<U>(next: DispatchOptions<U>) {\n warmContinuation(next);\n invariant(conversation, \"No conversation was emitted\");\n return result.resume(conversation, { agent: selected, ...next });\n },\n fork<U>(next: DispatchOptions<U>) {\n warmContinuation(next);\n invariant(conversation, \"No conversation was emitted\");\n return result.fork(conversation, { agent: selected, ...next });\n },\n };\n}\n"]}
1
+ {"version":3,"file":"sandbox-dispatch.js","sourceRoot":"","sources":["../../src/application/sandbox-dispatch.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport type { ConversationRecord } from \"../domain/conversation.types.ts\";\nimport { invariant, recordRecovery } from \"../domain/errors.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { commits } from \"../infrastructure/git/history.ts\";\nimport { journal } from \"../infrastructure/journal.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport { warmContinuation } from \"./continuation.ts\";\nimport { preflightDispatch } from \"./dispatch-validation.ts\";\nimport { execute } from \"./execution.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\nimport type { Sandbox, WarmDispatchResult } from \"./outpost.types.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport async function dispatchInSandbox<T>(\n context: ProvisionedSandbox,\n agents: SandboxAgents,\n result: Sandbox,\n dispatch: DispatchOptions<T>,\n): Promise<WarmDispatchResult<T>> {\n const { options, sandboxProvider, workspace, runtime, sync, stop, staging } =\n context;\n const { selectAgent, restore } = agents;\n await preflightDispatch(\n dispatch,\n workspace.repository,\n dispatch.agent ?? options.agent,\n );\n const signal = dispatch.signal\n ? AbortSignal.any([dispatch.signal, stop.signal])\n : stop.signal;\n const { selected, adapter, executionLease } = await selectAgent(\n dispatch.agent ?? options.agent,\n signal,\n );\n if (dispatch.continuation) await restore(dispatch.continuation.id, selected);\n const baseline = (\n await git(workspace.directory, [\"rev-parse\", \"HEAD\"])\n ).trim();\n const log = await journal(\n workspace.repository,\n dispatch.logging ?? options.logging,\n dispatch.label,\n );\n let execution: Execution<T> | undefined,\n transcript: ConversationRecord | undefined;\n const captured = new Map<string, ConversationRecord>();\n const storage = storageFor(selected);\n let failure: unknown;\n let conversation = dispatch.continuation?.id;\n const conversations = new Set<string>(conversation ? [conversation] : []);\n const save = async (id: string) => {\n invariant(storage, \"Conversation storage is unavailable\");\n const location = await storage.capture(id, {\n repository: workspace.repository,\n sandbox: runtime,\n staging,\n ...(options.conversationHome ? { home: options.conversationHome } : {}),\n ...(dispatch.warn ? { warn: dispatch.warn } : {}),\n local: sandboxProvider.placement === \"host\",\n });\n captured.set(id, location);\n transcript = location;\n return location;\n };\n try {\n execution = await execute(\n workspace,\n executionLease,\n adapter,\n sandboxProvider.placement === \"host\",\n {\n ...dispatch,\n signal,\n observe(event) {\n if (event.kind === \"conversation\") {\n conversation = event.id;\n conversations.add(event.id);\n agents.remember(selected, event.id);\n }\n log.record(event);\n notify(dispatch.observe, event);\n },\n },\n async (turn) => {\n if (!turn.conversation || !storage || selected.capture === false)\n return turn;\n const location = await save(turn.conversation);\n const usage = selected.transcriptUsage?.(\n await readFile(location.file, \"utf8\"),\n );\n return {\n ...turn,\n transcript: location.file,\n ...(location.reference\n ? { transcriptReference: location.reference }\n : {}),\n ...(usage ? { usage } : {}),\n };\n },\n );\n } catch (cause) {\n failure = cause;\n log.record({\n kind: \"failure\",\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n try {\n await sync?.pull();\n if (storage && selected.capture !== false)\n for (const id of conversations)\n if (failure || !captured.has(id)) await save(id);\n } catch (cause) {\n failure = failure\n ? new AggregateError(\n [failure, cause],\n \"Execution and recovery both failed\",\n )\n : cause;\n }\n try {\n await log.close();\n } catch (cause) {\n failure ??= cause;\n }\n const changes = await commits(\n workspace.directory,\n baseline,\n options.limits?.collectMs,\n );\n if (failure) {\n recordRecovery(failure, {\n branch: workspace.branch,\n directory: workspace.directory,\n commits: changes,\n transcript: transcript?.file,\n log: log.file,\n logReference: log.reference,\n transcriptReference: transcript?.reference,\n });\n throw failure;\n }\n invariant(execution, \"Execution did not produce a result\");\n return {\n ...execution,\n branch: workspace.branch,\n directory: workspace.directory,\n commits: changes,\n ...(transcript ? { transcript: transcript.file } : {}),\n ...(log.file ? { log: log.file } : {}),\n ...(log.reference ? { logReference: log.reference } : {}),\n ...(transcript?.reference\n ? { transcriptReference: transcript.reference }\n : {}),\n resume<U>(next: DispatchOptions<U>) {\n warmContinuation(next);\n invariant(conversation, \"No conversation was emitted\");\n return result.resume(conversation, { agent: selected, ...next });\n },\n fork<U>(next: DispatchOptions<U>) {\n warmContinuation(next);\n invariant(conversation, \"No conversation was emitted\");\n return result.fork(conversation, { agent: selected, ...next });\n },\n };\n}\n"]}
@@ -7,7 +7,7 @@ import { resolveVariables } from "../infrastructure/settings.js";
7
7
  import { registerResourceActivity } from "../infrastructure/resource-activity.js";
8
8
  import { trackedSandboxLease } from "./sandbox-activity.js";
9
9
  import { boundedTransfers } from "../infrastructure/transfer.js";
10
- import { docker } from "../providers/docker.js";
10
+ import { dockerSandboxProvider } from "../providers/docker.js";
11
11
  import { prepareAdapter } from "./agent-bootstrap.js";
12
12
  import { hooks } from "./lifecycle-hooks.js";
13
13
  import { uploadFiles } from "./remote-upload.js";
@@ -16,9 +16,12 @@ import { startupFailure } from "./startup-recovery.js";
16
16
  import { workspaces } from "./workspace-registry.js";
17
17
  import { openWorkspace } from "./workspace.js";
18
18
  export async function provisionSandbox(options) {
19
+ invariant(!("provider" in options), "Use sandboxProvider instead of provider");
19
20
  options.signal?.throwIfAborted();
20
- const provider = options.provider ?? docker();
21
- if (provider.placement === "remote" && !options.workspace && !options.branch)
21
+ const sandboxProvider = options.sandboxProvider ?? dockerSandboxProvider();
22
+ if (sandboxProvider.placement === "remote" &&
23
+ !options.workspace &&
24
+ !options.branch)
22
25
  options = { ...options, branch: { mode: "integrate" } };
23
26
  invariant(!options.workspace ||
24
27
  (!options.repository &&
@@ -26,7 +29,7 @@ export async function provisionSandbox(options) {
26
29
  !options.copies &&
27
30
  !options.storageQuota), "A supplied workspace owns its repository, branch, copied inputs and storage quota");
28
31
  const owned = !options.workspace;
29
- invariant(provider.placement !== "remote" ||
32
+ invariant(sandboxProvider.placement !== "remote" ||
30
33
  ((options.workspace?.policy ?? options.branch)?.mode !== "current" &&
31
34
  (options.workspace || options.branch)), "Remote providers require a named or integration workspace");
32
35
  const workspace = options.workspace ?? (await openWorkspace(options));
@@ -50,10 +53,10 @@ export async function provisionSandbox(options) {
50
53
  ? { transporter: options.activityTransport }
51
54
  : {}),
52
55
  workspace: workspace.directory,
53
- provider: provider.name,
54
- placement: provider.placement,
56
+ sandboxProvider: sandboxProvider.name,
57
+ placement: sandboxProvider.placement,
55
58
  });
56
- const configured = await resolveVariables(workspace.repository, {}, provider.variables);
59
+ const configured = await resolveVariables(workspace.repository, {}, sandboxProvider.variables);
57
60
  const name = (await git(workspace.repository, ["config", "--get", "user.name"]).catch(() => "Outpost")).trim();
58
61
  const email = (await git(workspace.repository, ["config", "--get", "user.email"]).catch(() => "outpost@localhost")).trim();
59
62
  const variables = {
@@ -64,7 +67,7 @@ export async function provisionSandbox(options) {
64
67
  ...configured,
65
68
  };
66
69
  acquisitionStarted = true;
67
- lease = boundedTransfers(trackedSandboxLease(await provider.acquire({
70
+ lease = boundedTransfers(trackedSandboxLease(await sandboxProvider.acquire({
68
71
  repository: workspace.repository,
69
72
  directory: workspace.directory,
70
73
  gitDirectories: workspace.gitDirectories,
@@ -75,7 +78,7 @@ export async function provisionSandbox(options) {
75
78
  ? { deadlineMs: options.limits.copyMs }
76
79
  : {}),
77
80
  });
78
- if (provider.placement === "remote") {
81
+ if (sandboxProvider.placement === "remote") {
79
82
  sync = await seedRemote(workspace, lease, {
80
83
  ...(options.recoveryTransport
81
84
  ? { recoveryTransport: options.recoveryTransport }
@@ -144,7 +147,7 @@ export async function provisionSandbox(options) {
144
147
  }
145
148
  return {
146
149
  options,
147
- provider,
150
+ sandboxProvider,
148
151
  workspace,
149
152
  state,
150
153
  owned,
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-provision.js","sourceRoot":"","sources":["../../src/application/sandbox-provision.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\nimport type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { executeProcess } from \"../infrastructure/process.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { registerResourceActivity } from \"../infrastructure/resource-activity.ts\";\nimport type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\nimport { trackedSandboxLease } from \"./sandbox-activity.ts\";\nimport { boundedTransfers } from \"../infrastructure/transfer.ts\";\nimport { docker } from \"../providers/docker.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { hooks } from \"./lifecycle-hooks.ts\";\nimport type { SandboxOptions } from \"./outpost.types.ts\";\nimport { uploadFiles } from \"./remote-upload.ts\";\nimport { seedRemote } from \"./remote-workspace.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\nimport type { ProvisionedSandbox } from \"./sandbox-session.types.ts\";\nimport { startupFailure } from \"./startup-recovery.ts\";\nimport { workspaces } from \"./workspace-registry.ts\";\nimport { openWorkspace } from \"./workspace.ts\";\n\nexport async function provisionSandbox(\n options: SandboxOptions,\n): Promise<ProvisionedSandbox> {\n options.signal?.throwIfAborted();\n const provider = options.provider ?? docker();\n if (provider.placement === \"remote\" && !options.workspace && !options.branch)\n options = { ...options, branch: { mode: \"integrate\" } };\n invariant(\n !options.workspace ||\n (!options.repository &&\n !options.branch &&\n !options.copies &&\n !options.storageQuota),\n \"A supplied workspace owns its repository, branch, copied inputs and storage quota\",\n );\n const owned = !options.workspace;\n invariant(\n provider.placement !== \"remote\" ||\n ((options.workspace?.policy ?? options.branch)?.mode !== \"current\" &&\n (options.workspace || options.branch)),\n \"Remote providers require a named or integration workspace\",\n );\n const workspace = options.workspace ?? (await openWorkspace(options));\n const state = workspaces.get(workspace);\n invariant(\n state && !state.closed && !state.active,\n \"Workspace must be open and cannot belong to another sandbox\",\n );\n state.active = true;\n const lifecycle = options.hooks ?? state.hooks;\n const stop = new AbortController();\n const setupSignal = options.signal\n ? AbortSignal.any([options.signal, stop.signal])\n : stop.signal;\n let lease: SandboxLease | undefined, sync: RemoteSync | undefined;\n let activity: ResourceActivity | undefined;\n let acquisitionStarted = false;\n const prepared = new Map<AgentAdapter, AgentAdapter>();\n const staging = join(\n workspace.repository,\n \".outpost\",\n \"recovery\",\n \"conversations\",\n );\n try {\n activity = await registerResourceActivity({\n repository: workspace.repository,\n ...(options.activityTransport\n ? { transporter: options.activityTransport }\n : {}),\n workspace: workspace.directory,\n provider: provider.name,\n placement: provider.placement,\n });\n const configured = await resolveVariables(\n workspace.repository,\n {},\n provider.variables,\n );\n const name = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.name\"]).catch(\n () => \"Outpost\",\n )\n ).trim();\n const email = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.email\"]).catch(\n () => \"outpost@localhost\",\n )\n ).trim();\n const variables = {\n GIT_AUTHOR_NAME: name,\n GIT_COMMITTER_NAME: name,\n GIT_AUTHOR_EMAIL: email,\n GIT_COMMITTER_EMAIL: email,\n ...configured,\n };\n acquisitionStarted = true;\n lease = boundedTransfers(\n trackedSandboxLease(\n await provider.acquire({\n repository: workspace.repository,\n directory: workspace.directory,\n gitDirectories: workspace.gitDirectories,\n variables,\n signal: setupSignal,\n }),\n activity,\n ),\n {\n ...(options.limits?.copyMs\n ? { deadlineMs: options.limits.copyMs }\n : {}),\n },\n );\n if (provider.placement === \"remote\") {\n sync = await seedRemote(workspace, lease, {\n ...(options.recoveryTransport\n ? { recoveryTransport: options.recoveryTransport }\n : {}),\n ...(options.includeUncommitted ? { includeUncommitted: true } : {}),\n ...(options.limits ? { limits: options.limits } : {}),\n signal: setupSignal,\n });\n const copiedFiles: string[] = [];\n for (const path of options.copies ?? []) {\n const info = await lstat(join(workspace.directory, path)).catch(\n (error) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\")\n return undefined;\n throw error;\n },\n );\n if (!info) continue;\n if (info.isFile() || info.isSymbolicLink()) {\n copiedFiles.push(path.replaceAll(\"\\\\\", \"/\"));\n continue;\n }\n await lease.upload(\n join(workspace.directory, path),\n posix.join(lease.root, path.replaceAll(\"\\\\\", \"/\")),\n { signal: setupSignal },\n );\n }\n await uploadFiles(lease, workspace.directory, [...new Set(copiedFiles)], {\n signal: setupSignal,\n });\n if (options.bootstrap !== false && options.agent)\n prepared.set(\n options.agent,\n await prepareAdapter(options.agent, lease, setupSignal),\n );\n }\n const initialized = await Promise.allSettled(\n [\n hooks(\n lifecycle?.hostReady ?? [],\n workspace.directory,\n executeProcess,\n setupSignal,\n ),\n hooks(\n lifecycle?.sandboxReady ?? [],\n lease.root,\n lease.invoke.bind(lease),\n setupSignal,\n true,\n ),\n ].map((pending) =>\n pending.catch((cause) => {\n stop.abort(cause);\n throw cause;\n }),\n ),\n );\n const failure = initialized.find((item) => item.status === \"rejected\");\n if (failure?.status === \"rejected\") throw failure.reason;\n await activity.phase(\"ready\");\n } catch (cause) {\n await startupFailure(workspace, cause, options);\n const allocationUncertain = acquisitionStarted && !lease;\n let cleanupFailed = allocationUncertain;\n await activity?.phase(\"closing\").catch(() => {\n cleanupFailed = true;\n });\n await lease?.release().catch(() => {\n cleanupFailed = true;\n });\n if (activity && !(await activity.idle())) cleanupFailed = true;\n state.active = false;\n if (owned)\n await workspace.close({ preserve: cleanupFailed }).catch(() => {\n cleanupFailed = true;\n });\n if (cleanupFailed)\n await activity\n ?.phase(allocationUncertain ? \"allocation-uncertain\" : \"cleanup-failed\")\n .catch(() => undefined);\n if (!cleanupFailed) await activity?.remove().catch(() => undefined);\n throw cause;\n }\n\n return {\n options,\n provider,\n workspace,\n state,\n owned,\n stop,\n runtime: lease,\n activity,\n sync,\n prepared,\n staging,\n };\n}\n"]}
1
+ {"version":3,"file":"sandbox-provision.js","sourceRoot":"","sources":["../../src/application/sandbox-provision.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { executeProcess } from \"../infrastructure/process.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { registerResourceActivity } from \"../infrastructure/resource-activity.ts\";\nimport type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\nimport { trackedSandboxLease } from \"./sandbox-activity.ts\";\nimport { boundedTransfers } from \"../infrastructure/transfer.ts\";\nimport { dockerSandboxProvider } from \"../providers/docker.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { hooks } from \"./lifecycle-hooks.ts\";\nimport type { SandboxOptions } from \"./outpost.types.ts\";\nimport { uploadFiles } from \"./remote-upload.ts\";\nimport { seedRemote } from \"./remote-workspace.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\nimport type { ProvisionedSandbox } from \"./sandbox-session.types.ts\";\nimport { startupFailure } from \"./startup-recovery.ts\";\nimport { workspaces } from \"./workspace-registry.ts\";\nimport { openWorkspace } from \"./workspace.ts\";\n\nexport async function provisionSandbox(\n options: SandboxOptions,\n): Promise<ProvisionedSandbox> {\n invariant(\n !(\"provider\" in options),\n \"Use sandboxProvider instead of provider\",\n );\n options.signal?.throwIfAborted();\n const sandboxProvider = options.sandboxProvider ?? dockerSandboxProvider();\n if (\n sandboxProvider.placement === \"remote\" &&\n !options.workspace &&\n !options.branch\n )\n options = { ...options, branch: { mode: \"integrate\" } };\n invariant(\n !options.workspace ||\n (!options.repository &&\n !options.branch &&\n !options.copies &&\n !options.storageQuota),\n \"A supplied workspace owns its repository, branch, copied inputs and storage quota\",\n );\n const owned = !options.workspace;\n invariant(\n sandboxProvider.placement !== \"remote\" ||\n ((options.workspace?.policy ?? options.branch)?.mode !== \"current\" &&\n (options.workspace || options.branch)),\n \"Remote providers require a named or integration workspace\",\n );\n const workspace = options.workspace ?? (await openWorkspace(options));\n const state = workspaces.get(workspace);\n invariant(\n state && !state.closed && !state.active,\n \"Workspace must be open and cannot belong to another sandbox\",\n );\n state.active = true;\n const lifecycle = options.hooks ?? state.hooks;\n const stop = new AbortController();\n const setupSignal = options.signal\n ? AbortSignal.any([options.signal, stop.signal])\n : stop.signal;\n let lease: SandboxLease | undefined, sync: RemoteSync | undefined;\n let activity: ResourceActivity | undefined;\n let acquisitionStarted = false;\n const prepared = new Map<Agent, Agent>();\n const staging = join(\n workspace.repository,\n \".outpost\",\n \"recovery\",\n \"conversations\",\n );\n try {\n activity = await registerResourceActivity({\n repository: workspace.repository,\n ...(options.activityTransport\n ? { transporter: options.activityTransport }\n : {}),\n workspace: workspace.directory,\n sandboxProvider: sandboxProvider.name,\n placement: sandboxProvider.placement,\n });\n const configured = await resolveVariables(\n workspace.repository,\n {},\n sandboxProvider.variables,\n );\n const name = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.name\"]).catch(\n () => \"Outpost\",\n )\n ).trim();\n const email = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.email\"]).catch(\n () => \"outpost@localhost\",\n )\n ).trim();\n const variables = {\n GIT_AUTHOR_NAME: name,\n GIT_COMMITTER_NAME: name,\n GIT_AUTHOR_EMAIL: email,\n GIT_COMMITTER_EMAIL: email,\n ...configured,\n };\n acquisitionStarted = true;\n lease = boundedTransfers(\n trackedSandboxLease(\n await sandboxProvider.acquire({\n repository: workspace.repository,\n directory: workspace.directory,\n gitDirectories: workspace.gitDirectories,\n variables,\n signal: setupSignal,\n }),\n activity,\n ),\n {\n ...(options.limits?.copyMs\n ? { deadlineMs: options.limits.copyMs }\n : {}),\n },\n );\n if (sandboxProvider.placement === \"remote\") {\n sync = await seedRemote(workspace, lease, {\n ...(options.recoveryTransport\n ? { recoveryTransport: options.recoveryTransport }\n : {}),\n ...(options.includeUncommitted ? { includeUncommitted: true } : {}),\n ...(options.limits ? { limits: options.limits } : {}),\n signal: setupSignal,\n });\n const copiedFiles: string[] = [];\n for (const path of options.copies ?? []) {\n const info = await lstat(join(workspace.directory, path)).catch(\n (error) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\")\n return undefined;\n throw error;\n },\n );\n if (!info) continue;\n if (info.isFile() || info.isSymbolicLink()) {\n copiedFiles.push(path.replaceAll(\"\\\\\", \"/\"));\n continue;\n }\n await lease.upload(\n join(workspace.directory, path),\n posix.join(lease.root, path.replaceAll(\"\\\\\", \"/\")),\n { signal: setupSignal },\n );\n }\n await uploadFiles(lease, workspace.directory, [...new Set(copiedFiles)], {\n signal: setupSignal,\n });\n if (options.bootstrap !== false && options.agent)\n prepared.set(\n options.agent,\n await prepareAdapter(options.agent, lease, setupSignal),\n );\n }\n const initialized = await Promise.allSettled(\n [\n hooks(\n lifecycle?.hostReady ?? [],\n workspace.directory,\n executeProcess,\n setupSignal,\n ),\n hooks(\n lifecycle?.sandboxReady ?? [],\n lease.root,\n lease.invoke.bind(lease),\n setupSignal,\n true,\n ),\n ].map((pending) =>\n pending.catch((cause) => {\n stop.abort(cause);\n throw cause;\n }),\n ),\n );\n const failure = initialized.find((item) => item.status === \"rejected\");\n if (failure?.status === \"rejected\") throw failure.reason;\n await activity.phase(\"ready\");\n } catch (cause) {\n await startupFailure(workspace, cause, options);\n const allocationUncertain = acquisitionStarted && !lease;\n let cleanupFailed = allocationUncertain;\n await activity?.phase(\"closing\").catch(() => {\n cleanupFailed = true;\n });\n await lease?.release().catch(() => {\n cleanupFailed = true;\n });\n if (activity && !(await activity.idle())) cleanupFailed = true;\n state.active = false;\n if (owned)\n await workspace.close({ preserve: cleanupFailed }).catch(() => {\n cleanupFailed = true;\n });\n if (cleanupFailed)\n await activity\n ?.phase(allocationUncertain ? \"allocation-uncertain\" : \"cleanup-failed\")\n .catch(() => undefined);\n if (!cleanupFailed) await activity?.remove().catch(() => undefined);\n throw cause;\n }\n\n return {\n options,\n sandboxProvider,\n workspace,\n state,\n owned,\n stop,\n runtime: lease,\n activity,\n sync,\n prepared,\n staging,\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { ResourceActivity } from "../infrastructure/resource-activity.types.ts";
2
- import type { AgentAdapter } from "../domain/agent.types.ts";
2
+ import type { Agent } from "../domain/agent.types.ts";
3
3
  import type { SandboxLease, SandboxProvider } from "../domain/sandbox.types.ts";
4
4
  import type { LifecycleHooks } from "../domain/workspace.types.ts";
5
5
  import type { WorkspaceLease } from "../infrastructure/git/workspace.types.ts";
@@ -13,7 +13,7 @@ export interface WorkspaceState {
13
13
  }
14
14
  export interface ProvisionedSandbox {
15
15
  readonly options: SandboxOptions;
16
- readonly provider: SandboxProvider;
16
+ readonly sandboxProvider: SandboxProvider;
17
17
  readonly workspace: Workspace;
18
18
  readonly state: WorkspaceState;
19
19
  readonly owned: boolean;
@@ -21,18 +21,18 @@ export interface ProvisionedSandbox {
21
21
  readonly runtime: SandboxLease;
22
22
  readonly activity: ResourceActivity;
23
23
  readonly sync: RemoteSync | undefined;
24
- readonly prepared: Map<AgentAdapter, AgentAdapter>;
24
+ readonly prepared: Map<Agent, Agent>;
25
25
  readonly staging: string;
26
26
  }
27
27
  export interface SelectedAgent {
28
- readonly selected: AgentAdapter;
29
- readonly adapter: AgentAdapter;
28
+ readonly selected: Agent;
29
+ readonly adapter: Agent;
30
30
  readonly executionLease: SandboxLease;
31
31
  }
32
32
  export interface SandboxAgents {
33
- selectAgent(agent: AgentAdapter | undefined, signal: AbortSignal): Promise<SelectedAgent>;
34
- restore(id: string, agent: AgentAdapter): Promise<void>;
35
- remember(agent: AgentAdapter, id: string): void;
33
+ selectAgent(agent: Agent | undefined, signal: AbortSignal): Promise<SelectedAgent>;
34
+ restore(id: string, agent: Agent): Promise<void>;
35
+ remember(agent: Agent, id: string): void;
36
36
  }
37
37
  export interface OperationGate {
38
38
  run<T>(action: () => Promise<T>): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-session.types.js","sourceRoot":"","sources":["../../src/application/sandbox-session.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\nimport type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { SandboxLease, SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type { LifecycleHooks } from \"../domain/workspace.types.ts\";\nimport type { WorkspaceLease } from \"../infrastructure/git/workspace.types.ts\";\nimport type { SandboxOptions, Workspace } from \"./outpost.types.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\n\nexport interface WorkspaceState {\n lease: WorkspaceLease;\n active: boolean;\n closed: boolean;\n hooks?: LifecycleHooks;\n}\n\nexport interface ProvisionedSandbox {\n readonly options: SandboxOptions;\n readonly provider: SandboxProvider;\n readonly workspace: Workspace;\n readonly state: WorkspaceState;\n readonly owned: boolean;\n readonly stop: AbortController;\n readonly runtime: SandboxLease;\n readonly activity: ResourceActivity;\n readonly sync: RemoteSync | undefined;\n readonly prepared: Map<AgentAdapter, AgentAdapter>;\n readonly staging: string;\n}\n\nexport interface SelectedAgent {\n readonly selected: AgentAdapter;\n readonly adapter: AgentAdapter;\n readonly executionLease: SandboxLease;\n}\n\nexport interface SandboxAgents {\n selectAgent(\n agent: AgentAdapter | undefined,\n signal: AbortSignal,\n ): Promise<SelectedAgent>;\n restore(id: string, agent: AgentAdapter): Promise<void>;\n remember(agent: AgentAdapter, id: string): void;\n}\n\nexport interface OperationGate {\n run<T>(action: () => Promise<T>): Promise<T>;\n close(): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"sandbox-session.types.js","sourceRoot":"","sources":["../../src/application/sandbox-session.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport type { SandboxLease, SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type { LifecycleHooks } from \"../domain/workspace.types.ts\";\nimport type { WorkspaceLease } from \"../infrastructure/git/workspace.types.ts\";\nimport type { SandboxOptions, Workspace } from \"./outpost.types.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\n\nexport interface WorkspaceState {\n lease: WorkspaceLease;\n active: boolean;\n closed: boolean;\n hooks?: LifecycleHooks;\n}\n\nexport interface ProvisionedSandbox {\n readonly options: SandboxOptions;\n readonly sandboxProvider: SandboxProvider;\n readonly workspace: Workspace;\n readonly state: WorkspaceState;\n readonly owned: boolean;\n readonly stop: AbortController;\n readonly runtime: SandboxLease;\n readonly activity: ResourceActivity;\n readonly sync: RemoteSync | undefined;\n readonly prepared: Map<Agent, Agent>;\n readonly staging: string;\n}\n\nexport interface SelectedAgent {\n readonly selected: Agent;\n readonly adapter: Agent;\n readonly executionLease: SandboxLease;\n}\n\nexport interface SandboxAgents {\n selectAgent(\n agent: Agent | undefined,\n signal: AbortSignal,\n ): Promise<SelectedAgent>;\n restore(id: string, agent: Agent): Promise<void>;\n remember(agent: Agent, id: string): void;\n}\n\nexport interface OperationGate {\n run<T>(action: () => Promise<T>): Promise<T>;\n close(): Promise<void>;\n}\n"]}
@@ -6,6 +6,7 @@ import { diagnoseSandbox } from "./doctor-sandbox.js";
6
6
  import { operationGate } from "./operation-gate.js";
7
7
  import { sandboxAgents } from "./sandbox-agents.js";
8
8
  import { attachInSandbox } from "./sandbox-attach.js";
9
+ import { observeDispatch } from "./dispatch-observation.js";
9
10
  import { dispatchInSandbox } from "./sandbox-dispatch.js";
10
11
  import { provisionSandbox } from "./sandbox-provision.js";
11
12
  export async function createSandbox(options = {}) {
@@ -19,8 +20,10 @@ export async function createSandbox(options = {}) {
19
20
  workspace,
20
21
  root: runtime.root,
21
22
  dispatch(settings) {
22
- validateDispatch(settings);
23
- return exclusive("dispatch", () => dispatchInSandbox(context, agents, result, settings));
23
+ return observeDispatch(settings, (observed) => {
24
+ validateDispatch(observed);
25
+ return exclusive("dispatch", () => dispatchInSandbox(context, agents, result, observed));
26
+ });
24
27
  },
25
28
  resume(id, settings) {
26
29
  return result.dispatch({ ...settings, continuation: { id } });
@@ -37,7 +40,7 @@ export async function createSandbox(options = {}) {
37
40
  settings.signal?.throwIfAborted();
38
41
  return exclusive("diagnose", () => diagnoseSandbox(runtime, {
39
42
  ...settings,
40
- provider: context.provider,
43
+ sandboxProvider: context.sandboxProvider,
41
44
  signal: settings.signal
42
45
  ? AbortSignal.any([settings.signal, stop.signal])
43
46
  : stop.signal,
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/application/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ResourceOperationKind } from \"../infrastructure/resource-activity.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { validateBrief } from \"../domain/prompts.ts\";\nimport type { Disposal } from \"../domain/workspace.types.ts\";\nimport { registerCleanup } from \"../infrastructure/shutdown.ts\";\nimport { validateDispatch } from \"./dispatch-validation.ts\";\nimport { diagnoseSandbox } from \"./doctor-sandbox.ts\";\nimport { operationGate } from \"./operation-gate.ts\";\nimport type { Sandbox, SandboxOptions } from \"./outpost.types.ts\";\nimport { sandboxAgents } from \"./sandbox-agents.ts\";\nimport { attachInSandbox } from \"./sandbox-attach.ts\";\nimport { dispatchInSandbox } from \"./sandbox-dispatch.ts\";\nimport { provisionSandbox } from \"./sandbox-provision.ts\";\n\nexport async function createSandbox(\n options: SandboxOptions = {},\n): Promise<Sandbox> {\n const context = await provisionSandbox(options);\n const { workspace, runtime, sync, stop, state, owned } = context;\n const agents = sandboxAgents(context);\n const gate = operationGate();\n const exclusive = <T>(\n kind: ResourceOperationKind,\n action: () => Promise<T>,\n ) => gate.run(() => context.activity.run(kind, action));\n let closing: Promise<Disposal> | undefined;\n const result: Sandbox = {\n workspace,\n root: runtime.root,\n dispatch(settings) {\n validateDispatch(settings);\n return exclusive(\"dispatch\", () =>\n dispatchInSandbox(context, agents, result, settings),\n );\n },\n resume(id, settings) {\n return result.dispatch({ ...settings, continuation: { id } });\n },\n fork(id, settings) {\n return result.dispatch({ ...settings, continuation: { id, fork: true } });\n },\n attach(settings = {}) {\n settings.signal?.throwIfAborted();\n validateBrief(settings.brief, true);\n return exclusive(\"attach\", () =>\n attachInSandbox(context, agents, settings),\n );\n },\n diagnose(settings = {}) {\n settings.signal?.throwIfAborted();\n return exclusive(\"diagnose\", () =>\n diagnoseSandbox(runtime, {\n ...settings,\n provider: context.provider,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n }),\n );\n },\n command(command) {\n command.signal?.throwIfAborted();\n return exclusive(\"command\", async () => {\n try {\n return await runtime.invoke({\n ...command,\n signal: command.signal\n ? AbortSignal.any([command.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n await sync?.pull();\n }\n });\n },\n close(settings = {}) {\n if (closing) return closing;\n closing = (async () => {\n stop.abort(new OutpostError(\"aborted\", \"Sandbox closed\"));\n await gate.close();\n let failure: unknown;\n await context.activity.phase(\"closing\").catch(() => undefined);\n try {\n await runtime.release();\n await sync?.close();\n if (!(await context.activity.idle()))\n throw new OutpostError(\n \"provider\",\n \"Sandbox operations remain unsettled after release\",\n );\n } catch (cause) {\n failure = cause;\n }\n state.active = false;\n\n unregister();\n let disposal: Disposal = {};\n try {\n if (owned)\n disposal = await workspace.close({\n preserve: settings.preserve || !!failure,\n });\n if (failure) throw failure;\n await context.activity.remove();\n return disposal;\n } catch (cause) {\n await context.activity.phase(\"cleanup-failed\").catch(() => undefined);\n throw cause;\n }\n })();\n return closing;\n },\n async [Symbol.asyncDispose]() {\n await result.close();\n },\n };\n const unregister = registerCleanup(() => result.close({ preserve: true }));\n return result;\n}\n"]}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/application/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ResourceOperationKind } from \"../infrastructure/resource-activity.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { validateBrief } from \"../domain/prompts.ts\";\nimport type { Disposal } from \"../domain/workspace.types.ts\";\nimport { registerCleanup } from \"../infrastructure/shutdown.ts\";\nimport { validateDispatch } from \"./dispatch-validation.ts\";\nimport { diagnoseSandbox } from \"./doctor-sandbox.ts\";\nimport { operationGate } from \"./operation-gate.ts\";\nimport type { Sandbox, SandboxOptions } from \"./outpost.types.ts\";\nimport { sandboxAgents } from \"./sandbox-agents.ts\";\nimport { attachInSandbox } from \"./sandbox-attach.ts\";\nimport { observeDispatch } from \"./dispatch-observation.ts\";\nimport { dispatchInSandbox } from \"./sandbox-dispatch.ts\";\nimport { provisionSandbox } from \"./sandbox-provision.ts\";\n\nexport async function createSandbox(\n options: SandboxOptions = {},\n): Promise<Sandbox> {\n const context = await provisionSandbox(options);\n const { workspace, runtime, sync, stop, state, owned } = context;\n const agents = sandboxAgents(context);\n const gate = operationGate();\n const exclusive = <T>(\n kind: ResourceOperationKind,\n action: () => Promise<T>,\n ) => gate.run(() => context.activity.run(kind, action));\n let closing: Promise<Disposal> | undefined;\n const result: Sandbox = {\n workspace,\n root: runtime.root,\n dispatch(settings) {\n return observeDispatch(settings, (observed) => {\n validateDispatch(observed);\n return exclusive(\"dispatch\", () =>\n dispatchInSandbox(context, agents, result, observed),\n );\n });\n },\n resume(id, settings) {\n return result.dispatch({ ...settings, continuation: { id } });\n },\n fork(id, settings) {\n return result.dispatch({ ...settings, continuation: { id, fork: true } });\n },\n attach(settings = {}) {\n settings.signal?.throwIfAborted();\n validateBrief(settings.brief, true);\n return exclusive(\"attach\", () =>\n attachInSandbox(context, agents, settings),\n );\n },\n diagnose(settings = {}) {\n settings.signal?.throwIfAborted();\n return exclusive(\"diagnose\", () =>\n diagnoseSandbox(runtime, {\n ...settings,\n sandboxProvider: context.sandboxProvider,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n }),\n );\n },\n command(command) {\n command.signal?.throwIfAborted();\n return exclusive(\"command\", async () => {\n try {\n return await runtime.invoke({\n ...command,\n signal: command.signal\n ? AbortSignal.any([command.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n await sync?.pull();\n }\n });\n },\n close(settings = {}) {\n if (closing) return closing;\n closing = (async () => {\n stop.abort(new OutpostError(\"aborted\", \"Sandbox closed\"));\n await gate.close();\n let failure: unknown;\n await context.activity.phase(\"closing\").catch(() => undefined);\n try {\n await runtime.release();\n await sync?.close();\n if (!(await context.activity.idle()))\n throw new OutpostError(\n \"provider\",\n \"Sandbox operations remain unsettled after release\",\n );\n } catch (cause) {\n failure = cause;\n }\n state.active = false;\n\n unregister();\n let disposal: Disposal = {};\n try {\n if (owned)\n disposal = await workspace.close({\n preserve: settings.preserve || !!failure,\n });\n if (failure) throw failure;\n await context.activity.remove();\n return disposal;\n } catch (cause) {\n await context.activity.phase(\"cleanup-failed\").catch(() => undefined);\n throw cause;\n }\n })();\n return closing;\n },\n async [Symbol.asyncDispose]() {\n await result.close();\n },\n };\n const unregister = registerCleanup(() => result.close({ preserve: true }));\n return result;\n}\n"]}
@@ -60,7 +60,7 @@ export async function speculate(options) {
60
60
  sandbox = await createSandbox({
61
61
  ...options.sandbox,
62
62
  repository: options.repository,
63
- provider: options.provider,
63
+ sandboxProvider: options.sandboxProvider,
64
64
  branch: { mode: "named", name: initial.branch, from: baseline },
65
65
  agent: candidate.agent,
66
66
  signal,
@@ -1 +1 @@
1
- {"version":3,"file":"speculation.js","sourceRoot":"","sources":["../../src/application/speculation.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { invariant, recoveryDetails } from \"../domain/errors.ts\";\nimport { workflowAccounting } from \"../domain/workflow/budget.ts\";\nimport { speculativeHostSnapshot } from \"./speculation-host.ts\";\nimport type { Sandbox } from \"./outpost.types.ts\";\nimport { createSandbox } from \"./sandbox.ts\";\nimport { speculationLimits } from \"./speculation.constants.ts\";\nimport type {\n SpeculationOptions,\n SpeculationResult,\n SpeculativeCandidateResult,\n SpeculativeOutput,\n} from \"./speculation.types.ts\";\nimport { taskUsage } from \"./task-usage.ts\";\n\nexport async function speculate<T = undefined>(\n options: SpeculationOptions<T>,\n): Promise<SpeculationResult<T>> {\n const { candidates } = options;\n invariant(\n candidates.length > 0 && candidates.length <= speculationLimits.candidates,\n `Speculation requires 1 to ${speculationLimits.candidates} candidates`,\n );\n invariant(\n new Set(candidates.map((candidate) => candidate.key)).size ===\n candidates.length &&\n candidates.every((candidate) =>\n /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(candidate.key),\n ),\n \"Speculative candidate keys must be unique simple names of 1 to 64 characters\",\n );\n const concurrency = options.concurrency ?? speculationLimits.concurrency;\n invariant(\n Number.isSafeInteger(concurrency) &&\n concurrency > 0 &&\n concurrency <= speculationLimits.candidates,\n `Speculation concurrency must be 1 to ${speculationLimits.candidates}`,\n );\n const stop = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([options.signal, stop.signal])\n : stop.signal;\n let budgetError: unknown;\n const accounting = workflowAccounting(options.budget, (error) => {\n budgetError = error;\n // Attempt limits stop admissions; already admitted candidates may finish.\n if (error.dimension !== \"attempts\") stop.abort(error);\n });\n const before = await speculativeHostSnapshot(options.repository);\n const baseline = before.head;\n const id = randomUUID();\n const records: SpeculativeCandidateResult<T>[] = candidates.map(\n (candidate) => ({\n key: candidate.key,\n branch: `outpost/speculation/${id}/${candidate.key}`,\n status: \"skipped\",\n }),\n );\n let winner: SpeculativeCandidateResult<T> | undefined;\n let next = 0;\n async function worker(): Promise<void> {\n while (!signal.aborted && !winner && !accounting.exhausted) {\n const index = next++;\n const candidate = candidates[index];\n if (!candidate) return;\n try {\n accounting.admit();\n } catch {\n return;\n }\n const initial = records[index]!;\n let sandbox: Sandbox | undefined;\n let result: SpeculativeOutput<T> | undefined;\n let error: unknown;\n let accepted = false;\n let cleanupFailed = false;\n let retainedDirectory: string | undefined;\n const usage = taskUsage(\n { reportUsage: (value) => accounting.report(value) },\n candidate.request.observe,\n );\n try {\n sandbox = await createSandbox({\n ...options.sandbox,\n repository: options.repository,\n provider: options.provider,\n branch: { mode: \"named\", name: initial.branch, from: baseline },\n agent: candidate.agent,\n signal,\n });\n signal.throwIfAborted();\n invariant(\n sandbox.workspace.baseline === baseline,\n \"Speculative workspace does not match the pinned baseline\",\n );\n const {\n resume: _resume,\n fork: _fork,\n ...output\n } = await sandbox.dispatch({\n ...candidate.request,\n signal,\n observe: usage.observe,\n });\n result = output;\n usage.reconcile(output.usage);\n signal.throwIfAborted();\n accepted = await options.validate({\n key: candidate.key,\n result,\n sandbox,\n signal,\n });\n signal.throwIfAborted();\n } catch (cause) {\n error = cause;\n }\n if (sandbox) {\n try {\n const disposal = await sandbox.close({\n preserve: error !== undefined,\n });\n retainedDirectory = disposal.retainedDirectory;\n } catch (cause) {\n cleanupFailed = true;\n error =\n error === undefined\n ? cause\n : new AggregateError(\n [error, cause],\n \"Speculative execution and cleanup failed\",\n );\n retainedDirectory = sandbox.workspace.directory;\n }\n }\n const recovery = recoveryDetails(error);\n const recoveredDirectory =\n typeof recovery?.directory === \"string\"\n ? recovery.directory\n : undefined;\n const directory = sandbox?.workspace.directory ?? recoveredDirectory;\n retainedDirectory ??= recoveredDirectory;\n function candidateStatus(): SpeculativeCandidateResult<T>[\"status\"] {\n if (cleanupFailed) return \"failed\";\n if (signal.aborted) return \"cancelled\";\n if (error !== undefined) return \"failed\";\n if (accepted && !winner) return \"winner\";\n return \"rejected\";\n }\n const status = candidateStatus();\n const record: SpeculativeCandidateResult<T> = {\n ...initial,\n status,\n ...(directory ? { directory } : {}),\n ...(retainedDirectory ? { retainedDirectory } : {}),\n ...(result ? { result } : {}),\n ...(error !== undefined ? { error } : {}),\n };\n records[index] = record;\n if (status === \"winner\") {\n winner = record;\n stop.abort(\n new Error(`Speculative candidate ${candidate.key} selected`),\n );\n }\n }\n }\n await Promise.all(\n Array.from({ length: Math.min(concurrency, candidates.length) }, worker),\n );\n function outcome(): SpeculationResult<T>[\"status\"] {\n if (winner) return \"winner\";\n if (options.signal?.aborted) return \"aborted\";\n if (budgetError !== undefined) return \"budget-exhausted\";\n return \"no-winner\";\n }\n const status = outcome();\n const host = await speculativeHostSnapshot(options.repository).then(\n (after) => ({\n before,\n after,\n changed:\n before.fingerprint !== after.fingerprint ||\n before.branch !== after.branch,\n }),\n (error: unknown) => ({ before, changed: true, error }),\n );\n return {\n id,\n baseline,\n host,\n status,\n candidates: records,\n usage: accounting.snapshot(),\n ...(winner ? { winner } : {}),\n ...(budgetError !== undefined ? { error: budgetError } : {}),\n };\n}\n"]}
1
+ {"version":3,"file":"speculation.js","sourceRoot":"","sources":["../../src/application/speculation.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { invariant, recoveryDetails } from \"../domain/errors.ts\";\nimport { workflowAccounting } from \"../domain/workflow/budget.ts\";\nimport { speculativeHostSnapshot } from \"./speculation-host.ts\";\nimport type { Sandbox } from \"./outpost.types.ts\";\nimport { createSandbox } from \"./sandbox.ts\";\nimport { speculationLimits } from \"./speculation.constants.ts\";\nimport type {\n SpeculationOptions,\n SpeculationResult,\n SpeculativeCandidateResult,\n SpeculativeOutput,\n} from \"./speculation.types.ts\";\nimport { taskUsage } from \"./task-usage.ts\";\n\nexport async function speculate<T = undefined>(\n options: SpeculationOptions<T>,\n): Promise<SpeculationResult<T>> {\n const { candidates } = options;\n invariant(\n candidates.length > 0 && candidates.length <= speculationLimits.candidates,\n `Speculation requires 1 to ${speculationLimits.candidates} candidates`,\n );\n invariant(\n new Set(candidates.map((candidate) => candidate.key)).size ===\n candidates.length &&\n candidates.every((candidate) =>\n /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(candidate.key),\n ),\n \"Speculative candidate keys must be unique simple names of 1 to 64 characters\",\n );\n const concurrency = options.concurrency ?? speculationLimits.concurrency;\n invariant(\n Number.isSafeInteger(concurrency) &&\n concurrency > 0 &&\n concurrency <= speculationLimits.candidates,\n `Speculation concurrency must be 1 to ${speculationLimits.candidates}`,\n );\n const stop = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([options.signal, stop.signal])\n : stop.signal;\n let budgetError: unknown;\n const accounting = workflowAccounting(options.budget, (error) => {\n budgetError = error;\n // Attempt limits stop admissions; already admitted candidates may finish.\n if (error.dimension !== \"attempts\") stop.abort(error);\n });\n const before = await speculativeHostSnapshot(options.repository);\n const baseline = before.head;\n const id = randomUUID();\n const records: SpeculativeCandidateResult<T>[] = candidates.map(\n (candidate) => ({\n key: candidate.key,\n branch: `outpost/speculation/${id}/${candidate.key}`,\n status: \"skipped\",\n }),\n );\n let winner: SpeculativeCandidateResult<T> | undefined;\n let next = 0;\n async function worker(): Promise<void> {\n while (!signal.aborted && !winner && !accounting.exhausted) {\n const index = next++;\n const candidate = candidates[index];\n if (!candidate) return;\n try {\n accounting.admit();\n } catch {\n return;\n }\n const initial = records[index]!;\n let sandbox: Sandbox | undefined;\n let result: SpeculativeOutput<T> | undefined;\n let error: unknown;\n let accepted = false;\n let cleanupFailed = false;\n let retainedDirectory: string | undefined;\n const usage = taskUsage(\n { reportUsage: (value) => accounting.report(value) },\n candidate.request.observe,\n );\n try {\n sandbox = await createSandbox({\n ...options.sandbox,\n repository: options.repository,\n sandboxProvider: options.sandboxProvider,\n branch: { mode: \"named\", name: initial.branch, from: baseline },\n agent: candidate.agent,\n signal,\n });\n signal.throwIfAborted();\n invariant(\n sandbox.workspace.baseline === baseline,\n \"Speculative workspace does not match the pinned baseline\",\n );\n const {\n resume: _resume,\n fork: _fork,\n ...output\n } = await sandbox.dispatch({\n ...candidate.request,\n signal,\n observe: usage.observe,\n });\n result = output;\n usage.reconcile(output.usage);\n signal.throwIfAborted();\n accepted = await options.validate({\n key: candidate.key,\n result,\n sandbox,\n signal,\n });\n signal.throwIfAborted();\n } catch (cause) {\n error = cause;\n }\n if (sandbox) {\n try {\n const disposal = await sandbox.close({\n preserve: error !== undefined,\n });\n retainedDirectory = disposal.retainedDirectory;\n } catch (cause) {\n cleanupFailed = true;\n error =\n error === undefined\n ? cause\n : new AggregateError(\n [error, cause],\n \"Speculative execution and cleanup failed\",\n );\n retainedDirectory = sandbox.workspace.directory;\n }\n }\n const recovery = recoveryDetails(error);\n const recoveredDirectory =\n typeof recovery?.directory === \"string\"\n ? recovery.directory\n : undefined;\n const directory = sandbox?.workspace.directory ?? recoveredDirectory;\n retainedDirectory ??= recoveredDirectory;\n function candidateStatus(): SpeculativeCandidateResult<T>[\"status\"] {\n if (cleanupFailed) return \"failed\";\n if (signal.aborted) return \"cancelled\";\n if (error !== undefined) return \"failed\";\n if (accepted && !winner) return \"winner\";\n return \"rejected\";\n }\n const status = candidateStatus();\n const record: SpeculativeCandidateResult<T> = {\n ...initial,\n status,\n ...(directory ? { directory } : {}),\n ...(retainedDirectory ? { retainedDirectory } : {}),\n ...(result ? { result } : {}),\n ...(error !== undefined ? { error } : {}),\n };\n records[index] = record;\n if (status === \"winner\") {\n winner = record;\n stop.abort(\n new Error(`Speculative candidate ${candidate.key} selected`),\n );\n }\n }\n }\n await Promise.all(\n Array.from({ length: Math.min(concurrency, candidates.length) }, worker),\n );\n function outcome(): SpeculationResult<T>[\"status\"] {\n if (winner) return \"winner\";\n if (options.signal?.aborted) return \"aborted\";\n if (budgetError !== undefined) return \"budget-exhausted\";\n return \"no-winner\";\n }\n const status = outcome();\n const host = await speculativeHostSnapshot(options.repository).then(\n (after) => ({\n before,\n after,\n changed:\n before.fingerprint !== after.fingerprint ||\n before.branch !== after.branch,\n }),\n (error: unknown) => ({ before, changed: true, error }),\n );\n return {\n id,\n baseline,\n host,\n status,\n candidates: records,\n usage: accounting.snapshot(),\n ...(winner ? { winner } : {}),\n ...(budgetError !== undefined ? { error: budgetError } : {}),\n };\n}\n"]}
@@ -1,10 +1,10 @@
1
- import type { AgentAdapter } from "../domain/agent.types.ts";
1
+ import type { Agent } from "../domain/agent.types.ts";
2
2
  import type { WorkflowBudget, WorkflowUsage } from "../domain/workflow/budget.types.ts";
3
3
  import type { DispatchOptions } from "./execution.types.ts";
4
4
  import type { Sandbox, SandboxOptions, WarmDispatchResult } from "./outpost.types.ts";
5
5
  export interface SpeculativeCandidate<T = undefined> {
6
6
  readonly key: string;
7
- readonly agent: AgentAdapter;
7
+ readonly agent: Agent;
8
8
  readonly request: Omit<DispatchOptions<T>, "agent" | "signal" | "continuation">;
9
9
  }
10
10
  export type SpeculativeOutput<T> = Omit<WarmDispatchResult<T>, "resume" | "fork">;
@@ -16,7 +16,7 @@ export interface SpeculativeValidation<T> {
16
16
  }
17
17
  export interface SpeculationOptions<T = undefined> {
18
18
  readonly repository: string;
19
- readonly provider: NonNullable<SandboxOptions["provider"]>;
19
+ readonly sandboxProvider: NonNullable<SandboxOptions["sandboxProvider"]>;
20
20
  readonly candidates: readonly SpeculativeCandidate<T>[];
21
21
  readonly concurrency?: number;
22
22
  readonly budget: WorkflowBudget;
@@ -1 +1 @@
1
- {"version":3,"file":"speculation.types.js","sourceRoot":"","sources":["../../src/application/speculation.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type {\n WorkflowBudget,\n WorkflowUsage,\n} from \"../domain/workflow/budget.types.ts\";\nimport type { DispatchOptions } from \"./execution.types.ts\";\nimport type {\n Sandbox,\n SandboxOptions,\n WarmDispatchResult,\n} from \"./outpost.types.ts\";\n\nexport interface SpeculativeCandidate<T = undefined> {\n readonly key: string;\n readonly agent: AgentAdapter;\n readonly request: Omit<\n DispatchOptions<T>,\n \"agent\" | \"signal\" | \"continuation\"\n >;\n}\n\nexport type SpeculativeOutput<T> = Omit<\n WarmDispatchResult<T>,\n \"resume\" | \"fork\"\n>;\n\nexport interface SpeculativeValidation<T> {\n readonly key: string;\n readonly result: SpeculativeOutput<T>;\n readonly sandbox: Sandbox;\n readonly signal: AbortSignal;\n}\n\nexport interface SpeculationOptions<T = undefined> {\n readonly repository: string;\n readonly provider: NonNullable<SandboxOptions[\"provider\"]>;\n readonly candidates: readonly SpeculativeCandidate<T>[];\n readonly concurrency?: number;\n readonly budget: WorkflowBudget;\n readonly signal?: AbortSignal;\n readonly sandbox?: Pick<\n SandboxOptions,\n | \"hooks\"\n | \"bootstrap\"\n | \"logging\"\n | \"limits\"\n | \"storageQuota\"\n | \"conversationHome\"\n >;\n readonly validate: (\n candidate: SpeculativeValidation<T>,\n ) => boolean | Promise<boolean>;\n}\n\nexport interface SpeculativeCandidateResult<T = undefined> {\n readonly key: string;\n readonly branch: string;\n readonly status: \"winner\" | \"rejected\" | \"failed\" | \"cancelled\" | \"skipped\";\n readonly directory?: string;\n readonly retainedDirectory?: string;\n readonly result?: SpeculativeOutput<T>;\n readonly error?: unknown;\n}\n\nexport interface SpeculationResult<T = undefined> {\n readonly id: string;\n readonly baseline: string;\n readonly host: {\n readonly before: SpeculativeHostSnapshot;\n readonly after?: SpeculativeHostSnapshot;\n readonly changed: boolean;\n readonly error?: unknown;\n };\n readonly status: \"winner\" | \"no-winner\" | \"aborted\" | \"budget-exhausted\";\n readonly winner?: SpeculativeCandidateResult<T>;\n readonly candidates: readonly SpeculativeCandidateResult<T>[];\n readonly usage: WorkflowUsage;\n readonly error?: unknown;\n}\n\nexport interface SpeculativeHostSnapshot {\n readonly head: string;\n readonly branch: string;\n readonly fingerprint: string;\n readonly dirty: boolean;\n}\n"]}
1
+ {"version":3,"file":"speculation.types.js","sourceRoot":"","sources":["../../src/application/speculation.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Agent } from \"../domain/agent.types.ts\";\nimport type {\n WorkflowBudget,\n WorkflowUsage,\n} from \"../domain/workflow/budget.types.ts\";\nimport type { DispatchOptions } from \"./execution.types.ts\";\nimport type {\n Sandbox,\n SandboxOptions,\n WarmDispatchResult,\n} from \"./outpost.types.ts\";\n\nexport interface SpeculativeCandidate<T = undefined> {\n readonly key: string;\n readonly agent: Agent;\n readonly request: Omit<\n DispatchOptions<T>,\n \"agent\" | \"signal\" | \"continuation\"\n >;\n}\n\nexport type SpeculativeOutput<T> = Omit<\n WarmDispatchResult<T>,\n \"resume\" | \"fork\"\n>;\n\nexport interface SpeculativeValidation<T> {\n readonly key: string;\n readonly result: SpeculativeOutput<T>;\n readonly sandbox: Sandbox;\n readonly signal: AbortSignal;\n}\n\nexport interface SpeculationOptions<T = undefined> {\n readonly repository: string;\n readonly sandboxProvider: NonNullable<SandboxOptions[\"sandboxProvider\"]>;\n readonly candidates: readonly SpeculativeCandidate<T>[];\n readonly concurrency?: number;\n readonly budget: WorkflowBudget;\n readonly signal?: AbortSignal;\n readonly sandbox?: Pick<\n SandboxOptions,\n | \"hooks\"\n | \"bootstrap\"\n | \"logging\"\n | \"limits\"\n | \"storageQuota\"\n | \"conversationHome\"\n >;\n readonly validate: (\n candidate: SpeculativeValidation<T>,\n ) => boolean | Promise<boolean>;\n}\n\nexport interface SpeculativeCandidateResult<T = undefined> {\n readonly key: string;\n readonly branch: string;\n readonly status: \"winner\" | \"rejected\" | \"failed\" | \"cancelled\" | \"skipped\";\n readonly directory?: string;\n readonly retainedDirectory?: string;\n readonly result?: SpeculativeOutput<T>;\n readonly error?: unknown;\n}\n\nexport interface SpeculationResult<T = undefined> {\n readonly id: string;\n readonly baseline: string;\n readonly host: {\n readonly before: SpeculativeHostSnapshot;\n readonly after?: SpeculativeHostSnapshot;\n readonly changed: boolean;\n readonly error?: unknown;\n };\n readonly status: \"winner\" | \"no-winner\" | \"aborted\" | \"budget-exhausted\";\n readonly winner?: SpeculativeCandidateResult<T>;\n readonly candidates: readonly SpeculativeCandidateResult<T>[];\n readonly usage: WorkflowUsage;\n readonly error?: unknown;\n}\n\nexport interface SpeculativeHostSnapshot {\n readonly head: string;\n readonly branch: string;\n readonly fingerprint: string;\n readonly dirty: boolean;\n}\n"]}