gemi 0.110.0 → 0.112.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/dist/ai/Agent.d.ts +65 -1
  2. package/dist/ai/Agent.d.ts.map +1 -1
  3. package/dist/ai/AgentController.d.ts +48 -0
  4. package/dist/ai/AgentController.d.ts.map +1 -1
  5. package/dist/ai/client/index.d.ts +1 -1
  6. package/dist/ai/client/index.d.ts.map +1 -1
  7. package/dist/ai/contextCompaction.d.ts +247 -0
  8. package/dist/ai/contextCompaction.d.ts.map +1 -0
  9. package/dist/ai/contextWindow.d.ts +18 -0
  10. package/dist/ai/contextWindow.d.ts.map +1 -1
  11. package/dist/ai/index.d.ts +5 -1
  12. package/dist/ai/index.d.ts.map +1 -1
  13. package/dist/ai/index.js +93 -14
  14. package/dist/ai/index.js.map +16 -10
  15. package/dist/ai/jobs/AgentJob.d.ts +259 -0
  16. package/dist/ai/jobs/AgentJob.d.ts.map +1 -0
  17. package/dist/ai/jobs/AgentJobDeadlineSweep.d.ts +18 -0
  18. package/dist/ai/jobs/AgentJobDeadlineSweep.d.ts.map +1 -0
  19. package/dist/ai/jobs/AgentJobStore.d.ts +141 -0
  20. package/dist/ai/jobs/AgentJobStore.d.ts.map +1 -0
  21. package/dist/ai/jobs/DatabaseAgentJobStore.d.ts +82 -0
  22. package/dist/ai/jobs/DatabaseAgentJobStore.d.ts.map +1 -0
  23. package/dist/ai/jobs/contextBlock.d.ts +31 -0
  24. package/dist/ai/jobs/contextBlock.d.ts.map +1 -0
  25. package/dist/ai/jobs/index.d.ts +6 -0
  26. package/dist/ai/jobs/index.d.ts.map +1 -0
  27. package/dist/ai/jobs/overlay.d.ts +49 -0
  28. package/dist/ai/jobs/overlay.d.ts.map +1 -0
  29. package/dist/ai/providers/request.d.ts.map +1 -1
  30. package/dist/ai/store/Attachments.d.ts +6 -0
  31. package/dist/ai/store/Attachments.d.ts.map +1 -1
  32. package/dist/ai/store/MemoryAgentStore.d.ts +3 -0
  33. package/dist/ai/store/MemoryAgentStore.d.ts.map +1 -1
  34. package/dist/ai/types.d.ts +28 -0
  35. package/dist/ai/types.d.ts.map +1 -1
  36. package/dist/app/index.js +1 -1
  37. package/dist/bin/gemi.js +13 -2
  38. package/dist/bin/gemi.js.map +4 -4
  39. package/dist/bun/plugin.js +1 -1
  40. package/dist/bun/preload.js +1 -1
  41. package/dist/{chunk-30xjcyzh.js → chunk-0z2h35d7.js} +2 -2
  42. package/dist/{chunk-30xjcyzh.js.map → chunk-0z2h35d7.js.map} +1 -1
  43. package/dist/{chunk-358sdcx9.js → chunk-15a1mrdv.js} +2 -2
  44. package/dist/{chunk-358sdcx9.js.map → chunk-15a1mrdv.js.map} +1 -1
  45. package/dist/{chunk-hf7a51s3.js → chunk-18c3y8m3.js} +2 -2
  46. package/dist/{chunk-hf7a51s3.js.map → chunk-18c3y8m3.js.map} +1 -1
  47. package/dist/{chunk-tq85n8zh.js → chunk-1pvkw2pq.js} +2 -2
  48. package/dist/{chunk-tq85n8zh.js.map → chunk-1pvkw2pq.js.map} +1 -1
  49. package/dist/{chunk-8afxrmdc.js → chunk-2taa0brj.js} +2 -2
  50. package/dist/{chunk-8afxrmdc.js.map → chunk-2taa0brj.js.map} +1 -1
  51. package/dist/{chunk-5cygrbxv.js → chunk-30yg31sz.js} +2 -2
  52. package/dist/{chunk-5cygrbxv.js.map → chunk-30yg31sz.js.map} +1 -1
  53. package/dist/{chunk-3y8q8x11.js → chunk-3z9vhjd7.js} +2 -2
  54. package/dist/{chunk-3y8q8x11.js.map → chunk-3z9vhjd7.js.map} +1 -1
  55. package/dist/chunk-4sb1484x.js +46 -0
  56. package/dist/{chunk-h3864a8z.js.map → chunk-4sb1484x.js.map} +13 -4
  57. package/dist/{chunk-0sjh5v1n.js → chunk-53bek7sp.js} +1 -1
  58. package/dist/{chunk-xkc7ftnq.js → chunk-57edag57.js} +3 -3
  59. package/dist/{chunk-xkc7ftnq.js.map → chunk-57edag57.js.map} +1 -1
  60. package/dist/{chunk-ddr4qvvt.js → chunk-5az0mq4p.js} +3 -3
  61. package/dist/{chunk-ddr4qvvt.js.map → chunk-5az0mq4p.js.map} +1 -1
  62. package/dist/{chunk-nsvktvp4.js → chunk-5waxjsvv.js} +2 -2
  63. package/dist/{chunk-nsvktvp4.js.map → chunk-5waxjsvv.js.map} +1 -1
  64. package/dist/{chunk-rfcygmf5.js → chunk-6w79zajj.js} +3 -3
  65. package/dist/{chunk-rfcygmf5.js.map → chunk-6w79zajj.js.map} +1 -1
  66. package/dist/{chunk-gb37722w.js → chunk-75ptmewf.js} +3 -3
  67. package/dist/{chunk-gb37722w.js.map → chunk-75ptmewf.js.map} +1 -1
  68. package/dist/{chunk-pyj7cd9t.js → chunk-851k0b26.js} +2 -2
  69. package/dist/{chunk-pyj7cd9t.js.map → chunk-851k0b26.js.map} +1 -1
  70. package/dist/{chunk-m6ystvtk.js → chunk-8reepafh.js} +2 -2
  71. package/dist/{chunk-m6ystvtk.js.map → chunk-8reepafh.js.map} +1 -1
  72. package/dist/{chunk-nvv9wej6.js → chunk-9hr0bcfy.js} +3 -3
  73. package/dist/{chunk-nvv9wej6.js.map → chunk-9hr0bcfy.js.map} +1 -1
  74. package/dist/{chunk-yqavgpwd.js → chunk-a9q2cr4w.js} +2 -2
  75. package/dist/{chunk-yqavgpwd.js.map → chunk-a9q2cr4w.js.map} +1 -1
  76. package/dist/{chunk-cy5qp6mz.js → chunk-amvy4r59.js} +2 -2
  77. package/dist/{chunk-cy5qp6mz.js.map → chunk-amvy4r59.js.map} +1 -1
  78. package/dist/{chunk-twnn7r66.js → chunk-b1mk12xg.js} +2 -2
  79. package/dist/{chunk-twnn7r66.js.map → chunk-b1mk12xg.js.map} +1 -1
  80. package/dist/{chunk-a6453d9s.js → chunk-b7cqwcbm.js} +2 -2
  81. package/dist/{chunk-a6453d9s.js.map → chunk-b7cqwcbm.js.map} +1 -1
  82. package/dist/{chunk-nncz308h.js → chunk-b7qjp7r1.js} +2 -2
  83. package/dist/{chunk-nncz308h.js.map → chunk-b7qjp7r1.js.map} +1 -1
  84. package/dist/chunk-beks65me.js +19 -0
  85. package/dist/{chunk-mb7q7s0a.js.map → chunk-beks65me.js.map} +3 -4
  86. package/dist/chunk-bf1ets45.js +5 -0
  87. package/dist/{chunk-11fsn5mr.js.map → chunk-bf1ets45.js.map} +4 -3
  88. package/dist/{chunk-9rchedr4.js → chunk-bhw7k8vp.js} +2 -2
  89. package/dist/{chunk-9rchedr4.js.map → chunk-bhw7k8vp.js.map} +1 -1
  90. package/dist/{chunk-k1vw22t2.js → chunk-ck0v2kzw.js} +2 -2
  91. package/dist/{chunk-k1vw22t2.js.map → chunk-ck0v2kzw.js.map} +1 -1
  92. package/dist/{chunk-e1n8zs3h.js → chunk-cptzbdn6.js} +2 -2
  93. package/dist/{chunk-e1n8zs3h.js.map → chunk-cptzbdn6.js.map} +1 -1
  94. package/dist/{chunk-6vr7f5fq.js → chunk-csbc1fxa.js} +3 -3
  95. package/dist/{chunk-6vr7f5fq.js.map → chunk-csbc1fxa.js.map} +1 -1
  96. package/dist/{chunk-kf71mjxa.js → chunk-d0trs736.js} +3 -3
  97. package/dist/{chunk-kf71mjxa.js.map → chunk-d0trs736.js.map} +1 -1
  98. package/dist/{chunk-zhs1r1z0.js → chunk-d8ekyng4.js} +3 -3
  99. package/dist/{chunk-zhs1r1z0.js.map → chunk-d8ekyng4.js.map} +1 -1
  100. package/dist/chunk-d9an2nra.js +5 -0
  101. package/dist/{chunk-hn67spz6.js.map → chunk-d9an2nra.js.map} +1 -1
  102. package/dist/{chunk-0d9qsmx2.js → chunk-dan79jab.js} +2 -2
  103. package/dist/{chunk-0d9qsmx2.js.map → chunk-dan79jab.js.map} +1 -1
  104. package/dist/{chunk-1yx2e0bh.js → chunk-ddad3902.js} +2 -2
  105. package/dist/{chunk-1yx2e0bh.js.map → chunk-ddad3902.js.map} +1 -1
  106. package/dist/{chunk-3cg7y62b.js → chunk-dm59ze55.js} +2 -2
  107. package/dist/{chunk-3cg7y62b.js.map → chunk-dm59ze55.js.map} +1 -1
  108. package/dist/{chunk-wvsv1jgg.js → chunk-dx7wpz5b.js} +2 -2
  109. package/dist/{chunk-wvsv1jgg.js.map → chunk-dx7wpz5b.js.map} +1 -1
  110. package/dist/{chunk-q9s7kwgt.js → chunk-eazqda9z.js} +3 -3
  111. package/dist/{chunk-q9s7kwgt.js.map → chunk-eazqda9z.js.map} +1 -1
  112. package/dist/{chunk-td8tha3j.js → chunk-es487acc.js} +1 -1
  113. package/dist/{chunk-9s851qz8.js → chunk-et3vhkbf.js} +2 -2
  114. package/dist/{chunk-9s851qz8.js.map → chunk-et3vhkbf.js.map} +1 -1
  115. package/dist/{chunk-qd2v93y4.js → chunk-f1y8eggf.js} +2 -2
  116. package/dist/{chunk-qd2v93y4.js.map → chunk-f1y8eggf.js.map} +1 -1
  117. package/dist/{chunk-1pem26zc.js → chunk-ga7c7tq0.js} +3 -3
  118. package/dist/{chunk-1pem26zc.js.map → chunk-ga7c7tq0.js.map} +1 -1
  119. package/dist/{chunk-c098fzvk.js → chunk-gcs9ydjv.js} +2 -2
  120. package/dist/{chunk-c098fzvk.js.map → chunk-gcs9ydjv.js.map} +1 -1
  121. package/dist/{chunk-bn5yn731.js → chunk-hfyxvdjj.js} +2 -2
  122. package/dist/{chunk-bn5yn731.js.map → chunk-hfyxvdjj.js.map} +1 -1
  123. package/dist/chunk-j0sncgxc.js +14 -0
  124. package/dist/{chunk-mn5xw79b.js.map → chunk-j0sncgxc.js.map} +6 -5
  125. package/dist/{chunk-p7r2w4qw.js → chunk-j9jqxv1d.js} +3 -3
  126. package/dist/{chunk-p7r2w4qw.js.map → chunk-j9jqxv1d.js.map} +1 -1
  127. package/dist/{chunk-jbrwt3cs.js → chunk-jdtn0zk2.js} +4 -4
  128. package/dist/{chunk-jbrwt3cs.js.map → chunk-jdtn0zk2.js.map} +1 -1
  129. package/dist/{chunk-s6jjy4y9.js → chunk-jn59bsww.js} +2 -2
  130. package/dist/{chunk-s6jjy4y9.js.map → chunk-jn59bsww.js.map} +1 -1
  131. package/dist/{chunk-he7z7y9j.js → chunk-kk502yk2.js} +2 -2
  132. package/dist/{chunk-he7z7y9j.js.map → chunk-kk502yk2.js.map} +1 -1
  133. package/dist/{chunk-wsttx9rg.js → chunk-mrdarm2q.js} +2 -2
  134. package/dist/{chunk-wsttx9rg.js.map → chunk-mrdarm2q.js.map} +1 -1
  135. package/dist/chunk-mvtgx1mr.js +4 -0
  136. package/dist/{chunk-x78jrs4y.js.map → chunk-mvtgx1mr.js.map} +2 -2
  137. package/dist/{chunk-et4pv1b1.js → chunk-mx9y9mtx.js} +1 -1
  138. package/dist/chunk-nv7mv51r.js +6 -0
  139. package/dist/{chunk-61f4m5px.js.map → chunk-nv7mv51r.js.map} +2 -2
  140. package/dist/{chunk-cttmy1jp.js → chunk-p2fhtf5r.js} +3 -3
  141. package/dist/{chunk-cttmy1jp.js.map → chunk-p2fhtf5r.js.map} +1 -1
  142. package/dist/{chunk-w7jsh3xd.js → chunk-qtbf3w6w.js} +2 -2
  143. package/dist/{chunk-w7jsh3xd.js.map → chunk-qtbf3w6w.js.map} +1 -1
  144. package/dist/chunk-qx87cdfg.js +5 -0
  145. package/dist/chunk-qx87cdfg.js.map +10 -0
  146. package/dist/{chunk-1kr25rcg.js → chunk-qyp652jz.js} +3 -3
  147. package/dist/{chunk-1kr25rcg.js.map → chunk-qyp652jz.js.map} +1 -1
  148. package/dist/{chunk-8b2tw2yp.js → chunk-rend2sbk.js} +1 -1
  149. package/dist/chunk-rx2shb3t.js +25 -0
  150. package/dist/chunk-rx2shb3t.js.map +19 -0
  151. package/dist/{chunk-mwqg079k.js → chunk-ryzcfxq7.js} +2 -2
  152. package/dist/{chunk-mwqg079k.js.map → chunk-ryzcfxq7.js.map} +1 -1
  153. package/dist/{chunk-7tx5y712.js → chunk-s9rfgxj5.js} +2 -2
  154. package/dist/{chunk-7tx5y712.js.map → chunk-s9rfgxj5.js.map} +1 -1
  155. package/dist/{chunk-1c1d0e60.js → chunk-scbvv2e4.js} +3 -3
  156. package/dist/{chunk-1c1d0e60.js.map → chunk-scbvv2e4.js.map} +1 -1
  157. package/dist/chunk-sj8jp4p9.js +24 -0
  158. package/dist/{chunk-k9wgtrc5.js.map → chunk-sj8jp4p9.js.map} +2 -2
  159. package/dist/{chunk-pwmgqq7z.js → chunk-teny6xkw.js} +2 -2
  160. package/dist/{chunk-pwmgqq7z.js.map → chunk-teny6xkw.js.map} +1 -1
  161. package/dist/{chunk-09ypnhjv.js → chunk-tmrmwthr.js} +2 -2
  162. package/dist/{chunk-09ypnhjv.js.map → chunk-tmrmwthr.js.map} +1 -1
  163. package/dist/{chunk-h4sw6nt3.js → chunk-vgdcz7tk.js} +3 -3
  164. package/dist/{chunk-h4sw6nt3.js.map → chunk-vgdcz7tk.js.map} +1 -1
  165. package/dist/{chunk-xk930yaw.js → chunk-wexs11yy.js} +2 -2
  166. package/dist/{chunk-xk930yaw.js.map → chunk-wexs11yy.js.map} +1 -1
  167. package/dist/{chunk-k1xt2tw7.js → chunk-xs4c2nvz.js} +2 -2
  168. package/dist/{chunk-k1xt2tw7.js.map → chunk-xs4c2nvz.js.map} +1 -1
  169. package/dist/{chunk-1va15sfq.js → chunk-xv74rhay.js} +2 -2
  170. package/dist/{chunk-1va15sfq.js.map → chunk-xv74rhay.js.map} +1 -1
  171. package/dist/{chunk-sq2wkynk.js → chunk-yv1psptb.js} +2 -2
  172. package/dist/{chunk-sq2wkynk.js.map → chunk-yv1psptb.js.map} +1 -1
  173. package/dist/{chunk-tk5q8hkv.js → chunk-zfter1x0.js} +4 -4
  174. package/dist/{chunk-tk5q8hkv.js.map → chunk-zfter1x0.js.map} +1 -1
  175. package/dist/client/index.d.ts +2 -0
  176. package/dist/client/index.d.ts.map +1 -1
  177. package/dist/client/index.js +214 -1
  178. package/dist/client/index.js.map +1 -1
  179. package/dist/client/useSubscription.d.ts +70 -0
  180. package/dist/client/useSubscription.d.ts.map +1 -0
  181. package/dist/config/index.js +1 -1
  182. package/dist/console/run.js +2 -2
  183. package/dist/console/run.js.map +2 -2
  184. package/dist/container/index.js +2 -2
  185. package/dist/container/index.js.map +1 -1
  186. package/dist/database/index.js +2 -2
  187. package/dist/database/index.js.map +1 -1
  188. package/dist/email/index.js +2 -2
  189. package/dist/email/index.js.map +1 -1
  190. package/dist/facades/ChangeFeed.d.ts +42 -0
  191. package/dist/facades/ChangeFeed.d.ts.map +1 -0
  192. package/dist/facades/index.d.ts +1 -0
  193. package/dist/facades/index.d.ts.map +1 -1
  194. package/dist/facades/index.js +2 -2
  195. package/dist/facades/index.js.map +1 -1
  196. package/dist/foundation/index.js +2 -2
  197. package/dist/foundation/index.js.map +1 -1
  198. package/dist/http/ResourcePolicy.d.ts +141 -0
  199. package/dist/http/ResourcePolicy.d.ts.map +1 -0
  200. package/dist/http/errors.d.ts +13 -0
  201. package/dist/http/errors.d.ts.map +1 -1
  202. package/dist/http/index.d.ts +2 -1
  203. package/dist/http/index.d.ts.map +1 -1
  204. package/dist/http/index.js +2 -2
  205. package/dist/http/index.js.map +1 -1
  206. package/dist/i18n/dictionaryRuntime.js +2 -2
  207. package/dist/i18n/dictionaryRuntime.js.map +1 -1
  208. package/dist/i18n/index.js +2 -2
  209. package/dist/i18n/index.js.map +2 -2
  210. package/dist/kernel/index.js +3 -3
  211. package/dist/kernel/index.js.map +3 -3
  212. package/dist/kernel/providers.d.ts.map +1 -1
  213. package/dist/orm/index.js +2 -2
  214. package/dist/orm/index.js.map +1 -1
  215. package/dist/server/index.js +2 -2
  216. package/dist/server/index.js.map +1 -1
  217. package/dist/services/change-feed/ChangeFeedDriver.d.ts +94 -0
  218. package/dist/services/change-feed/ChangeFeedDriver.d.ts.map +1 -0
  219. package/dist/services/change-feed/ChangeFeedManager.d.ts +166 -0
  220. package/dist/services/change-feed/ChangeFeedManager.d.ts.map +1 -0
  221. package/dist/services/change-feed/ChangeFeedServiceProvider.d.ts +11 -0
  222. package/dist/services/change-feed/ChangeFeedServiceProvider.d.ts.map +1 -0
  223. package/dist/services/change-feed/DatabaseChangeFeedDriver.d.ts +84 -0
  224. package/dist/services/change-feed/DatabaseChangeFeedDriver.d.ts.map +1 -0
  225. package/dist/services/change-feed/MemoryChangeFeedDriver.d.ts +26 -0
  226. package/dist/services/change-feed/MemoryChangeFeedDriver.d.ts.map +1 -0
  227. package/dist/services/change-feed/changeFeedDriverContract.d.ts +8 -0
  228. package/dist/services/change-feed/changeFeedDriverContract.d.ts.map +1 -0
  229. package/dist/services/change-feed/config.d.ts +42 -0
  230. package/dist/services/change-feed/config.d.ts.map +1 -0
  231. package/dist/services/change-feed/cursor.d.ts +17 -0
  232. package/dist/services/change-feed/cursor.d.ts.map +1 -0
  233. package/dist/services/change-feed/postgresListen.d.ts +30 -0
  234. package/dist/services/change-feed/postgresListen.d.ts.map +1 -0
  235. package/dist/services/change-feed/stream.d.ts +16 -0
  236. package/dist/services/change-feed/stream.d.ts.map +1 -0
  237. package/dist/services/change-feed/wire.d.ts +20 -0
  238. package/dist/services/change-feed/wire.d.ts.map +1 -0
  239. package/dist/services/index.d.ts +9 -0
  240. package/dist/services/index.d.ts.map +1 -1
  241. package/dist/services/index.js +3 -3
  242. package/dist/services/index.js.map +2 -2
  243. package/dist/services/queue/work.js +2 -2
  244. package/dist/services/queue/work.js.map +1 -1
  245. package/dist/services/router/ViewRouteDispatcher.d.ts +16 -0
  246. package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
  247. package/dist/stats/route-table.js +1 -1
  248. package/dist/support/index.js +2 -2
  249. package/dist/support/index.js.map +1 -1
  250. package/dist/vitest/index.js +1 -1
  251. package/package.json +6 -2
  252. package/skills/gemi-react-best-practices/rules/controller-authorize-every-tenant-read.md +16 -1
  253. package/dist/chunk-11fsn5mr.js +0 -5
  254. package/dist/chunk-61f4m5px.js +0 -6
  255. package/dist/chunk-h3864a8z.js +0 -17
  256. package/dist/chunk-hn67spz6.js +0 -5
  257. package/dist/chunk-k9wgtrc5.js +0 -24
  258. package/dist/chunk-mb7q7s0a.js +0 -19
  259. package/dist/chunk-mn5xw79b.js +0 -9
  260. package/dist/chunk-x78jrs4y.js +0 -4
  261. /package/dist/{chunk-0sjh5v1n.js.map → chunk-53bek7sp.js.map} +0 -0
  262. /package/dist/{chunk-td8tha3j.js.map → chunk-es487acc.js.map} +0 -0
  263. /package/dist/{chunk-et4pv1b1.js.map → chunk-mx9y9mtx.js.map} +0 -0
  264. /package/dist/{chunk-8b2tw2yp.js.map → chunk-rend2sbk.js.map} +0 -0
@@ -0,0 +1,259 @@
1
+ import { Job } from "../../services/queue/Job";
2
+ import type { GeneratedAttachment, ToolGenerateImageParams, ToolEditImageParams } from "../Agent";
3
+ import { type GenerateParams, type GenerateResult } from "../generate";
4
+ import type { ImageModel } from "../ImageModel";
5
+ import { ToolError } from "../redact";
6
+ import type { Infer, Schema } from "../Schema";
7
+ import { type Attachment, type AttachmentStorage, type AttachmentStore, ScopedAttachments } from "../store/Attachments";
8
+ import type { AgentError, Usage } from "../types";
9
+ import { type AgentJobRecord, type AgentJobStore } from "./AgentJobStore";
10
+ declare const HANDLE: unique symbol;
11
+ /**
12
+ * What `ctx.jobs.start` and `ctx.jobs.track` answer, and what a tool returns to
13
+ * say "this call goes on in the background" (#461).
14
+ *
15
+ * Returning it is what makes the call's result `running` rather than `ok`: the
16
+ * model reads that the job started and is told not to start it again, the turn
17
+ * goes on and ends as usual, and when the job settles the controller renders
18
+ * its outcome over that result the next time it loads the thread.
19
+ *
20
+ * `Output` is the job's settled output, and it is what the tool's output type
21
+ * becomes, so a client's `ToolShapes` see the job's result as the tool's.
22
+ */
23
+ export declare class JobHandle<Output = unknown> {
24
+ /** The job's id. Hand it to whatever settles a tracked job. */
25
+ readonly id: string;
26
+ readonly toolCallId: string;
27
+ readonly summary: unknown;
28
+ /** Epoch milliseconds, on the job store's clock. */
29
+ readonly deadlineAt: number;
30
+ /** Phantom: the settled output's type. Never set. */
31
+ readonly $output: Output;
32
+ readonly [HANDLE]: true;
33
+ constructor(
34
+ /** The job's id. Hand it to whatever settles a tracked job. */
35
+ id: string, toolCallId: string, summary: unknown,
36
+ /** Epoch milliseconds, on the job store's clock. */
37
+ deadlineAt: number);
38
+ }
39
+ /** Whether a tool's return value is a `JobHandle`, across copies of the module. */
40
+ export declare function isJobHandle(value: unknown): value is JobHandle;
41
+ /**
42
+ * `ctx.jobs.start` or `track` from a run that has nowhere to settle a job
43
+ * into: a stateless turn, a run started without a job store, or a sub-run.
44
+ *
45
+ * A `ToolError`, so the model reads why the tool could not go to the
46
+ * background and can say so, rather than being told the tool broke.
47
+ */
48
+ export declare class JobsRequireThreadError extends ToolError {
49
+ readonly code: "jobs_require_thread";
50
+ constructor(message: string);
51
+ }
52
+ /** What a job settles with. */
53
+ export type AgentJobOutcome = {
54
+ output: unknown;
55
+ usage?: Usage;
56
+ } | {
57
+ error: string | Error | (Pick<AgentError, "message"> & Partial<AgentError>);
58
+ usage?: Usage;
59
+ };
60
+ /**
61
+ * Background jobs, from anywhere in the app: settle one, fail one, look one up.
62
+ *
63
+ * PROCESS-WIDE, and that is forced. A job is started by a tool inside a run,
64
+ * and settled by a queue worker, a provider's webhook, a poller or the deadline
65
+ * sweep, none of which has a controller to read a store from. So the store is
66
+ * set once, at boot, for every one of them:
67
+ *
68
+ * AgentJobs.use(new DatabaseAgentJobStore(app(DatabaseManager).connection()));
69
+ *
70
+ * Until then it is a `MemoryAgentJobStore`, which works in one process and
71
+ * forgets on restart.
72
+ */
73
+ export declare const AgentJobs: {
74
+ /** The store every part of the feature reads and writes. */
75
+ readonly store: AgentJobStore;
76
+ /** Sets the store. Call it once, at boot, in every process that starts or runs jobs. */
77
+ use(store: AgentJobStore): void;
78
+ get(id: string): Promise<AgentJobRecord | null>;
79
+ /**
80
+ * Settles a running job with its output or its error, and answers whether
81
+ * this call did it.
82
+ *
83
+ * COMPARE-AND-SET FROM `running`. The first settle wins and every later one
84
+ * answers `false` and changes nothing, so a webhook, a poller and the
85
+ * deadline sweep can all race on one job. A job the deadline sweep has
86
+ * already failed stays failed: a late result is refused, so the model never
87
+ * sees a job flip from failed to done.
88
+ *
89
+ * An error given as a `ToolError`, a string or an `AgentError`-like object is
90
+ * shown to the model as it is. Any other `Error` is logged in full and the
91
+ * model is told only that the job failed, as for a tool that throws (#446).
92
+ */
93
+ settle(id: string, outcome: AgentJobOutcome): Promise<boolean>;
94
+ /** `settle(id, { error })`. */
95
+ fail(id: string, error: string | Error | AgentError): Promise<boolean>;
96
+ /**
97
+ * The deadline sweep: fails every running job whose deadline has passed
98
+ * with code `"timeout"`, and answers how many it failed.
99
+ *
100
+ * Compare-and-set like every settle, so it is safe to run on every
101
+ * instance at once, and a result that arrives after it is refused. Run it
102
+ * every minute with `AgentJobDeadlineSweep`; the controller also checks a
103
+ * thread's jobs when it loads the thread, so an app without cron still sees
104
+ * overdue jobs fail, just later. The job's queue worker is not stopped: what
105
+ * it returns afterwards is dropped.
106
+ */
107
+ sweep(options?: {
108
+ limit?: number;
109
+ }): Promise<number>;
110
+ };
111
+ /** The store's clock, or this process's for a store without one. */
112
+ export declare function clockOf(store: AgentJobStore): Promise<number>;
113
+ /** Fails a running job for its deadline. Compare-and-set: false when it had settled. */
114
+ export declare function expire(store: AgentJobStore, record: AgentJobRecord): Promise<boolean>;
115
+ /** Options for `ctx.jobs.start` and `ctx.jobs.track`. */
116
+ export type StartJobOptions = {
117
+ /**
118
+ * What the model and the UI see while the job runs, in place of a result:
119
+ * which images, which pages. Plain data, and keep it small, since it is in
120
+ * the history on every later turn.
121
+ */
122
+ summary?: unknown;
123
+ /**
124
+ * How long the job may run, in milliseconds. Defaults to the tool's
125
+ * `async.deadlineMs`, else an hour. A job still running then is failed with
126
+ * code `"timeout"` by the deadline sweep, and a later result is refused.
127
+ */
128
+ deadlineMs?: number;
129
+ };
130
+ /** A tool's `ctx.jobs`. See `ToolContext.jobs`. */
131
+ export interface ToolJobs {
132
+ /**
133
+ * Records a background job for this tool call and queues `job` to do it.
134
+ * Return the handle from `execute` to make the call's result `running`.
135
+ *
136
+ * At least once, like every queued job: `job.run` may run again after a
137
+ * crash, so make it idempotent. Only on a threaded run (a turn with a
138
+ * `threadId` through `AgentController`), and only from a top-level tool.
139
+ */
140
+ start<A, O>(job: AgentJobClass<A, O>, args: A, options?: StartJobOptions): Promise<JobHandle<O>>;
141
+ /**
142
+ * Records a background job that something else settles: a provider's
143
+ * webhook, a poller. Pass `handle.id` to it, and call
144
+ * `AgentJobs.settle(id, { output })` when the work is done.
145
+ */
146
+ track<O = unknown>(options?: StartJobOptions): Promise<JobHandle<O>>;
147
+ }
148
+ /** What a run that may start jobs is given. `AgentController` passes it on a threaded turn. */
149
+ export type RunJobs = {
150
+ /** The run's owner (`runOwner`), recorded on each job. */
151
+ owner: string | null;
152
+ };
153
+ /** The longest a job runs when nothing says otherwise. */
154
+ export declare const DEFAULT_JOB_DEADLINE_MS: number;
155
+ /** @internal `ctx.jobs` for one tool call. Built by the run, per call. */
156
+ export declare function toolJobs(params: {
157
+ jobs: RunJobs | undefined;
158
+ threadId: string | undefined;
159
+ runId: string;
160
+ toolCallId: string;
161
+ toolName: string;
162
+ depth: number;
163
+ /** The tool's `async` declaration; `undefined` for a tool without one. */
164
+ async: {
165
+ deadlineMs?: number;
166
+ } | undefined;
167
+ attachments: ScopedAttachments | null;
168
+ }): ToolJobs;
169
+ /** An `AgentJob` subclass, as `ctx.jobs.start` takes it. */
170
+ export type AgentJobClass<A, O> = new () => AgentJob<A, O>;
171
+ /** `generateImage`'s params inside a job: as in a tool, without `showModel` (there is no run to show). */
172
+ export type JobGenerateImageParams = Omit<ToolGenerateImageParams, "showModel">;
173
+ export type JobEditImageParams = Omit<ToolEditImageParams, "showModel">;
174
+ /** Attachments inside a job: the scope of the run that started it. */
175
+ export interface JobAttachments {
176
+ put(blob: Blob, params?: {
177
+ name?: string;
178
+ mimeType?: string;
179
+ }): Promise<Attachment>;
180
+ get(id: string): Promise<Attachment>;
181
+ read: ScopedAttachments["read"];
182
+ file(id: string): Promise<File>;
183
+ }
184
+ /**
185
+ * What `AgentJob.run` is handed beside its arguments: the parts of a tool's
186
+ * `ToolContext` that still mean something with no run around them.
187
+ */
188
+ export interface AgentJobContext {
189
+ /** The job's id (`ajob_…`). */
190
+ readonly id: string;
191
+ readonly threadId: string;
192
+ readonly toolCallId: string;
193
+ readonly toolName: string;
194
+ /** The `runOwner` of the run that started it. */
195
+ readonly owner: string | null;
196
+ readonly summary: unknown;
197
+ /** Not aborted yet: cancellation comes with a later release (#461, phase 4). */
198
+ readonly signal: AbortSignal;
199
+ /**
200
+ * The attachments of the run that started the job: what the tool's
201
+ * `ctx.attachments` was. Throws when that run had no attachment scope.
202
+ */
203
+ readonly attachments: JobAttachments;
204
+ /** `generate`, with its usage counted on the job. See `ToolContext.generate`. */
205
+ generate<O extends Schema<any>>(params: GenerateParams<O>): Promise<GenerateResult<Infer<O>>>;
206
+ /** Renders an image and stores it under the run's attachments. Usage is counted on the job. */
207
+ generateImage(model: ImageModel, params: JobGenerateImageParams): Promise<GeneratedAttachment>;
208
+ /** Edits images (bytes or attachment ids) and stores the result. Usage is counted on the job. */
209
+ editImage(model: ImageModel, params: JobEditImageParams): Promise<GeneratedAttachment>;
210
+ /** What this attempt has spent so far. */
211
+ readonly usage: Usage;
212
+ }
213
+ /**
214
+ * A queued job that settles a tool call (#461).
215
+ *
216
+ * class RenderImagesJob extends AgentJob<{ pageId: number; prompts: string[] }, { made: number }> {
217
+ * static name = "RenderImagesJob";
218
+ * async run({ pageId, prompts }, job) {
219
+ * for (const prompt of prompts) await job.generateImage(model, { prompt });
220
+ * return { made: prompts.length };
221
+ * }
222
+ * }
223
+ *
224
+ * A gemi `Job`, so it gets the queue's leases, retries, backoff and dead
225
+ * letters. Register it with the queue like any other job. What `run` returns
226
+ * settles the tool call `ok`; a throw on the last attempt settles it `error`.
227
+ * At least once: make `run` idempotent.
228
+ *
229
+ * Declare `run` as a method, not as an arrow-function field. Override
230
+ * `onDeadletter` only with a call to `super.onDeadletter`, which is what fails
231
+ * the job. `worker = true` is not supported. The queue hands `uniqueId`,
232
+ * `throttle`, `concurrency`, `onFail` and `onDeadletter` the envelope
233
+ * `{ jobId, args }`, not `args`.
234
+ */
235
+ export declare abstract class AgentJob<Args = unknown, Output = unknown> extends Job {
236
+ /** Phantom: the arguments' type. Never set. */
237
+ readonly $args: Args;
238
+ /** Phantom: the output's type. Never set. */
239
+ readonly $output: Output;
240
+ /**
241
+ * Where the job's `attachments` records live. Set it to what the
242
+ * controller's `attachments` is, as for the controller itself.
243
+ */
244
+ attachments: AttachmentStore;
245
+ /** Where the attachments' bytes live. Defaults to the app's `Storage`. */
246
+ attachmentStorage: AttachmentStorage;
247
+ abstract run(args: Args, job: AgentJobContext): Promise<Output> | Output;
248
+ constructor();
249
+ /**
250
+ * Fails the job once the queue has given up on it: its last attempt threw,
251
+ * it called `this.fail(error, { retry: false })`, or its process died on the
252
+ * last attempt.
253
+ */
254
+ onDeadletter(error: Error, ..._args: any[]): void;
255
+ /** @internal The queue-facing `run`: see the constructor. */
256
+ private $runEnvelope;
257
+ }
258
+ export {};
259
+ //# sourceMappingURL=AgentJob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentJob.d.ts","sourceRoot":"","sources":["../../../ai/jobs/AgentJob.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAE/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAClG,OAAO,EAAkB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAe,SAAS,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EACL,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EAGpB,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,aAAa,EAEnB,MAAM,iBAAiB,CAAC;AAIzB,QAAA,MAAM,MAAM,eAAkC,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,qBAAa,SAAS,CAAC,MAAM,GAAG,OAAO;IAMnC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM;IAV7B,qDAAqD;IACrD,SAAiB,OAAO,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAG,IAAI,CAAU;;IAGhC,+DAA+D;IACtD,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO;IACzB,oDAAoD;IAC3C,UAAU,EAAE,MAAM;CAE9B;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAID;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBAEnC,OAAO,EAAE,MAAM;CAI5B;AASD,+BAA+B;AAC/B,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAClC;IAAE,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEnG;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS;IACpB,4DAA4D;oBAC/C,aAAa;IAI1B,wFAAwF;eAC7E,aAAa,GAAG,IAAI;YAIvB,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAI/C;;;;;;;;;;;;;OAaG;eACc,MAAM,WAAW,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpE,+BAA+B;aAChB,MAAM,SAAS,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5E;;;;;;;;;;OAUG;oBACkB;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAQ,OAAO,CAAC,MAAM,CAAC;CAU/D,CAAC;AAEF,oEAAoE;AACpE,wBAAsB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAEnE;AAED,wFAAwF;AACxF,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAUrF;AAqED,yDAAyD;AACzD,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,mDAAmD;AACnD,MAAM,WAAW,QAAQ;IACvB;;;;;;;OAOG;IACH,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACjG;;;;OAIG;IACH,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CACtE;AAED,+FAA+F;AAC/F,MAAM,MAAM,OAAO,GAAG;IACpB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB,QAAc,CAAC;AAEnD,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,MAAM,EAAE;IAC/B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,KAAK,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAC3C,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACvC,GAAG,QAAQ,CA8FX;AAkBD,4DAA4D;AAC5D,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE3D,0GAA0G;AAC1G,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,uBAAuB,EAAE,WAAW,CAAC,CAAC;AAChF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;AAExE,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,iFAAiF;IACjF,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9F,+FAA+F;IAC/F,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/F,iGAAiG;IACjG,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvF,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,8BAAsB,QAAQ,CAAC,IAAI,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,CAAE,SAAQ,GAAG;IAC1E,+CAA+C;IAC/C,SAAiB,KAAK,EAAE,IAAI,CAAC;IAC7B,6CAA6C;IAC7C,SAAiB,OAAO,EAAE,MAAM,CAAC;IAEjC;;;OAGG;IACH,WAAW,EAAE,eAAe,CAA0B;IACtD,0EAA0E;IAC1E,iBAAiB,EAAE,iBAAiB,CAAW;IAE/C,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;IAYxE;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAQjD,6DAA6D;YAC/C,YAAY;CA0B3B"}
@@ -0,0 +1,18 @@
1
+ import { CronJob } from "../../services/cron/CronJob";
2
+ /**
3
+ * Fails background jobs that ran past their deadline (#461), every minute.
4
+ *
5
+ * Schedule it by exporting it from a file under `app/cron`:
6
+ *
7
+ * export { AgentJobDeadlineSweep } from "gemi/ai";
8
+ *
9
+ * Safe on every instance at once: each job is failed by compare-and-set. An
10
+ * app without it still sees an overdue job fail, when the controller next
11
+ * loads the job's thread.
12
+ */
13
+ export declare class AgentJobDeadlineSweep extends CronJob {
14
+ name: string;
15
+ cron: string;
16
+ callback(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=AgentJobDeadlineSweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentJobDeadlineSweep.d.ts","sourceRoot":"","sources":["../../../ai/jobs/AgentJobDeadlineSweep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGtD;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,SAAQ,OAAO;IAChD,IAAI,SAA2B;IAC/B,IAAI,SAAe;IAEb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC"}
@@ -0,0 +1,141 @@
1
+ import type { AgentError, Usage } from "../types";
2
+ /**
3
+ * Where a background job stands (#461).
4
+ *
5
+ * `running` until something settles it; `ok` and `error` are final. A job
6
+ * moves out of `running` once, by compare-and-set (`AgentJobStore.transition`),
7
+ * so a queue worker, a provider's webhook, a poller and the deadline sweep can
8
+ * all race to settle the same job and exactly one of them wins.
9
+ */
10
+ export type AgentJobState = "running" | "ok" | "error";
11
+ /**
12
+ * One background job, as the job store keeps it.
13
+ *
14
+ * The record is the job's state, and it is NOT the tool result. The tool
15
+ * result in the thread says `running` and points here by `id`; the controller
16
+ * renders the record's current state over it whenever it loads the thread (see
17
+ * `overlayJobs`). The record is kept apart from the messages because a live
18
+ * run writes whole messages to the store, and a job settling during that run
19
+ * would race those writes and lose.
20
+ */
21
+ export type AgentJobRecord = {
22
+ /** `ajob_…`. Handed to the app (`JobHandle.id`) to settle a tracked job. */
23
+ id: string;
24
+ threadId: string;
25
+ /** The run whose tool started the job. */
26
+ runId: string;
27
+ /** The tool call whose result this job settles. */
28
+ toolCallId: string;
29
+ toolName: string;
30
+ /** The `runOwner` of the run that started it, or `null` for an anonymous run. */
31
+ owner: string | null;
32
+ /** The `AgentJob` class's queue name, or `null` for a job made with `track`. */
33
+ job: string | null;
34
+ /**
35
+ * What the tool said about the job when it started it: what the model and
36
+ * the UI see while it runs. Server-owned, and kept small by the tool.
37
+ */
38
+ summary?: unknown;
39
+ state: AgentJobState;
40
+ /** The settled output, on `ok`. */
41
+ output?: unknown;
42
+ /** Why it failed, on `error`. Already redacted: this is what the model reads. */
43
+ error?: AgentError;
44
+ /** What the job spent on model and image calls. Counted on the turn that started it. */
45
+ usage?: Usage;
46
+ /**
47
+ * Set when the job's tool result never reached the thread: the run died
48
+ * after the job started and before the result was stored. The job still
49
+ * runs and settles; nothing in the thread shows it.
50
+ */
51
+ orphaned?: true;
52
+ /**
53
+ * The attachment scope key of the run that started the job, so the job's
54
+ * `attachments` are the ones the tool would have had. `null` when the run
55
+ * had none.
56
+ */
57
+ attachmentScope: string | null;
58
+ /** Epoch milliseconds, on the store's clock. */
59
+ createdAt: number;
60
+ updatedAt: number;
61
+ /** When the deadline sweep fails the job if it is still running. */
62
+ deadlineAt: number;
63
+ settledAt?: number;
64
+ };
65
+ /** What `create` is given: the record minus what the store stamps. */
66
+ export type NewAgentJobRecord = Omit<AgentJobRecord, "state" | "createdAt" | "updatedAt" | "deadlineAt" | "settledAt"> & {
67
+ /** How long from now the job may run, in milliseconds. */
68
+ deadlineMs: number;
69
+ };
70
+ /** The fields a transition may write. `id`, the thread and the call never change. */
71
+ export type AgentJobUpdate = Partial<Pick<AgentJobRecord, "state" | "output" | "error" | "usage" | "orphaned" | "settledAt">>;
72
+ /**
73
+ * Where background jobs live.
74
+ *
75
+ * `MemoryAgentJobStore` is the default and is not durable. `DatabaseAgentJobStore`
76
+ * keeps them in a table. An app that already has a jobs table can implement
77
+ * this over it.
78
+ */
79
+ export interface AgentJobStore {
80
+ /** Writes a new `running` record and returns it as stored. */
81
+ create(job: NewAgentJobRecord): Promise<AgentJobRecord>;
82
+ get(id: string): Promise<AgentJobRecord | null>;
83
+ /**
84
+ * A thread's jobs, newest first. `states` filters, `limit` bounds. Each
85
+ * record is a copy the caller may keep.
86
+ */
87
+ listForThread(threadId: string, options?: {
88
+ states?: AgentJobState[];
89
+ limit?: number;
90
+ }): Promise<AgentJobRecord[]>;
91
+ /**
92
+ * Compare-and-set: applies `to` only when the job's state is one of `from`,
93
+ * and answers whether it did. Bumps `updatedAt`, and stamps `settledAt` when
94
+ * `to.state` moves the job out of `running`.
95
+ */
96
+ transition(id: string, from: AgentJobState[], to: AgentJobUpdate): Promise<boolean>;
97
+ /** Running jobs whose `deadlineAt` is at or before `now`, oldest deadline first. */
98
+ overdue(now: number, limit: number): Promise<AgentJobRecord[]>;
99
+ /**
100
+ * The store's clock, in epoch milliseconds. The deadline sweep compares
101
+ * `deadlineAt` against this rather than the process's clock. Optional: a
102
+ * store without one is compared against `Date.now()`.
103
+ */
104
+ now?(): Promise<number>;
105
+ /**
106
+ * Runs `fn` in a transaction, so `ctx.jobs.start` writes the record and
107
+ * queues the job together: both or neither. Optional: without it the record
108
+ * is written first, and a dispatch that fails then fails the record.
109
+ */
110
+ transaction?<T>(fn: () => Promise<T>): Promise<T>;
111
+ }
112
+ /**
113
+ * Jobs in a map, for as long as the process lives.
114
+ *
115
+ * NOT DURABLE, like `MemoryAgentStore`: a restart loses every record, and a
116
+ * job that was running is then lost too. The tool result that pointed at it
117
+ * reads as a lost job on the next turn. It is the default so that jobs work in
118
+ * development and tests without a table; use `DatabaseAgentJobStore` in
119
+ * production.
120
+ *
121
+ * It only works when the queue runs the jobs in this same process (the memory
122
+ * queue driver, or a database driver claiming here), since a worker in another
123
+ * process has a map of its own.
124
+ */
125
+ export declare class MemoryAgentJobStore implements AgentJobStore {
126
+ private jobs;
127
+ create(job: NewAgentJobRecord): Promise<AgentJobRecord>;
128
+ get(id: string): Promise<AgentJobRecord | null>;
129
+ listForThread(threadId: string, options?: {
130
+ states?: AgentJobState[];
131
+ limit?: number;
132
+ }): Promise<AgentJobRecord[]>;
133
+ transition(id: string, from: AgentJobState[], to: AgentJobUpdate): Promise<boolean>;
134
+ overdue(now: number, limit: number): Promise<AgentJobRecord[]>;
135
+ now(): Promise<number>;
136
+ /** Bounds a long-lived thread: running jobs are never dropped, settled ones oldest first. */
137
+ private trim;
138
+ }
139
+ /** Newest first, with the id as a tie-break so the order is stable. */
140
+ export declare function newestFirst(a: AgentJobRecord, b: AgentJobRecord): number;
141
+ //# sourceMappingURL=AgentJobStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentJobStore.d.ts","sourceRoot":"","sources":["../../../ai/jobs/AgentJobStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import type { DatabaseConnection } from "../../database/Connection";
2
+ import type { Dialect } from "../../database/dialect";
3
+ import type { AgentJobRecord, AgentJobState, AgentJobStore, AgentJobUpdate, NewAgentJobRecord } from "./AgentJobStore";
4
+ export type DatabaseAgentJobStoreOptions = {
5
+ /**
6
+ * The table. Default `gemi_agent_jobs`. A plain identifier (letters, digits
7
+ * and underscores), because it is spliced into every statement.
8
+ */
9
+ table?: string;
10
+ };
11
+ /**
12
+ * Background jobs (#461) in a table of the app's own database, so a job and
13
+ * its outcome outlive the process: a deploy in the middle of a render no
14
+ * longer loses it, and every instance sees the same state.
15
+ *
16
+ * Opt in, like the agent store:
17
+ *
18
+ * AgentJobs.use(new DatabaseAgentJobStore(app(DatabaseManager).connection()));
19
+ *
20
+ * Written for SQLite, Postgres and MySQL 8 / MariaDB 10.6+ in raw SQL, as the
21
+ * database queue driver is, and the table is the app's to create: add the
22
+ * Prisma model from the docs, or call `createTable()`.
23
+ *
24
+ * - **Compare-and-set** is `UPDATE … WHERE id = ? AND state IN (…)`, so two
25
+ * instances settling one job cannot both win.
26
+ * - **Time** is epoch milliseconds read from the database's clock, so the
27
+ * deadline sweep on any instance agrees on when a job is overdue.
28
+ * - **Transactions.** `ctx.jobs.start` writes the record and queues the job
29
+ * inside `transaction()`. On Postgres and MySQL, with the database queue
30
+ * driver on the same connection, both rows commit together or not at all.
31
+ * With any other queue the dispatch is held until the record has committed.
32
+ */
33
+ export declare class DatabaseAgentJobStore implements AgentJobStore {
34
+ readonly table: string;
35
+ private readonly sql;
36
+ private readonly dialect;
37
+ private readonly connection;
38
+ constructor(connection: Pick<DatabaseConnection, "sql" | "dialect"> & Partial<Pick<DatabaseConnection, "name">>, options?: DatabaseAgentJobStoreOptions);
39
+ /**
40
+ * Creates the table and its indexes if they do not exist: the DDL Prisma
41
+ * generates for the model in the docs. For tests and for an app that does
42
+ * not manage its schema with Prisma.
43
+ */
44
+ createTable(): Promise<void>;
45
+ /**
46
+ * Runs `fn` in a transaction on this store's connection, joining one that is
47
+ * already open on it. `ctx.jobs.start` writes the record and queues the job
48
+ * in here.
49
+ */
50
+ transaction<T>(fn: () => Promise<T>): Promise<T>;
51
+ create(job: NewAgentJobRecord): Promise<AgentJobRecord>;
52
+ get(id: string): Promise<AgentJobRecord | null>;
53
+ listForThread(threadId: string, options?: {
54
+ states?: AgentJobState[];
55
+ limit?: number;
56
+ }): Promise<AgentJobRecord[]>;
57
+ transition(id: string, from: AgentJobState[], to: AgentJobUpdate): Promise<boolean>;
58
+ overdue(now: number, limit: number): Promise<AgentJobRecord[]>;
59
+ now(): Promise<number>;
60
+ /**
61
+ * Deletes settled jobs that settled more than `olderThanMs` ago, and answers
62
+ * how many. A settled result is written back into the thread on the next
63
+ * turn, after which the record is only history; nothing removes it unless
64
+ * this is called, from a cron job say. Running jobs are never pruned.
65
+ */
66
+ prune(olderThanMs: number): Promise<number>;
67
+ /** The open ORM transaction, when it is on this store's connection. */
68
+ private joinable;
69
+ /** Read at each call and never kept: a stored transaction handle outlives its transaction. */
70
+ private q;
71
+ private column;
72
+ private name;
73
+ /** The database's clock, in epoch milliseconds. As in `DatabaseQueueDriver`. */
74
+ private clock;
75
+ private ms;
76
+ }
77
+ /**
78
+ * The table as Prisma generates it for the model in the docs, with
79
+ * `IF NOT EXISTS` added.
80
+ */
81
+ export declare function createAgentJobsTableStatements(dialect: Dialect, table: string): string[];
82
+ //# sourceMappingURL=DatabaseAgentJobStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseAgentJobStore.d.ts","sourceRoot":"","sources":["../../../ai/jobs/DatabaseAgentJobStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAG9C,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,EAC3C,OAAO,GAAE,4BAAiC;IAc5C;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC;;;;OAIG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAOhD,MAAM,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBvD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAM/C,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GACzD,OAAO,CAAC,cAAc,EAAE,CAAC;IAwBtB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BnF,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAW9D,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAM5B;;;;;OAKG;IACG,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASjD,uEAAuE;IACvE,OAAO,CAAC,QAAQ;IAOhB,8FAA8F;IAC9F,OAAO,CAAC,CAAC;IAIT,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,IAAI;IAKZ,gFAAgF;IAChF,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,EAAE;CAMX;AAqDD;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAyDxF"}
@@ -0,0 +1,31 @@
1
+ import type { AgentJobRecord } from "./AgentJobStore";
2
+ /** How many jobs the `<jobs>` block lists by default. */
3
+ export declare const DEFAULT_JOBS_CONTEXT_MAX = 20;
4
+ /** `Agent.create({ jobs })`. */
5
+ export type AgentJobsOptions = {
6
+ /**
7
+ * The `<jobs>` block added to the system prompt on a thread that has
8
+ * background jobs: at most `max` of them (default 20), running ones first,
9
+ * then the newest settled. `false` leaves it out.
10
+ */
11
+ contextBlock?: {
12
+ max?: number;
13
+ } | false;
14
+ };
15
+ /**
16
+ * The `<jobs>` block (#461): what the model is told about the thread's
17
+ * background jobs on every turn, beside the tool results in the history.
18
+ *
19
+ * The history already shows each job's call and its `running` or settled
20
+ * result. The block is for what the history cannot show: a job whose result
21
+ * never reached the thread (an orphan), and a list in one place, so a model
22
+ * asked to "make the images" sees that a job for them is already running
23
+ * rather than starting another.
24
+ *
25
+ * Bounded by count, `max`, running before settled and newest first inside
26
+ * each. Times are absolute (UTC) rather than ages, so the block is the same
27
+ * text from one turn to the next until a job starts or settles, and the
28
+ * prompt cache holds in between. `null` when there is nothing to list.
29
+ */
30
+ export declare function renderJobsBlock(jobs: AgentJobRecord[], max: number): string | null;
31
+ //# sourceMappingURL=contextBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextBlock.d.ts","sourceRoot":"","sources":["../../../ai/jobs/contextBlock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,yDAAyD;AACzD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,gCAAgC;AAChC,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;CACzC,CAAC;AAKF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmClF"}
@@ -0,0 +1,6 @@
1
+ export { AgentJob, type AgentJobClass, type AgentJobContext, type AgentJobOutcome, AgentJobs, DEFAULT_JOB_DEADLINE_MS, type JobAttachments, type JobEditImageParams, type JobGenerateImageParams, JobHandle, JobsRequireThreadError, type RunJobs, type StartJobOptions, type ToolJobs, } from "./AgentJob";
2
+ export { type AgentJobRecord, type AgentJobState, type AgentJobStore, type AgentJobUpdate, MemoryAgentJobStore, type NewAgentJobRecord, } from "./AgentJobStore";
3
+ export { AgentJobDeadlineSweep } from "./AgentJobDeadlineSweep";
4
+ export { type AgentJobsOptions, DEFAULT_JOBS_CONTEXT_MAX } from "./contextBlock";
5
+ export { DatabaseAgentJobStore, type DatabaseAgentJobStoreOptions } from "./DatabaseAgentJobStore";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../ai/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,SAAS,EACT,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,SAAS,EACT,sBAAsB,EACtB,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,KAAK,QAAQ,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,mBAAmB,EACnB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,KAAK,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,KAAK,4BAA4B,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { Schema } from "../Schema";
2
+ import type { AgentMessage } from "../types";
3
+ import type { AgentJobRecord, AgentJobStore } from "./AgentJobStore";
4
+ /**
5
+ * The thread with each background job's current state rendered over the tool
6
+ * result that points at it (#461).
7
+ *
8
+ * A tool that returned a `JobHandle` left a `running` result in the thread.
9
+ * The job settles later, into the job store, and never into the messages: a
10
+ * live run writes whole messages, and a settle racing those writes would be
11
+ * overwritten by the run's stale copy. So the messages are brought up to date
12
+ * here, when the thread is loaded, which `AgentController` does under the
13
+ * thread's lock before a turn and without writing for `readThread`.
14
+ *
15
+ * - A `running` result whose job settled becomes the job's `ok` or `error`
16
+ * result, in place, with the job still named on it (`job`).
17
+ * - A `running` result whose job is still running is left exactly as it is,
18
+ * so the request stays byte-identical, and the prompt cache with it, until
19
+ * the job settles.
20
+ * - A `running` result whose job the store does not have becomes an `error`:
21
+ * the record was lost (a memory store across a restart), and the work may or
22
+ * may not have happened.
23
+ *
24
+ * `settled` is the messages that changed, for the caller to write back, so
25
+ * the store converges and a job settled long ago costs nothing on later loads.
26
+ *
27
+ * `orphans` are jobs whose tool result never reached the thread: the run died
28
+ * between starting the job and storing the result. They are found among the
29
+ * thread's newest jobs, only once the run that started them is gone, and only
30
+ * the ones not marked yet; the caller marks them (`orphaned`).
31
+ */
32
+ export declare function overlayJobs(messages: AgentMessage[], params: {
33
+ threadId: string;
34
+ store: AgentJobStore;
35
+ isRunLive: (runId: string) => boolean | Promise<boolean>;
36
+ /** The tool's output schema, to check a settled output against. */
37
+ outputSchemaFor?: (toolName: string) => Schema<any> | undefined;
38
+ /** How many of the thread's newest jobs to read. At least 50. */
39
+ scan?: number;
40
+ }): Promise<{
41
+ messages: AgentMessage[];
42
+ settled: AgentMessage[];
43
+ orphans: AgentJobRecord[];
44
+ /** The thread's newest jobs, as they stand after this pass: for the `<jobs>` block. */
45
+ jobs: AgentJobRecord[];
46
+ }>;
47
+ /** Marks orphans found by `overlayJobs`. Never throws: it is bookkeeping. */
48
+ export declare function markOrphans(store: AgentJobStore, orphans: AgentJobRecord[], report: (error: unknown) => void): Promise<void>;
49
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../ai/jobs/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAe,YAAY,EAAkB,MAAM,UAAU,CAAC;AAE1E,OAAO,KAAK,EAAE,cAAc,EAAiB,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOpF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,YAAY,EAAE,EACxB,MAAM,EAAE;IACN,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,mEAAmE;IACnE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAChE,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACA,OAAO,CAAC;IACT,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,uFAAuF;IACvF,IAAI,EAAE,cAAc,EAAE,CAAC;CACxB,CAAC,CA2DD;AAED,6EAA6E;AAC7E,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,EAAE,EACzB,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAC/B,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../ai/providers/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAY,cAAc,EAAoB,MAAM,UAAU,CAAC;AAEzF;;;;;;;GAOG;AAKH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,oBAAoB,CAAA;CAAE,GACzD,gBAAgB,CAuDlB;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,EACxB,YAAY,EAAE,oBAAoB,EAClC,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GACnD,kBAAkB,EAAE,CAmJtB;AA4QD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAuB7D;AAuFD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GAAG,SAAS,EAC/D,YAAY,EAAE,oBAAoB,GACjC,aAAa,EAAE,CA2CjB"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../ai/providers/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAY,cAAc,EAAoB,MAAM,UAAU,CAAC;AAEzF;;;;;;;GAOG;AAKH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,oBAAoB,CAAA;CAAE,GACzD,gBAAgB,CAuDlB;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,EACxB,YAAY,EAAE,oBAAoB,EAClC,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GACnD,kBAAkB,EAAE,CAmJtB;AA4QD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAiC7D;AAuFD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GAAG,SAAS,EAC/D,YAAY,EAAE,oBAAoB,GACjC,aAAa,EAAE,CA2CjB"}