@vercel/factory 0.0.14 → 0.0.15

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 (467) hide show
  1. package/README.md +306 -0
  2. package/dist/agent-routes.d.mts +69 -0
  3. package/dist/agent-routes.mjs +64 -0
  4. package/dist/agent-routes.mjs.map +1 -0
  5. package/dist/api-contracts.d.mts +1749 -0
  6. package/dist/api-contracts.mjs +118 -0
  7. package/dist/api-contracts.mjs.map +1 -0
  8. package/dist/api-images.d.mts +30 -0
  9. package/dist/api-images.mjs +28 -0
  10. package/dist/api-images.mjs.map +1 -0
  11. package/dist/api-task-graph.mjs +57 -0
  12. package/dist/api-task-graph.mjs.map +1 -0
  13. package/dist/api.d.mts +68 -216
  14. package/dist/api.mjs +872 -97
  15. package/dist/api.mjs.map +1 -1
  16. package/dist/approval-access.d.mts +39 -0
  17. package/dist/approval-access.mjs +62 -0
  18. package/dist/approval-access.mjs.map +1 -0
  19. package/dist/approval-contracts.d.mts +692 -0
  20. package/dist/approval-contracts.mjs +27 -0
  21. package/dist/approval-contracts.mjs.map +1 -0
  22. package/dist/approval.d.mts +49 -0
  23. package/dist/approval.mjs +39 -0
  24. package/dist/approval.mjs.map +1 -0
  25. package/dist/blob/artifacts.d.mts +37 -0
  26. package/dist/blob/artifacts.mjs +45 -0
  27. package/dist/blob/artifacts.mjs.map +1 -0
  28. package/dist/blob/index.d.mts +41 -6
  29. package/dist/blob/index.mjs +158 -40
  30. package/dist/blob/index.mjs.map +1 -1
  31. package/dist/budget.d.mts +108 -0
  32. package/dist/budget.mjs +141 -0
  33. package/dist/budget.mjs.map +1 -0
  34. package/dist/budgets.d.mts +4 -0
  35. package/dist/budgets.mjs +4 -0
  36. package/dist/build-factory.d.mts +6 -4
  37. package/dist/build-factory.mjs +2 -1
  38. package/dist/build-factory.mjs.map +1 -1
  39. package/dist/change-verification/brief.d.mts +9 -0
  40. package/dist/change-verification/brief.mjs +13 -0
  41. package/dist/change-verification/brief.mjs.map +1 -0
  42. package/dist/change-verification/dispatch.d.mts +24 -0
  43. package/dist/change-verification/dispatch.mjs +45 -0
  44. package/dist/change-verification/dispatch.mjs.map +1 -0
  45. package/dist/change-verification/eve-tool.d.mts +60 -0
  46. package/dist/change-verification/eve-tool.mjs +101 -0
  47. package/dist/change-verification/eve-tool.mjs.map +1 -0
  48. package/dist/changes/eve-record-change.d.mts +56 -0
  49. package/dist/changes/eve-record-change.mjs +97 -0
  50. package/dist/changes/eve-record-change.mjs.map +1 -0
  51. package/dist/changes/presentation.d.mts +14 -0
  52. package/dist/changes.d.mts +23 -0
  53. package/dist/changes.mjs +29 -0
  54. package/dist/changes.mjs.map +1 -0
  55. package/dist/client-events.d.mts +18 -0
  56. package/dist/client-events.mjs +41 -0
  57. package/dist/client-events.mjs.map +1 -0
  58. package/dist/client-stream.d.mts +28 -0
  59. package/dist/client-stream.mjs +204 -0
  60. package/dist/client-stream.mjs.map +1 -0
  61. package/dist/client-transcript.d.mts +41 -0
  62. package/dist/client-transcript.mjs +229 -0
  63. package/dist/client-transcript.mjs.map +1 -0
  64. package/dist/client.d.mts +234 -0
  65. package/dist/client.mjs +258 -0
  66. package/dist/client.mjs.map +1 -0
  67. package/dist/code-review/contracts.d.mts +26 -0
  68. package/dist/code-review/eve-post-review.d.mts +70 -0
  69. package/dist/code-review/eve-post-review.mjs +183 -0
  70. package/dist/code-review/eve-post-review.mjs.map +1 -0
  71. package/dist/code-review/eve-review-comments.d.mts +64 -0
  72. package/dist/code-review/eve-review-comments.mjs +159 -0
  73. package/dist/code-review/eve-review-comments.mjs.map +1 -0
  74. package/dist/code-review/github-contracts.d.mts +10 -0
  75. package/dist/code-review/github-reporter.d.mts +44 -0
  76. package/dist/code-review/github-reporter.mjs +260 -0
  77. package/dist/code-review/github-reporter.mjs.map +1 -0
  78. package/dist/code-review/preparation.d.mts +34 -0
  79. package/dist/code-review/preparation.mjs +23 -0
  80. package/dist/code-review/preparation.mjs.map +1 -0
  81. package/dist/code-review/stall.d.mts +17 -0
  82. package/dist/code-review/stall.mjs +30 -0
  83. package/dist/code-review/stall.mjs.map +1 -0
  84. package/dist/code-review.d.mts +6 -0
  85. package/dist/code-review.mjs +5 -0
  86. package/dist/communication.d.mts +9 -0
  87. package/dist/communication.mjs +9 -0
  88. package/dist/connectors/github.d.mts +26 -0
  89. package/dist/connectors/github.mjs +55 -0
  90. package/dist/connectors/github.mjs.map +1 -0
  91. package/dist/connectors/index.d.mts +35 -3
  92. package/dist/connectors/index.mjs +3 -52
  93. package/dist/connectors/index.mjs.map +1 -1
  94. package/dist/connectors/outbox.d.mts +34 -0
  95. package/dist/connectors/outbox.mjs +50 -0
  96. package/dist/connectors/outbox.mjs.map +1 -0
  97. package/dist/connectors/slack-approval-blocks.mjs +136 -0
  98. package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
  99. package/dist/connectors/slack-approvals.d.mts +29 -0
  100. package/dist/connectors/slack-approvals.mjs +346 -0
  101. package/dist/connectors/slack-approvals.mjs.map +1 -0
  102. package/dist/connectors/slack.d.mts +35 -52
  103. package/dist/connectors/slack.mjs +13 -85
  104. package/dist/connectors/slack.mjs.map +1 -1
  105. package/dist/deepsec/eve-tool.d.mts +110 -0
  106. package/dist/deepsec/eve-tool.mjs +164 -0
  107. package/dist/deepsec/eve-tool.mjs.map +1 -0
  108. package/dist/deepsec/finding.d.mts +84 -0
  109. package/dist/deepsec/finding.mjs +56 -0
  110. package/dist/deepsec/finding.mjs.map +1 -0
  111. package/dist/deepsec.d.mts +3 -0
  112. package/dist/delivery-metrics/metrics.d.mts +93 -0
  113. package/dist/delivery-metrics/metrics.mjs +200 -0
  114. package/dist/delivery-metrics/metrics.mjs.map +1 -0
  115. package/dist/delivery-metrics.d.mts +2 -0
  116. package/dist/delivery-metrics.mjs +2 -0
  117. package/dist/dispatch.d.mts +81 -0
  118. package/dist/dispatch.mjs +140 -0
  119. package/dist/dispatch.mjs.map +1 -0
  120. package/dist/errors.d.mts +15 -0
  121. package/dist/errors.mjs +38 -0
  122. package/dist/errors.mjs.map +1 -0
  123. package/dist/eve/index.d.mts +143 -1271
  124. package/dist/eve/index.mjs +233 -1065
  125. package/dist/eve/index.mjs.map +1 -1
  126. package/dist/eve/invoke.d.mts +144 -0
  127. package/dist/eve/invoke.mjs +241 -0
  128. package/dist/eve/invoke.mjs.map +1 -0
  129. package/dist/eve/session-client.d.mts +68 -0
  130. package/dist/eve/session-client.mjs +131 -0
  131. package/dist/eve/session-client.mjs.map +1 -0
  132. package/dist/eve/task-execution.mjs +18 -0
  133. package/dist/eve/task-execution.mjs.map +1 -0
  134. package/dist/eve/task-session.d.mts +87 -0
  135. package/dist/eve/task-session.mjs +203 -0
  136. package/dist/eve/task-session.mjs.map +1 -0
  137. package/dist/eve/transcript.d.mts +37 -0
  138. package/dist/eve/transcript.mjs +65 -0
  139. package/dist/eve/transcript.mjs.map +1 -0
  140. package/dist/execution-public.d.mts +8 -0
  141. package/dist/execution-public.mjs +7 -0
  142. package/dist/execution.d.mts +75 -0
  143. package/dist/execution.mjs +153 -0
  144. package/dist/execution.mjs.map +1 -0
  145. package/dist/finding-remediation/admission.d.mts +51 -0
  146. package/dist/finding-remediation/admission.mjs +87 -0
  147. package/dist/finding-remediation/admission.mjs.map +1 -0
  148. package/dist/finding-remediation/brief.d.mts +14 -0
  149. package/dist/finding-remediation/brief.mjs +25 -0
  150. package/dist/finding-remediation/brief.mjs.map +1 -0
  151. package/dist/finding-remediation/eve-tool.d.mts +29 -0
  152. package/dist/finding-remediation/eve-tool.mjs +34 -0
  153. package/dist/finding-remediation/eve-tool.mjs.map +1 -0
  154. package/dist/findings/fingerprint.d.mts +14 -0
  155. package/dist/findings/fingerprint.mjs +28 -0
  156. package/dist/findings/fingerprint.mjs.map +1 -0
  157. package/dist/findings.d.mts +6 -0
  158. package/dist/findings.mjs +6 -0
  159. package/dist/github-app.d.mts +54 -0
  160. package/dist/github-app.mjs +121 -0
  161. package/dist/github-app.mjs.map +1 -0
  162. package/dist/github-publication.d.mts +198 -0
  163. package/dist/github-publication.mjs +429 -0
  164. package/dist/github-publication.mjs.map +1 -0
  165. package/dist/github-transfer.d.mts +72 -0
  166. package/dist/github-transfer.mjs +125 -0
  167. package/dist/github-transfer.mjs.map +1 -0
  168. package/dist/github.d.mts +406 -2
  169. package/dist/github.mjs +239 -40
  170. package/dist/github.mjs.map +1 -1
  171. package/dist/image-input.d.mts +51 -0
  172. package/dist/image-input.mjs +63 -0
  173. package/dist/image-input.mjs.map +1 -0
  174. package/dist/index.d.mts +14 -484
  175. package/dist/index.mjs +14 -522
  176. package/dist/intake-contracts.d.mts +56 -0
  177. package/dist/intake-contracts.mjs +33 -0
  178. package/dist/intake-contracts.mjs.map +1 -0
  179. package/dist/integrations/deepsec.d.mts +4 -0
  180. package/dist/integrations/deepsec.mjs +3 -0
  181. package/dist/integrations/github.d.mts +11 -0
  182. package/dist/integrations/github.mjs +9 -0
  183. package/dist/integrations/slack.d.mts +3 -0
  184. package/dist/integrations/slack.mjs +3 -0
  185. package/dist/integrations/vercel.d.mts +3 -0
  186. package/dist/integrations/vercel.mjs +3 -0
  187. package/dist/merge-resolution/contracts.d.mts +17 -0
  188. package/dist/merge-resolution/contracts.mjs +19 -0
  189. package/dist/merge-resolution/contracts.mjs.map +1 -0
  190. package/dist/merge-resolution/eve-tools.d.mts +46 -0
  191. package/dist/merge-resolution/eve-tools.mjs +117 -0
  192. package/dist/merge-resolution/eve-tools.mjs.map +1 -0
  193. package/dist/multi-repository-changes/coordination.d.mts +49 -0
  194. package/dist/multi-repository-changes/coordination.mjs +115 -0
  195. package/dist/multi-repository-changes/coordination.mjs.map +1 -0
  196. package/dist/planning/cancellation.mjs +82 -0
  197. package/dist/planning/cancellation.mjs.map +1 -0
  198. package/dist/planning/configuration.d.mts +23 -0
  199. package/dist/planning/configuration.mjs +56 -0
  200. package/dist/planning/configuration.mjs.map +1 -0
  201. package/dist/planning/contracts.d.mts +136 -0
  202. package/dist/planning/contracts.mjs +42 -0
  203. package/dist/planning/contracts.mjs.map +1 -0
  204. package/dist/planning/dependencies.mjs +44 -0
  205. package/dist/planning/dependencies.mjs.map +1 -0
  206. package/dist/planning/effects.mjs +122 -0
  207. package/dist/planning/effects.mjs.map +1 -0
  208. package/dist/planning/reconcile.mjs +273 -0
  209. package/dist/planning/reconcile.mjs.map +1 -0
  210. package/dist/planning/runtime.d.mts +27 -0
  211. package/dist/planning/runtime.mjs +25 -0
  212. package/dist/planning/runtime.mjs.map +1 -0
  213. package/dist/planning/state.mjs +92 -0
  214. package/dist/planning/state.mjs.map +1 -0
  215. package/dist/planning/turns.mjs +262 -0
  216. package/dist/planning/turns.mjs.map +1 -0
  217. package/dist/planning/validation.mjs +106 -0
  218. package/dist/planning/validation.mjs.map +1 -0
  219. package/dist/postgres/index.d.mts +7 -1
  220. package/dist/postgres/index.mjs +7 -3
  221. package/dist/postgres/index.mjs.map +1 -1
  222. package/dist/presets/software-development/approval.d.mts +14 -0
  223. package/dist/presets/software-development/approval.mjs +21 -0
  224. package/dist/presets/software-development/approval.mjs.map +1 -0
  225. package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
  226. package/dist/presets/software-development/deepsec-brief.mjs +14 -0
  227. package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
  228. package/dist/presets/software-development/dispatch.d.mts +53 -0
  229. package/dist/presets/software-development/dispatch.mjs +66 -0
  230. package/dist/presets/software-development/dispatch.mjs.map +1 -0
  231. package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
  232. package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
  233. package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
  234. package/dist/presets/software-development/eve.d.mts +18 -0
  235. package/dist/presets/software-development/eve.mjs +19 -0
  236. package/dist/presets/software-development/eve.mjs.map +1 -0
  237. package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
  238. package/dist/presets/software-development/finish-task-policy.mjs +9 -0
  239. package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
  240. package/dist/presets/software-development/recovery.d.mts +32 -0
  241. package/dist/presets/software-development/recovery.mjs +120 -0
  242. package/dist/presets/software-development/recovery.mjs.map +1 -0
  243. package/dist/presets/software-development/task-communication.d.mts +23 -0
  244. package/dist/presets/software-development/task-communication.mjs +120 -0
  245. package/dist/presets/software-development/task-communication.mjs.map +1 -0
  246. package/dist/presets/software-development.d.mts +9 -0
  247. package/dist/presets/software-development.mjs +9 -0
  248. package/dist/pull-requests/contracts.d.mts +72 -0
  249. package/dist/pull-requests/eve-fetch.d.mts +57 -0
  250. package/dist/pull-requests/eve-fetch.mjs +151 -0
  251. package/dist/pull-requests/eve-fetch.mjs.map +1 -0
  252. package/dist/pull-requests/github-label-manager.d.mts +27 -0
  253. package/dist/pull-requests/github-label-manager.mjs +40 -0
  254. package/dist/pull-requests/github-label-manager.mjs.map +1 -0
  255. package/dist/pull-requests/github-publisher.d.mts +53 -0
  256. package/dist/pull-requests/github-publisher.mjs +345 -0
  257. package/dist/pull-requests/github-publisher.mjs.map +1 -0
  258. package/dist/pull-requests.d.mts +5 -0
  259. package/dist/pull-requests.mjs +4 -0
  260. package/dist/receipts.d.mts +4 -0
  261. package/dist/receipts.mjs +3 -0
  262. package/dist/repositories.d.mts +18 -0
  263. package/dist/repositories.mjs +33 -0
  264. package/dist/repositories.mjs.map +1 -0
  265. package/dist/sandbox/command.d.mts +18 -0
  266. package/dist/sandbox/execution-abort.d.mts +16 -0
  267. package/dist/sandbox/execution-abort.mjs +49 -0
  268. package/dist/sandbox/execution-abort.mjs.map +1 -0
  269. package/dist/sandbox/execution-environment.d.mts +25 -0
  270. package/dist/sandbox/execution-run-ledger.d.mts +115 -0
  271. package/dist/sandbox/execution-run-ledger.mjs +209 -0
  272. package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
  273. package/dist/sandbox/execution.d.mts +54 -0
  274. package/dist/sandbox/execution.mjs +228 -0
  275. package/dist/sandbox/execution.mjs.map +1 -0
  276. package/dist/sandbox/harness-runner.d.mts +79 -0
  277. package/dist/sandbox/harness-runner.mjs +162 -0
  278. package/dist/sandbox/harness-runner.mjs.map +1 -0
  279. package/dist/sandbox/index.d.mts +9 -0
  280. package/dist/sandbox/index.mjs +7 -0
  281. package/dist/sandbox/task-environment.d.mts +50 -0
  282. package/dist/sandbox/task-environment.mjs +140 -0
  283. package/dist/sandbox/task-environment.mjs.map +1 -0
  284. package/dist/sandbox/workspace.d.mts +29 -0
  285. package/dist/sandbox/workspace.mjs +28 -0
  286. package/dist/sandbox/workspace.mjs.map +1 -0
  287. package/dist/schema/agent-route.d.mts +22 -0
  288. package/dist/schema/agent-route.mjs +15 -0
  289. package/dist/schema/agent-route.mjs.map +1 -0
  290. package/dist/schema/answer.d.mts +23 -0
  291. package/dist/schema/answer.mjs +21 -0
  292. package/dist/schema/answer.mjs.map +1 -0
  293. package/dist/schema/budget.d.mts +38 -0
  294. package/dist/schema/budget.mjs +30 -0
  295. package/dist/schema/budget.mjs.map +1 -0
  296. package/dist/schema/catalog.mjs +72 -0
  297. package/dist/schema/catalog.mjs.map +1 -0
  298. package/dist/schema/change.d.mts +117 -0
  299. package/dist/schema/change.mjs +68 -0
  300. package/dist/schema/change.mjs.map +1 -0
  301. package/dist/schema/common.d.mts +33 -0
  302. package/dist/{id-BLIkCVue.mjs → schema/common.mjs} +7 -16
  303. package/dist/schema/common.mjs.map +1 -0
  304. package/dist/schema/communication.d.mts +52 -0
  305. package/dist/{communication-Kd9nU5RP.mjs → schema/communication.mjs} +8 -3
  306. package/dist/schema/communication.mjs.map +1 -0
  307. package/dist/schema/execution.d.mts +101 -0
  308. package/dist/schema/execution.mjs +86 -0
  309. package/dist/schema/execution.mjs.map +1 -0
  310. package/dist/schema/factory-config.d.mts +95 -0
  311. package/dist/schema/factory-config.mjs +60 -0
  312. package/dist/schema/factory-config.mjs.map +1 -0
  313. package/dist/schema/finding.d.mts +125 -0
  314. package/dist/schema/finding.mjs +67 -0
  315. package/dist/schema/finding.mjs.map +1 -0
  316. package/dist/schema/id.d.mts +43 -0
  317. package/dist/schema/id.mjs +32 -0
  318. package/dist/schema/id.mjs.map +1 -0
  319. package/dist/schema/outbox.d.mts +240 -0
  320. package/dist/schema/outbox.mjs +53 -0
  321. package/dist/schema/outbox.mjs.map +1 -0
  322. package/dist/schema/question-route.mjs +16 -0
  323. package/dist/schema/question-route.mjs.map +1 -0
  324. package/dist/schema/receipt.d.mts +81 -0
  325. package/dist/schema/receipt.mjs +94 -0
  326. package/dist/schema/receipt.mjs.map +1 -0
  327. package/dist/schema/repository.d.mts +26 -0
  328. package/dist/schema/repository.mjs +25 -0
  329. package/dist/schema/repository.mjs.map +1 -0
  330. package/dist/schema/session.d.mts +135 -0
  331. package/dist/schema/session.mjs +53 -0
  332. package/dist/schema/session.mjs.map +1 -0
  333. package/dist/schema/signal.d.mts +105 -0
  334. package/dist/schema/signal.mjs +81 -0
  335. package/dist/schema/signal.mjs.map +1 -0
  336. package/dist/schema/stored-session.mjs +10 -0
  337. package/dist/schema/stored-session.mjs.map +1 -0
  338. package/dist/schema/stored-task.mjs +20 -0
  339. package/dist/schema/stored-task.mjs.map +1 -0
  340. package/dist/schema/task-effect.d.mts +39 -0
  341. package/dist/schema/task-effect.mjs +29 -0
  342. package/dist/schema/task-effect.mjs.map +1 -0
  343. package/dist/schema/task-graph.d.mts +3134 -0
  344. package/dist/schema/task-graph.mjs +97 -0
  345. package/dist/schema/task-graph.mjs.map +1 -0
  346. package/dist/schema/task-message.d.mts +254 -0
  347. package/dist/schema/task-message.mjs +189 -0
  348. package/dist/schema/task-message.mjs.map +1 -0
  349. package/dist/schema/task.d.mts +272 -0
  350. package/dist/schema/task.mjs +199 -0
  351. package/dist/schema/task.mjs.map +1 -0
  352. package/dist/schema/transcript.d.mts +170 -0
  353. package/dist/schema/transcript.mjs +86 -0
  354. package/dist/schema/transcript.mjs.map +1 -0
  355. package/dist/schema/transitions.d.mts +50 -0
  356. package/dist/schema/transitions.mjs +303 -0
  357. package/dist/schema/transitions.mjs.map +1 -0
  358. package/dist/schema/work.d.mts +101 -0
  359. package/dist/schema/work.mjs +102 -0
  360. package/dist/schema/work.mjs.map +1 -0
  361. package/dist/signal-triage.d.mts +20 -0
  362. package/dist/signal-triage.mjs +85 -0
  363. package/dist/signal-triage.mjs.map +1 -0
  364. package/dist/signals.d.mts +19 -0
  365. package/dist/signals.mjs +19 -0
  366. package/dist/signals.mjs.map +1 -0
  367. package/dist/stall.d.mts +38 -0
  368. package/dist/stall.mjs +79 -0
  369. package/dist/stall.mjs.map +1 -0
  370. package/dist/storage.d.mts +4 -0
  371. package/dist/storage.mjs +4 -0
  372. package/dist/store/driver.d.mts +65 -0
  373. package/dist/store/driver.mjs +42 -0
  374. package/dist/store/driver.mjs.map +1 -0
  375. package/dist/store/engine.d.mts +485 -0
  376. package/dist/store/engine.mjs +2175 -0
  377. package/dist/store/engine.mjs.map +1 -0
  378. package/dist/store/memory.d.mts +7 -0
  379. package/dist/store/memory.mjs +52 -0
  380. package/dist/store/memory.mjs.map +1 -0
  381. package/dist/store/task-effects.d.mts +38 -0
  382. package/dist/store/task-effects.mjs +118 -0
  383. package/dist/store/task-effects.mjs.map +1 -0
  384. package/dist/store/task-graphs.d.mts +60 -0
  385. package/dist/store/task-graphs.mjs +212 -0
  386. package/dist/store/task-graphs.mjs.map +1 -0
  387. package/dist/store/task-messages.d.mts +136 -0
  388. package/dist/store/task-messages.mjs +475 -0
  389. package/dist/store/task-messages.mjs.map +1 -0
  390. package/dist/store/task-work.d.mts +65 -0
  391. package/dist/store/task-work.mjs +134 -0
  392. package/dist/store/task-work.mjs.map +1 -0
  393. package/dist/store/work-notifications.d.mts +19 -0
  394. package/dist/store/work-notifications.mjs +48 -0
  395. package/dist/store/work-notifications.mjs.map +1 -0
  396. package/dist/sweep.d.mts +57 -0
  397. package/dist/sweep.mjs +143 -0
  398. package/dist/sweep.mjs.map +1 -0
  399. package/dist/task-communication.d.mts +35 -0
  400. package/dist/task-communication.mjs +47 -0
  401. package/dist/task-communication.mjs.map +1 -0
  402. package/dist/task-graph-view.d.mts +264 -0
  403. package/dist/task-graph-view.mjs +17 -0
  404. package/dist/task-graph-view.mjs.map +1 -0
  405. package/dist/task-message-processing.d.mts +60 -0
  406. package/dist/task-message-processing.mjs +200 -0
  407. package/dist/task-message-processing.mjs.map +1 -0
  408. package/dist/task-protocols.d.mts +80 -0
  409. package/dist/task-protocols.mjs +47 -0
  410. package/dist/task-protocols.mjs.map +1 -0
  411. package/dist/tasks.d.mts +17 -0
  412. package/dist/tasks.mjs +17 -0
  413. package/dist/vercel-git.d.mts +21 -0
  414. package/dist/vercel-git.mjs +112 -0
  415. package/dist/vercel-git.mjs.map +1 -0
  416. package/dist/vercel.d.mts +33 -2
  417. package/dist/vercel.mjs +48 -3
  418. package/dist/vercel.mjs.map +1 -1
  419. package/dist/work-triage/eve-tool.d.mts +29 -0
  420. package/dist/work-triage/eve-tool.mjs +32 -0
  421. package/dist/work-triage/eve-tool.mjs.map +1 -0
  422. package/dist/work-triage/find-existing-work.d.mts +32 -0
  423. package/dist/work-triage/find-existing-work.mjs +31 -0
  424. package/dist/work-triage/find-existing-work.mjs.map +1 -0
  425. package/dist/work-triage/github.d.mts +15 -0
  426. package/dist/work-triage/github.mjs +14 -0
  427. package/dist/work-triage/github.mjs.map +1 -0
  428. package/dist/work-triage.d.mts +3 -0
  429. package/dist/work-triage.mjs +3 -0
  430. package/dist/workflows.d.mts +48 -0
  431. package/dist/workflows.mjs +86 -0
  432. package/dist/workflows.mjs.map +1 -0
  433. package/dist/workspace-diff-assembly.d.mts +33 -0
  434. package/dist/workspace-diff-assembly.mjs +95 -0
  435. package/dist/workspace-diff-assembly.mjs.map +1 -0
  436. package/dist/workspace-diff.d.mts +90 -0
  437. package/dist/workspace-diff.mjs +61 -0
  438. package/dist/workspace-diff.mjs.map +1 -0
  439. package/dist/workspace-snapshot.d.mts +26 -0
  440. package/dist/workspace-snapshot.mjs +80 -0
  441. package/dist/workspace-snapshot.mjs.map +1 -0
  442. package/package.json +129 -44
  443. package/dist/approval-JX2Px9IC.mjs +0 -132
  444. package/dist/approval-JX2Px9IC.mjs.map +0 -1
  445. package/dist/budget-DzSiIA4t.mjs +0 -42
  446. package/dist/budget-DzSiIA4t.mjs.map +0 -1
  447. package/dist/change-D2U6v7Ek.mjs +0 -554
  448. package/dist/change-D2U6v7Ek.mjs.map +0 -1
  449. package/dist/communication-Kd9nU5RP.mjs.map +0 -1
  450. package/dist/coordination-Cq08hb1l.mjs +0 -76
  451. package/dist/coordination-Cq08hb1l.mjs.map +0 -1
  452. package/dist/dispatch-BaZS3PT8.d.mts +0 -76
  453. package/dist/driver-BC0Mt5KG.d.mts +0 -34
  454. package/dist/driver-Bbd25rNM.mjs +0 -23
  455. package/dist/driver-Bbd25rNM.mjs.map +0 -1
  456. package/dist/engine-DFHU2Pe-.d.mts +0 -781
  457. package/dist/engine-WaUM2cGA.mjs +0 -1068
  458. package/dist/engine-WaUM2cGA.mjs.map +0 -1
  459. package/dist/factory-config-BoRXOw43.mjs +0 -50
  460. package/dist/factory-config-BoRXOw43.mjs.map +0 -1
  461. package/dist/factory-config-D2yU3G0c.d.mts +0 -58
  462. package/dist/github-C5HNBN6p.d.mts +0 -279
  463. package/dist/id-BLIkCVue.mjs.map +0 -1
  464. package/dist/index-Bw6hggoH.d.mts +0 -40
  465. package/dist/index.mjs.map +0 -1
  466. package/dist/task-CcOyOJ3k.mjs +0 -154
  467. package/dist/task-CcOyOJ3k.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/eve/conflict.ts","../../src/eve/finding.ts","../../src/eve/deepsec.ts","../../src/eve/fetch.ts","../../src/eve/invoke.ts","../../src/eve/post-review.ts","../../src/eve/review.ts","../../src/eve/verification.ts","../../src/eve/index.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { taskIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\nimport { defineTool } from \"eve/tools\";\nimport type { CommandSandbox } from \"./fetch\";\n\nconst gitShaSchema = z.string().regex(/^[0-9a-f]{40}$/);\nconst gitBranchSchema = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._/-]*$/).refine((value) => !value.includes(\"..\"));\n\nexport const mergeConflictPayloadSchema = z.strictObject({\n repository: z.string().regex(/^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/),\n prNumber: z.number().int().positive(),\n prUrl: z.url(),\n headBranch: gitBranchSchema.refine((value) => value.startsWith(\"factory/\")),\n headSha: gitShaSchema,\n baseBranch: gitBranchSchema,\n baseSha: gitShaSchema,\n});\n\nexport type MergeConflictPayload = z.infer<typeof mergeConflictPayloadSchema>;\n\nexport interface MergeConflictToolOptions<S extends CommandSandbox = CommandSandbox> {\n withCredential: (\n sandbox: S,\n repository: string,\n command: string,\n ) => Promise<{ stdout: string; stderr?: string; exitCode?: number }>;\n repoPath?: string;\n}\n\nexport function mergeConflictTools<S extends CommandSandbox>(\n stores: FactoryStores,\n options: MergeConflictToolOptions<S>,\n) {\n const repoPath = options.repoPath ?? \"repo\";\n\n async function context(taskId: z.infer<typeof taskIdSchema>) {\n const task = await stores.tasks.get(taskId);\n if (task === null) throw new Error(`task ${taskId} does not exist`);\n if (task.kind !== \"merge_conflict\") throw new Error(`task ${taskId} is ${task.kind}, not merge_conflict`);\n if (task.state !== \"running\") throw new Error(`task ${taskId} is ${task.state}, not running`);\n if (task.origin.signalId === undefined) throw new Error(`task ${taskId} has no conflict signal`);\n const signal = await stores.signals.get(task.origin.signalId);\n if (signal === null || signal.source !== \"github_merge_conflict\") {\n throw new Error(`task ${taskId} has no GitHub merge conflict signal`);\n }\n return { task, conflict: mergeConflictPayloadSchema.parse(signal.payload) };\n }\n\n return {\n fetch_merge_conflict: defineTool({\n description:\n \"Fetch the conflicted factory pull request and its current base, check out the PR head, and start the merge. Resolve every file returned in conflictedFiles, then test and commit the merge.\",\n inputSchema: z.object({ taskId: taskIdSchema }),\n async execute({ taskId }, ctx) {\n const { conflict } = await context(taskId);\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const git = `git -C ${repoPath}`;\n const headRef = `refs/remotes/origin/conflict-pr-${conflict.prNumber}`;\n const baseRef = `refs/remotes/origin/conflict-base-${conflict.prNumber}`;\n const fetch = await options.withCredential(\n sandbox,\n conflict.repository,\n `${git} fetch --depth 100 origin +refs/pull/${conflict.prNumber}/head:${headRef} +refs/heads/${conflict.baseBranch}:${baseRef}`,\n );\n if (typeof fetch.exitCode === \"number\" && fetch.exitCode !== 0) {\n throw new Error(`could not fetch pull request: ${(fetch.stderr ?? \"\").trim()}`);\n }\n const fetched = await sandbox.run({\n command: `${git} rev-parse ${headRef} && ${git} rev-parse ${baseRef}`,\n });\n const [headSha, baseSha] = fetched.stdout.trim().split(\"\\n\");\n if (headSha !== conflict.headSha || baseSha !== conflict.baseSha) {\n throw new Error(\"pull request or base changed while conflict resolution was starting; retry from a new task\");\n }\n await sandbox.run({ command: `${git} checkout -B conflict-pr ${headRef}` });\n const merge = await sandbox.run({ command: `${git} merge --no-commit --no-ff ${baseRef}` });\n const conflicts = await sandbox.run({ command: `${git} diff --name-only --diff-filter=U` });\n const conflictedFiles = conflicts.stdout.trim().split(\"\\n\").filter(Boolean);\n if (conflictedFiles.length === 0) {\n throw new Error(\n typeof merge.exitCode === \"number\" && merge.exitCode !== 0\n ? `merge failed without file conflicts: ${(merge.stderr ?? \"\").trim()}`\n : \"pull request no longer has merge conflicts\",\n );\n }\n return { ...conflict, conflictedFiles };\n },\n }),\n publish_merge_resolution: defineTool({\n description:\n \"Publish a tested, committed conflict resolution to the existing pull request branch. Fails if the remote branch changed since this task started.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n summary: z.string().min(1).max(2000),\n }),\n async execute({ taskId, summary }, ctx) {\n const { conflict } = await context(taskId);\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const git = `git -C ${repoPath}`;\n const clean = await sandbox.run({ command: `${git} status --porcelain` });\n if (clean.stdout.trim() !== \"\") throw new Error(\"commit the conflict resolution before publishing\");\n const unresolved = await sandbox.run({ command: `${git} diff --name-only --diff-filter=U` });\n if (unresolved.stdout.trim() !== \"\") throw new Error(\"merge conflicts remain unresolved\");\n const push = await options.withCredential(\n sandbox,\n conflict.repository,\n `${git} push --force-with-lease=refs/heads/${conflict.headBranch}:${conflict.headSha} origin HEAD:refs/heads/${conflict.headBranch}`,\n );\n if (typeof push.exitCode === \"number\" && push.exitCode !== 0) {\n throw new Error(`could not update pull request branch: ${(push.stderr ?? \"\").trim()}`);\n }\n await stores.tasks.transition(taskId, \"verifying\", { reason: summary });\n await stores.tasks.transition(taskId, \"succeeded\", { reason: summary });\n return { updated: true as const, prNumber: conflict.prNumber, prUrl: conflict.prUrl };\n },\n }),\n };\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { defaultApprovalPolicy, requiresApproval, type ApprovalPolicy } from \"../approval\";\nimport { findingFingerprint, findingSchema, type Finding } from \"../schema/finding\";\nimport { repositoryIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\n// Matched by name, not instanceof: the Blob driver is a separate package entry\n// point, so its error classes are distinct objects from any imported here.\nfunction isLostRaceError(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.name === \"VersionConflictError\" || error.name === \"InvalidTransitionError\")\n );\n}\n\nexport interface RecordFindingOptions {\n /** Signal source the findings are recorded under. Defaults to security_scan. */\n source?: string;\n /** Which resulting tasks wait for a human. Defaults to the standard policy. */\n approval?: ApprovalPolicy;\n}\n\nexport type RecordFindingResult =\n | { recorded: false; reason: string; duplicate?: true; signalId?: string }\n | { recorded: true; signalId: string; taskId: string; approval: \"required\" | \"not_required\" };\n\n/**\n * Turn one finding into a signal and a fix task. The fingerprint is the\n * signal's delivery id, so the same problem reported twice is a no-op. The\n * signal is accepted on the reporter's own verification (a human gate follows\n * when the approval policy says so), and the task carries the approval\n * decision from the moment it exists. Shared by record_finding and scanner\n * tools that record on the agent's behalf.\n */\nexport async function recordFinding(\n stores: FactoryStores,\n repositoryId: string,\n finding: Finding,\n options: RecordFindingOptions = {},\n): Promise<RecordFindingResult> {\n const source = options.source ?? \"security_scan\";\n const policy = options.approval ?? defaultApprovalPolicy;\n const repository = await stores.repositories.get(repositoryId);\n if (repository === null) {\n return { recorded: false, reason: `repository ${repositoryId} does not exist` };\n }\n\n const fingerprint = findingFingerprint(repositoryId, finding);\n const signal = await stores.signals.create({\n repositoryId,\n source,\n deliveryId: fingerprint,\n replyTo: { channel: \"finding\", address: fingerprint },\n payload: finding,\n });\n if (signal.outcome !== \"pending\") {\n return { recorded: false, duplicate: true, signalId: signal.id, reason: `already recorded as ${signal.id}` };\n }\n\n // Overlapping scanner sessions can record the same finding. The signal is\n // created idempotently by fingerprint; accepting it is the compare-and-swap.\n try {\n await stores.signals.decide(signal.id, \"accepted\", {\n detail: finding.priority,\n reason: `${finding.tool ?? \"scanner\"} reported it, ${finding.verification.level} by ${finding.verification.method}`,\n });\n } catch (error) {\n // Lost the race: if the winner already decided the signal, this is a\n // duplicate; only a still-pending signal is a real failure to re-raise.\n if (isLostRaceError(error)) {\n const current = await stores.signals.get(signal.id);\n if (current !== null && current.outcome !== \"pending\") {\n return { recorded: false, duplicate: true, signalId: signal.id, reason: `already recorded as ${signal.id}` };\n }\n }\n throw error;\n }\n\n const approval = requiresApproval(policy, { source, kind: \"code_change\", priority: finding.priority });\n const task = await stores.tasks.create({\n repositoryIds: [repositoryId],\n kind: \"code_change\",\n origin: { signalId: signal.id },\n replyTo: signal.replyTo,\n ...(approval ? { approval: \"required\" as const } : {}),\n });\n\n return { recorded: true, signalId: signal.id, taskId: task.id, approval: approval ? \"required\" : \"not_required\" };\n}\n\n/**\n * The scanner's outcome tool: turns one finding into a signal and a fix task\n * in a single deterministic step. The finding's fingerprint is the signal's\n * delivery id, so reporting the same problem twice is a no-op. The signal is\n * accepted on the reporter's own verification (a human gate follows when the\n * approval policy says so), and the task carries the approval decision from\n * the moment it exists.\n */\nexport function recordFindingTool(stores: FactoryStores, options: RecordFindingOptions = {}) {\n return defineTool({\n description:\n \"Record one problem you found in the repository. Creates a fix task (which may wait for human approval) unless the same finding was already recorded. Report every finding separately; never batch.\",\n inputSchema: z.object({\n repositoryId: repositoryIdSchema,\n finding: findingSchema,\n }),\n execute({ repositoryId, finding }) {\n return recordFinding(stores, repositoryId, finding, options);\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { findingSchema, type Finding, type FindingPriority } from \"../schema/finding\";\nimport { repositoryIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\nimport type { CommandSandbox } from \"./fetch\";\nimport { recordFinding, type RecordFindingOptions, type RecordFindingResult } from \"./finding\";\n\nexport interface DeepsecScanOptions<S extends CommandSandbox = CommandSandbox> extends RecordFindingOptions {\n /**\n * Runs one shell command with the model credential deepsec's gateway route\n * expects, and removes it again before resolving. Supplied by the app, which\n * owns where the credential comes from: on Vercel it is the deployment's own\n * OIDC identity (VERCEL_OIDC_TOKEN), so nothing has to be configured.\n */\n withModelCredential: (sandbox: S, command: string) => Promise<{ stdout: string; stderr?: string; exitCode?: number }>;\n /** deepsec agent backend: claude, codex, or pi. */\n agent?: \"claude\" | \"codex\" | \"pi\";\n /** Model deepsec's investigation agent uses, through the AI Gateway (e.g. claude-sonnet-4-6). */\n model?: string;\n /** Reasoning effort for the investigation: minimal, low, medium, high, or xhigh. */\n thinkingLevel?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n /** Parallel investigation batches. */\n concurrency?: number;\n /** deepsec version to install. */\n version?: string;\n /** Repository checkout inside the sandbox. Defaults to `repo`. */\n repoPath?: string;\n /** deepsec workspace inside the sandbox. Defaults to `deepsec`. */\n workspacePath?: string;\n /** Shell run before every deepsec command, e.g. to put a Node 24 on PATH. */\n commandPrefix?: string;\n /**\n * Candidate files investigated per run. deepsec keeps state, so successive\n * scans continue where the last one stopped; the cap keeps one run inside\n * the deployment's time limit on large repositories. Defaults to 40.\n */\n filesPerRun?: number;\n}\n\n/** deepsec's exported finding shape, as far as we depend on it. */\nconst deepsecFindingSchema = z.looseObject({\n title: z.string().min(1),\n description: z.string().min(1),\n severity: z.string().min(1),\n metadata: z\n .looseObject({\n filePath: z.string().min(1).optional(),\n lineNumbers: z.array(z.number().int().min(1)).optional(),\n vulnSlug: z.string().min(1).optional(),\n confidence: z.string().optional(),\n runId: z.string().optional(),\n })\n .optional(),\n});\n\nconst deepsecExportSchema = z.union([\n z.array(deepsecFindingSchema),\n z.looseObject({ findings: z.array(deepsecFindingSchema) }).transform((value) => value.findings),\n]);\n\nconst priorityBySeverity: Record<string, FindingPriority> = {\n CRITICAL: \"P0\",\n HIGH: \"P1\",\n MEDIUM: \"P2\",\n HIGH_BUG: \"P2\",\n BUG: \"P3\",\n LOW: \"P3\",\n};\n\n/** Convert one deepsec finding into the factory's Finding. Pure; exported for tests. */\nexport function findingFromDeepsec(raw: z.infer<typeof deepsecFindingSchema>): Finding {\n const meta = raw.metadata ?? {};\n const confidence = (meta.confidence ?? \"\").toLowerCase();\n const line = meta.lineNumbers?.[0];\n const endLine = meta.lineNumbers === undefined ? undefined : Math.max(...meta.lineNumbers);\n return findingSchema.parse({\n title: raw.title.replace(/^\\[[A-Z_]+\\]\\s*/u, \"\").slice(0, 200),\n body: raw.description.slice(0, 8000),\n ...(meta.filePath === undefined ? {} : { path: meta.filePath.slice(0, 500) }),\n ...(line === undefined ? {} : { line }),\n ...(endLine === undefined || endLine === line ? {} : { endLine }),\n priority: priorityBySeverity[raw.severity.toUpperCase()] ?? \"P3\",\n category: \"security\",\n verification: {\n // deepsec's agent reads the code; it does not run it. Say so.\n level: confidence === \"high\" ? \"supported\" : \"unverified\",\n method: \"static_analysis\",\n summary: `deepsec ${meta.vulnSlug ?? \"finding\"} with ${confidence || \"unknown\"} confidence${meta.runId === undefined ? \"\" : ` (run ${meta.runId})`}.`,\n limitations: \"AI-assisted static analysis of the checkout; not reproduced at runtime.\",\n },\n tool: \"deepsec\",\n ...(meta.vulnSlug === undefined ? {} : { ruleId: meta.vulnSlug }),\n });\n}\n\nconst findingsPath = \"/tmp/deepsec-findings.json\";\n\n/** Parse \"N file(s) with candidates\" out of deepsec scan output; null when absent. */\nfunction candidateCount(output: string): number | null {\n const match = /(\\d+)\\s+file\\(s\\) with candidates/u.exec(output);\n return match?.[1] === undefined ? null : Number(match[1]);\n}\n\n/** The last few meaningful lines of a command's output, ANSI stripped, for a receipt. */\nfunction tail(output: string, lines = 4): string {\n // eslint-disable-next-line no-control-regex -- stripping terminal colour codes\n const ansi = /\\u001b\\[[0-9;]*m/gu;\n return output\n .replaceAll(ansi, \"\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\")\n .slice(-lines)\n .join(\" | \")\n .slice(0, 600);\n}\n\n/**\n * Runs deepsec (vercel-labs/deepsec) against the sandbox checkout and records\n * what it finds through the same path as record_finding, so every deepsec\n * finding becomes a fix task subject to the approval policy. Trusted code\n * owns the command sequence and the credential; the agent chooses when to\n * scan and reports the outcome.\n */\nexport function deepsecScanTool<S extends CommandSandbox>(stores: FactoryStores, options: DeepsecScanOptions<S>) {\n const repoPath = options.repoPath ?? \"repo\";\n const workspace = options.workspacePath ?? \"deepsec\";\n const version = options.version ?? \"2.3.8\";\n const agent = options.agent ?? \"claude\";\n const model = options.model ?? \"claude-sonnet-4-6\";\n const thinkingLevel = options.thinkingLevel ?? \"medium\";\n const concurrency = options.concurrency ?? 4;\n const prefix = options.commandPrefix === undefined ? [] : [options.commandPrefix];\n const filesPerRun = options.filesPerRun ?? 40;\n\n return defineTool({\n description:\n \"Run deepsec, the AI-powered vulnerability scanner, over the repository checkout and record every finding it reports as a fix task. Takes minutes. Call once per scan; then summarize the result.\",\n inputSchema: z.object({\n repositoryId: repositoryIdSchema,\n limit: z\n .number()\n .int()\n .min(1)\n .max(500)\n .optional()\n .describe(\"Candidate files to investigate this run (default 40; deepsec resumes where it left off next time).\"),\n }),\n async execute({ repositoryId, limit }, ctx) {\n const repository = await stores.repositories.get(repositoryId);\n if (repository === null) {\n return { scanned: false as const, reason: `repository ${repositoryId} does not exist` };\n }\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const projectId = repository.slug.replace(/[^a-z0-9]+/gu, \"-\");\n const startedAt = Date.now();\n\n // One receipt per phase, so the ledger answers \"where is the scan\" while\n // deepsec runs and shows what each phase cost afterwards.\n const phase = async (state: string, reason: string): Promise<void> => {\n await stores.receipts.append({\n repositoryIds: [repositoryId],\n kind: \"deepsec\",\n state,\n phase: \"security_scan\",\n reason: `${reason} (${Math.round((Date.now() - startedAt) / 1000)}s in)`,\n });\n };\n await phase(\"started\", `deepsec ${version} on ${repository.slug}, ${agent}/${model}`);\n\n // Workspace: scaffolded once per sandbox, installed from npm. deepsec\n // needs Node 24; the sandbox bootstrap is expected to provide it.\n const prepare = await sandbox.run({\n command: [\n ...prefix,\n \"set -e\",\n `if [ ! -f ${workspace}/deepsec.config.ts ]; then`,\n ` npx -y deepsec@${version} init ./${workspace} ./${repoPath} --id ${projectId} --scaffold-only --headless --yes --skip-install`,\n ` (cd ${workspace} && npm install --no-audit --no-fund --loglevel=error)`,\n \"fi\",\n // deepsec resolves deepsec.config.ts from the current directory, so\n // every deepsec command runs inside the workspace. No --root: it is a\n // one-off override that skips the project's file records, leaving\n // `process` with nothing to investigate.\n `cd ${workspace}`,\n `./node_modules/.bin/deepsec scan --project-id ${projectId}`,\n ].join(\"\\n\"),\n });\n if (typeof prepare.exitCode === \"number\" && prepare.exitCode !== 0) {\n const detail = (prepare.stderr ?? prepare.stdout).trim().slice(-1500);\n await phase(\"failed\", `scan phase failed: ${detail.slice(-300)}`);\n return { scanned: false as const, reason: `deepsec scan failed: ${detail}` };\n }\n const candidates = candidateCount(prepare.stdout);\n await phase(\n \"scanned\",\n `${candidates === null ? \"scan output\" : `${candidates} files with candidates`}: ${tail(`${prepare.stdout}\\n${prepare.stderr ?? \"\"}`)}`,\n );\n\n // Investigation talks to the model through the AI Gateway (deepsec's\n // default route); this is the only step that needs a credential.\n const investigate = await options.withModelCredential(\n sandbox,\n [\n ...prefix,\n \"set -e\",\n `cd ${workspace}`,\n `./node_modules/.bin/deepsec process --project-id ${projectId} --agent ${agent} --model ${model} --thinking-level ${thinkingLevel} --concurrency ${concurrency} --limit ${limit ?? filesPerRun}`,\n `./node_modules/.bin/deepsec export --project-id ${projectId} --format json --out ${findingsPath}`,\n ].join(\"\\n\"),\n );\n if (typeof investigate.exitCode === \"number\" && investigate.exitCode !== 0) {\n const detail = (investigate.stderr ?? investigate.stdout).trim().slice(-1500);\n await phase(\"failed\", `process phase failed: ${detail.slice(-300)}`);\n return { scanned: false as const, reason: `deepsec process failed: ${detail}` };\n }\n\n const exported = await sandbox.run({ command: `cat ${findingsPath}` });\n let parsed: unknown;\n try {\n parsed = JSON.parse(exported.stdout);\n } catch {\n return { scanned: false as const, reason: \"deepsec export was not valid JSON\" };\n }\n const raw = deepsecExportSchema.safeParse(parsed);\n if (!raw.success) {\n return { scanned: false as const, reason: `deepsec export had an unexpected shape: ${raw.error.issues[0]?.message ?? \"unknown\"}` };\n }\n\n const results: { finding: Finding; result: RecordFindingResult }[] = [];\n for (const entry of raw.data) {\n const finding = findingFromDeepsec(entry);\n results.push({ finding, result: await recordFinding(stores, repositoryId, finding, options) });\n }\n const recorded = results.filter(({ result }) => result.recorded);\n await phase(\n \"completed\",\n `${results.length} findings, ${recorded.length} new. process output: ${tail(`${investigate.stdout}\\n${investigate.stderr ?? \"\"}`, 6)}`,\n );\n return {\n scanned: true as const,\n tool: \"deepsec\",\n found: results.length,\n recorded: recorded.length,\n duplicates: results.length - recorded.length,\n awaitingApproval: recorded.filter(({ result }) => result.recorded && result.approval === \"required\").length,\n findings: results.map(({ finding, result }) => ({\n title: finding.title,\n priority: finding.priority,\n path: finding.path,\n line: finding.line,\n ...(result.recorded ? { taskId: result.taskId, approval: result.approval } : { duplicate: true }),\n })),\n };\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { changeIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\n/** The subset of the eve sandbox handle a credentialed git operation needs. */\nexport interface CommandSandbox {\n run(options: { command: string }): PromiseLike<{\n stdout: string;\n stderr?: string;\n exitCode?: number;\n }>;\n}\n\nexport interface FetchPullRequestOptions<S extends CommandSandbox = CommandSandbox> {\n /**\n * Runs one git command against `slug` with a credential the sandbox does not\n * otherwise have, and removes it again before resolving. Supplied by the\n * app, which owns how credentials are minted and where they are injected;\n * the library only decides what is fetched.\n */\n withCredential: (\n sandbox: S,\n slug: string,\n command: string,\n ) => Promise<{ stdout: string; stderr?: string; exitCode?: number }>;\n /** Path of the checkout inside the sandbox. Defaults to `repo`. */\n repoPath?: string;\n /** Fetch depth for the pull request head. Defaults to 50. */\n depth?: number;\n}\n\nexport type FetchPullRequestResult =\n | { fetched: false; reason: string }\n | {\n fetched: true;\n prNumber: number;\n prUrl: string;\n branch: string;\n headSha: string;\n baseBranch: string;\n baseSha: string;\n mergeBaseSha: string;\n diffCommand: string;\n };\n\n/**\n * The verifier's way in to the change under review. The sandbox has no\n * GitHub credential while the agent runs, so trusted code does the one fetch\n * the agent cannot: the pull request number and repository come from the\n * change record, never from the agent, and the credential is gone again\n * before control returns. Mirrors how publication reads commits out of the\n * sandbox instead of letting the agent push.\n */\nexport function fetchPullRequestTool<S extends CommandSandbox>(\n stores: FactoryStores,\n options: FetchPullRequestOptions<S>,\n) {\n const repoPath = options.repoPath ?? \"repo\";\n const depth = options.depth ?? 50;\n return defineTool({\n description:\n \"Fetch the pull request and the repository's current default branch, then check out the pull request as local branch `pr`. Call this after get_task, before inspecting or testing the change. Returns an exact diff command based on their merge base; use it instead of origin/HEAD.\",\n inputSchema: z.object({\n changeId: changeIdSchema.describe(\"The Change linked to your Task, returned by get_task.\"),\n }),\n async execute({ changeId }, ctx): Promise<FetchPullRequestResult> {\n const boundTaskId = taskIdSchema.safeParse(\n ctx.session?.auth.initiator?.attributes.factoryTaskId,\n );\n if (boundTaskId.success) {\n const task = await stores.tasks.get(boundTaskId.data);\n if (task === null) {\n return { fetched: false, reason: `task ${boundTaskId.data} does not exist` };\n }\n if (task.changeId !== undefined && task.changeId !== changeId) {\n return {\n fetched: false,\n reason: `change ${changeId} is not linked to task ${boundTaskId.data}`,\n };\n }\n }\n const change = await stores.changes.get(changeId);\n if (change === null) {\n return { fetched: false, reason: `change ${changeId} does not exist` };\n }\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n return { fetched: false, reason: `change is ${change.state}, not open for review; nothing to fetch` };\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) {\n return { fetched: false, reason: `repository ${change.repositoryId} does not exist` };\n }\n\n // Fetch into a remote-tracking ref (never the checked-out branch, which\n // git refuses to update), then move the local `pr` branch onto it so a\n // repeated call picks up a force-pushed head.\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const tracking = `refs/remotes/origin/pr-${change.prNumber}`;\n const baseTracking = `refs/remotes/origin/${repository.defaultBranch}`;\n const git = `git -C ${repoPath}`;\n const result = await options.withCredential(\n sandbox,\n repository.slug,\n `${git} fetch --depth ${depth} origin +refs/heads/${repository.defaultBranch}:${baseTracking} +refs/pull/${change.prNumber}/head:${tracking} && ${git} checkout -B pr ${tracking}`,\n );\n if (typeof result.exitCode === \"number\" && result.exitCode !== 0) {\n return {\n fetched: false,\n reason: `git fetch of pull request ${change.prNumber} failed: ${(result.stderr ?? \"\").trim()}`,\n };\n }\n\n const head = await sandbox.run({ command: `${git} rev-parse HEAD` });\n const base = await sandbox.run({ command: `${git} rev-parse ${baseTracking}` });\n const mergeBase = await sandbox.run({ command: `${git} merge-base ${baseTracking} pr` });\n if (typeof mergeBase.exitCode === \"number\" && mergeBase.exitCode !== 0) {\n return {\n fetched: false,\n reason: `could not determine the pull request merge base: ${(mergeBase.stderr ?? \"\").trim()}`,\n };\n }\n const mergeBaseSha = mergeBase.stdout.trim();\n return {\n fetched: true,\n prNumber: change.prNumber,\n prUrl: change.prUrl,\n branch: \"pr\",\n headSha: head.stdout.trim(),\n baseBranch: repository.defaultBranch,\n baseSha: base.stdout.trim(),\n mergeBaseSha,\n diffCommand: `${git} diff ${mergeBaseSha}..pr`,\n };\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport type { AgentRoute, AgentRouteRegistry } from \"../agent-routes\";\nimport { createCoordination } from \"../coordination\";\nimport { dispatchTask, type DispatchBudget } from \"../dispatch\";\nimport { changeIdSchema, repositoryIdSchema, signalIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { Task } from \"../schema/task\";\nimport type { FactoryStores } from \"../store/engine\";\n\nexport interface InvokeAgentOptions {\n /** The factory task kind the handoff creates, e.g. \"verification\". */\n kind: string;\n /** Model-facing description of what the target agent does and when to invoke it. */\n description: string;\n /**\n * Base URL of the target agent's eve transport, e.g.\n * `https://factory.example.com/eve/agents/verifier`. Resolved at call time so\n * a deployment can derive it from its own origin.\n */\n targetUrl: () => string;\n /** Bearer token for the target agent's eve channel, when it requires auth. */\n token?: () => Promise<string | undefined>;\n /** Extra headers for the session request, e.g. a deployment protection bypass. */\n headers?: (task: Task) => Record<string, string> | Promise<Record<string, string>>;\n /**\n * Reserve-before-execution limits for the handoff dispatch, resolved at\n * call time. Without it, handoff tasks run outside the budget.\n */\n budget?: () => DispatchBudget | undefined;\n fetch?: typeof fetch;\n}\n\nexport interface DelegateAgentOptions {\n routes: AgentRouteRegistry;\n targetUrl: (route: AgentRoute) => string;\n token?: (route: AgentRoute) => Promise<string | undefined>;\n headers?: (task: Task, route: AgentRoute) => Record<string, string> | Promise<Record<string, string>>;\n budget?: (route: AgentRoute) => DispatchBudget | undefined;\n fetch?: typeof fetch;\n}\n\n/**\n * A tool that lets one agent hand work to another, NMA-style: the caller\n * decides to invoke; trusted code owns the how. The handoff is recorded as a\n * factory task (single-winner dispatch, receipts), then a fresh session is\n * started on the target agent carrying only the task id — never the caller's\n * context. The session start is create-once on the task id, so a retried\n * tool call cannot start a second session.\n */\nexport function invokeAgentTool(stores: FactoryStores, options: InvokeAgentOptions) {\n const doFetch = options.fetch ?? fetch;\n return defineTool({\n description: `${options.description} Hands the work to a separate agent in a fresh session; you will not see its reasoning. Returns the handoff task id.`,\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n parentTaskId: taskIdSchema.optional().describe(\"Your own task, when this work continues it.\"),\n changeId: changeIdSchema.optional().describe(\"The change the target agent should work on.\"),\n channel: z.string().min(1).describe(\"Reply connector, e.g. github.\"),\n address: z.string().min(1).describe(\"Reply address, e.g. acme/web#41.\"),\n brief: z\n .string()\n .min(1)\n .max(4000)\n .describe(\"What the target agent needs to know. Facts and references only, not your reasoning.\"),\n }),\n async execute(input) {\n const task = await stores.tasks.create({\n repositoryIds: input.repositoryIds,\n kind: options.kind,\n origin:\n input.parentTaskId === undefined ? { operator: \"factory\" } : { parentTaskId: input.parentTaskId },\n replyTo: { channel: input.channel, address: input.address },\n });\n\n const running = await dispatchTask(stores, task.id, {\n // Handoffs are launched by the caller, not the sweep, so a refused\n // session must fail now — no sweep would pick a re-queued handoff up.\n maxLaunchAttempts: 1,\n budget: options.budget?.(),\n launch: async (dispatched) => {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n ...(await options.headers?.(dispatched)),\n };\n const token = await options.token?.();\n if (token !== undefined) {\n headers.authorization = `Bearer ${token}`;\n }\n const message = [\n `You are assigned factory task ${dispatched.id}.`,\n input.changeId === undefined ? null : `Change under review: ${input.changeId}.`,\n `Reply address: ${input.channel} ${input.address}.`,\n \"\",\n input.brief,\n \"\",\n \"Read the task with get_task first, do the work, and record the outcome with your factory tools.\",\n ]\n .filter((line) => line !== null)\n .join(\"\\n\");\n const response = await doFetch(`${options.targetUrl()}/eve/v1/session`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ message, operationId: `factory-task:${dispatched.id}` }),\n });\n if (!response.ok) {\n throw new Error(`target agent refused the session: ${response.status}`);\n }\n },\n });\n\n return { taskId: running.id, kind: running.kind, state: running.state };\n },\n });\n}\n\n/**\n * Give a conversational agent one bounded delegation surface backed by the\n * application's route registry. The caller selects a declared route; trusted\n * code owns task creation, budget enforcement, and the fresh target session.\n */\nexport function delegateAgentTool(stores: FactoryStores, options: DelegateAgentOptions) {\n const doFetch = options.fetch ?? fetch;\n const routeSummary = options.routes.routes\n .map((route) => `${route.id}: ${route.description}`)\n .join(\"\\n\");\n return defineTool({\n description:\n \"Delegate durable work to one registered specialist. Select only a listed route; \" +\n \"the specialist runs independently and reports its result through Factory.\\n\" +\n routeSummary,\n inputSchema: z.object({\n routeId: z.string().min(1).describe(\"One route id listed in this tool's description.\"),\n repositoryIds: z.array(repositoryIdSchema).min(1),\n signalId: signalIdSchema.optional().describe(\"Pending external signal this delegation accepts.\"),\n parentTaskId: taskIdSchema.optional().describe(\"Existing task this work continues.\"),\n changeId: changeIdSchema.optional().describe(\"Existing change the specialist should inspect.\"),\n channel: z.string().min(1).describe(\"Originating conversation channel.\"),\n address: z.string().min(1).describe(\"Originating conversation reply address.\"),\n brief: z.string().min(1).max(4000).describe(\"Facts and desired outcome, without hidden reasoning.\"),\n }),\n async execute(input, ctx) {\n const route = options.routes.get(input.routeId);\n if (route === undefined) {\n throw new Error(`Unknown agent route ${input.routeId}.`);\n }\n const replyTo = { channel: input.channel, address: input.address };\n const attributes = ctx.session.auth.initiator?.attributes;\n const repositoryAttribute = attributes?.factoryRepositoryIds;\n const boundRepositoryIds =\n typeof repositoryAttribute === \"string\"\n ? repositoryAttribute.split(\",\").filter(Boolean)\n : repositoryAttribute;\n if (\n boundRepositoryIds !== undefined &&\n (boundRepositoryIds.length !== input.repositoryIds.length ||\n boundRepositoryIds.some((id) => !input.repositoryIds.includes(id)))\n ) {\n throw new Error(\"Delegation repositories do not match the connector-authenticated context.\");\n }\n if (\n (attributes?.factoryReplyChannel !== undefined && attributes.factoryReplyChannel !== replyTo.channel) ||\n (attributes?.factoryReplyAddress !== undefined && attributes.factoryReplyAddress !== replyTo.address)\n ) {\n throw new Error(\"Delegation reply address does not match the authenticated conversation.\");\n }\n for (const repositoryId of input.repositoryIds) {\n const repository = await stores.repositories.get(repositoryId);\n if (repository === null || !repository.enabled) {\n throw new Error(`Repository ${repositoryId} is not enabled in this factory.`);\n }\n }\n const boundChange = changeIdSchema.safeParse(attributes?.factoryChangeId);\n if (attributes?.factoryChangeId !== undefined && !boundChange.success) {\n throw new Error(\"Connector-authenticated change context is invalid.\");\n }\n if (\n input.changeId !== undefined &&\n boundChange.success &&\n input.changeId !== boundChange.data\n ) {\n throw new Error(\"Delegated change does not match the connector-authenticated context.\");\n }\n const changeId = input.changeId ?? (boundChange.success ? boundChange.data : undefined);\n if (changeId !== undefined) {\n if (input.repositoryIds.length !== 1) {\n throw new Error(\"Delegating work on an existing Change requires exactly one repository.\");\n }\n const change = await stores.changes.get(changeId);\n if (\n change === null ||\n change.repositoryId !== input.repositoryIds[0] ||\n (change.state !== \"verifying\" && change.state !== \"ready\")\n ) {\n throw new Error(`Change ${changeId} is not an open pull request in the selected repository.`);\n }\n }\n if (input.signalId !== undefined) {\n const signal = await stores.signals.get(input.signalId);\n if (signal === null) throw new Error(`Signal ${input.signalId} does not exist.`);\n if (\n !input.repositoryIds.includes(signal.repositoryId) ||\n signal.replyTo.channel !== replyTo.channel ||\n signal.replyTo.address !== replyTo.address\n ) {\n throw new Error(\"Delegation does not match the signal's authenticated repository and reply address.\");\n }\n if (signal.outcome === \"pending\") {\n await stores.signals.decide(signal.id, \"accepted\", { reason: `Foreman selected ${route.id}.` });\n } else if (signal.outcome !== \"accepted\") {\n throw new Error(`Signal ${signal.id} is already ${signal.outcome}.`);\n }\n }\n const initiator = ctx.session.auth.initiator;\n const operator = initiator?.principalId ?? \"foreman\";\n if (route.taskKind === \"code_change\" && input.repositoryIds.length > 1) {\n const [first, second, ...rest] = input.repositoryIds;\n if (first === undefined || second === undefined) throw new Error(\"Coordination requires two repositories.\");\n const coordination = await createCoordination(stores, {\n repositoryIds: [first, second, ...rest],\n replyTo,\n ...(input.signalId === undefined ? {} : { dedupeKey: `route:${input.signalId}:${route.id}` }),\n ...(input.signalId === undefined ? { operator } : { signalId: input.signalId }),\n });\n await Promise.all(coordination.children.filter((child) => child.state === \"queued\").map((child) =>\n dispatchRouteTask(stores, options, doFetch, route, child, changeId, input.brief),\n ));\n return {\n taskId: coordination.parent.id,\n childTaskIds: coordination.children.map(({ id }) => id),\n routeId: route.id,\n agent: route.agent,\n state: coordination.parent.state,\n };\n }\n const task = await stores.tasks.create({\n repositoryIds: input.repositoryIds,\n kind: route.taskKind,\n origin:\n input.signalId !== undefined\n ? { signalId: input.signalId }\n : input.parentTaskId !== undefined\n ? { parentTaskId: input.parentTaskId }\n : { operator },\n replyTo,\n changeId,\n ...(input.signalId === undefined ? {} : { dedupeKey: `route:${input.signalId}:${route.id}` }),\n });\n const running = task.state === \"queued\"\n ? await dispatchRouteTask(\n stores,\n options,\n doFetch,\n route,\n task,\n changeId,\n input.brief,\n )\n : task;\n return { taskId: running.id, routeId: route.id, agent: route.agent, state: running.state };\n },\n });\n}\n\nasync function dispatchRouteTask(\n stores: FactoryStores,\n options: DelegateAgentOptions,\n doFetch: typeof fetch,\n route: AgentRoute,\n task: Task,\n changeId: string | undefined,\n brief: string,\n): Promise<Task> {\n return dispatchTask(stores, task.id, {\n maxLaunchAttempts: 1,\n budget: options.budget?.(route),\n launch: async (dispatched) => {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n ...(await options.headers?.(dispatched, route)),\n };\n const token = await options.token?.(route);\n if (token !== undefined) headers.authorization = `Bearer ${token}`;\n const message = [\n `You are assigned factory task ${dispatched.id} through route ${route.id}.`,\n changeId === undefined ? null : `Change under review: ${changeId}.`,\n brief,\n \"Read the task first and return exactly one bounded Factory outcome.\",\n ]\n .filter((line) => line !== null)\n .join(\"\\n\\n\");\n const response = await doFetch(`${options.targetUrl(route)}/eve/v1/session`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ message, operationId: `factory-task:${dispatched.id}` }),\n });\n if (!response.ok) throw new Error(`${route.agent} refused the session: ${response.status}`);\n },\n });\n}\n","import { createHash } from \"node:crypto\";\nimport { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport {\n readPullRequestHead,\n submitPullRequestReview,\n type PullRequestReviewComment,\n type SubmittedPullRequestReview,\n} from \"../github\";\nimport { changeIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\nexport interface CompletedReview {\n taskId: string;\n changeId: string;\n repository: string;\n pullRequestNumber: number;\n headSha: string;\n verdict: \"approve\" | \"request_changes\" | \"comment\";\n summary: string;\n comments: readonly CompletedReviewFinding[];\n}\n\nexport interface CompletedReviewFinding extends PullRequestReviewComment {\n fingerprint: string;\n key: string;\n title: string;\n}\n\nexport interface PublishedReview extends CompletedReview {\n review: SubmittedPullRequestReview;\n}\n\nexport interface PostReviewToolOptions {\n tokenForRepository: (repository: string) => Promise<string>;\n publishReviews?: boolean;\n onCompleted?: (completed: CompletedReview) => Promise<void>;\n onPublished?: (published: PublishedReview) => Promise<void>;\n fetch?: typeof globalThis.fetch;\n}\n\nconst reviewCommentSchema = z.strictObject({\n key: z\n .string()\n .min(1)\n .max(80)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/)\n .optional()\n .describe(\"Stable kebab-case identity for this defect and cause; keep it unchanged across reruns.\"),\n title: z.string().min(1).max(200).optional().describe(\"Short finding title.\"),\n path: z.string().min(1).max(500).describe(\"Repository-relative file path.\"),\n line: z.number().int().min(1).describe(\"Line in the pull request's new version.\"),\n body: z.string().min(1).max(5000).describe(\"Markdown explaining the finding and a concrete fix.\"),\n});\nconst reviewCommentsSchema = z\n .array(reviewCommentSchema)\n .max(50)\n .default([])\n .superRefine((comments, context) => {\n const seen = new Set<string>();\n comments.forEach((comment, index) => {\n if (comment.key === undefined) return;\n if (seen.has(comment.key)) {\n context.addIssue({ code: \"custom\", message: `duplicate finding key: ${comment.key}`, path: [index, \"key\"] });\n }\n seen.add(comment.key);\n });\n });\n\n/**\n * Publish an independent review of an existing pull request and finish the\n * review task without changing the pull request's factory lifecycle.\n */\nexport function postReviewTool(stores: FactoryStores, options: PostReviewToolOptions) {\n return defineTool({\n description:\n \"Record a completed code review and finish your code_review task. Results may be reported through completion callbacks instead of a GitHub review; use request_changes only for blocking findings.\",\n inputSchema: z.object({\n taskId: taskIdSchema.describe(\"Your code_review task.\"),\n changeId: changeIdSchema.describe(\"The pull request change from your starting message.\"),\n verdict: z.enum([\"approve\", \"request_changes\", \"comment\"]),\n headSha: z.string().regex(/^[0-9a-f]{40}$/).describe(\"Commit returned by fetch_pull_request.\"),\n summary: z.string().min(1).max(5000).describe(\"Markdown summary of what you reviewed and found.\"),\n comments: reviewCommentsSchema,\n }),\n async execute({ taskId, changeId, verdict, headSha, summary, comments }) {\n const task = await stores.tasks.get(taskId);\n if (task === null || task.kind !== \"code_review\") {\n return { recorded: false as const, reason: `${taskId} is not a code_review task` };\n }\n if (task.state !== \"running\") {\n return { recorded: false as const, reason: `task is ${task.state}, not running` };\n }\n\n const change = await stores.changes.get(changeId);\n if (change === null) {\n return { recorded: false as const, reason: `change ${changeId} does not exist` };\n }\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n return { recorded: false as const, reason: `change is ${change.state}, not open for review` };\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) {\n return { recorded: false as const, reason: `repository ${change.repositoryId} does not exist` };\n }\n\n const token = await options.tokenForRepository(repository.slug);\n const completedComments = comments.map((comment) => {\n const key = comment.key ?? legacyFindingKey(comment);\n return {\n ...comment,\n key,\n title: comment.title ?? \"Review finding\",\n fingerprint: createHash(\"sha256\")\n .update(`${repository.slug.toLowerCase()}#${change.prNumber}:${key}`)\n .digest(\"hex\"),\n };\n });\n const completed = {\n taskId,\n changeId,\n repository: repository.slug,\n pullRequestNumber: change.prNumber,\n headSha,\n verdict,\n summary,\n comments: completedComments,\n } satisfies CompletedReview;\n const publish = options.publishReviews !== false;\n let review: SubmittedPullRequestReview | undefined;\n if (publish) {\n review = await submitPullRequestReview({\n repository: repository.slug,\n token,\n fetch: options.fetch,\n pullRequestNumber: change.prNumber,\n commitId: headSha,\n event:\n verdict === \"approve\"\n ? \"APPROVE\"\n : verdict === \"request_changes\"\n ? \"REQUEST_CHANGES\"\n : \"COMMENT\",\n body: summary,\n comments: completedComments,\n });\n await options.onPublished?.({ ...completed, review });\n } else {\n const head = await readPullRequestHead({\n repository: repository.slug,\n token,\n fetch: options.fetch,\n pullRequestNumber: change.prNumber,\n });\n if (head.sha !== headSha) {\n throw new Error(`pull request changed after review: expected ${headSha}, found ${head.sha}`);\n }\n }\n await options.onCompleted?.(completed);\n await stores.tasks.transition(taskId, \"verifying\", { reason: summary });\n const finished = await stores.tasks.transition(taskId, \"succeeded\");\n return {\n recorded: true as const,\n verdict,\n published: review !== undefined,\n ...(review === undefined ? {} : { review }),\n taskState: finished.state,\n };\n },\n });\n}\n\nfunction legacyFindingKey(comment: PullRequestReviewComment): string {\n const digest = createHash(\"sha256\")\n .update(`${comment.path}:${comment.line}:${comment.body}`)\n .digest(\"hex\")\n .slice(0, 24);\n return `legacy-${digest}`;\n}\n","import { answerReviewComment, readPullRequestHead, readReviewComment } from \"../github\";\nimport { changeIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\nimport { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport type { CommandSandbox } from \"./fetch\";\n\nexport interface ReviewCommentToolOptions<S extends CommandSandbox = CommandSandbox> {\n tokenForRepository: (repository: string) => Promise<string>;\n withCredential?: (\n sandbox: S,\n repository: string,\n command: string,\n ) => Promise<{ stdout: string; stderr?: string; exitCode?: number }>;\n fetch?: typeof globalThis.fetch;\n repoPath?: string;\n}\n\nexport function reviewCommentTools<S extends CommandSandbox>(\n stores: FactoryStores,\n options: ReviewCommentToolOptions<S>,\n) {\n const repoPath = options.repoPath ?? \"repo\";\n const commentInputSchema = z.object({\n changeId: changeIdSchema.describe(\"The change under review, from your starting message.\"),\n commentId: z.number().int().positive().describe(\"The GitHub review comment id.\"),\n });\n\n return {\n read_review_comment: defineTool({\n description:\n \"Read an inline review comment on a change under verification or ready for human review. By default this refuses to return comments from people without write access to the repository.\",\n inputSchema: commentInputSchema,\n async execute({ changeId, commentId }) {\n const change = await stores.changes.get(changeId);\n if (change === null) throw new Error(`change ${changeId} does not exist`);\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n throw new Error(`change is ${change.state}, not open for review`);\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) throw new Error(`repository ${change.repositoryId} does not exist`);\n return readReviewComment({\n repository: repository.slug,\n token: await options.tokenForRepository(repository.slug),\n fetch: options.fetch,\n commentId,\n });\n },\n }),\n answer_review_comment: defineTool({\n description:\n \"Reply to an inline review comment on a change under verification or ready for human review. Use for findings and low-confidence responses, not for a concrete medium- or high-confidence fix.\",\n inputSchema: commentInputSchema.extend({\n body: z.string().min(1).max(5000).describe(\"The Markdown reply to post.\"),\n }),\n async execute({ changeId, commentId, body }) {\n const change = await stores.changes.get(changeId);\n if (change === null) throw new Error(`change ${changeId} does not exist`);\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n throw new Error(`change is ${change.state}, not open for review`);\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) throw new Error(`repository ${change.repositoryId} does not exist`);\n return answerReviewComment({\n repository: repository.slug,\n token: await options.tokenForRepository(repository.slug),\n fetch: options.fetch,\n pullRequestNumber: change.prNumber,\n commentId,\n body,\n });\n },\n }),\n suggest_review_fix: defineTool({\n description:\n \"Post a concrete, apply-able GitHub suggested change for a medium-confidence fix. The replacement must cover exactly the lines attached to the inline review comment.\",\n inputSchema: commentInputSchema.extend({\n confidence: z.literal(\"medium\"),\n replacement: z.string().min(1).max(5000).describe(\"Exact replacement text for the commented lines.\"),\n summary: z.string().min(1).max(1000).describe(\"A brief explanation of the suggested fix.\"),\n }),\n async execute({ changeId, commentId, replacement, summary }) {\n const change = await stores.changes.get(changeId);\n if (change === null) throw new Error(`change ${changeId} does not exist`);\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n throw new Error(`change is ${change.state}, not open for review`);\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) throw new Error(`repository ${change.repositoryId} does not exist`);\n return answerReviewComment({\n repository: repository.slug,\n token: await options.tokenForRepository(repository.slug),\n fetch: options.fetch,\n pullRequestNumber: change.prNumber,\n commentId,\n body: `${summary}\\n\\n\\`\\`\\`suggestion\\n${replacement}\\n\\`\\`\\``,\n });\n },\n }),\n apply_review_fix: defineTool({\n description:\n \"Publish a tested, committed high-confidence fix to the existing same-repository pull request branch. Fails if the checkout is dirty, the PR changed, or the PR comes from a fork.\",\n inputSchema: commentInputSchema.extend({\n confidence: z.literal(\"high\"),\n summary: z.string().min(1).max(1000).describe(\"What was fixed and verified.\"),\n }),\n async execute({ changeId, commentId, summary }, ctx) {\n const change = await stores.changes.get(changeId);\n if (change === null) throw new Error(`change ${changeId} does not exist`);\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n throw new Error(`change is ${change.state}, not open for review`);\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) throw new Error(`repository ${change.repositoryId} does not exist`);\n if (options.withCredential === undefined) {\n throw new Error(\"applying review fixes is not configured\");\n }\n const token = await options.tokenForRepository(repository.slug);\n await readReviewComment({\n repository: repository.slug,\n token,\n fetch: options.fetch,\n commentId,\n });\n const head = await readPullRequestHead({\n repository: repository.slug,\n token,\n fetch: options.fetch,\n pullRequestNumber: change.prNumber,\n });\n if (head.repository !== repository.slug.toLowerCase()) {\n throw new Error(\"cannot apply a fix to a pull request from a fork\");\n }\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const git = `git -C ${repoPath}`;\n const clean = await sandbox.run({ command: `${git} status --porcelain` });\n if (clean.stdout.trim() !== \"\") throw new Error(\"commit the review fix before publishing\");\n const ancestor = await sandbox.run({ command: `${git} merge-base --is-ancestor ${head.sha} HEAD` });\n if (ancestor.exitCode !== 0) {\n throw new Error(\"pull request changed after it was fetched; fetch it again before applying the fix\");\n }\n const localHead = await sandbox.run({ command: `${git} rev-parse HEAD` });\n if (localHead.stdout.trim() === head.sha) throw new Error(\"no committed review fix to publish\");\n const push = await options.withCredential(\n sandbox,\n repository.slug,\n `${git} push --force-with-lease=refs/heads/${head.branch}:${head.sha} origin HEAD:refs/heads/${head.branch}`,\n );\n if (typeof push.exitCode === \"number\" && push.exitCode !== 0) {\n throw new Error(`could not update pull request branch: ${(push.stderr ?? \"\").trim()}`);\n }\n const reply = await answerReviewComment({\n repository: repository.slug,\n token,\n fetch: options.fetch,\n pullRequestNumber: change.prNumber,\n commentId,\n body: summary,\n });\n return { updated: true as const, prNumber: change.prNumber, prUrl: change.prUrl, reply };\n },\n }),\n };\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { changeEvidenceSchema, levelSchema } from \"../schema/change\";\nimport { changeIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\nexport interface RecordVerificationOptions {\n presentResult?: (input: {\n taskId: string;\n changeId: string;\n verdict: \"pass\" | \"fail\";\n summary: string;\n }) => Promise<void>;\n}\n\n/**\n * The verifier's outcome tool. Writes evidence onto the change and moves it\n * to ready only when the verdict is pass; a failed verdict leaves the change\n * verifying with the evidence recorded, and the verification task itself\n * ends with a receipt either way. The change's own code_change task follows\n * the verdict too: succeeded on pass, failed on fail with the verifier's\n * summary as the reason, so the ledger never shows a verified-and-rejected fix\n * as still in progress. Fail closed: the agent cannot mark a change ready\n * without supplying every evidence field.\n */\nexport function recordVerificationTool(\n stores: FactoryStores,\n options: RecordVerificationOptions = {},\n) {\n return defineTool({\n description:\n \"Record the outcome of a verification task: the evidence you gathered and whether the change passed. Pass moves the change to ready for human review; fail keeps it out of review.\",\n inputSchema: z.object({\n taskId: taskIdSchema.describe(\"Your verification task.\"),\n changeId: changeIdSchema.describe(\"The change you verified.\"),\n verdict: z.enum([\"pass\", \"fail\"]),\n evidence: changeEvidenceSchema,\n confidence: levelSchema.describe(\"How certain you are in the verdict.\"),\n summary: z.string().min(1).max(2000).describe(\"What you checked and what you found.\"),\n }),\n async execute({ taskId, changeId, verdict, evidence, confidence, summary }) {\n const change = await stores.changes.get(changeId);\n if (change === null) {\n return { recorded: false as const, reason: `change ${changeId} does not exist` };\n }\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n return {\n recorded: false as const,\n reason: `change is ${change.state}, not open for verification; nothing to record`,\n };\n }\n\n const task = await stores.tasks.get(taskId);\n if (task === null || task.kind !== \"verification\") {\n return { recorded: false as const, reason: `${taskId} is not a verification task` };\n }\n\n let updatedChange = change;\n if (verdict === \"pass\" && change.state === \"verifying\") {\n updatedChange = await stores.changes.transition(changeId, \"ready\", {\n patch: { evidence, confidence },\n reason: summary,\n });\n } else if (verdict === \"fail\" && change.state === \"ready\") {\n updatedChange = await stores.changes.transition(changeId, \"verifying\", {\n reason: summary,\n });\n }\n\n // The task machine has no running -> succeeded edge; a passing\n // verification walks running -> verifying -> succeeded, a failing one\n // ends directly at failed.\n let finished;\n if (verdict === \"pass\") {\n await stores.tasks.transition(taskId, \"verifying\", { reason: summary });\n finished = await stores.tasks.transition(taskId, \"succeeded\");\n } else {\n finished = await stores.tasks.transition(taskId, \"failed\", { reason: summary });\n }\n\n // Verification settles the code_change Task that requested this run.\n // For legacy verification Tasks without a parent, fall back to the Task\n // that originally produced the Change.\n const sourceTaskId = task.origin.parentTaskId ?? change.taskId;\n if (sourceTaskId !== undefined) {\n const parent = await stores.tasks.get(sourceTaskId);\n if (parent?.state === \"verifying\") {\n await stores.tasks\n .transition(\n sourceTaskId,\n verdict === \"pass\" ? \"succeeded\" : \"failed\",\n verdict === \"pass\" ? {} : { reason: `verification failed: ${summary}` },\n )\n .catch(() => undefined);\n }\n }\n\n await options.presentResult?.({ taskId, changeId, verdict, summary });\n\n return {\n recorded: true as const,\n verdict,\n changeState: updatedChange.state,\n taskState: finished.state,\n };\n },\n });\n}\n","import type { SessionContext } from \"eve/context\";\nimport { defineHook } from \"eve/hooks\";\nimport { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport {\n changeIdSchema,\n repositoryIdSchema,\n signalIdSchema,\n taskIdSchema,\n type TaskId,\n} from \"../schema/id\";\nimport { levelSchema } from \"../schema/change\";\nimport { vocabularySchema } from \"../schema/common\";\nimport { taskQuestionSchema, type Task } from \"../schema/task\";\nimport type { FactoryStores } from \"../store/engine\";\n\nconst decidedOutcomeSchema = z.enum([\n \"accepted\",\n \"duplicate\",\n \"unactionable\",\n \"low_confidence\",\n \"ignored\",\n]);\n\nconst recordChangeInputSchema = z.object({\n taskId: taskIdSchema,\n repositoryId: repositoryIdSchema,\n prNumber: z.number().int().min(1),\n prUrl: z.url(),\n risk: levelSchema.describe(\"Blast radius of the change if it is wrong.\"),\n confidence: levelSchema.describe(\"How certain you are the change is correct.\"),\n summary: z.string().min(1).describe(\"One-sentence description of the change.\"),\n});\n\nexport type RecordChangeInput = z.infer<typeof recordChangeInputSchema>;\n\nexport type GateVerdict = { ok: true } | { ok: false; reason: string };\n\nexport interface FactoryToolsOptions {\n /**\n * Pre-action gate for record_change, run as an eve approval policy before\n * the tool executes. Refusals reach the model as a denial with the reason.\n * Gates must fail closed: when they cannot verify, they refuse.\n */\n recordChangeGate?: (input: RecordChangeInput) => Promise<GateVerdict>;\n /** Whether recorded code changes wait for an independent verification task. Default: required. */\n verification?: \"required\" | \"disabled\";\n /** Present the pull request after record_change persists its durable state. */\n presentChange?: (input: {\n taskId: string;\n changeId: string;\n verification: \"required\" | \"disabled\";\n summary: string;\n }) => Promise<void>;\n /** Present a persisted human question through the application's Foreman communication boundary. */\n presentQuestion?: (task: Task) => Promise<void>;\n}\n\ntype PresentQuestion = NonNullable<FactoryToolsOptions[\"presentQuestion\"]>;\n\nasync function createAndPresentQuestion(\n stores: FactoryStores,\n parent: Task,\n question: z.infer<typeof taskQuestionSchema>,\n presentQuestion: PresentQuestion,\n): Promise<Task> {\n const task = await stores.tasks.create({\n repositoryIds: parent.repositoryIds,\n kind: \"question\",\n origin: { parentTaskId: parent.id },\n replyTo: parent.replyTo,\n question,\n });\n const waiting = await stores.tasks.transition(task.id, \"needs_human\");\n try {\n if (parent.state === \"running\") {\n await stores.tasks.transition(parent.id, \"needs_human\", {\n reason: `waiting for answer to question ${waiting.id}`,\n questionTaskId: waiting.id,\n });\n }\n await presentQuestion(waiting);\n } catch (error) {\n const currentParent = await stores.tasks.get(parent.id);\n if (currentParent?.state === \"needs_human\") {\n await stores.tasks.transition(parent.id, \"queued\", {\n reason: `delivery of question ${waiting.id} failed`,\n });\n }\n const currentQuestion = await stores.tasks.get(waiting.id);\n if (currentQuestion?.state === \"needs_human\") {\n await stores.tasks.transition(waiting.id, \"cancelled\", {\n reason: \"question delivery failed\",\n });\n }\n throw error;\n }\n return waiting;\n}\n\n/**\n * The factory's store operations wrapped as eve tools. Expose a tool to an\n * agent by re-exporting it from a file under agent/tools/, e.g.\n * `export default factoryTools(stores).get_task;`. Every write goes through\n * the engine, so agents inherit transition legality and receipts.\n */\nexport function factoryTools(stores: FactoryStores, options: FactoryToolsOptions = {}) {\n const recordChangeGate = options.recordChangeGate;\n const verification = options.verification ?? \"required\";\n return {\n get_task: defineTool({\n description:\n \"Read one factory task by id: its kind, state, repositories, origin, and results.\",\n inputSchema: z.object({ taskId: taskIdSchema }),\n async execute({ taskId }) {\n const task = await stores.tasks.get(taskId);\n return task ?? { found: false as const, taskId };\n },\n }),\n\n decide_signal: defineTool({\n description:\n \"Record the triage decision for a pending signal. A signal is decided exactly once.\",\n inputSchema: z.object({\n signalId: signalIdSchema,\n outcome: decidedOutcomeSchema,\n reason: z.string().min(1).describe(\"Why this outcome was chosen.\"),\n detail: z\n .string()\n .min(1)\n .optional()\n .describe(\"Severity if accepted, or the duplicate-of signal id.\"),\n }),\n execute({ signalId, outcome, reason, detail }) {\n return stores.signals.decide(signalId, outcome, { reason, detail });\n },\n }),\n\n record_change: defineTool({\n description:\n verification === \"required\"\n ? \"Record the pull request produced for a code_change task. Creates the change, links it to the task, and moves the task to verifying.\"\n : \"Record the pull request produced for a code_change task. Creates the change and marks it ready for human review without independent verification.\",\n inputSchema: recordChangeInputSchema,\n ...(recordChangeGate === undefined\n ? {}\n : {\n approval: async ({ toolInput }: { toolInput?: unknown }) => {\n const parsed = recordChangeInputSchema.safeParse(toolInput);\n if (!parsed.success) {\n return {\n type: \"denied\" as const,\n reason: \"record_change input is malformed; fix the arguments and retry\",\n };\n }\n const verdict = await recordChangeGate(parsed.data);\n return verdict.ok\n ? (\"not-applicable\" as const)\n : { type: \"denied\" as const, reason: verdict.reason };\n },\n }),\n async execute({ taskId, repositoryId, prNumber, prUrl, risk, confidence, summary }) {\n const currentTask = await stores.tasks.get(taskId);\n if (currentTask === null) throw new Error(`task ${taskId} does not exist`);\n if (\n currentTask.state !== \"running\" &&\n currentTask.state !== \"verifying\" &&\n currentTask.state !== \"succeeded\"\n ) {\n throw new Error(`task ${taskId} is ${currentTask.state}, not running`);\n }\n const linkedChange =\n currentTask.changeId === undefined\n ? undefined\n : await stores.changes.get(currentTask.changeId);\n if (currentTask.changeId !== undefined && linkedChange === null) {\n throw new Error(`change ${currentTask.changeId} does not exist`);\n }\n let change =\n linkedChange ?? (await stores.changes.list()).find((candidate) => candidate.taskId === taskId);\n\n if (change === undefined) {\n if (currentTask.state !== \"running\") {\n throw new Error(`task ${taskId} has no recorded change`);\n }\n change = await stores.changes.create({\n repositoryId,\n taskId,\n prNumber,\n prUrl,\n author: \"factory\",\n risk,\n confidence,\n evidence: {\n reproVerified: false,\n testsAdded: 0,\n checksGreen: false,\n attackPassed: false,\n scopeMatches: false,\n },\n });\n }\n\n if (currentTask.state === \"running\") {\n await options.presentChange?.({\n taskId,\n changeId: change.id,\n verification,\n summary,\n });\n }\n\n let task = currentTask;\n if (task.state === \"running\") {\n task = await stores.tasks.transition(taskId, \"verifying\", {\n patch: { changeId: change.id },\n reason: summary,\n });\n }\n if (verification === \"required\") return { change, task };\n\n if (change.state === \"verifying\") {\n change = await stores.changes.transition(change.id, \"ready\", {\n reason: \"independent verification is not configured\",\n });\n }\n if (task.state === \"verifying\") {\n task = await stores.tasks.transition(taskId, \"succeeded\", {\n reason: \"change recorded for human review without independent verification\",\n });\n }\n return { change, task };\n },\n }),\n\n finish_task: defineTool({\n description:\n \"Mark your task finished with a summary, for task kinds that have no other outcome tool (for example a security_scan). Not for code_change or verification tasks: those end with record_change and record_verification.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n summary: z.string().min(1).max(4000).describe(\"What you did and found, for the ledger.\"),\n }),\n async execute({ taskId, summary }) {\n const task = await stores.tasks.get(taskId);\n if (task === null) {\n return { finished: false as const, reason: `${taskId} does not exist` };\n }\n if (task.kind === \"code_change\" || task.kind === \"verification\") {\n return { finished: false as const, reason: `${task.kind} tasks end with their own outcome tool` };\n }\n if (task.state !== \"running\") {\n return { finished: false as const, reason: `task is ${task.state}, not running` };\n }\n // The task machine has no running -> succeeded edge; walk through verifying.\n await stores.tasks.transition(taskId, \"verifying\", { reason: summary });\n const finished = await stores.tasks.transition(taskId, \"succeeded\", { reason: summary });\n return { finished: true as const, taskState: finished.state };\n },\n }),\n\n request_human_input: defineTool({\n description:\n \"Request human input or action and pause your task until the human replies. The parent task determines the repositories and reply destination.\",\n inputSchema: z.object({\n parentTaskId: taskIdSchema.describe(\"Your running task, which the answer will unblock.\"),\n question: taskQuestionSchema.omit({ answer: true, answeredBy: true }),\n }),\n async execute({ parentTaskId, question }) {\n if (options.presentQuestion === undefined) {\n throw new Error(\"request_human_input requires a configured question presenter.\");\n }\n const parent = await stores.tasks.get(parentTaskId);\n if (parent === null) throw new Error(`Parent task ${parentTaskId} does not exist.`);\n if (parent.state !== \"running\" && parent.state !== \"needs_human\") {\n throw new Error(`Parent task ${parentTaskId} is ${parent.state}, not running.`);\n }\n return createAndPresentQuestion(stores, parent, question, options.presentQuestion);\n },\n }),\n\n answer_question: defineTool({\n description:\n \"Record the authenticated user's answer to a waiting question and requeue the parent specialist task. A blocked parent task id is also accepted and resolves its persisted QuestionTask id.\",\n inputSchema: z.object({\n questionTaskId: taskIdSchema,\n answer: z.string().min(1).max(4000),\n }),\n async execute({ questionTaskId, answer }, ctx) {\n const requestedTask = await stores.tasks.get(questionTaskId);\n const resolvedQuestionTaskId =\n requestedTask?.kind === \"question\" ? requestedTask.id : requestedTask?.questionTaskId;\n const questionTask = resolvedQuestionTaskId === undefined\n ? null\n : await stores.tasks.get(resolvedQuestionTaskId);\n if (\n questionTask === null ||\n questionTask.kind !== \"question\" ||\n questionTask.question === undefined\n ) {\n throw new Error(`Question task ${questionTaskId} does not exist.`);\n }\n const attributes = ctx.session.auth.initiator?.attributes;\n if (\n attributes?.factoryReplyChannel !== questionTask.replyTo.channel ||\n attributes.factoryReplyAddress !== questionTask.replyTo.address\n ) {\n throw new Error(\"Question reply does not match the authenticated conversation.\");\n }\n const answeredBy = ctx.session.auth.initiator?.principalId ?? \"operator\";\n return stores.tasks.answerQuestion({\n questionTaskId: questionTask.id,\n answer,\n answeredBy,\n });\n },\n }),\n\n append_receipt: defineTool({\n description:\n \"Append one immutable audit receipt for an event worth remembering. Receipts can never be edited or deleted.\",\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n taskId: taskIdSchema.optional(),\n changeId: changeIdSchema.optional(),\n kind: vocabularySchema.describe(\"What the receipt is about, e.g. investigation.\"),\n state: vocabularySchema.describe(\"What happened, e.g. flag_ramped.\"),\n reason: z.string().min(1).max(2000).optional(),\n dedupeKey: z\n .string()\n .min(1)\n .optional()\n .describe(\"Same key twice records one receipt instead of two.\"),\n }),\n execute(input) {\n return stores.receipts.append(input);\n },\n }),\n };\n}\n\nexport type FactoryTools = ReturnType<typeof factoryTools>;\n\nexport interface FactoryHooksOptions {\n /** Session auth attribute naming the task a dispatched session works on. Default `factoryTaskId`. */\n taskIdAttribute?: string;\n /** Present the recovery question created when a task turn ends without an outcome. */\n presentQuestion: PresentQuestion;\n}\n\nconst terminalTaskStates: ReadonlySet<Task[\"state\"]> = new Set([\"succeeded\", \"failed\", \"cancelled\"]);\n\n/**\n * Observe-only eve hooks that keep the ledger honest about session outcomes.\n * Mount by re-exporting from agent/hooks/, e.g.\n * `export default factoryHooks(stores, { presentQuestion }).factory;`.\n *\n * step.completed: records the step's tokens and AI Gateway cost on the bound\n * task. Delivery is at least once; recordUsage dedupes by (turnId, stepIndex).\n *\n * turn.completed: settles the bound task's recorded usage if the task is\n * already terminal (the sweep handles tasks that end later), then moves any\n * still-running task at this session's reply address behind a surfaced human\n * question, because the agent finished talking without recording an outcome.\n *\n * Every store call is swallowed: a hook throw fails the turn.\n */\nexport function factoryHooks(stores: FactoryStores, options: FactoryHooksOptions) {\n const taskIdAttribute = options.taskIdAttribute ?? \"factoryTaskId\";\n\n function boundTaskId(ctx: Pick<SessionContext, \"session\">): TaskId | undefined {\n const parsed = taskIdSchema.safeParse(ctx.session.auth.initiator?.attributes[taskIdAttribute]);\n return parsed.success ? parsed.data : undefined;\n }\n\n async function settleIfTerminal(taskId: TaskId): Promise<void> {\n const task = await stores.tasks.get(taskId);\n if (task?.usage === undefined || task.settledUsd !== undefined || !terminalTaskStates.has(task.state)) {\n return;\n }\n await stores.tasks.settle(task.id, { totalUsd: task.usage.costUsd }, {\n reason: \"measured usage settled at turn end\",\n });\n }\n\n return {\n factory: defineHook({\n events: {\n async \"step.completed\"(event, ctx) {\n const taskId = boundTaskId(ctx);\n const usage = event.data.usage;\n if (taskId === undefined || usage === undefined) {\n return;\n }\n await stores.tasks\n .recordUsage(taskId, { turnId: event.data.turnId, stepIndex: event.data.stepIndex, ...usage })\n .catch(() => undefined);\n },\n async \"turn.completed\"(_event, ctx) {\n const taskId = boundTaskId(ctx);\n if (taskId !== undefined) {\n await settleIfTerminal(taskId).catch(() => undefined);\n }\n const address = ctx.channel.continuationToken;\n if (address === undefined) {\n return;\n }\n const tasks = await stores.tasks.list().catch(() => []);\n const abandoned = tasks.filter(\n (task) => task.state === \"running\" && task.replyTo.address === address,\n );\n for (const task of abandoned) {\n await createAndPresentQuestion(\n stores,\n task,\n {\n text:\n \"The worker stopped without recording an outcome. Please review the task and reply when Factory should retry it.\",\n options: [\"Retry the task\"],\n },\n options.presentQuestion,\n ).catch(() => undefined);\n }\n },\n },\n }),\n };\n}\n\nexport type FactoryHooks = ReturnType<typeof factoryHooks>;\n\nexport {\n mergeConflictPayloadSchema,\n mergeConflictTools,\n type MergeConflictPayload,\n type MergeConflictToolOptions,\n} from \"./conflict\";\nexport { deepsecScanTool, findingFromDeepsec, type DeepsecScanOptions } from \"./deepsec\";\nexport { recordFinding, recordFindingTool, type RecordFindingOptions, type RecordFindingResult } from \"./finding\";\nexport {\n fetchPullRequestTool,\n type CommandSandbox,\n type FetchPullRequestOptions,\n type FetchPullRequestResult,\n} from \"./fetch\";\nexport {\n delegateAgentTool,\n invokeAgentTool,\n type DelegateAgentOptions,\n type InvokeAgentOptions,\n} from \"./invoke\";\nexport {\n postReviewTool,\n type CompletedReview,\n type CompletedReviewFinding,\n type PostReviewToolOptions,\n type PublishedReview,\n} from \"./post-review\";\nexport { reviewCommentTools, type ReviewCommentToolOptions } from \"./review\";\nexport { recordVerificationTool, type RecordVerificationOptions } from \"./verification\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/eve/index.ts"],"sourcesContent":["import type { SessionContext } from \"eve/context\";\nimport { defineHook, type HookDefinition } from \"eve/hooks\";\nimport { defineTool, type ToolContext, type ToolDefinition } from \"eve/tools\";\nimport { z } from \"zod\";\nimport {\n changeIdSchema,\n repositoryIdsSchema,\n signalIdSchema,\n taskIdSchema,\n type ChangeId,\n type RepositoryIds,\n type SignalId,\n type TaskId,\n} from \"../schema/id\";\nimport {\n receiptKindSchema,\n receiptStateSchema,\n type Receipt,\n type ReceiptKind,\n type ReceiptState,\n} from \"../schema/receipt\";\nimport type { MaybePromise } from \"../schema/common\";\nimport type { TaskAttemptRef } from \"../schema/execution\";\nimport { taskQuestionSchema, type Task, type TaskQuestion } from \"../schema/task\";\nimport type { Signal, SignalOutcome } from \"../schema/signal\";\nimport { taskWork, type JsonValue } from \"../schema/work\";\nimport type { AnswerQuestionResult, FactoryStores } from \"../store/engine\";\nimport type { EveTranscriptMaterializer, TranscriptMaterializationInput } from \"./transcript\";\nimport { requireTaskExecution } from \"./task-execution\";\n\nexport {\n conversationBinding,\n conversationBindingForSession,\n conversationHeaders,\n factoryReplyAddressAttribute,\n factoryReplyAddressHeader,\n factoryReplyChannelAttribute,\n factoryReplyChannelHeader,\n factoryRepositoryIdsAttribute,\n factoryRepositoryIdsHeader,\n factoryTaskAttemptAttribute,\n factoryTaskAttemptHeader,\n factoryTaskAttribute,\n factoryTaskHeader,\n hasFactoryTaskBinding,\n optionalTaskIdForSession,\n requireTaskIdForSession,\n replyToForSession,\n repositoryIdsForSession,\n taskBindingForSession,\n taskHeaders,\n taskSessionAuth,\n withFactoryTask,\n withOptionalFactoryTask,\n type ConversationBinding,\n type FactoryConversationSessionBinding,\n} from \"./task-session\";\nexport {\n createEveTranscriptMaterializer,\n type EveTranscriptMaterializerOptions,\n type EveTranscriptMaterializer,\n type EveTranscriptRequestScope,\n type TranscriptMaterializationInput,\n} from \"./transcript\";\nexport {\n cancelEveSession,\n forwardEveSessionRequest,\n readCompletedEveTurn,\n startEveSession,\n type CancelEveSessionOptions,\n type EveSessionEvent,\n type EveSessionStream,\n type EveSessionStreamInput,\n type ForwardEveSessionRequestOptions,\n type ReadCompletedEveTurnOptions,\n type StartEveSessionOptions,\n} from \"./session-client\";\n\nconst decidedOutcomeSchema = z.enum([\n \"accepted\",\n \"duplicate\",\n \"unactionable\",\n \"low_confidence\",\n \"ignored\",\n]);\n\n/** Receipt, Signal, and Task capabilities used by the provider-neutral Eve tool bundle. */\nexport type TaskToolsStores = Pick<FactoryStores, \"receipts\" | \"signals\" | \"tasks\">;\n\n/** Task capability used to project Eve lifecycle events onto durable Factory state. */\nexport type FactoryHooksStores = Pick<FactoryStores, \"tasks\">;\n\n/** Configures the provider-neutral Task, signal, question, and receipt Eve tools. */\nexport interface TaskToolsOptions {\n /** Present a persisted human question through the application's Foreman communication boundary. */\n presentQuestion?: (task: Task) => Promise<void>;\n /** Return a refusal reason when this task must use a more specific outcome tool. */\n finishTaskPolicy?: (task: Task) => MaybePromise<string | null>;\n}\n\n/** Delivers a persisted human-question Task through an application-owned channel. */\nexport type PresentQuestion = NonNullable<TaskToolsOptions[\"presentQuestion\"]>;\n\n/** Identifies the Task to read through the provider-neutral task tool. */\nexport interface GetTaskToolInput {\n taskId: TaskId;\n}\n\n/** Explicit not-found result returned when a requested Task does not exist. */\nexport interface TaskNotFoundResult {\n readonly found: false;\n readonly taskId: TaskId;\n}\n\n/** Existing Task or explicit not-found result returned by the task lookup tool. */\nexport type GetTaskToolResult = Task | TaskNotFoundResult;\n\n/** Provider-neutral Eve tool for reading one Factory Task. */\nexport interface GetTaskTool extends ToolDefinition<GetTaskToolInput, GetTaskToolResult> {\n execute(input: GetTaskToolInput, ctx: ToolContext): Promise<GetTaskToolResult>;\n}\n\n/** One final triage decision submitted for a pending Signal. */\nexport interface DecideSignalToolInput {\n signalId: SignalId;\n outcome: Exclude<SignalOutcome, \"pending\">;\n reason: string;\n detail?: string;\n}\n\n/** Provider-neutral Eve tool for recording a Signal decision. */\nexport interface DecideSignalTool extends ToolDefinition<DecideSignalToolInput, Signal> {\n execute(input: DecideSignalToolInput, ctx: ToolContext): Promise<Signal>;\n}\n\n/** Running Task and summary supplied to the generic completion tool. */\nexport interface FinishTaskToolInput {\n taskId: TaskId;\n summary: string;\n}\n\n/** Successful generic Task completion. */\nexport interface FinishTaskSuccess {\n readonly finished: true;\n readonly taskState: \"succeeded\";\n}\n\n/** Policy or lifecycle refusal returned by the generic Task completion tool. */\nexport interface FinishTaskRefusal {\n readonly finished: false;\n readonly reason: string;\n}\n\n/** Completion or bounded refusal returned by the generic Task completion tool. */\nexport type FinishTaskToolResult = FinishTaskSuccess | FinishTaskRefusal;\n\n/** Provider-neutral Eve tool for completing a running Task. */\nexport interface FinishTaskTool extends ToolDefinition<FinishTaskToolInput, FinishTaskToolResult> {\n execute(input: FinishTaskToolInput, ctx: ToolContext): Promise<FinishTaskToolResult>;\n}\n\n/** Unanswered question shape accepted when a Task requests human input. */\nexport type HumanInputQuestion = Omit<TaskQuestion, \"answer\" | \"answeredBy\">;\n\n/** Currently running parent Task and its single human question for this execution. */\nexport interface RequestHumanInputToolInput {\n parentTaskId: TaskId;\n question: HumanInputQuestion;\n}\n\n/** Provider-neutral Eve tool for pausing one running execution on one persisted human question. */\nexport interface RequestHumanInputTool extends ToolDefinition<RequestHumanInputToolInput, Task> {\n execute(input: RequestHumanInputToolInput, ctx: ToolContext): Promise<Task>;\n}\n\n/** Question Task and authenticated answer supplied to the answer tool. */\nexport interface AnswerQuestionToolInput {\n questionTaskId: TaskId;\n answer: string;\n}\n\n/** Provider-neutral Eve tool for answering a persisted human question. */\nexport interface AnswerQuestionTool extends ToolDefinition<\n AnswerQuestionToolInput,\n AnswerQuestionResult\n> {\n execute(input: AnswerQuestionToolInput, ctx: ToolContext): Promise<AnswerQuestionResult>;\n}\n\n/** Immutable audit event accepted by the generic receipt tool. */\nexport interface AppendReceiptToolInput {\n repositoryIds: RepositoryIds;\n taskId?: TaskId;\n changeId?: ChangeId;\n kind: ReceiptKind;\n state: ReceiptState;\n reason?: string;\n dedupeKey?: string;\n}\n\n/** Provider-neutral Eve tool for appending one immutable audit Receipt. */\nexport interface AppendReceiptTool extends ToolDefinition<AppendReceiptToolInput, Receipt> {\n execute(input: AppendReceiptToolInput, ctx: ToolContext): Promise<Receipt>;\n}\n\n/** The provider-neutral Task, Signal, question, and Receipt tools exposed to an Eve agent. */\nexport interface TaskTools {\n readonly get_task: GetTaskTool;\n readonly decide_signal: DecideSignalTool;\n readonly finish_task: FinishTaskTool;\n readonly request_human_input: RequestHumanInputTool;\n readonly answer_question: AnswerQuestionTool;\n readonly append_receipt: AppendReceiptTool;\n}\n\nasync function createAndPresentQuestion(\n stores: Pick<FactoryStores, \"tasks\">,\n parent: Task,\n question: z.infer<typeof taskQuestionSchema>,\n presentQuestion: PresentQuestion,\n): Promise<Task> {\n const needsHumanAction = question.text.trim();\n if (needsHumanAction === \"\") throw new Error(\"A human question must contain non-blank text.\");\n const task = await stores.tasks.create({\n repositoryIds: parent.repositoryIds,\n kind: \"question\",\n work: taskWork({ title: needsHumanAction.slice(0, 256), input: { question } }),\n parentTaskId: parent.id,\n parentTaskAttempt: parent.attempt,\n origin: {},\n replyTo: parent.replyTo,\n question,\n });\n try {\n const waiting = await stores.tasks.transition(task.id, \"needs_human\", { needsHumanAction });\n if (parent.state === \"running\") {\n await stores.tasks.transition(parent.id, \"needs_human\", {\n expectFrom: \"running\",\n expectAttempt: parent.attempt,\n reason: `waiting for answer to question ${waiting.id}`,\n questionTaskId: waiting.id,\n needsHumanAction,\n });\n }\n await presentQuestion(waiting);\n return waiting;\n } catch (error) {\n const currentParent = await stores.tasks.get(parent.id);\n if (\n currentParent?.state === \"needs_human\" &&\n currentParent.attempt === parent.attempt &&\n currentParent.questionTaskId === task.id\n ) {\n try {\n await stores.tasks.transition(parent.id, \"queued\", {\n expectFrom: \"needs_human\",\n expectAttempt: currentParent.attempt,\n expectQuestionTaskId: task.id,\n reason: `delivery of question ${task.id} failed`,\n });\n } catch (cleanupError) {\n const latest = await stores.tasks.get(parent.id);\n if (\n latest?.state === \"needs_human\" &&\n latest.attempt === currentParent.attempt &&\n latest.questionTaskId === task.id\n )\n throw cleanupError;\n }\n }\n const currentQuestion = await stores.tasks.get(task.id);\n if (currentQuestion?.state === \"needs_human\" || currentQuestion?.state === \"queued\") {\n await stores.tasks.transition(task.id, \"cancelled\", {\n expectFrom: currentQuestion.state,\n expectAttempt: currentQuestion.attempt,\n reason: \"question delivery failed\",\n });\n }\n throw error;\n }\n}\n\n/**\n * The factory's provider-neutral store operations wrapped as Eve tools. Expose a tool to an\n * agent by re-exporting it from a file under agent/tools/, e.g.\n * `export default createTaskTools(stores).get_task;`. Every write goes through\n * the engine, so agents inherit transition legality and receipts.\n */\nexport function createTaskTools(\n stores: TaskToolsStores,\n options: TaskToolsOptions = {},\n): TaskTools {\n return {\n get_task: defineTool({\n description:\n \"Read one factory task by id: its kind, state, repositories, origin, and results.\",\n inputSchema: z.object({ taskId: taskIdSchema }),\n async execute({ taskId }) {\n const task = await stores.tasks.get(taskId);\n return task ?? { found: false as const, taskId };\n },\n }),\n\n decide_signal: defineTool({\n description:\n \"Record the triage decision for a pending signal. A signal is decided exactly once.\",\n inputSchema: z.object({\n signalId: signalIdSchema,\n outcome: decidedOutcomeSchema,\n reason: z.string().min(1).describe(\"Why this outcome was chosen.\"),\n detail: z\n .string()\n .min(1)\n .optional()\n .describe(\"Severity if accepted, or the duplicate-of signal id.\"),\n }),\n execute({ signalId, outcome, reason, detail }) {\n return stores.signals.decide(signalId, { outcome: outcome, ...{ reason, detail } });\n },\n }),\n\n finish_task: defineTool({\n description:\n \"Mark your running task finished with a summary. The configured workflow policy may require a more specific outcome tool.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n summary: z.string().min(1).max(4000).describe(\"What you did and found, for the ledger.\"),\n }),\n async execute({ taskId, summary }, ctx) {\n const task = await requireTaskExecution(stores, ctx, taskId);\n const refusal = await options.finishTaskPolicy?.(task);\n if (refusal !== undefined && refusal !== null) {\n return {\n finished: false as const,\n reason: refusal,\n };\n }\n if (task.state !== \"running\") {\n return { finished: false as const, reason: `task is ${task.state}, not running` };\n }\n await stores.tasks.transition(taskId, \"succeeded\", {\n expectFrom: \"running\",\n expectAttempt: task.attempt,\n expectExecution: task.execution,\n reason: summary,\n output: { summary },\n });\n return { finished: true as const, taskState: \"succeeded\" as const };\n },\n }),\n\n request_human_input: defineTool({\n description:\n 'Request one human input or action and pause your currently running task until the human replies. A paused task cannot request another question; wait for the answer and replacement execution. The parent task determines the repositories and reply destination. Name any suggested reply in question.closingOptions when that exact answer means no further attempt can help (for example \"nothing to do, close it\"); Factory resolves the task instead of requeuing an identical retry when the human picks one.',\n inputSchema: z.object({\n parentTaskId: taskIdSchema.describe(\"Your running task, which the answer will unblock.\"),\n question: taskQuestionSchema.omit({ answer: true, answeredBy: true }),\n }),\n async execute({ parentTaskId, question }, ctx) {\n if (options.presentQuestion === undefined) {\n throw new Error(\"request_human_input requires a configured question presenter.\");\n }\n const parent = await requireTaskExecution(stores, ctx, parentTaskId);\n return createAndPresentQuestion(stores, parent, question, options.presentQuestion);\n },\n }),\n\n answer_question: defineTool({\n description:\n \"Record the authenticated user's answer to a waiting question and requeue the parent specialist task, unless the answer matches one of the question's closingOptions, which resolves the parent task instead. A blocked parent task id is also accepted and resolves its persisted QuestionTask id.\",\n inputSchema: z.object({\n questionTaskId: taskIdSchema,\n answer: z.string().min(1).max(4000),\n }),\n async execute({ questionTaskId, answer }, ctx) {\n const requestedTask = await stores.tasks.get(questionTaskId);\n const resolvedQuestionTaskId =\n requestedTask?.kind === \"question\" ? requestedTask.id : requestedTask?.questionTaskId;\n const questionTask =\n resolvedQuestionTaskId === undefined\n ? null\n : await stores.tasks.get(resolvedQuestionTaskId);\n if (\n questionTask === null ||\n questionTask.kind !== \"question\" ||\n questionTask.question === undefined\n ) {\n throw new Error(`Question task ${questionTaskId} does not exist.`);\n }\n const { initiator, current } = ctx.session.auth;\n if (\n !initiator ||\n !current ||\n [initiator, current].some(\n ({ attributes }) =>\n attributes.factoryReplyChannel !== questionTask.replyTo.channel ||\n attributes.factoryReplyAddress !== questionTask.replyTo.address,\n )\n ) {\n throw new Error(\"Question reply does not match the authenticated conversation.\");\n }\n const answeredBy = current.principalId;\n return stores.tasks.answerQuestion({\n questionTaskId: questionTask.id,\n answer,\n answeredBy,\n });\n },\n }),\n\n append_receipt: defineTool({\n description:\n \"Append one immutable audit receipt for an event worth remembering. Receipts can never be edited or deleted.\",\n inputSchema: z.object({\n repositoryIds: repositoryIdsSchema,\n taskId: taskIdSchema.optional(),\n changeId: changeIdSchema.optional(),\n kind: receiptKindSchema.describe(\"What the receipt is about, e.g. investigation.\"),\n state: receiptStateSchema.describe(\"What happened, e.g. flag_ramped.\"),\n reason: z.string().min(1).max(2000).optional(),\n dedupeKey: z\n .string()\n .min(1)\n .optional()\n .describe(\"Same key twice records one receipt instead of two.\"),\n }),\n execute(input) {\n return stores.receipts.append(input);\n },\n }),\n };\n}\n\n/** Completed conversation output, or `false` when the Task is not a conversation. */\nexport type ConversationCompletionResult = { readonly output: JsonValue } | false;\n\n/** Configures attempt recovery, conversation completion, and transcript projection for Eve hooks. */\nexport interface FactoryHooksOptions {\n /** Session auth attribute naming the task a dispatched session works on. Default `factoryTaskId`. */\n taskIdAttribute?: string;\n /** Session auth attribute naming the execution attempt. Default `factoryTaskAttempt`. */\n taskAttemptAttribute?: string;\n /** Attempts allowed before an explicit provider failure becomes terminal. Default: 3. */\n maxAttempts?: number;\n /** Present the recovery question created when a task turn ends without an outcome. */\n presentQuestion: PresentQuestion;\n /** Classify discussion Tasks on failure or cancellation without collecting a successful response. */\n isConversation?: (task: Task) => MaybePromise<boolean>;\n /** Return the actual completed response for an opted-in discussion, or false for other work. */\n completeConversation?: (task: Task) => Promise<ConversationCompletionResult>;\n /** Persist the browser-safe transcript projection after Eve durably records a response boundary. */\n materializeTranscript?: EveTranscriptMaterializer;\n}\n\nfunction materializationInput(\n ctx: import(\"eve/hooks\").HookContext,\n): TranscriptMaterializationInput {\n return {\n agent: ctx.agent.name,\n execution: { provider: \"eve\", sessionId: ctx.session.id },\n attributes: ctx.session.auth.initiator?.attributes ?? {},\n };\n}\n\n/** Observe-only hook for agents that do not use the Factory task-lifecycle hook. */\nexport function createTranscriptSnapshotHook(\n materialize: EveTranscriptMaterializer,\n): TranscriptSnapshotHook {\n const snapshot = (_event: unknown, ctx: import(\"eve/hooks\").HookContext) =>\n materialize(materializationInput(ctx)).catch(() => undefined);\n return defineHook({\n events: {\n \"session.waiting\": snapshot,\n \"session.completed\": snapshot,\n \"session.failed\": snapshot,\n },\n });\n}\n\n/** Observe-only Eve hook that materializes transcript snapshots at response boundaries. */\nexport type TranscriptSnapshotHook = HookDefinition<\n \"session.waiting\" | \"session.completed\" | \"session.failed\"\n>;\n\nconst terminalTaskStates: ReadonlySet<Task[\"state\"]> = new Set([\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n]);\n\ntype FactoryHookEvent =\n | \"step.completed\"\n | \"turn.failed\"\n | \"session.failed\"\n | \"session.waiting\"\n | \"session.completed\"\n | \"turn.cancelled\"\n | \"turn.completed\";\n\n/** The Eve lifecycle hook projected onto durable Factory Task state. */\nexport interface FactoryHooks {\n readonly factory: HookDefinition<FactoryHookEvent>;\n}\n\n/**\n * The turn contract's escalation question: a specialist turn ended cleanly\n * (eve durably recorded `turn.completed`) but the bound task is still\n * `running`, so no transition was recorded. That is never a \"worker died\n * mid-turn\" situation -- eve confirms the turn finished -- so retrying the\n * identical brief cannot succeed any differently. Escalating straight to\n * `needs_human` instead of waiting for the stall window (up to 45 minutes,\n * times `maxAttempts`) surfaces the dead end immediately. \"Close the task\"\n * is a declared closingOptions entry: answering with it resolves the task\n * instead of requeuing an identical retry.\n */\nconst UNRESOLVED_TURN_QUESTION: z.infer<typeof taskQuestionSchema> = {\n text: \"The specialist ended its turn without recording a result for this task. Reply to retry it, or close it if the work no longer applies (for example, a newer attempt already superseded it).\",\n options: [\"Retry the task\", \"Close the task\"],\n closingOptions: [\"Close the task\"],\n};\n\n/**\n * Observe-only eve hooks that keep the ledger honest about session outcomes.\n * Mount by re-exporting from agent/hooks/, e.g.\n * `export default createFactoryHooks(stores, { presentQuestion }).factory;`.\n *\n * step.completed: records the step's tokens and AI Gateway cost on the bound\n * task. Delivery is at least once; recordUsage dedupes by (turnId, stepIndex).\n *\n * turn.failed/session.failed: immediately re-queues the current attempt, or\n * fails it when its configured attempts are exhausted. turn.cancelled marks\n * the current Task cancelled. Late events from prior attempts are ignored.\n *\n * turn.completed: settles the bound task's recorded usage if the task is\n * already terminal, and enforces the turn contract otherwise: a still-running\n * bound task (or a still-running task at this session's reply address, for\n * conversational continuations that never got their own bound session)\n * escalates immediately to a surfaced human question instead of waiting out\n * the stall window, because the agent finished without recording an outcome.\n *\n * Every store call is swallowed: a hook throw fails the turn.\n * Transcript projection writes at session response boundaries are likewise\n * best-effort; the API can rebuild a missing projection from durable events.\n */\nexport function createFactoryHooks(\n stores: FactoryHooksStores,\n options: FactoryHooksOptions,\n): FactoryHooks {\n const taskIdAttribute = options.taskIdAttribute ?? \"factoryTaskId\";\n const taskAttemptAttribute = options.taskAttemptAttribute ?? \"factoryTaskAttempt\";\n const maxAttempts = z\n .number()\n .int()\n .min(1)\n .parse(options.maxAttempts ?? 3);\n\n function boundTaskId(ctx: Pick<SessionContext, \"session\">): TaskId | undefined {\n const parsed = taskIdSchema.safeParse(ctx.session.auth.initiator?.attributes[taskIdAttribute]);\n return parsed.success ? parsed.data : undefined;\n }\n\n function boundExecution(ctx: Pick<SessionContext, \"session\">): TaskAttemptRef | undefined {\n const attributes = ctx.session.auth.initiator?.attributes;\n const taskId = boundTaskId(ctx);\n const attempt = z.coerce.number().int().min(1).safeParse(attributes?.[taskAttemptAttribute]);\n return taskId !== undefined && attempt.success ? { taskId, attempt: attempt.data } : undefined;\n }\n\n async function recoverFailedAttempt(binding: TaskAttemptRef, failure: string): Promise<void> {\n const task = await stores.tasks.get(binding.taskId);\n if (task?.state !== \"running\" || task.attempt !== binding.attempt) {\n return;\n }\n const exhausted = task.attempt >= maxAttempts;\n await stores.tasks.transition(task.id, exhausted ? \"failed\" : \"queued\", {\n expectFrom: \"running\",\n expectAttempt: binding.attempt,\n phase: \"retry\",\n reason: exhausted\n ? `${failure} on attempt ${task.attempt} of ${maxAttempts}; attempts exhausted`\n : `${failure} on attempt ${task.attempt} of ${maxAttempts}; replacement queued`,\n });\n }\n\n async function cancelAttempt(binding: TaskAttemptRef, reason: string): Promise<void> {\n const task = await stores.tasks.get(binding.taskId);\n if (task?.state !== \"running\" || task.attempt !== binding.attempt) {\n return;\n }\n await stores.tasks.transition(task.id, \"cancelled\", {\n expectFrom: \"running\",\n expectAttempt: binding.attempt,\n phase: \"execution\",\n reason,\n });\n }\n\n async function isConversation(task: Task): Promise<boolean> {\n try {\n return (await options.isConversation?.(task)) ?? false;\n } catch {\n return false;\n }\n }\n\n async function settleIfTerminal(taskId: TaskId): Promise<void> {\n const task = await stores.tasks.get(taskId);\n if (\n task?.usage === undefined ||\n task.settledUsd !== undefined ||\n !terminalTaskStates.has(task.state)\n ) {\n return;\n }\n await stores.tasks.settle(task.id, {\n cost: { totalUsd: task.usage.costUsd },\n ...{\n reason: \"measured usage settled at turn end\",\n },\n });\n }\n\n async function escalateUnresolvedTurn(task: Task): Promise<void> {\n await createAndPresentQuestion(\n stores,\n task,\n UNRESOLVED_TURN_QUESTION,\n options.presentQuestion,\n ).catch(() => undefined);\n }\n\n return {\n factory: defineHook({\n events: {\n async \"step.completed\"(event, ctx) {\n const taskId = boundTaskId(ctx);\n const usage = event.data.usage;\n if (taskId === undefined || usage === undefined) {\n return;\n }\n const binding = boundExecution(ctx);\n if (binding !== undefined) {\n const task = await stores.tasks.get(taskId).catch(() => null);\n if (task?.attempt !== binding.attempt) return;\n }\n await stores.tasks\n .recordUsage(taskId, {\n step: {\n turnId: event.data.turnId,\n stepIndex: event.data.stepIndex,\n ...usage,\n },\n })\n .catch(() => undefined);\n },\n async \"turn.failed\"(event, ctx) {\n const binding = boundExecution(ctx);\n if (binding !== undefined) {\n await recoverFailedAttempt(\n binding,\n `provider turn failed (${event.data.code}): ${event.data.message}`,\n ).catch(() => undefined);\n return;\n }\n const taskId = boundTaskId(ctx);\n const task = taskId ? await stores.tasks.get(taskId).catch(() => null) : null;\n if (task?.state === \"running\" && (await isConversation(task))) {\n await stores.tasks\n .transition(task.id, \"failed\", {\n expectFrom: \"running\",\n reason: \"Conversation turn failed\",\n })\n .catch(() => undefined);\n await settleIfTerminal(task.id).catch(() => undefined);\n }\n },\n async \"session.failed\"(event, ctx) {\n const binding = boundExecution(ctx);\n if (binding !== undefined) {\n await recoverFailedAttempt(\n binding,\n `provider session failed (${event.data.code}): ${event.data.message}`,\n ).catch(() => undefined);\n }\n await options.materializeTranscript?.(materializationInput(ctx)).catch(() => undefined);\n },\n async \"session.waiting\"(_event, ctx) {\n await options.materializeTranscript?.(materializationInput(ctx)).catch(() => undefined);\n },\n async \"session.completed\"(_event, ctx) {\n await options.materializeTranscript?.(materializationInput(ctx)).catch(() => undefined);\n },\n async \"turn.cancelled\"(_event, ctx) {\n const binding = boundExecution(ctx);\n if (binding !== undefined) {\n await cancelAttempt(\n binding,\n `provider turn cancelled on attempt ${binding.attempt}`,\n ).catch(() => undefined);\n return;\n }\n const taskId = boundTaskId(ctx);\n const task = taskId ? await stores.tasks.get(taskId).catch(() => null) : null;\n if (task && (await isConversation(task))) {\n if (task.state === \"running\")\n await stores.tasks\n .transition(task.id, \"cancelled\", {\n expectFrom: \"running\",\n reason: \"Conversation turn interrupted\",\n })\n .catch(() => undefined);\n await settleIfTerminal(task.id).catch(() => undefined);\n }\n },\n async \"turn.completed\"(_event, ctx) {\n const taskId = boundTaskId(ctx);\n const binding = boundExecution(ctx);\n if (taskId !== undefined) {\n const task = await stores.tasks.get(taskId).catch(() => null);\n if (binding !== undefined && task?.attempt !== binding.attempt) return;\n if (task?.state === \"running\" && !task.waitingForMessages) {\n const completion = await options\n .completeConversation?.(task)\n .catch(() => false as const);\n if (completion) {\n await stores.tasks\n .transition(taskId, \"succeeded\", {\n expectFrom: \"running\",\n expectAttempt: task.attempt,\n reason: \"Conversation turn completed\",\n output: completion.output,\n })\n .catch(() => undefined);\n } else {\n // The turn genuinely finished (this is `turn.completed`, not a\n // crash or an interrupted turn.failed/turn.cancelled) with the\n // task still running: nothing was recorded, and an identical\n // retry cannot do better than this one did. Enforce the turn\n // contract now instead of leaving it to the 45-minute stall\n // window, which would otherwise burn up to `maxAttempts`\n // replacement attempts on a task no attempt can ever finish.\n await escalateUnresolvedTurn(task);\n }\n }\n await settleIfTerminal(taskId).catch(() => undefined);\n }\n const address = ctx.channel.continuationToken;\n if (address === undefined) {\n return;\n }\n const tasks = await stores.tasks.list().catch(() => []);\n const abandoned = tasks.filter(\n (task) =>\n task.id !== taskId &&\n task.state === \"running\" &&\n !task.waitingForMessages &&\n task.replyTo.address === address,\n );\n for (const task of abandoned) {\n await escalateUnresolvedTurn(task);\n }\n },\n },\n }),\n };\n}\n\n/** The minimal command-running sandbox surface used by Eve tools. */\nexport {\n createDelegateAgentTool,\n createInvokeAgentTool,\n type DelegateAgentLaunchInput,\n type DelegateAgentTool,\n type DelegateAgentToolInput,\n type DelegateAgentToolOptions,\n type DelegateAgentToolStores,\n type DelegateWorkflowInput,\n type DelegateWorkflowPolicy,\n type DelegateWorkflowResult,\n type InvokeAgentTool,\n type InvokeAgentToolInput,\n type InvokeAgentToolOptions,\n type InvokeAgentToolResult,\n type InvokeAgentToolStores,\n} from \"./invoke\";\n"],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ import { ChangeId, RepositoryId, RepositoryIds, SignalId, TaskId } from "../schema/id.mjs";
2
+ import { AgentRouteBinding } from "../schema/agent-route.mjs";
3
+ import { ExecutionReference, Task, TaskKind, TaskState } from "../schema/task.mjs";
4
+ import { AgentRoute, AgentRouteRegistry } from "../agent-routes.mjs";
5
+ import { MaybePromise, ReplyTo } from "../schema/common.mjs";
6
+ import { FactoryStores } from "../store/engine.mjs";
7
+ import { DispatchBudget } from "../dispatch.mjs";
8
+ import { ToolContext, ToolDefinition } from "eve/tools";
9
+ //#region src/eve/invoke.d.ts
10
+ /** Graph, receipt, and Task capabilities required by the fixed-route invocation tool. */
11
+ type InvokeAgentToolStores = Pick<FactoryStores, "graphs" | "receipts" | "tasks">;
12
+ /** Durable capabilities required by route-based agent delegation. */
13
+ type DelegateAgentToolStores = Pick<FactoryStores, "changes" | "graphs" | "receipts" | "repositories" | "signals" | "tasks" | "work">;
14
+ /** Configures one fixed agent handoff route and its authenticated Eve session boundary. */
15
+ interface InvokeAgentToolOptions {
16
+ /** Application-selected exact route for this handoff. */
17
+ route: AgentRoute;
18
+ /** Model-facing description of what the target agent does and when to invoke it. */
19
+ description: string;
20
+ /**
21
+ * Base URL of the target agent's eve transport, e.g.
22
+ * `https://factory.example.com/eve/agents/verifier`. Resolved at call time so
23
+ * a deployment can derive it from its own origin.
24
+ */
25
+ targetUrl: () => string;
26
+ /** Bearer token for the target agent's eve channel, when it requires auth. */
27
+ token?: () => MaybePromise<string | undefined>;
28
+ /** Extra headers for the session request, e.g. a deployment protection bypass. */
29
+ headers?: (task: Task) => MaybePromise<HeadersInit>;
30
+ /**
31
+ * Reserve-before-execution limits for the handoff dispatch, resolved at
32
+ * call time. Without it, handoff tasks run outside the budget.
33
+ */
34
+ budget?: () => DispatchBudget | undefined;
35
+ fetch?: typeof fetch;
36
+ }
37
+ /** Scope, lineage, reply destination, and brief supplied to a fixed-route handoff. */
38
+ interface InvokeAgentToolInput {
39
+ repositoryIds: RepositoryIds;
40
+ parentTaskId?: TaskId;
41
+ changeId?: ChangeId;
42
+ channel: string;
43
+ address: string;
44
+ brief: string;
45
+ }
46
+ /** Durable Task identity and lifecycle returned after a fixed-route handoff launches. */
47
+ interface InvokeAgentToolResult {
48
+ readonly taskId: TaskId;
49
+ readonly kind: TaskKind;
50
+ readonly state: TaskState;
51
+ }
52
+ /** Eve tool that launches work through one configured exact agent route. */
53
+ interface InvokeAgentTool extends ToolDefinition<InvokeAgentToolInput, InvokeAgentToolResult> {
54
+ execute(input: InvokeAgentToolInput, ctx: ToolContext): Promise<InvokeAgentToolResult>;
55
+ }
56
+ interface DelegateAgentToolCommonOptions {
57
+ routes: AgentRouteRegistry;
58
+ /** Retry bound for application-owned routes with a reconciler; default is one launch. */
59
+ maxLaunchAttempts?: (route: AgentRoute) => number;
60
+ budget?: (route: AgentRoute) => DispatchBudget | undefined;
61
+ /** Application workflow policy that may replace single-task delegation. */
62
+ workflow?: DelegateWorkflowPolicy;
63
+ }
64
+ /** Identifies one validated delegated Task launch on its exact registered route. */
65
+ interface DelegateAgentLaunchInput {
66
+ readonly task: Task;
67
+ readonly route: AgentRoute;
68
+ readonly brief: string;
69
+ }
70
+ /** Delegation mode whose application owns the provider launch boundary. */
71
+ interface DelegateAgentCustomLaunchOptions extends DelegateAgentToolCommonOptions {
72
+ /** Application execution boundary, after route, scope, approval, and budget validation. */
73
+ launch(input: DelegateAgentLaunchInput): Promise<ExecutionReference>;
74
+ targetUrl?: never;
75
+ token?: never;
76
+ headers?: never;
77
+ fetch?: never;
78
+ }
79
+ /** Delegation mode that starts a fresh session through an Eve HTTP endpoint. */
80
+ interface DelegateAgentEveLaunchOptions extends DelegateAgentToolCommonOptions {
81
+ launch?: never;
82
+ targetUrl(route: AgentRoute): string;
83
+ token?: (route: AgentRoute) => MaybePromise<string | undefined>;
84
+ headers?: (task: Task, route: AgentRoute) => MaybePromise<HeadersInit>;
85
+ fetch?: typeof fetch;
86
+ }
87
+ /** Configures route-based delegation with one explicit launch mode and workflow policy. */
88
+ type DelegateAgentToolOptions = DelegateAgentCustomLaunchOptions | DelegateAgentEveLaunchOptions;
89
+ /** Exact route, scope, provenance, and brief supplied to bounded agent delegation. */
90
+ interface DelegateAgentToolInput {
91
+ route: AgentRouteBinding;
92
+ repositoryIds: RepositoryIds;
93
+ signalId?: SignalId;
94
+ parentTaskId?: TaskId;
95
+ changeId?: ChangeId;
96
+ channel: string;
97
+ address: string;
98
+ brief: string;
99
+ }
100
+ /** Trusted context supplied to an application-owned delegation workflow policy. */
101
+ interface DelegateWorkflowInput {
102
+ stores: DelegateAgentToolStores;
103
+ route: AgentRoute;
104
+ repositoryIds: readonly RepositoryId[];
105
+ signalId?: SignalId;
106
+ parentTaskId?: TaskId;
107
+ changeId?: ChangeId;
108
+ replyTo: ReplyTo;
109
+ brief: string;
110
+ operator: string;
111
+ dispatch(task: Task): Promise<Task>;
112
+ }
113
+ /** Identifies the durable work and exact agent route selected by a delegation policy. */
114
+ interface DelegateWorkflowResult {
115
+ readonly taskId: TaskId;
116
+ readonly childTaskIds?: readonly TaskId[];
117
+ readonly route: AgentRouteBinding;
118
+ readonly agent: string;
119
+ readonly state: Task["state"];
120
+ }
121
+ /** Eve tool that delegates durable work through a registered exact agent route. */
122
+ interface DelegateAgentTool extends ToolDefinition<DelegateAgentToolInput, DelegateWorkflowResult> {
123
+ execute(input: DelegateAgentToolInput, ctx: ToolContext): Promise<DelegateWorkflowResult>;
124
+ }
125
+ /** Application policy that may replace ordinary single-Task delegation with a workflow. */
126
+ type DelegateWorkflowPolicy = (input: DelegateWorkflowInput) => Promise<DelegateWorkflowResult | null>;
127
+ /**
128
+ * A tool that lets one agent hand work to another, NMA-style: the caller
129
+ * decides to invoke; trusted code owns the how. The handoff is recorded as a
130
+ * factory task (single-winner dispatch, receipts), then a fresh session is
131
+ * started on the target agent carrying only the task id — never the caller's
132
+ * context. The session start is create-once on the task attempt, so a retried
133
+ * launch cannot duplicate that attempt while a later attempt starts fresh.
134
+ */
135
+ declare function createInvokeAgentTool(stores: InvokeAgentToolStores, options: InvokeAgentToolOptions): InvokeAgentTool;
136
+ /**
137
+ * Give a conversational agent one bounded delegation surface backed by the
138
+ * application's route registry. The caller selects a declared route; trusted
139
+ * code owns task creation, budget enforcement, and the fresh target session.
140
+ */
141
+ declare function createDelegateAgentTool(stores: DelegateAgentToolStores, options: DelegateAgentToolOptions): DelegateAgentTool;
142
+ //#endregion
143
+ export { DelegateAgentLaunchInput, DelegateAgentTool, DelegateAgentToolInput, DelegateAgentToolOptions, DelegateAgentToolStores, DelegateWorkflowInput, DelegateWorkflowPolicy, DelegateWorkflowResult, InvokeAgentTool, InvokeAgentToolInput, InvokeAgentToolOptions, InvokeAgentToolResult, InvokeAgentToolStores, createDelegateAgentTool, createInvokeAgentTool };
144
+ //# sourceMappingURL=invoke.d.mts.map