@sixb/core 0.1.6 → 0.1.7

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 (535) hide show
  1. package/dist/actions/index.js +37 -33
  2. package/dist/actions/index.js.map +1 -1
  3. package/dist/actions/worker.js +3 -3
  4. package/dist/agents/adapters.d.ts +33 -76
  5. package/dist/agents/adapters.d.ts.map +1 -1
  6. package/dist/agents/authority.d.ts +22 -6
  7. package/dist/agents/authority.d.ts.map +1 -1
  8. package/dist/agents/builders.d.ts +3 -11
  9. package/dist/agents/builders.d.ts.map +1 -1
  10. package/dist/agents/context.js +2 -2
  11. package/dist/agents/dispatch.d.ts +9 -1
  12. package/dist/agents/dispatch.d.ts.map +1 -1
  13. package/dist/agents/errors.d.ts +2 -2
  14. package/dist/agents/errors.d.ts.map +1 -1
  15. package/dist/agents/execution.d.ts +9 -10
  16. package/dist/agents/execution.d.ts.map +1 -1
  17. package/dist/agents/ids.d.ts +4 -0
  18. package/dist/agents/ids.d.ts.map +1 -1
  19. package/dist/agents/index.d.ts +13 -9
  20. package/dist/agents/index.d.ts.map +1 -1
  21. package/dist/agents/index.js +80 -68
  22. package/dist/agents/index.js.map +1 -1
  23. package/dist/agents/message.d.ts +17 -10
  24. package/dist/agents/message.d.ts.map +1 -1
  25. package/dist/agents/model-loop.d.ts +56 -0
  26. package/dist/agents/model-loop.d.ts.map +1 -0
  27. package/dist/agents/reference.d.ts +4 -0
  28. package/dist/agents/reference.d.ts.map +1 -0
  29. package/dist/agents/request.d.ts +10 -8
  30. package/dist/agents/request.d.ts.map +1 -1
  31. package/dist/agents/retired-config.d.ts +4 -0
  32. package/dist/agents/retired-config.d.ts.map +1 -0
  33. package/dist/agents/streams.d.ts +13 -8
  34. package/dist/agents/streams.d.ts.map +1 -1
  35. package/dist/agents/streams.js +7 -5
  36. package/dist/agents/streams.js.map +1 -1
  37. package/dist/agents/tool-catalog.d.ts +9 -0
  38. package/dist/agents/tool-catalog.d.ts.map +1 -0
  39. package/dist/agents/tool-definition.d.ts +1 -0
  40. package/dist/agents/tool-definition.d.ts.map +1 -1
  41. package/dist/agents/types.d.ts +31 -68
  42. package/dist/agents/types.d.ts.map +1 -1
  43. package/dist/agents/validation.d.ts +4 -10
  44. package/dist/agents/validation.d.ts.map +1 -1
  45. package/dist/ai-usage/execution.d.ts +53 -0
  46. package/dist/ai-usage/execution.d.ts.map +1 -0
  47. package/dist/ai-usage/index.d.ts +3 -0
  48. package/dist/ai-usage/index.d.ts.map +1 -0
  49. package/dist/auth/index.js +7 -7
  50. package/dist/authorization/decision.d.ts +5 -2
  51. package/dist/authorization/decision.d.ts.map +1 -1
  52. package/dist/authorization/grant-kinds.d.ts +24 -8
  53. package/dist/authorization/grant-kinds.d.ts.map +1 -1
  54. package/dist/authorization/index.d.ts +1 -1
  55. package/dist/authorization/index.d.ts.map +1 -1
  56. package/dist/authorization/index.js +8 -6
  57. package/dist/authorization/index.js.map +1 -1
  58. package/dist/authorization/resolve.d.ts +3 -3
  59. package/dist/authorization/resolve.d.ts.map +1 -1
  60. package/dist/authorization/types.d.ts +7 -5
  61. package/dist/authorization/types.d.ts.map +1 -1
  62. package/dist/blob-storage/browser.js +2 -2
  63. package/dist/blob-storage/index.js +3 -3
  64. package/dist/bootstrap/discovery.d.ts +1 -7
  65. package/dist/bootstrap/discovery.d.ts.map +1 -1
  66. package/dist/bootstrap/index.js +52 -48
  67. package/dist/bootstrap/index.js.map +1 -1
  68. package/dist/broker/index.js +2 -2
  69. package/dist/{chunk-zqysyfjt.js → chunk-08m3b6w8.js} +1 -1
  70. package/dist/{chunk-1g8negke.js → chunk-08twe8m6.js} +93 -8
  71. package/dist/chunk-08twe8m6.js.map +12 -0
  72. package/dist/{chunk-xkthy56g.js → chunk-1kamz6j0.js} +1 -1
  73. package/dist/{chunk-dy311asx.js → chunk-2b5qtban.js} +12 -12
  74. package/dist/{chunk-dy311asx.js.map → chunk-2b5qtban.js.map} +3 -3
  75. package/dist/{chunk-0172wgm9.js → chunk-2xns679x.js} +10 -2
  76. package/dist/{chunk-0172wgm9.js.map → chunk-2xns679x.js.map} +3 -3
  77. package/dist/{chunk-f83ka50g.js → chunk-37wk412q.js} +86 -28
  78. package/dist/{chunk-f83ka50g.js.map → chunk-37wk412q.js.map} +8 -8
  79. package/dist/{chunk-md8k0r54.js → chunk-3fqt22c4.js} +4 -4
  80. package/dist/{chunk-t9xghkva.js → chunk-3kv70xwp.js} +3 -2
  81. package/dist/{chunk-t9xghkva.js.map → chunk-3kv70xwp.js.map} +3 -3
  82. package/dist/{chunk-z3zp0bj1.js → chunk-407j3msh.js} +1 -1
  83. package/dist/{chunk-rhrbz7d4.js → chunk-4a849fr1.js} +1 -1
  84. package/dist/{chunk-62c7t4jc.js → chunk-4nxeacx7.js} +1 -1
  85. package/dist/{chunk-cy0n5dms.js → chunk-5jcdmjam.js} +1 -1
  86. package/dist/{chunk-819wnjz8.js → chunk-64sr682n.js} +7 -7
  87. package/dist/{chunk-t624af60.js → chunk-6ed5bwnd.js} +646 -67
  88. package/dist/{chunk-t624af60.js.map → chunk-6ed5bwnd.js.map} +10 -9
  89. package/dist/{chunk-x2yw73hy.js → chunk-7ds9620f.js} +1 -1
  90. package/dist/{chunk-dm72y8wt.js → chunk-7y0f6rf1.js} +29 -16
  91. package/dist/chunk-7y0f6rf1.js.map +10 -0
  92. package/dist/{chunk-72q2y8hn.js → chunk-8tsf6dmc.js} +2 -2
  93. package/dist/{chunk-nkbfrt0c.js → chunk-9aehf39w.js} +7 -7
  94. package/dist/{chunk-ezake7g1.js → chunk-agsvg9ar.js} +1 -1
  95. package/dist/{chunk-rdeagz6b.js → chunk-atmkaf60.js} +1 -1
  96. package/dist/{chunk-rdeagz6b.js.map → chunk-atmkaf60.js.map} +2 -2
  97. package/dist/chunk-c15dr03f.js +43 -0
  98. package/dist/chunk-c15dr03f.js.map +10 -0
  99. package/dist/{chunk-0hc5j867.js → chunk-d2ndstdf.js} +8 -6
  100. package/dist/{chunk-0hc5j867.js.map → chunk-d2ndstdf.js.map} +2 -2
  101. package/dist/{chunk-rnshztfq.js → chunk-d63tybny.js} +2 -2
  102. package/dist/{chunk-t0jjkep3.js → chunk-d8qkxt2v.js} +4 -2
  103. package/dist/chunk-d8qkxt2v.js.map +10 -0
  104. package/dist/{chunk-vybf6pkp.js → chunk-dbc80ad7.js} +1 -1
  105. package/dist/{chunk-4gz41why.js → chunk-dqn23610.js} +1 -1
  106. package/dist/{chunk-5sxb1168.js → chunk-e4rvtvpw.js} +13 -11
  107. package/dist/{chunk-5sxb1168.js.map → chunk-e4rvtvpw.js.map} +2 -2
  108. package/dist/{chunk-h9kxd41f.js → chunk-gbrpsx4m.js} +19 -6
  109. package/dist/chunk-gbrpsx4m.js.map +11 -0
  110. package/dist/{chunk-nva1xkjz.js → chunk-h0knpbz5.js} +468 -1236
  111. package/dist/chunk-h0knpbz5.js.map +38 -0
  112. package/dist/{chunk-tg5mee00.js → chunk-ha58tjtt.js} +6 -6
  113. package/dist/{chunk-f6erf2vv.js → chunk-hdz94br2.js} +2 -2
  114. package/dist/chunk-jecn6t54.js +307 -0
  115. package/dist/chunk-jecn6t54.js.map +12 -0
  116. package/dist/{chunk-dsrkgtnh.js → chunk-jq43kdvk.js} +1 -1
  117. package/dist/{chunk-wtmzkcht.js → chunk-k34z5rvh.js} +1 -1
  118. package/dist/{chunk-htq0qh7z.js → chunk-ka3a2ft3.js} +2 -2
  119. package/dist/{chunk-znagycq7.js → chunk-kt81c11h.js} +2 -2
  120. package/dist/chunk-n2arzn6e.js +1745 -0
  121. package/dist/chunk-n2arzn6e.js.map +20 -0
  122. package/dist/{chunk-f2rt4vkh.js → chunk-n2w475r0.js} +3 -3
  123. package/dist/{chunk-t8t39h7v.js → chunk-n6jxh8sw.js} +10 -2
  124. package/dist/chunk-n6jxh8sw.js.map +10 -0
  125. package/dist/{chunk-drjqm1aa.js → chunk-p03r0h5s.js} +310 -28
  126. package/dist/chunk-p03r0h5s.js.map +16 -0
  127. package/dist/chunk-p2vqaxkc.js +528 -0
  128. package/dist/chunk-p2vqaxkc.js.map +15 -0
  129. package/dist/{chunk-n4spznws.js → chunk-qjycjdj6.js} +84 -11
  130. package/dist/chunk-qjycjdj6.js.map +12 -0
  131. package/dist/chunk-qjzp9xyb.js +286 -0
  132. package/dist/chunk-qjzp9xyb.js.map +12 -0
  133. package/dist/{chunk-5gynx4xn.js → chunk-qv38twt8.js} +50 -69
  134. package/dist/{chunk-5gynx4xn.js.map → chunk-qv38twt8.js.map} +8 -8
  135. package/dist/{chunk-bhxaq2nn.js → chunk-qw9gvjv5.js} +1 -1
  136. package/dist/{chunk-8gv5z0zm.js → chunk-rp1mvzb4.js} +6 -6
  137. package/dist/{chunk-1e8m6yn3.js → chunk-rre42skh.js} +182 -18
  138. package/dist/chunk-rre42skh.js.map +39 -0
  139. package/dist/{chunk-ghteq96b.js → chunk-s5y30bc9.js} +2 -2
  140. package/dist/{chunk-a31h57d5.js → chunk-tn7xcs2n.js} +2 -2
  141. package/dist/{chunk-6gjqgd3d.js → chunk-tpnd31c1.js} +2 -1
  142. package/dist/chunk-tpnd31c1.js.map +11 -0
  143. package/dist/chunk-trxxmgnf.js +68 -0
  144. package/dist/chunk-trxxmgnf.js.map +11 -0
  145. package/dist/{chunk-e42bc6m3.js → chunk-vjjv9mrb.js} +2 -2
  146. package/dist/{chunk-8b55ygje.js → chunk-w3e09qqk.js} +1 -1
  147. package/dist/{chunk-ckxfnx7f.js → chunk-wjgm6jjt.js} +2 -2
  148. package/dist/{chunk-3j7573mj.js → chunk-x0qhkqje.js} +2 -2
  149. package/dist/{chunk-dysw7nsm.js → chunk-xdpwpkha.js} +2 -2
  150. package/dist/{chunk-a44d5zgd.js → chunk-y35ma3mj.js} +11 -16
  151. package/dist/{chunk-a44d5zgd.js.map → chunk-y35ma3mj.js.map} +3 -4
  152. package/dist/{chunk-qewtks41.js → chunk-z2sery1b.js} +64 -1
  153. package/dist/{chunk-qewtks41.js.map → chunk-z2sery1b.js.map} +3 -3
  154. package/dist/error-reporting/internal.js +4 -4
  155. package/dist/error-reporting/types.d.ts +7 -2
  156. package/dist/error-reporting/types.d.ts.map +1 -1
  157. package/dist/errors/catalog.d.ts +8 -0
  158. package/dist/errors/catalog.d.ts.map +1 -1
  159. package/dist/errors/internal.js +2 -2
  160. package/dist/events/index.js +4 -4
  161. package/dist/execution/agent.d.ts +18 -9
  162. package/dist/execution/agent.d.ts.map +1 -1
  163. package/dist/execution/agent.js +52 -43
  164. package/dist/execution/agent.js.map +1 -1
  165. package/dist/execution/authorization.d.ts +14 -4
  166. package/dist/execution/authorization.d.ts.map +1 -1
  167. package/dist/execution/primitive.js +45 -43
  168. package/dist/execution/primitive.js.map +2 -2
  169. package/dist/execution/request.d.ts +3 -1
  170. package/dist/execution/request.d.ts.map +1 -1
  171. package/dist/execution/request.js +46 -44
  172. package/dist/execution/request.js.map +3 -3
  173. package/dist/execution/types.d.ts +1 -1
  174. package/dist/execution/types.d.ts.map +1 -1
  175. package/dist/http/api-routes.d.ts.map +1 -1
  176. package/dist/http/index.js +1 -1
  177. package/dist/index.d.ts +9 -6
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +82 -77
  180. package/dist/index.js.map +1 -1
  181. package/dist/json.d.ts +2 -0
  182. package/dist/json.d.ts.map +1 -1
  183. package/dist/lake-storage/index.js +5 -5
  184. package/dist/logging/index.js +3 -3
  185. package/dist/logging/types.js +2 -2
  186. package/dist/materialization/index.js +2 -2
  187. package/dist/materializer/index.js +33 -29
  188. package/dist/materializer/index.js.map +1 -1
  189. package/dist/models/catalog.d.ts +40 -0
  190. package/dist/models/catalog.d.ts.map +1 -0
  191. package/dist/models/definitions.d.ts +25 -0
  192. package/dist/models/definitions.d.ts.map +1 -0
  193. package/dist/models/errors.d.ts +52 -0
  194. package/dist/models/errors.d.ts.map +1 -0
  195. package/dist/models/events.d.ts +192 -0
  196. package/dist/models/events.d.ts.map +1 -0
  197. package/dist/models/index.d.ts +17 -39
  198. package/dist/models/index.d.ts.map +1 -1
  199. package/dist/models/index.js +50 -0
  200. package/dist/models/index.js.map +9 -0
  201. package/dist/models/language-model.d.ts +90 -0
  202. package/dist/models/language-model.d.ts.map +1 -0
  203. package/dist/models/messages.d.ts +74 -0
  204. package/dist/models/messages.d.ts.map +1 -0
  205. package/dist/models/pricing.d.ts +69 -0
  206. package/dist/models/pricing.d.ts.map +1 -0
  207. package/dist/models/rate-card.d.ts +24 -0
  208. package/dist/models/rate-card.d.ts.map +1 -0
  209. package/dist/models/tools.d.ts +24 -0
  210. package/dist/models/tools.d.ts.map +1 -0
  211. package/dist/objects/index.js +38 -34
  212. package/dist/objects/index.js.map +1 -1
  213. package/dist/objects/query/index.js +32 -28
  214. package/dist/objects/query/index.js.map +1 -1
  215. package/dist/ontology/index.js +5 -5
  216. package/dist/ontology/internal.js +4 -4
  217. package/dist/pipelines/index.js +37 -35
  218. package/dist/pipelines/index.js.map +1 -1
  219. package/dist/projections/internal.js +35 -31
  220. package/dist/projections/internal.js.map +1 -1
  221. package/dist/queues/in-memory.d.ts +3 -2
  222. package/dist/queues/in-memory.d.ts.map +1 -1
  223. package/dist/queues/index.d.ts +3 -1
  224. package/dist/queues/index.d.ts.map +1 -1
  225. package/dist/queues/index.js +1 -1
  226. package/dist/queues/types.d.ts +15 -3
  227. package/dist/queues/types.d.ts.map +1 -1
  228. package/dist/runtime/create.d.ts +4 -4
  229. package/dist/runtime/create.d.ts.map +1 -1
  230. package/dist/runtime/definitions.d.ts +2 -2
  231. package/dist/runtime/definitions.d.ts.map +1 -1
  232. package/dist/runtime/host.d.ts +3 -2
  233. package/dist/runtime/host.d.ts.map +1 -1
  234. package/dist/runtime/resolve-definitions.d.ts +2 -2
  235. package/dist/runtime/resolve-definitions.d.ts.map +1 -1
  236. package/dist/runtime/sixb.d.ts +4 -2
  237. package/dist/runtime/sixb.d.ts.map +1 -1
  238. package/dist/security/every.d.ts +1 -4
  239. package/dist/security/every.d.ts.map +1 -1
  240. package/dist/security/grants.d.ts +6 -5
  241. package/dist/security/grants.d.ts.map +1 -1
  242. package/dist/security/index.d.ts +1 -1
  243. package/dist/security/index.d.ts.map +1 -1
  244. package/dist/security/registry.d.ts +1 -1
  245. package/dist/security/registry.d.ts.map +1 -1
  246. package/dist/security/types.d.ts +13 -5
  247. package/dist/security/types.d.ts.map +1 -1
  248. package/dist/security/validation.d.ts +4 -2
  249. package/dist/security/validation.d.ts.map +1 -1
  250. package/dist/storage/action-runs/failure.js +3 -3
  251. package/dist/storage/action-runs/provider.js +2 -2
  252. package/dist/storage/agents/errors.d.ts +1 -1
  253. package/dist/storage/agents/errors.d.ts.map +1 -1
  254. package/dist/storage/agents/in-memory.d.ts +3 -2
  255. package/dist/storage/agents/in-memory.d.ts.map +1 -1
  256. package/dist/storage/agents/index.d.ts +1 -1
  257. package/dist/storage/agents/index.d.ts.map +1 -1
  258. package/dist/storage/agents/provider.d.ts +11 -4
  259. package/dist/storage/agents/provider.d.ts.map +1 -1
  260. package/dist/storage/agents/provider.js +18 -15
  261. package/dist/storage/agents/provider.js.map +1 -1
  262. package/dist/storage/agents/types.d.ts +65 -17
  263. package/dist/storage/agents/types.d.ts.map +1 -1
  264. package/dist/storage/ai-cost/analytics.d.ts +2 -1
  265. package/dist/storage/ai-cost/analytics.d.ts.map +1 -1
  266. package/dist/storage/ai-cost/codec.d.ts +3 -2
  267. package/dist/storage/ai-cost/codec.d.ts.map +1 -1
  268. package/dist/storage/ai-cost/groups.d.ts +51 -0
  269. package/dist/storage/ai-cost/groups.d.ts.map +1 -0
  270. package/dist/storage/ai-cost/in-memory.d.ts +11 -1
  271. package/dist/storage/ai-cost/in-memory.d.ts.map +1 -1
  272. package/dist/storage/ai-cost/index.d.ts +1 -1
  273. package/dist/storage/ai-cost/index.d.ts.map +1 -1
  274. package/dist/storage/ai-cost/provider.d.ts +2 -0
  275. package/dist/storage/ai-cost/provider.d.ts.map +1 -1
  276. package/dist/storage/ai-cost/provider.js +29 -13
  277. package/dist/storage/ai-cost/provider.js.map +3 -3
  278. package/dist/storage/ai-cost/types.d.ts +64 -15
  279. package/dist/storage/ai-cost/types.d.ts.map +1 -1
  280. package/dist/storage/ai-cost/validation.d.ts +2 -1
  281. package/dist/storage/ai-cost/validation.d.ts.map +1 -1
  282. package/dist/storage/ai-limits/enforcement.d.ts +14 -0
  283. package/dist/storage/ai-limits/enforcement.d.ts.map +1 -0
  284. package/dist/storage/ai-limits/enforcement.js +21 -0
  285. package/dist/storage/ai-limits/enforcement.js.map +9 -0
  286. package/dist/storage/ai-limits/errors.d.ts +8 -0
  287. package/dist/storage/ai-limits/errors.d.ts.map +1 -0
  288. package/dist/storage/ai-limits/in-memory.d.ts +78 -0
  289. package/dist/storage/ai-limits/in-memory.d.ts.map +1 -0
  290. package/dist/storage/ai-limits/index.d.ts +7 -0
  291. package/dist/storage/ai-limits/index.d.ts.map +1 -0
  292. package/dist/storage/ai-limits/period.d.ts +4 -0
  293. package/dist/storage/ai-limits/period.d.ts.map +1 -0
  294. package/dist/storage/ai-limits/provider.d.ts +85 -0
  295. package/dist/storage/ai-limits/provider.d.ts.map +1 -0
  296. package/dist/storage/ai-limits/provider.js +62 -0
  297. package/dist/storage/ai-limits/provider.js.map +9 -0
  298. package/dist/storage/ai-limits/types.d.ts +175 -0
  299. package/dist/storage/ai-limits/types.d.ts.map +1 -0
  300. package/dist/storage/ai-usage/in-memory.d.ts +4 -0
  301. package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
  302. package/dist/storage/ai-usage/record.d.ts.map +1 -1
  303. package/dist/storage/ai-usage/types.d.ts +6 -2
  304. package/dist/storage/ai-usage/types.d.ts.map +1 -1
  305. package/dist/storage/auth/errors.d.ts +1 -1
  306. package/dist/storage/auth/errors.d.ts.map +1 -1
  307. package/dist/storage/auth/in-memory/auth-storage.d.ts +4 -1
  308. package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
  309. package/dist/storage/auth/in-memory/device-authorizations.d.ts +29 -0
  310. package/dist/storage/auth/in-memory/device-authorizations.d.ts.map +1 -0
  311. package/dist/storage/auth/in-memory/shared.d.ts +3 -1
  312. package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
  313. package/dist/storage/auth/index.d.ts +2 -1
  314. package/dist/storage/auth/index.d.ts.map +1 -1
  315. package/dist/storage/auth/types.d.ts +66 -0
  316. package/dist/storage/auth/types.d.ts.map +1 -1
  317. package/dist/storage/connector-connections/provider.js +2 -2
  318. package/dist/storage/executions/provider.js +1 -1
  319. package/dist/storage/executions/run-link.d.ts +7 -2
  320. package/dist/storage/executions/run-link.d.ts.map +1 -1
  321. package/dist/storage/executions/validation.d.ts.map +1 -1
  322. package/dist/storage/in-memory/index.d.ts +4 -0
  323. package/dist/storage/in-memory/index.d.ts.map +1 -1
  324. package/dist/storage/index.d.ts +7 -4
  325. package/dist/storage/index.d.ts.map +1 -1
  326. package/dist/storage/index.js +51 -38
  327. package/dist/storage/index.js.map +1 -1
  328. package/dist/storage/ontology/provider.js +3 -3
  329. package/dist/storage/pipeline-runs/provider.js +2 -2
  330. package/dist/storage/projection-runs/provider.js +4 -4
  331. package/dist/storage/sync-runs/provider.js +2 -2
  332. package/dist/storage/types.d.ts +5 -1
  333. package/dist/storage/types.d.ts.map +1 -1
  334. package/dist/storage/webhook-runs/provider.js +2 -2
  335. package/dist/storage/workflow-runs/provider.d.ts +1 -1
  336. package/dist/storage/workflow-runs/provider.js +10 -11
  337. package/dist/storage/workflow-runs/provider.js.map +1 -1
  338. package/dist/storage/workflow-runs/types.d.ts +5 -4
  339. package/dist/storage/workflow-runs/types.d.ts.map +1 -1
  340. package/dist/syncs/index.js +37 -35
  341. package/dist/syncs/index.js.map +1 -1
  342. package/dist/testing/agent-execution.d.ts +3 -1
  343. package/dist/testing/agent-execution.d.ts.map +1 -1
  344. package/dist/testing/agent-storage-contract.d.ts.map +1 -1
  345. package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -1
  346. package/dist/testing/ai-limit-storage-contract.d.ts +18 -0
  347. package/dist/testing/ai-limit-storage-contract.d.ts.map +1 -0
  348. package/dist/testing/ai-model-call-groups-contract.d.ts +6 -0
  349. package/dist/testing/ai-model-call-groups-contract.d.ts.map +1 -0
  350. package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
  351. package/dist/testing/auth-storage-contract.d.ts.map +1 -1
  352. package/dist/testing/index.d.ts +2 -0
  353. package/dist/testing/index.d.ts.map +1 -1
  354. package/dist/testing/index.js +3637 -1962
  355. package/dist/testing/index.js.map +14 -12
  356. package/dist/testing/queues-contract.d.ts.map +1 -1
  357. package/dist/webhooks/internal.js +32 -28
  358. package/dist/webhooks/internal.js.map +2 -2
  359. package/dist/workers/index.js +2 -2
  360. package/dist/workflows/agent-step-identity.d.ts +3 -0
  361. package/dist/workflows/agent-step-identity.d.ts.map +1 -0
  362. package/dist/workflows/builders.d.ts +2 -3
  363. package/dist/workflows/builders.d.ts.map +1 -1
  364. package/dist/workflows/execution.d.ts +1 -1
  365. package/dist/workflows/execution.d.ts.map +1 -1
  366. package/dist/workflows/failure.d.ts +1 -1
  367. package/dist/workflows/failure.d.ts.map +1 -1
  368. package/dist/workflows/index.d.ts +3 -2
  369. package/dist/workflows/index.d.ts.map +1 -1
  370. package/dist/workflows/index.js +53 -45
  371. package/dist/workflows/index.js.map +1 -1
  372. package/dist/workflows/types.d.ts +26 -11
  373. package/dist/workflows/types.d.ts.map +1 -1
  374. package/dist/workflows/validation.d.ts +7 -1
  375. package/dist/workflows/validation.d.ts.map +1 -1
  376. package/package.json +19 -4
  377. package/src/agents/adapters.ts +109 -115
  378. package/src/agents/authority.ts +214 -32
  379. package/src/agents/builders.ts +3 -50
  380. package/src/agents/context-compaction.ts +4 -0
  381. package/src/agents/dispatch.ts +59 -2
  382. package/src/agents/errors.ts +5 -2
  383. package/src/agents/execution.ts +53 -52
  384. package/src/agents/ids.ts +16 -1
  385. package/src/agents/index.ts +23 -11
  386. package/src/agents/message.ts +18 -9
  387. package/src/agents/model-loop.ts +1023 -0
  388. package/src/agents/reference.ts +7 -0
  389. package/src/agents/request.ts +141 -74
  390. package/src/agents/retired-config.ts +20 -0
  391. package/src/agents/streams.ts +45 -19
  392. package/src/agents/tool-catalog.ts +21 -0
  393. package/src/agents/tool-definition.ts +23 -0
  394. package/src/agents/types.ts +39 -81
  395. package/src/agents/validation.ts +34 -180
  396. package/src/ai-usage/execution.ts +196 -0
  397. package/src/ai-usage/index.ts +15 -0
  398. package/src/authorization/decision.ts +27 -10
  399. package/src/authorization/grant-kinds.ts +62 -15
  400. package/src/authorization/index.ts +1 -0
  401. package/src/authorization/resolve.ts +12 -5
  402. package/src/authorization/types.ts +7 -5
  403. package/src/bootstrap/discovery.ts +0 -3
  404. package/src/error-reporting/types.ts +4 -2
  405. package/src/errors/catalog.ts +8 -0
  406. package/src/execution/agent.ts +129 -22
  407. package/src/execution/authorization.ts +48 -18
  408. package/src/execution/request.ts +4 -1
  409. package/src/execution/types.ts +1 -1
  410. package/src/http/api-routes.ts +63 -0
  411. package/src/index.ts +36 -7
  412. package/src/json.ts +9 -0
  413. package/src/models/catalog.ts +137 -0
  414. package/src/models/definitions.ts +202 -0
  415. package/src/models/errors.ts +83 -0
  416. package/src/models/events.ts +198 -0
  417. package/src/models/index.ts +89 -71
  418. package/src/models/language-model.ts +143 -0
  419. package/src/models/messages.ts +78 -0
  420. package/src/models/pricing.ts +390 -0
  421. package/src/models/rate-card.ts +101 -0
  422. package/src/models/tools.ts +29 -0
  423. package/src/queues/in-memory.ts +5 -0
  424. package/src/queues/index.ts +11 -0
  425. package/src/queues/types.ts +20 -3
  426. package/src/runtime/create.ts +7 -5
  427. package/src/runtime/definitions.ts +2 -2
  428. package/src/runtime/host.ts +3 -2
  429. package/src/runtime/resolve-definitions.ts +13 -36
  430. package/src/runtime/sixb.ts +6 -8
  431. package/src/security/every.ts +0 -4
  432. package/src/security/grants.ts +55 -11
  433. package/src/security/index.ts +2 -0
  434. package/src/security/registry.ts +6 -5
  435. package/src/security/types.ts +15 -4
  436. package/src/security/validation.ts +30 -9
  437. package/src/storage/agents/errors.ts +1 -0
  438. package/src/storage/agents/in-memory.ts +121 -11
  439. package/src/storage/agents/index.ts +7 -0
  440. package/src/storage/agents/provider.ts +150 -6
  441. package/src/storage/agents/types.ts +73 -16
  442. package/src/storage/ai-cost/analytics.ts +63 -6
  443. package/src/storage/ai-cost/codec.ts +37 -12
  444. package/src/storage/ai-cost/groups.ts +248 -0
  445. package/src/storage/ai-cost/in-memory.ts +42 -0
  446. package/src/storage/ai-cost/index.ts +6 -0
  447. package/src/storage/ai-cost/provider.ts +7 -0
  448. package/src/storage/ai-cost/types.ts +76 -14
  449. package/src/storage/ai-cost/validation.ts +147 -17
  450. package/src/storage/ai-limits/enforcement.ts +68 -0
  451. package/src/storage/ai-limits/errors.ts +23 -0
  452. package/src/storage/ai-limits/in-memory.ts +671 -0
  453. package/src/storage/ai-limits/index.ts +31 -0
  454. package/src/storage/ai-limits/period.ts +11 -0
  455. package/src/storage/ai-limits/provider.ts +430 -0
  456. package/src/storage/ai-limits/types.ts +195 -0
  457. package/src/storage/ai-usage/in-memory.ts +13 -0
  458. package/src/storage/ai-usage/record.ts +17 -0
  459. package/src/storage/ai-usage/types.ts +6 -2
  460. package/src/storage/auth/errors.ts +6 -0
  461. package/src/storage/auth/in-memory/auth-storage.ts +69 -0
  462. package/src/storage/auth/in-memory/device-authorizations.ts +145 -0
  463. package/src/storage/auth/in-memory/shared.ts +7 -0
  464. package/src/storage/auth/index.ts +7 -0
  465. package/src/storage/auth/types.ts +73 -0
  466. package/src/storage/executions/run-link.ts +16 -6
  467. package/src/storage/executions/validation.ts +36 -6
  468. package/src/storage/in-memory/index.ts +48 -4
  469. package/src/storage/index.ts +51 -1
  470. package/src/storage/types.ts +37 -0
  471. package/src/storage/workflow-runs/in-memory.ts +3 -3
  472. package/src/storage/workflow-runs/provider.ts +2 -2
  473. package/src/storage/workflow-runs/types.ts +6 -3
  474. package/src/testing/agent-execution.ts +40 -28
  475. package/src/testing/agent-storage-contract.ts +249 -28
  476. package/src/testing/ai-cost-storage-contract.ts +96 -8
  477. package/src/testing/ai-limit-storage-contract.ts +1134 -0
  478. package/src/testing/ai-model-call-groups-contract.ts +353 -0
  479. package/src/testing/ai-usage-storage-contract.ts +31 -0
  480. package/src/testing/auth-storage-contract.ts +85 -0
  481. package/src/testing/execution-storage-contract.ts +2 -2
  482. package/src/testing/index.ts +10 -0
  483. package/src/testing/queues-contract.ts +36 -1
  484. package/src/workflows/agent-step-identity.ts +4 -0
  485. package/src/workflows/builders.ts +95 -9
  486. package/src/workflows/execution.ts +2 -2
  487. package/src/workflows/failure.ts +2 -2
  488. package/src/workflows/index.ts +3 -0
  489. package/src/workflows/types.ts +23 -11
  490. package/src/workflows/validation.ts +100 -7
  491. package/dist/chunk-1e8m6yn3.js.map +0 -37
  492. package/dist/chunk-1g8negke.js.map +0 -11
  493. package/dist/chunk-6gjqgd3d.js.map +0 -11
  494. package/dist/chunk-dm72y8wt.js.map +0 -10
  495. package/dist/chunk-drjqm1aa.js.map +0 -15
  496. package/dist/chunk-fe5ev6mr.js +0 -55
  497. package/dist/chunk-fe5ev6mr.js.map +0 -11
  498. package/dist/chunk-h9kxd41f.js.map +0 -11
  499. package/dist/chunk-hceck7dq.js +0 -137
  500. package/dist/chunk-hceck7dq.js.map +0 -10
  501. package/dist/chunk-n4spznws.js.map +0 -11
  502. package/dist/chunk-nva1xkjz.js.map +0 -46
  503. package/dist/chunk-t0jjkep3.js.map +0 -10
  504. package/dist/chunk-t8t39h7v.js.map +0 -10
  505. /package/dist/{chunk-zqysyfjt.js.map → chunk-08m3b6w8.js.map} +0 -0
  506. /package/dist/{chunk-xkthy56g.js.map → chunk-1kamz6j0.js.map} +0 -0
  507. /package/dist/{chunk-md8k0r54.js.map → chunk-3fqt22c4.js.map} +0 -0
  508. /package/dist/{chunk-z3zp0bj1.js.map → chunk-407j3msh.js.map} +0 -0
  509. /package/dist/{chunk-rhrbz7d4.js.map → chunk-4a849fr1.js.map} +0 -0
  510. /package/dist/{chunk-62c7t4jc.js.map → chunk-4nxeacx7.js.map} +0 -0
  511. /package/dist/{chunk-cy0n5dms.js.map → chunk-5jcdmjam.js.map} +0 -0
  512. /package/dist/{chunk-819wnjz8.js.map → chunk-64sr682n.js.map} +0 -0
  513. /package/dist/{chunk-x2yw73hy.js.map → chunk-7ds9620f.js.map} +0 -0
  514. /package/dist/{chunk-72q2y8hn.js.map → chunk-8tsf6dmc.js.map} +0 -0
  515. /package/dist/{chunk-nkbfrt0c.js.map → chunk-9aehf39w.js.map} +0 -0
  516. /package/dist/{chunk-ezake7g1.js.map → chunk-agsvg9ar.js.map} +0 -0
  517. /package/dist/{chunk-rnshztfq.js.map → chunk-d63tybny.js.map} +0 -0
  518. /package/dist/{chunk-vybf6pkp.js.map → chunk-dbc80ad7.js.map} +0 -0
  519. /package/dist/{chunk-4gz41why.js.map → chunk-dqn23610.js.map} +0 -0
  520. /package/dist/{chunk-tg5mee00.js.map → chunk-ha58tjtt.js.map} +0 -0
  521. /package/dist/{chunk-f6erf2vv.js.map → chunk-hdz94br2.js.map} +0 -0
  522. /package/dist/{chunk-dsrkgtnh.js.map → chunk-jq43kdvk.js.map} +0 -0
  523. /package/dist/{chunk-wtmzkcht.js.map → chunk-k34z5rvh.js.map} +0 -0
  524. /package/dist/{chunk-htq0qh7z.js.map → chunk-ka3a2ft3.js.map} +0 -0
  525. /package/dist/{chunk-znagycq7.js.map → chunk-kt81c11h.js.map} +0 -0
  526. /package/dist/{chunk-f2rt4vkh.js.map → chunk-n2w475r0.js.map} +0 -0
  527. /package/dist/{chunk-bhxaq2nn.js.map → chunk-qw9gvjv5.js.map} +0 -0
  528. /package/dist/{chunk-8gv5z0zm.js.map → chunk-rp1mvzb4.js.map} +0 -0
  529. /package/dist/{chunk-ghteq96b.js.map → chunk-s5y30bc9.js.map} +0 -0
  530. /package/dist/{chunk-a31h57d5.js.map → chunk-tn7xcs2n.js.map} +0 -0
  531. /package/dist/{chunk-e42bc6m3.js.map → chunk-vjjv9mrb.js.map} +0 -0
  532. /package/dist/{chunk-8b55ygje.js.map → chunk-w3e09qqk.js.map} +0 -0
  533. /package/dist/{chunk-ckxfnx7f.js.map → chunk-wjgm6jjt.js.map} +0 -0
  534. /package/dist/{chunk-3j7573mj.js.map → chunk-x0qhkqje.js.map} +0 -0
  535. /package/dist/{chunk-dysw7nsm.js.map → chunk-xdpwpkha.js.map} +0 -0
@@ -0,0 +1,671 @@
1
+ import type { AiModelCallCostRecord } from "../ai-cost"
2
+ import type { AiModelCallUsageRecord } from "../ai-usage"
3
+ import type { ExecutionRecord } from "../executions"
4
+ import { AiLimitStorageError } from "./errors"
5
+ import { aiLimitCalendarMonth } from "./period"
6
+ import type { AiLimitAccountingEntry } from "./provider"
7
+ import {
8
+ AiLimitOperationLock,
9
+ aiLimitAccountingEntryAppliesToSubject,
10
+ aiLimitAmountKey,
11
+ aiLimitPolicyDimensionKey,
12
+ aiLimitQuantityFromAmount,
13
+ aiLimitReservationBuckets,
14
+ aiLimitReservationRequestKey,
15
+ aiLimitReservationRequestMatches,
16
+ aiLimitSubjectKey,
17
+ aiLimitSubjectsFromAccountingEntry,
18
+ aiModelCallReservationKey,
19
+ assertAiLimitAccountingMatchesReservation,
20
+ assertNonBlank,
21
+ cloneAiLimitPolicy,
22
+ cloneValidDate,
23
+ type NormalizedAiLimitAmount,
24
+ normalizeAiLimitAmount,
25
+ normalizeAiModelCallReservationIdentity,
26
+ normalizeCreateAiLimitPolicy,
27
+ normalizeReserveAiModelCall,
28
+ normalizeUpdateAiLimitPolicy,
29
+ resolveAiLimitActual,
30
+ } from "./provider"
31
+ import type {
32
+ AiLimitPeriod,
33
+ AiLimitPolicy,
34
+ AiLimitPolicyStatus,
35
+ AiLimitQuantity,
36
+ AiLimitStorage,
37
+ AiLimitSubject,
38
+ AiModelCallReservation,
39
+ CreateAiLimitPolicyInput,
40
+ DeleteAiLimitPolicyInput,
41
+ GetAiLimitPolicyInput,
42
+ ListAiLimitPoliciesInput,
43
+ ListAiLimitPolicyStatusesInput,
44
+ MarkAiModelCallReservationUnknownInput,
45
+ ReconcileAiModelCallInput,
46
+ RecordAiModelCallLimitActualsInput,
47
+ ReserveAiModelCallInput,
48
+ ReserveAiModelCallResult,
49
+ UpdateAiLimitPolicyInput,
50
+ } from "./types"
51
+
52
+ interface AiLimitPeriodState {
53
+ readonly projectId: string
54
+ readonly subject: AiLimitSubject
55
+ readonly meter: AiLimitQuantity["meter"]
56
+ readonly currency: string
57
+ readonly period: AiLimitPeriod
58
+ actual: bigint
59
+ reserved: bigint
60
+ unknown: bigint
61
+ accountingStatus: "complete" | "unavailable"
62
+ updatedAt: Date
63
+ }
64
+
65
+ export interface InMemoryAiLimitStorageOptions {
66
+ readonly executionExists?: (input: {
67
+ readonly projectId: string
68
+ readonly executionId: string
69
+ }) => boolean | Promise<boolean>
70
+ readonly resolveExecution?: (input: {
71
+ readonly projectId: string
72
+ readonly executionId: string
73
+ }) => ExecutionRecord | null | Promise<ExecutionRecord | null>
74
+ readonly resolveUsageRecord?: (input: {
75
+ readonly projectId: string
76
+ readonly usageRecordId: string
77
+ }) => AiModelCallUsageRecord | null | Promise<AiModelCallUsageRecord | null>
78
+ readonly resolveCostRecord?: (input: {
79
+ readonly projectId: string
80
+ readonly usageRecordId: string
81
+ }) => AiModelCallCostRecord | null | Promise<AiModelCallCostRecord | null>
82
+ readonly listUsageRecords?: (input: {
83
+ readonly projectId: string
84
+ }) => readonly AiModelCallUsageRecord[] | Promise<readonly AiModelCallUsageRecord[]>
85
+ }
86
+
87
+ export interface InMemoryAiLimitStorageSnapshot {
88
+ readonly policies: Map<string, AiLimitPolicy>
89
+ readonly policyIdsByDimension: Map<string, string>
90
+ readonly periodStates: Map<string, AiLimitPeriodState>
91
+ readonly reservations: Map<string, AiModelCallReservation>
92
+ }
93
+
94
+ /** In-memory AI limit provider used by development runtimes and contract tests. */
95
+ export class InMemoryAiLimitStorage implements AiLimitStorage {
96
+ private readonly policies = new Map<string, AiLimitPolicy>()
97
+ private readonly policyIdsByDimension = new Map<string, string>()
98
+ private readonly periodStates = new Map<string, AiLimitPeriodState>()
99
+ private readonly reservations = new Map<string, AiModelCallReservation>()
100
+ private readonly operations = new AiLimitOperationLock()
101
+
102
+ constructor(private readonly options: InMemoryAiLimitStorageOptions = {}) {}
103
+
104
+ /** @internal The root transaction must settle queued work before restoring its snapshot. */
105
+ settleOperations(): Promise<void> {
106
+ return this.operations.settle()
107
+ }
108
+
109
+ async createPolicy(input: CreateAiLimitPolicyInput): Promise<AiLimitPolicy> {
110
+ return this.operations.run(async () => {
111
+ const policy = normalizeCreateAiLimitPolicy(input)
112
+ const key = policyKey(policy.projectId, policy.id)
113
+ const dimensionKey = aiLimitPolicyDimensionKey(policy)
114
+ if (this.policies.has(key) || this.policyIdsByDimension.has(dimensionKey)) {
115
+ throw new AiLimitStorageError(
116
+ "duplicate_policy",
117
+ `[Sixb] An AI limit policy already exists for '${aiLimitSubjectKey(policy.subject)}' and '${aiLimitAmountKey(normalizeAiLimitAmount(policy.limit))}'.`
118
+ )
119
+ }
120
+ this.policies.set(key, structuredClone(policy))
121
+ this.policyIdsByDimension.set(dimensionKey, key)
122
+ return cloneAiLimitPolicy(policy)
123
+ })
124
+ }
125
+
126
+ async updatePolicy(input: UpdateAiLimitPolicyInput): Promise<AiLimitPolicy> {
127
+ return this.operations.run(async () => {
128
+ const update = normalizeUpdateAiLimitPolicy(input)
129
+ const key = policyKey(update.projectId, update.id)
130
+ const existing = this.policies.get(key)
131
+ if (!existing) throw missingPolicy(update.projectId, update.id)
132
+ if (update.limit !== undefined) {
133
+ const previous = normalizeAiLimitAmount(existing.limit)
134
+ const next = normalizeAiLimitAmount(update.limit)
135
+ if (aiLimitAmountKey(previous) !== aiLimitAmountKey(next)) {
136
+ throw new TypeError("[Sixb] AI limit policy meter and cost currency are immutable.")
137
+ }
138
+ }
139
+ const policy: AiLimitPolicy = {
140
+ ...existing,
141
+ ...(update.limit === undefined ? {} : { limit: update.limit }),
142
+ ...(update.enabled === undefined ? {} : { enabled: update.enabled }),
143
+ updatedAt: update.updatedAt,
144
+ }
145
+ this.policies.set(key, structuredClone(policy))
146
+ return cloneAiLimitPolicy(policy)
147
+ })
148
+ }
149
+
150
+ async deletePolicy(input: DeleteAiLimitPolicyInput): Promise<boolean> {
151
+ return this.operations.run(async () => {
152
+ validatePolicyIdentity(input)
153
+ const key = policyKey(input.projectId, input.id)
154
+ const existing = this.policies.get(key)
155
+ if (!existing) return false
156
+ this.policies.delete(key)
157
+ this.policyIdsByDimension.delete(aiLimitPolicyDimensionKey(existing))
158
+ return true
159
+ })
160
+ }
161
+
162
+ async getPolicy(input: GetAiLimitPolicyInput): Promise<AiLimitPolicy | null> {
163
+ validatePolicyIdentity(input)
164
+ const policy = this.policies.get(policyKey(input.projectId, input.id))
165
+ return policy ? cloneAiLimitPolicy(policy) : null
166
+ }
167
+
168
+ async listPolicies(input: ListAiLimitPoliciesInput): Promise<readonly AiLimitPolicy[]> {
169
+ assertNonBlank(input.projectId, "projectId")
170
+ return [...this.policies.values()]
171
+ .filter(
172
+ (policy) =>
173
+ policy.projectId === input.projectId && (input.includeDisabled || policy.enabled)
174
+ )
175
+ .sort((left, right) => left.id.localeCompare(right.id))
176
+ .map(cloneAiLimitPolicy)
177
+ }
178
+
179
+ async listPolicyStatuses(
180
+ input: ListAiLimitPolicyStatusesInput
181
+ ): Promise<readonly AiLimitPolicyStatus[]> {
182
+ return this.operations.run(async () => {
183
+ assertNonBlank(input.projectId, "projectId")
184
+ const period = aiLimitCalendarMonth(input.at ?? new Date())
185
+ const existingGroups =
186
+ input.existingGroupIds === undefined ? undefined : new Set(input.existingGroupIds)
187
+ const policies = await this.listPolicies({
188
+ projectId: input.projectId,
189
+ includeDisabled: input.includeDisabled,
190
+ })
191
+ return Promise.all(
192
+ policies.map((policy) => this.policyStatus(policy, period, existingGroups))
193
+ )
194
+ })
195
+ }
196
+
197
+ async reserveModelCall(input: ReserveAiModelCallInput): Promise<ReserveAiModelCallResult> {
198
+ return this.operations.run(async () => {
199
+ const request = normalizeReserveAiModelCall(input)
200
+ const reservationKey = aiModelCallReservationKey(request.identity)
201
+ const existing = this.reservations.get(reservationKey)
202
+ if (existing) {
203
+ if (!aiLimitReservationRequestMatches(existing, request)) {
204
+ throw new AiLimitStorageError(
205
+ "reservation_conflict",
206
+ `[Sixb] AI model-call reservation '${input.callId}' was replayed with different subjects, estimates, or period.`
207
+ )
208
+ }
209
+ if (existing.state !== "active") {
210
+ return { status: "terminal", reservation: structuredClone(existing), created: false }
211
+ }
212
+ return { status: "reserved", reservation: structuredClone(existing), created: false }
213
+ }
214
+ await this.assertExecutionExists(request.identity.projectId, request.identity.executionId)
215
+
216
+ const enabledPolicies = [...this.policies.values()].filter(
217
+ (policy) => policy.projectId === request.identity.projectId && policy.enabled
218
+ )
219
+ const subjectKeys = new Set(request.subjects.map(aiLimitSubjectKey))
220
+ const estimates = new Map(
221
+ request.estimates.map((quantity) => {
222
+ const amount = normalizeAiLimitAmount(quantity)
223
+ return [aiLimitAmountKey(amount), amount] as const
224
+ })
225
+ )
226
+ const exhaustedPolicies: AiLimitPolicyStatus[] = []
227
+ const unavailablePolicies: AiLimitPolicyStatus[] = []
228
+ const unavailableReasons = new Set<"missingEstimate" | "incompleteAccounting">()
229
+ for (const policy of enabledPolicies) {
230
+ if (!subjectKeys.has(aiLimitSubjectKey(policy.subject))) continue
231
+ const limit = normalizeAiLimitAmount(policy.limit)
232
+ const estimate = estimates.get(aiLimitAmountKey(limit))
233
+ const status = await this.policyStatus(policy, request.period)
234
+ if (!estimate || status.accountingStatus === "unavailable") {
235
+ unavailablePolicies.push(status)
236
+ if (!estimate) unavailableReasons.add("missingEstimate")
237
+ if (status.accountingStatus === "unavailable") {
238
+ unavailableReasons.add("incompleteAccounting")
239
+ }
240
+ continue
241
+ }
242
+ const actual = normalizeAiLimitAmount(status.consumption.actual).amount
243
+ const reserved = normalizeAiLimitAmount(status.consumption.reserved).amount
244
+ const unknown = normalizeAiLimitAmount(status.consumption.unknown).amount
245
+ if (actual + reserved + unknown + estimate.amount > limit.amount) {
246
+ exhaustedPolicies.push(status)
247
+ }
248
+ }
249
+ if (unavailablePolicies.length > 0) {
250
+ unavailablePolicies.sort((left, right) => left.policy.id.localeCompare(right.policy.id))
251
+ return {
252
+ status: "unavailable",
253
+ unavailablePolicies,
254
+ reasons: [...unavailableReasons].sort(),
255
+ }
256
+ }
257
+ if (exhaustedPolicies.length > 0) {
258
+ exhaustedPolicies.sort((left, right) => left.policy.id.localeCompare(right.policy.id))
259
+ return {
260
+ status: "denied",
261
+ exhaustedPolicies,
262
+ resetAt: new Date(
263
+ Math.min(...exhaustedPolicies.map((status) => status.period.resetAt.getTime()))
264
+ ),
265
+ }
266
+ }
267
+
268
+ const buckets = aiLimitReservationBuckets(
269
+ enabledPolicies,
270
+ request.subjects,
271
+ request.estimates
272
+ )
273
+ if (buckets.length === 0) return { status: "notRequired" }
274
+ for (const bucket of buckets) {
275
+ const amount = normalizeAiLimitAmount(bucket.estimate)
276
+ const state = this.requirePeriodState(
277
+ request.identity.projectId,
278
+ bucket.subject,
279
+ amount,
280
+ request.period
281
+ )
282
+ state.reserved += amount.amount
283
+ state.updatedAt = new Date(request.reservedAt)
284
+ }
285
+ const reservation: AiModelCallReservation = {
286
+ ...request.identity,
287
+ buckets,
288
+ requestKey: aiLimitReservationRequestKey(request),
289
+ period: request.period,
290
+ state: "active",
291
+ reservedAt: request.reservedAt,
292
+ updatedAt: new Date(request.reservedAt),
293
+ }
294
+ this.reservations.set(reservationKey, structuredClone(reservation))
295
+ return { status: "reserved", reservation: structuredClone(reservation), created: true }
296
+ })
297
+ }
298
+
299
+ async recordModelCallActuals(input: RecordAiModelCallLimitActualsInput): Promise<void> {
300
+ return this.operations.run(async () => {
301
+ assertNonBlank(input.projectId, "projectId")
302
+ assertNonBlank(input.usageRecordId, "usageRecordId")
303
+ const recordedAt = cloneValidDate(input.recordedAt ?? new Date(), "recordedAt")
304
+ const entry = await this.requireAccountingEntry(input.projectId, input.usageRecordId)
305
+ const period = aiLimitCalendarMonth(entry.occurredAt)
306
+ const subjectKeys = new Set(aiLimitSubjectsFromAccountingEntry(entry).map(aiLimitSubjectKey))
307
+ for (const state of this.periodStates.values()) {
308
+ if (
309
+ state.projectId !== input.projectId ||
310
+ state.period.start.getTime() !== period.start.getTime() ||
311
+ !subjectKeys.has(aiLimitSubjectKey(state.subject))
312
+ ) {
313
+ continue
314
+ }
315
+ const actual = resolveAiLimitActual([entry], state)
316
+ state.actual += actual.amount
317
+ if (actual.accountingStatus === "unavailable") state.accountingStatus = "unavailable"
318
+ state.updatedAt = new Date(recordedAt)
319
+ }
320
+ })
321
+ }
322
+
323
+ async reconcileModelCall(input: ReconcileAiModelCallInput): Promise<AiModelCallReservation> {
324
+ return this.operations.run(async () => {
325
+ const identity = normalizeAiModelCallReservationIdentity(input)
326
+ assertNonBlank(input.usageRecordId, "usageRecordId")
327
+ const reconciledAt = cloneValidDate(input.reconciledAt ?? new Date(), "reconciledAt")
328
+ const key = aiModelCallReservationKey(identity)
329
+ const reservation = this.reservations.get(key)
330
+ if (!reservation) throw missingReservation(identity)
331
+ if (reservation.state === "reconciled") {
332
+ if (reservation.usageRecordId === input.usageRecordId) {
333
+ return structuredClone(reservation)
334
+ }
335
+ throw new AiLimitStorageError(
336
+ "reconciliation_conflict",
337
+ `[Sixb] AI model-call reservation '${identity.callId}' was reconciled with a different usage record.`
338
+ )
339
+ }
340
+ const accounting = await this.requireAccountingEntry(identity.projectId, input.usageRecordId)
341
+ assertAiLimitAccountingMatchesReservation(reservation, accounting)
342
+ this.reconcileEstimateCounters(reservation, accounting, reconciledAt)
343
+ const reconciled: AiModelCallReservation = {
344
+ ...reservation,
345
+ state: "reconciled",
346
+ usageRecordId: input.usageRecordId,
347
+ updatedAt: reconciledAt,
348
+ }
349
+ this.reservations.set(key, structuredClone(reconciled))
350
+ return structuredClone(reconciled)
351
+ })
352
+ }
353
+
354
+ async markReservationUnknown(
355
+ input: MarkAiModelCallReservationUnknownInput
356
+ ): Promise<AiModelCallReservation> {
357
+ return this.operations.run(async () => {
358
+ const identity = normalizeAiModelCallReservationIdentity(input)
359
+ const markedAt = cloneValidDate(input.markedAt ?? new Date(), "markedAt")
360
+ const key = aiModelCallReservationKey(identity)
361
+ const reservation = this.reservations.get(key)
362
+ if (!reservation) throw missingReservation(identity)
363
+ if (reservation.state === "unknown") return structuredClone(reservation)
364
+ if (reservation.state !== "active") throw invalidState(reservation, "mark unknown")
365
+ this.moveEstimateCounter(reservation, "reserved", -1n, markedAt)
366
+ this.moveEstimateCounter(reservation, "unknown", 1n, markedAt)
367
+ const unknown: AiModelCallReservation = {
368
+ ...reservation,
369
+ state: "unknown",
370
+ updatedAt: markedAt,
371
+ }
372
+ this.reservations.set(key, structuredClone(unknown))
373
+ return structuredClone(unknown)
374
+ })
375
+ }
376
+
377
+ snapshot(): InMemoryAiLimitStorageSnapshot {
378
+ return structuredClone({
379
+ policies: this.policies,
380
+ policyIdsByDimension: this.policyIdsByDimension,
381
+ periodStates: this.periodStates,
382
+ reservations: this.reservations,
383
+ })
384
+ }
385
+
386
+ restore(snapshot: InMemoryAiLimitStorageSnapshot): void {
387
+ replaceMap(this.policies, snapshot.policies)
388
+ replaceMap(this.policyIdsByDimension, snapshot.policyIdsByDimension)
389
+ replaceMap(this.periodStates, snapshot.periodStates)
390
+ replaceMap(this.reservations, snapshot.reservations)
391
+ }
392
+
393
+ private async policyStatus(
394
+ policy: AiLimitPolicy,
395
+ period: AiLimitPeriod,
396
+ existingGroups?: ReadonlySet<string>
397
+ ): Promise<AiLimitPolicyStatus> {
398
+ const limit = normalizeAiLimitAmount(policy.limit)
399
+ const state = await this.ensurePeriodState(policy, period)
400
+ const reserved = state.reserved
401
+ const unknown = state.unknown
402
+ const consumed = state.actual + reserved + unknown
403
+ const remaining = limit.amount > consumed ? limit.amount - consumed : 0n
404
+ const quantity = (amount: bigint): AiLimitQuantity =>
405
+ aiLimitQuantityFromAmount({ ...limit, amount })
406
+ return {
407
+ policy: cloneAiLimitPolicy(policy),
408
+ period: structuredClone(period),
409
+ consumption: {
410
+ actual: quantity(state.actual),
411
+ reserved: quantity(reserved),
412
+ unknown: quantity(unknown),
413
+ remaining: quantity(remaining),
414
+ },
415
+ accountingStatus: state.accountingStatus,
416
+ exhausted: consumed >= limit.amount,
417
+ orphaned:
418
+ policy.subject.type === "group" &&
419
+ existingGroups !== undefined &&
420
+ !existingGroups.has(policy.subject.id),
421
+ }
422
+ }
423
+
424
+ private async ensurePeriodState(
425
+ policy: AiLimitPolicy,
426
+ period: AiLimitPeriod
427
+ ): Promise<AiLimitPeriodState> {
428
+ const amount = normalizeAiLimitAmount(policy.limit)
429
+ const key = periodStateKey(policy.projectId, policy.subject, amount, period)
430
+ const existing = this.periodStates.get(key)
431
+ if (existing?.accountingStatus === "complete") return existing
432
+ // A late valuation can repair the ledger after this period was cached as unavailable.
433
+ const actual = await this.resolvePolicyActual(policy, period, amount)
434
+ if (existing) {
435
+ existing.actual = actual.amount
436
+ existing.accountingStatus = actual.accountingStatus
437
+ existing.updatedAt = new Date()
438
+ return existing
439
+ }
440
+ const state: AiLimitPeriodState = {
441
+ projectId: policy.projectId,
442
+ subject: structuredClone(policy.subject),
443
+ meter: amount.meter,
444
+ currency: amount.currency,
445
+ period: structuredClone(period),
446
+ actual: actual.amount,
447
+ reserved: 0n,
448
+ unknown: 0n,
449
+ accountingStatus: actual.accountingStatus,
450
+ updatedAt: new Date(),
451
+ }
452
+ this.periodStates.set(key, state)
453
+ return state
454
+ }
455
+
456
+ private moveEstimateCounter(
457
+ reservation: AiModelCallReservation,
458
+ counter: "reserved" | "unknown",
459
+ direction: 1n | -1n,
460
+ updatedAt: Date
461
+ ): void {
462
+ for (const bucket of reservation.buckets) {
463
+ const amount = normalizeAiLimitAmount(bucket.estimate)
464
+ const state = this.requirePeriodState(
465
+ reservation.projectId,
466
+ bucket.subject,
467
+ amount,
468
+ reservation.period
469
+ )
470
+ state[counter] += direction * amount.amount
471
+ if (state[counter] < 0n) {
472
+ throw new Error(`[Sixb] In-memory AI limit ${counter} counter became negative.`)
473
+ }
474
+ state.updatedAt = new Date(updatedAt)
475
+ }
476
+ }
477
+
478
+ private reconcileEstimateCounters(
479
+ reservation: AiModelCallReservation,
480
+ entry: AiLimitAccountingEntry,
481
+ updatedAt: Date
482
+ ): void {
483
+ for (const bucket of reservation.buckets) {
484
+ const amount = normalizeAiLimitAmount(bucket.estimate)
485
+ const state = this.requirePeriodState(
486
+ reservation.projectId,
487
+ bucket.subject,
488
+ amount,
489
+ reservation.period
490
+ )
491
+ const counter = reservation.state === "active" ? "reserved" : "unknown"
492
+ const actual = resolveAiLimitActual([entry], amount)
493
+ if (actual.accountingStatus === "complete") {
494
+ state[counter] -= amount.amount
495
+ } else if (reservation.state === "active") {
496
+ state.reserved -= amount.amount
497
+ state.unknown += amount.amount
498
+ }
499
+ if (state.reserved < 0n || state.unknown < 0n) {
500
+ throw new Error("[Sixb] In-memory AI limit reservation counter became negative.")
501
+ }
502
+ state.updatedAt = new Date(updatedAt)
503
+ }
504
+ }
505
+
506
+ private requirePeriodState(
507
+ projectId: string,
508
+ subject: AiLimitSubject,
509
+ amount: NormalizedAiLimitAmount,
510
+ period: AiLimitPeriod
511
+ ): AiLimitPeriodState {
512
+ const state = this.periodStates.get(periodStateKey(projectId, subject, amount, period))
513
+ if (!state) throw new Error("[Sixb] In-memory AI limit period state is inconsistent.")
514
+ return state
515
+ }
516
+
517
+ private async assertExecutionExists(projectId: string, executionId: string): Promise<void> {
518
+ if (this.options.resolveExecution) {
519
+ if (await this.options.resolveExecution({ projectId, executionId })) return
520
+ throw new AiLimitStorageError(
521
+ "missing_execution",
522
+ `[Sixb] AI limit execution '${executionId}' does not exist in project '${projectId}'.`
523
+ )
524
+ }
525
+ if (
526
+ this.options.executionExists &&
527
+ (await this.options.executionExists({ projectId, executionId }))
528
+ ) {
529
+ return
530
+ }
531
+ throw new AiLimitStorageError(
532
+ "missing_execution",
533
+ `[Sixb] AI limit execution '${executionId}' does not exist in project '${projectId}'.`
534
+ )
535
+ }
536
+
537
+ private async resolvePolicyActual(
538
+ policy: AiLimitPolicy,
539
+ period: AiLimitPeriod,
540
+ dimension: NormalizedAiLimitAmount
541
+ ): Promise<ReturnType<typeof resolveAiLimitActual>> {
542
+ if (
543
+ !this.options.listUsageRecords ||
544
+ ((policy.subject.type === "user" || policy.subject.type === "serviceAccount") &&
545
+ !this.options.resolveExecution)
546
+ ) {
547
+ return { amount: 0n, accountingStatus: "unavailable" }
548
+ }
549
+ const records = await this.options.listUsageRecords({ projectId: policy.projectId })
550
+ const entries = await Promise.all(
551
+ records
552
+ .filter(
553
+ (record) =>
554
+ record.occurredAt.getTime() >= period.start.getTime() &&
555
+ record.occurredAt.getTime() < period.end.getTime()
556
+ )
557
+ .map((record) => this.accountingEntry(record))
558
+ )
559
+ return resolveAiLimitActual(
560
+ entries.filter((entry) => aiLimitAccountingEntryAppliesToSubject(entry, policy.subject)),
561
+ dimension
562
+ )
563
+ }
564
+
565
+ private async requireAccountingEntry(
566
+ projectId: string,
567
+ usageRecordId: string
568
+ ): Promise<AiLimitAccountingEntry> {
569
+ if (!this.options.resolveUsageRecord) {
570
+ throw new AiLimitStorageError(
571
+ "unavailable_actuals",
572
+ "[Sixb] In-memory AI limit storage has no immutable accounting source."
573
+ )
574
+ }
575
+ const record = await this.options.resolveUsageRecord({ projectId, usageRecordId })
576
+ if (!record) {
577
+ throw new AiLimitStorageError(
578
+ "missing_usage_record",
579
+ `[Sixb] AI usage record '${usageRecordId}' does not exist in project '${projectId}'.`
580
+ )
581
+ }
582
+ return this.accountingEntry(record)
583
+ }
584
+
585
+ private async accountingEntry(record: AiModelCallUsageRecord): Promise<AiLimitAccountingEntry> {
586
+ const [execution, cost] = await Promise.all([
587
+ this.options.resolveExecution?.({
588
+ projectId: record.projectId,
589
+ executionId: record.executionId,
590
+ }),
591
+ this.options.resolveCostRecord?.({
592
+ projectId: record.projectId,
593
+ usageRecordId: record.id,
594
+ }),
595
+ ])
596
+ const requester = execution?.requestedBy
597
+ return {
598
+ projectId: record.projectId,
599
+ usageRecordId: record.id,
600
+ executionId: record.executionId,
601
+ attempt: record.attempt,
602
+ callId: record.callId,
603
+ occurredAt: new Date(record.occurredAt),
604
+ ...(record.usage.totalTokens === undefined ? {} : { totalTokens: record.usage.totalTokens }),
605
+ requesterGroupIds: [...record.requesterGroupIds],
606
+ ...(requester?.type === "user" || requester?.type === "serviceAccount"
607
+ ? { requester: { type: requester.type, id: requester.id } }
608
+ : {}),
609
+ ...(cost?.status === "rated"
610
+ ? { valuation: { status: "rated" as const, money: structuredClone(cost.money) } }
611
+ : cost
612
+ ? { valuation: { status: "unavailable" as const } }
613
+ : {}),
614
+ }
615
+ }
616
+ }
617
+
618
+ function policyKey(projectId: string, id: string): string {
619
+ return JSON.stringify([projectId, id])
620
+ }
621
+
622
+ function periodStateKey(
623
+ projectId: string,
624
+ subject: AiLimitSubject,
625
+ amount: Pick<NormalizedAiLimitAmount, "meter" | "currency">,
626
+ period: AiLimitPeriod
627
+ ): string {
628
+ return JSON.stringify([
629
+ projectId,
630
+ aiLimitSubjectKey(subject),
631
+ amount.meter,
632
+ amount.currency,
633
+ period.start.toISOString(),
634
+ ])
635
+ }
636
+
637
+ function validatePolicyIdentity(input: GetAiLimitPolicyInput): void {
638
+ assertNonBlank(input.projectId, "projectId")
639
+ assertNonBlank(input.id, "policy id")
640
+ }
641
+
642
+ function missingPolicy(projectId: string, id: string): AiLimitStorageError {
643
+ return new AiLimitStorageError(
644
+ "missing_policy",
645
+ `[Sixb] AI limit policy '${id}' does not exist in project '${projectId}'.`
646
+ )
647
+ }
648
+
649
+ function missingReservation(identity: {
650
+ readonly projectId: string
651
+ readonly executionId: string
652
+ readonly attempt: number
653
+ readonly callId: string
654
+ }): AiLimitStorageError {
655
+ return new AiLimitStorageError(
656
+ "missing_reservation",
657
+ `[Sixb] AI model-call reservation '${identity.callId}' does not exist for execution '${identity.executionId}' attempt ${identity.attempt}.`
658
+ )
659
+ }
660
+
661
+ function invalidState(reservation: AiModelCallReservation, operation: string): AiLimitStorageError {
662
+ return new AiLimitStorageError(
663
+ "invalid_reservation_state",
664
+ `[Sixb] Cannot ${operation} AI model-call reservation '${reservation.callId}' in state '${reservation.state}'.`
665
+ )
666
+ }
667
+
668
+ function replaceMap<TKey, TValue>(target: Map<TKey, TValue>, source: Map<TKey, TValue>): void {
669
+ target.clear()
670
+ for (const [key, value] of structuredClone(source)) target.set(key, value)
671
+ }
@@ -0,0 +1,31 @@
1
+ export type { AiLimitStorageErrorCode } from "./errors"
2
+ export { AiLimitStorageError } from "./errors"
3
+ export type { InMemoryAiLimitStorageOptions, InMemoryAiLimitStorageSnapshot } from "./in-memory"
4
+ export { InMemoryAiLimitStorage } from "./in-memory"
5
+ export { aiLimitCalendarMonth } from "./period"
6
+ export type {
7
+ AiLimitConsumption,
8
+ AiLimitMeter,
9
+ AiLimitPeriod,
10
+ AiLimitPeriodKind,
11
+ AiLimitPolicy,
12
+ AiLimitPolicyStatus,
13
+ AiLimitQuantity,
14
+ AiLimitReservationBucket,
15
+ AiLimitStorage,
16
+ AiLimitSubject,
17
+ AiModelCallReservation,
18
+ AiModelCallReservationIdentity,
19
+ AiModelCallReservationState,
20
+ CreateAiLimitPolicyInput,
21
+ DeleteAiLimitPolicyInput,
22
+ GetAiLimitPolicyInput,
23
+ ListAiLimitPoliciesInput,
24
+ ListAiLimitPolicyStatusesInput,
25
+ MarkAiModelCallReservationUnknownInput,
26
+ ReconcileAiModelCallInput,
27
+ RecordAiModelCallLimitActualsInput,
28
+ ReserveAiModelCallInput,
29
+ ReserveAiModelCallResult,
30
+ UpdateAiLimitPolicyInput,
31
+ } from "./types"