@sixb/core 0.1.2 → 0.1.4

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 (383) hide show
  1. package/dist/actions/index.js +19 -17
  2. package/dist/actions/index.js.map +1 -1
  3. package/dist/actions/worker.js +4 -4
  4. package/dist/actions/worker.js.map +1 -1
  5. package/dist/agents/adapters.d.ts +11 -1
  6. package/dist/agents/adapters.d.ts.map +1 -1
  7. package/dist/agents/context-compaction.d.ts +40 -0
  8. package/dist/agents/context-compaction.d.ts.map +1 -0
  9. package/dist/agents/context.js +1 -1
  10. package/dist/agents/errors.d.ts +1 -1
  11. package/dist/agents/errors.d.ts.map +1 -1
  12. package/dist/agents/execution.d.ts +3 -0
  13. package/dist/agents/execution.d.ts.map +1 -1
  14. package/dist/agents/ids.d.ts +2 -0
  15. package/dist/agents/ids.d.ts.map +1 -1
  16. package/dist/agents/index.d.ts +10 -6
  17. package/dist/agents/index.d.ts.map +1 -1
  18. package/dist/agents/index.js +51 -35
  19. package/dist/agents/index.js.map +1 -1
  20. package/dist/agents/request.d.ts.map +1 -1
  21. package/dist/agents/streams.d.ts +17 -1
  22. package/dist/agents/streams.d.ts.map +1 -1
  23. package/dist/agents/streams.js +5 -3
  24. package/dist/agents/streams.js.map +1 -1
  25. package/dist/agents/thread-context-projection.d.ts +19 -0
  26. package/dist/agents/thread-context-projection.d.ts.map +1 -0
  27. package/dist/agents/tool-definition.d.ts.map +1 -1
  28. package/dist/agents/tool-result.d.ts +6 -0
  29. package/dist/agents/tool-result.d.ts.map +1 -0
  30. package/dist/agents/types.d.ts +46 -1
  31. package/dist/agents/types.d.ts.map +1 -1
  32. package/dist/agents/validation.d.ts +2 -2
  33. package/dist/agents/validation.d.ts.map +1 -1
  34. package/dist/auth/index.js +11 -5
  35. package/dist/auth/index.js.map +1 -1
  36. package/dist/authorization/index.js +6 -2
  37. package/dist/authorization/index.js.map +1 -1
  38. package/dist/bootstrap/index.js +33 -31
  39. package/dist/bootstrap/index.js.map +1 -1
  40. package/dist/{chunk-ys1nse2v.js → chunk-1wk20wn3.js} +438 -246
  41. package/dist/{chunk-ys1nse2v.js.map → chunk-1wk20wn3.js.map} +11 -11
  42. package/dist/{chunk-sa4340y1.js → chunk-1yz3x65y.js} +7 -7
  43. package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
  44. package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
  45. package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +4 -4
  46. package/dist/{chunk-nnyp53zt.js → chunk-7gw7mepb.js} +259 -9
  47. package/dist/chunk-7gw7mepb.js.map +14 -0
  48. package/dist/{chunk-nten49ta.js → chunk-819wnjz8.js} +11 -5
  49. package/dist/chunk-819wnjz8.js.map +12 -0
  50. package/dist/chunk-96swp2wd.js +47 -0
  51. package/dist/chunk-96swp2wd.js.map +10 -0
  52. package/dist/{chunk-4x43bkbp.js → chunk-a09jx26t.js} +1 -1
  53. package/dist/{chunk-st4xgxey.js → chunk-afjpa2hs.js} +205 -48
  54. package/dist/chunk-afjpa2hs.js.map +45 -0
  55. package/dist/{chunk-0mbx247x.js → chunk-c43qr6s0.js} +427 -99
  56. package/dist/chunk-c43qr6s0.js.map +46 -0
  57. package/dist/{chunk-zg9yryhz.js → chunk-cbkm2vam.js} +3 -3
  58. package/dist/{chunk-57zpb99z.js → chunk-dm72y8wt.js} +26 -3
  59. package/dist/chunk-dm72y8wt.js.map +10 -0
  60. package/dist/chunk-drjqm1aa.js +913 -0
  61. package/dist/chunk-drjqm1aa.js.map +15 -0
  62. package/dist/chunk-dysw7nsm.js.map +1 -1
  63. package/dist/{chunk-8ryen3p3.js → chunk-f6erf2vv.js} +1 -1
  64. package/dist/{chunk-34bqh420.js → chunk-f83ka50g.js} +188 -44
  65. package/dist/chunk-f83ka50g.js.map +23 -0
  66. package/dist/{chunk-bct7hmfc.js → chunk-g13869yf.js} +3 -3
  67. package/dist/{chunk-0k4avqr2.js → chunk-hbeh8j9w.js} +2 -2
  68. package/dist/{chunk-qvybnnpe.js → chunk-nzw7sm3b.js} +2 -2
  69. package/dist/{chunk-k9pts48t.js → chunk-pn8n8sba.js} +16 -15
  70. package/dist/{chunk-k9pts48t.js.map → chunk-pn8n8sba.js.map} +3 -3
  71. package/dist/{chunk-63te770v.js → chunk-qewtks41.js} +8 -8
  72. package/dist/{chunk-63te770v.js.map → chunk-qewtks41.js.map} +2 -2
  73. package/dist/{chunk-85j5ybfj.js → chunk-rdeagz6b.js} +2 -2
  74. package/dist/{chunk-85j5ybfj.js.map → chunk-rdeagz6b.js.map} +3 -3
  75. package/dist/chunk-rhrbz7d4.js +36 -0
  76. package/dist/chunk-rhrbz7d4.js.map +10 -0
  77. package/dist/{chunk-bh6k3nc6.js → chunk-rs1wbvy6.js} +1 -1
  78. package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
  79. package/dist/chunk-rte5sm3z.js.map +12 -0
  80. package/dist/{chunk-n8herkry.js → chunk-s31d0qmq.js} +57 -20
  81. package/dist/{chunk-n8herkry.js.map → chunk-s31d0qmq.js.map} +8 -7
  82. package/dist/{chunk-7pc8b818.js → chunk-sxwk41qa.js} +1 -1
  83. package/dist/{chunk-663csy96.js → chunk-t0jjkep3.js} +2 -1
  84. package/dist/chunk-t0jjkep3.js.map +10 -0
  85. package/dist/{chunk-c6qd89g5.js → chunk-tek1qwgm.js} +6 -6
  86. package/dist/{chunk-c6qd89g5.js.map → chunk-tek1qwgm.js.map} +1 -1
  87. package/dist/{chunk-jaj13078.js → chunk-tkdscva6.js} +3 -33
  88. package/dist/{chunk-jaj13078.js.map → chunk-tkdscva6.js.map} +3 -4
  89. package/dist/{chunk-5egfka8j.js → chunk-tycbzedm.js} +2 -2
  90. package/dist/{chunk-g9t3kdtx.js → chunk-x2yw73hy.js} +1 -1
  91. package/dist/{chunk-57r1cpxx.js → chunk-xc7hq65b.js} +3 -2
  92. package/dist/{chunk-57r1cpxx.js.map → chunk-xc7hq65b.js.map} +3 -3
  93. package/dist/chunk-xdf9yswn.js +133 -0
  94. package/dist/chunk-xdf9yswn.js.map +11 -0
  95. package/dist/execution/agent.js +29 -27
  96. package/dist/execution/agent.js.map +1 -1
  97. package/dist/execution/primitive.js +29 -27
  98. package/dist/execution/primitive.js.map +2 -2
  99. package/dist/execution/request.js +30 -28
  100. package/dist/execution/request.js.map +2 -2
  101. package/dist/http/index.js +1 -1
  102. package/dist/index.d.ts +6 -5
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +60 -58
  105. package/dist/index.js.map +1 -1
  106. package/dist/lake-storage/types.d.ts +2 -1
  107. package/dist/lake-storage/types.d.ts.map +1 -1
  108. package/dist/materialization/model.d.ts +4 -0
  109. package/dist/materialization/model.d.ts.map +1 -1
  110. package/dist/materializer/edits/apply.d.ts +6 -1
  111. package/dist/materializer/edits/apply.d.ts.map +1 -1
  112. package/dist/materializer/edits/working-state.d.ts +2 -0
  113. package/dist/materializer/edits/working-state.d.ts.map +1 -1
  114. package/dist/materializer/effective/resolve.d.ts +3 -1
  115. package/dist/materializer/effective/resolve.d.ts.map +1 -1
  116. package/dist/materializer/execution/work-records.d.ts.map +1 -1
  117. package/dist/materializer/index.js +19 -17
  118. package/dist/materializer/index.js.map +1 -1
  119. package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
  120. package/dist/materializer/shared/normalize.d.ts.map +1 -1
  121. package/dist/models/index.d.ts +40 -0
  122. package/dist/models/index.d.ts.map +1 -0
  123. package/dist/objects/execution.d.ts +6 -1
  124. package/dist/objects/execution.d.ts.map +1 -1
  125. package/dist/objects/index.js +21 -19
  126. package/dist/objects/index.js.map +1 -1
  127. package/dist/objects/link/endpoints.d.ts.map +1 -1
  128. package/dist/objects/query/executor.d.ts +1 -0
  129. package/dist/objects/query/executor.d.ts.map +1 -1
  130. package/dist/objects/query/explain.d.ts +1 -0
  131. package/dist/objects/query/explain.d.ts.map +1 -1
  132. package/dist/objects/query/index.d.ts +3 -1
  133. package/dist/objects/query/index.d.ts.map +1 -1
  134. package/dist/objects/query/index.js +30 -5
  135. package/dist/objects/query/index.js.map +1 -1
  136. package/dist/objects/query/ir.d.ts +14 -1
  137. package/dist/objects/query/ir.d.ts.map +1 -1
  138. package/dist/objects/query/links.d.ts +25 -0
  139. package/dist/objects/query/links.d.ts.map +1 -0
  140. package/dist/objects/query/normalize.d.ts.map +1 -1
  141. package/dist/objects/query/planner.d.ts.map +1 -1
  142. package/dist/objects/query/validate.d.ts +1 -0
  143. package/dist/objects/query/validate.d.ts.map +1 -1
  144. package/dist/pipelines/index.js +16 -15
  145. package/dist/pipelines/index.js.map +1 -1
  146. package/dist/projections/builders.d.ts +52 -10
  147. package/dist/projections/builders.d.ts.map +1 -1
  148. package/dist/projections/index.d.ts +2 -1
  149. package/dist/projections/index.d.ts.map +1 -1
  150. package/dist/projections/internal.d.ts +4 -1
  151. package/dist/projections/internal.d.ts.map +1 -1
  152. package/dist/projections/internal.js +22 -17
  153. package/dist/projections/internal.js.map +1 -1
  154. package/dist/projections/run-dispatch.d.ts +1 -0
  155. package/dist/projections/run-dispatch.d.ts.map +1 -1
  156. package/dist/projections/timestamp.d.ts +3 -0
  157. package/dist/projections/timestamp.d.ts.map +1 -0
  158. package/dist/projections/types.d.ts +21 -9
  159. package/dist/projections/types.d.ts.map +1 -1
  160. package/dist/projections/validation.d.ts +6 -5
  161. package/dist/projections/validation.d.ts.map +1 -1
  162. package/dist/query.d.ts +2 -1
  163. package/dist/query.d.ts.map +1 -1
  164. package/dist/query.js +2 -2
  165. package/dist/queues/index.d.ts +1 -1
  166. package/dist/queues/index.d.ts.map +1 -1
  167. package/dist/queues/types.d.ts +7 -0
  168. package/dist/queues/types.d.ts.map +1 -1
  169. package/dist/runtime/ai-cost.d.ts +8 -0
  170. package/dist/runtime/ai-cost.d.ts.map +1 -0
  171. package/dist/runtime/create.d.ts +3 -0
  172. package/dist/runtime/create.d.ts.map +1 -1
  173. package/dist/runtime/definitions.d.ts +3 -0
  174. package/dist/runtime/definitions.d.ts.map +1 -1
  175. package/dist/runtime/host.d.ts +2 -0
  176. package/dist/runtime/host.d.ts.map +1 -1
  177. package/dist/runtime/resolve-definitions.d.ts +2 -0
  178. package/dist/runtime/resolve-definitions.d.ts.map +1 -1
  179. package/dist/storage/agents/in-memory.d.ts +22 -4
  180. package/dist/storage/agents/in-memory.d.ts.map +1 -1
  181. package/dist/storage/agents/index.d.ts +1 -1
  182. package/dist/storage/agents/index.d.ts.map +1 -1
  183. package/dist/storage/agents/provider.d.ts +31 -0
  184. package/dist/storage/agents/provider.d.ts.map +1 -1
  185. package/dist/storage/agents/provider.js +22 -7
  186. package/dist/storage/agents/provider.js.map +1 -1
  187. package/dist/storage/agents/types.d.ts +75 -4
  188. package/dist/storage/agents/types.d.ts.map +1 -1
  189. package/dist/storage/ai-cost/analytics.d.ts +61 -0
  190. package/dist/storage/ai-cost/analytics.d.ts.map +1 -0
  191. package/dist/storage/ai-cost/codec.d.ts +14 -0
  192. package/dist/storage/ai-cost/codec.d.ts.map +1 -0
  193. package/dist/storage/ai-cost/errors.d.ts +7 -0
  194. package/dist/storage/ai-cost/errors.d.ts.map +1 -0
  195. package/dist/storage/ai-cost/in-memory.d.ts +32 -0
  196. package/dist/storage/ai-cost/in-memory.d.ts.map +1 -0
  197. package/dist/storage/ai-cost/index.d.ts +6 -0
  198. package/dist/storage/ai-cost/index.d.ts.map +1 -0
  199. package/dist/storage/ai-cost/provider.d.ts +7 -0
  200. package/dist/storage/ai-cost/provider.d.ts.map +1 -0
  201. package/dist/storage/ai-cost/provider.js +132 -0
  202. package/dist/storage/ai-cost/provider.js.map +10 -0
  203. package/dist/storage/ai-cost/types.d.ts +154 -0
  204. package/dist/storage/ai-cost/types.d.ts.map +1 -0
  205. package/dist/storage/ai-cost/validation.d.ts +7 -0
  206. package/dist/storage/ai-cost/validation.d.ts.map +1 -0
  207. package/dist/storage/ai-usage/in-memory.d.ts +2 -1
  208. package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
  209. package/dist/storage/ai-usage/index.d.ts +1 -1
  210. package/dist/storage/ai-usage/index.d.ts.map +1 -1
  211. package/dist/storage/ai-usage/types.d.ts +6 -0
  212. package/dist/storage/ai-usage/types.d.ts.map +1 -1
  213. package/dist/storage/in-memory/index.d.ts +5 -0
  214. package/dist/storage/in-memory/index.d.ts.map +1 -1
  215. package/dist/storage/index.d.ts +6 -3
  216. package/dist/storage/index.d.ts.map +1 -1
  217. package/dist/storage/index.js +33 -21
  218. package/dist/storage/index.js.map +1 -1
  219. package/dist/storage/objects/in-memory.d.ts +6 -3
  220. package/dist/storage/objects/in-memory.d.ts.map +1 -1
  221. package/dist/storage/objects/index.d.ts +3 -1
  222. package/dist/storage/objects/index.d.ts.map +1 -1
  223. package/dist/storage/objects/keys.d.ts +16 -0
  224. package/dist/storage/objects/keys.d.ts.map +1 -0
  225. package/dist/storage/objects/types.d.ts +33 -6
  226. package/dist/storage/objects/types.d.ts.map +1 -1
  227. package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
  228. package/dist/storage/ontology/materializations.d.ts +3 -0
  229. package/dist/storage/ontology/materializations.d.ts.map +1 -1
  230. package/dist/storage/ontology/provider.js +1 -1
  231. package/dist/storage/operation-scope.d.ts.map +1 -1
  232. package/dist/storage/operation-scope.js +1 -1
  233. package/dist/storage/types.d.ts +2 -0
  234. package/dist/storage/types.d.ts.map +1 -1
  235. package/dist/storage/workflow-runs/provider.js +10 -5
  236. package/dist/storage/workflow-runs/provider.js.map +1 -1
  237. package/dist/syncs/index.js +16 -15
  238. package/dist/syncs/index.js.map +1 -1
  239. package/dist/testing/agent-storage-contract.d.ts +3 -2
  240. package/dist/testing/agent-storage-contract.d.ts.map +1 -1
  241. package/dist/testing/ai-cost-storage-contract.d.ts +12 -0
  242. package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -0
  243. package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
  244. package/dist/testing/effective-storage-contract.d.ts +1 -1
  245. package/dist/testing/effective-storage-contract.d.ts.map +1 -1
  246. package/dist/testing/index.d.ts +1 -0
  247. package/dist/testing/index.d.ts.map +1 -1
  248. package/dist/testing/index.js +2525 -1480
  249. package/dist/testing/index.js.map +10 -9
  250. package/dist/testing/lake-storage-contract.d.ts.map +1 -1
  251. package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
  252. package/dist/testing/object-query-contract.d.ts +1 -1
  253. package/dist/testing/object-query-contract.d.ts.map +1 -1
  254. package/dist/webhooks/internal.js +14 -13
  255. package/dist/webhooks/internal.js.map +2 -2
  256. package/dist/workers/index.js +12 -2
  257. package/dist/workers/index.js.map +3 -3
  258. package/dist/workers/queue-worker.d.ts +2 -0
  259. package/dist/workers/queue-worker.d.ts.map +1 -1
  260. package/dist/workflows/execution.d.ts +3 -0
  261. package/dist/workflows/execution.d.ts.map +1 -1
  262. package/dist/workflows/index.js +30 -28
  263. package/dist/workflows/index.js.map +1 -1
  264. package/package.json +7 -1
  265. package/src/agents/adapters.ts +64 -23
  266. package/src/agents/builders.ts +3 -3
  267. package/src/agents/context-compaction.ts +261 -0
  268. package/src/agents/errors.ts +2 -2
  269. package/src/agents/execution.ts +14 -2
  270. package/src/agents/ids.ts +5 -0
  271. package/src/agents/index.ts +32 -6
  272. package/src/agents/request.ts +5 -0
  273. package/src/agents/streams.ts +56 -0
  274. package/src/agents/thread-context-projection.ts +93 -0
  275. package/src/agents/tool-definition.ts +17 -2
  276. package/src/agents/tool-result.ts +61 -0
  277. package/src/agents/types.ts +57 -1
  278. package/src/agents/validation.ts +36 -6
  279. package/src/http/api-routes.ts +7 -7
  280. package/src/index.ts +27 -0
  281. package/src/lake-storage/types.ts +2 -1
  282. package/src/materialization/model.ts +4 -0
  283. package/src/materializer/edits/apply.ts +55 -2
  284. package/src/materializer/edits/operations.ts +8 -1
  285. package/src/materializer/edits/working-state.ts +7 -0
  286. package/src/materializer/effective/resolve.ts +78 -9
  287. package/src/materializer/execution/work-records.ts +3 -1
  288. package/src/materializer/projections/entry-validator.ts +23 -1
  289. package/src/materializer/projections/replacement-plan.ts +2 -0
  290. package/src/materializer/shared/normalize.ts +16 -0
  291. package/src/materializer/telemetry/append.ts +33 -16
  292. package/src/models/index.ts +71 -0
  293. package/src/objects/execution.ts +20 -0
  294. package/src/objects/link/endpoints.ts +2 -1
  295. package/src/objects/query/executor.ts +42 -11
  296. package/src/objects/query/explain.ts +11 -0
  297. package/src/objects/query/index.ts +6 -0
  298. package/src/objects/query/ir.ts +16 -0
  299. package/src/objects/query/links.ts +308 -0
  300. package/src/objects/query/normalize.ts +40 -1
  301. package/src/objects/query/planner.ts +5 -0
  302. package/src/objects/query/validate.ts +58 -2
  303. package/src/projections/builders.ts +320 -50
  304. package/src/projections/index.ts +7 -0
  305. package/src/projections/internal.ts +4 -1
  306. package/src/projections/ownership.ts +5 -5
  307. package/src/projections/registry.ts +16 -3
  308. package/src/projections/revision.ts +35 -5
  309. package/src/projections/run-dispatch.ts +10 -1
  310. package/src/projections/timestamp.ts +66 -0
  311. package/src/projections/types.ts +20 -9
  312. package/src/projections/validation.ts +85 -19
  313. package/src/query.ts +2 -0
  314. package/src/queues/index.ts +1 -0
  315. package/src/queues/types.ts +8 -0
  316. package/src/runtime/ai-cost.ts +15 -0
  317. package/src/runtime/create.ts +4 -0
  318. package/src/runtime/definitions.ts +3 -0
  319. package/src/runtime/host.ts +2 -0
  320. package/src/runtime/resolve-definitions.ts +28 -0
  321. package/src/storage/agents/in-memory.ts +186 -4
  322. package/src/storage/agents/index.ts +5 -0
  323. package/src/storage/agents/provider.ts +225 -0
  324. package/src/storage/agents/types.ts +82 -3
  325. package/src/storage/ai-cost/analytics.ts +602 -0
  326. package/src/storage/ai-cost/codec.ts +136 -0
  327. package/src/storage/ai-cost/errors.ts +12 -0
  328. package/src/storage/ai-cost/in-memory.ts +164 -0
  329. package/src/storage/ai-cost/index.ts +35 -0
  330. package/src/storage/ai-cost/provider.ts +20 -0
  331. package/src/storage/ai-cost/types.ts +193 -0
  332. package/src/storage/ai-cost/validation.ts +337 -0
  333. package/src/storage/ai-usage/in-memory.ts +23 -0
  334. package/src/storage/ai-usage/index.ts +1 -0
  335. package/src/storage/ai-usage/types.ts +10 -0
  336. package/src/storage/in-memory/index.ts +50 -0
  337. package/src/storage/index.ts +48 -0
  338. package/src/storage/objects/in-memory.ts +103 -16
  339. package/src/storage/objects/index.ts +9 -0
  340. package/src/storage/objects/keys.ts +36 -0
  341. package/src/storage/objects/types.ts +34 -6
  342. package/src/storage/ontology/in-memory/materializations.ts +1 -0
  343. package/src/storage/ontology/materializations.ts +3 -0
  344. package/src/storage/ontology/provider-header-validation.ts +2 -2
  345. package/src/storage/operation-scope.ts +1 -0
  346. package/src/storage/types.ts +2 -0
  347. package/src/testing/agent-storage-contract.ts +353 -2
  348. package/src/testing/ai-cost-storage-contract.ts +320 -0
  349. package/src/testing/ai-usage-storage-contract.ts +35 -0
  350. package/src/testing/effective-storage-contract.ts +194 -4
  351. package/src/testing/index.ts +5 -0
  352. package/src/testing/lake-storage-contract.ts +56 -0
  353. package/src/testing/materializer-storage-contract.ts +120 -2
  354. package/src/testing/object-query-contract.ts +208 -1
  355. package/src/workers/queue-worker.ts +14 -1
  356. package/src/workflows/execution.ts +31 -10
  357. package/dist/agents/prompt.d.ts +0 -15
  358. package/dist/agents/prompt.d.ts.map +0 -1
  359. package/dist/chunk-0mbx247x.js.map +0 -43
  360. package/dist/chunk-34bqh420.js.map +0 -23
  361. package/dist/chunk-57zpb99z.js.map +0 -10
  362. package/dist/chunk-663csy96.js.map +0 -10
  363. package/dist/chunk-6wetht33.js +0 -89
  364. package/dist/chunk-6wetht33.js.map +0 -10
  365. package/dist/chunk-88ppkr54.js.map +0 -12
  366. package/dist/chunk-nnyp53zt.js.map +0 -13
  367. package/dist/chunk-nten49ta.js.map +0 -12
  368. package/dist/chunk-st4xgxey.js.map +0 -45
  369. package/dist/chunk-vp1vc6ee.js +0 -35
  370. package/dist/chunk-vp1vc6ee.js.map +0 -11
  371. package/src/agents/prompt.ts +0 -57
  372. /package/dist/{chunk-sa4340y1.js.map → chunk-1yz3x65y.js.map} +0 -0
  373. /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
  374. /package/dist/{chunk-4x43bkbp.js.map → chunk-a09jx26t.js.map} +0 -0
  375. /package/dist/{chunk-zg9yryhz.js.map → chunk-cbkm2vam.js.map} +0 -0
  376. /package/dist/{chunk-8ryen3p3.js.map → chunk-f6erf2vv.js.map} +0 -0
  377. /package/dist/{chunk-bct7hmfc.js.map → chunk-g13869yf.js.map} +0 -0
  378. /package/dist/{chunk-0k4avqr2.js.map → chunk-hbeh8j9w.js.map} +0 -0
  379. /package/dist/{chunk-qvybnnpe.js.map → chunk-nzw7sm3b.js.map} +0 -0
  380. /package/dist/{chunk-bh6k3nc6.js.map → chunk-rs1wbvy6.js.map} +0 -0
  381. /package/dist/{chunk-7pc8b818.js.map → chunk-sxwk41qa.js.map} +0 -0
  382. /package/dist/{chunk-5egfka8j.js.map → chunk-tycbzedm.js.map} +0 -0
  383. /package/dist/{chunk-g9t3kdtx.js.map → chunk-x2yw73hy.js.map} +0 -0
@@ -0,0 +1,913 @@
1
+ // @bun
2
+ import {
3
+ normalizeRequesterGroupIds
4
+ } from "./chunk-rhrbz7d4.js";
5
+ import {
6
+ assertJsonValue,
7
+ isPlainRecord
8
+ } from "./chunk-t8t39h7v.js";
9
+
10
+ // src/storage/ai-usage/errors.ts
11
+ class AiUsageStorageError extends Error {
12
+ code;
13
+ name = "AiUsageStorageError";
14
+ constructor(code, message) {
15
+ super(message);
16
+ this.code = code;
17
+ }
18
+ }
19
+
20
+ // src/storage/ai-usage/usage.ts
21
+ var USAGE_FIELDS = [
22
+ "inputTokens",
23
+ "outputTokens",
24
+ "uncachedInputTokens",
25
+ "cacheReadInputTokens",
26
+ "cacheWriteInputTokens",
27
+ "textOutputTokens",
28
+ "reasoningOutputTokens"
29
+ ];
30
+ function normalizeAiModelCallUsage(input) {
31
+ for (const field of USAGE_FIELDS) {
32
+ assertUsageCount(input[field], field);
33
+ }
34
+ const totalTokens = input.inputTokens === undefined || input.outputTokens === undefined ? undefined : addUsageCounts(input.inputTokens, input.outputTokens, "totalTokens");
35
+ const reportingStatus = input.inputTokens !== undefined && input.outputTokens !== undefined ? "complete" : USAGE_FIELDS.some((field) => input[field] !== undefined) ? "partial" : "unavailable";
36
+ return {
37
+ ...input.inputTokens === undefined ? {} : { inputTokens: input.inputTokens },
38
+ ...input.outputTokens === undefined ? {} : { outputTokens: input.outputTokens },
39
+ ...totalTokens === undefined ? {} : { totalTokens },
40
+ ...input.uncachedInputTokens === undefined ? {} : { uncachedInputTokens: input.uncachedInputTokens },
41
+ ...input.cacheReadInputTokens === undefined ? {} : { cacheReadInputTokens: input.cacheReadInputTokens },
42
+ ...input.cacheWriteInputTokens === undefined ? {} : { cacheWriteInputTokens: input.cacheWriteInputTokens },
43
+ ...input.textOutputTokens === undefined ? {} : { textOutputTokens: input.textOutputTokens },
44
+ ...input.reasoningOutputTokens === undefined ? {} : { reasoningOutputTokens: input.reasoningOutputTokens },
45
+ reportingStatus
46
+ };
47
+ }
48
+ function aggregateAiModelCallUsage(usages) {
49
+ const normalized = Array.from(usages, normalizeAiModelCallUsage);
50
+ const fields = Object.fromEntries(USAGE_FIELDS.map((field) => [field, sumUsageField(normalized, field)]));
51
+ const aggregate = normalizeAiModelCallUsage(fields);
52
+ if (aggregate.reportingStatus === "unavailable" && normalized.some((usage) => usage.reportingStatus !== "unavailable")) {
53
+ return { ...aggregate, reportingStatus: "partial" };
54
+ }
55
+ return aggregate;
56
+ }
57
+ function sumUsageField(usages, field) {
58
+ if (usages.length === 0)
59
+ return;
60
+ let total = 0;
61
+ for (const usage of usages) {
62
+ const value = usage[field];
63
+ if (value === undefined)
64
+ return;
65
+ total = addUsageCounts(total, value, `aggregate ${field}`);
66
+ }
67
+ return total;
68
+ }
69
+ function assertUsageCount(value, field) {
70
+ if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
71
+ throw new TypeError(`[Sixb] AI model-call usage ${field} must be a non-negative safe integer.`);
72
+ }
73
+ }
74
+ function addUsageCounts(left, right, field) {
75
+ const result = left + right;
76
+ if (!Number.isSafeInteger(result)) {
77
+ throw new TypeError(`[Sixb] AI model-call usage ${field} exceeds the safe integer range.`);
78
+ }
79
+ return result;
80
+ }
81
+
82
+ // src/storage/ai-usage/record.ts
83
+ function normalizeAiModelCallRecord(input) {
84
+ assertNonBlank(input.id, "id");
85
+ assertNonBlank(input.projectId, "projectId");
86
+ assertAiUsageExecutionId(input.executionId);
87
+ assertPositiveSafeInteger(input.attempt, "attempt");
88
+ assertNonBlank(input.callId, "callId");
89
+ assertNonBlank(input.providerId, "providerId");
90
+ assertNonBlank(input.requestedModelId, "requestedModelId");
91
+ if (input.responseModelId !== undefined) {
92
+ assertNonBlank(input.responseModelId, "responseModelId");
93
+ }
94
+ assertNonBlank(input.responseId, "responseId");
95
+ const occurredAt = cloneValidDate(input.occurredAt, "occurredAt");
96
+ const recordedAt = cloneValidDate(input.recordedAt ?? new Date, "recordedAt");
97
+ const requesterGroupIds = normalizeRequesterGroupIds(input.requesterGroupIds);
98
+ const rawUsage = cloneRawUsage(input.rawUsage);
99
+ return {
100
+ id: input.id,
101
+ projectId: input.projectId,
102
+ executionId: input.executionId,
103
+ attempt: input.attempt,
104
+ callId: input.callId,
105
+ requesterGroupIds,
106
+ providerId: input.providerId,
107
+ requestedModelId: input.requestedModelId,
108
+ ...input.responseModelId === undefined ? {} : { responseModelId: input.responseModelId },
109
+ responseId: input.responseId,
110
+ usage: normalizeAiModelCallUsage(input.usage),
111
+ ...rawUsage === undefined ? {} : { rawUsage },
112
+ occurredAt,
113
+ recordedAt
114
+ };
115
+ }
116
+ function assertAiUsageExecutionId(executionId) {
117
+ assertNonBlank(executionId, "executionId");
118
+ }
119
+ function cloneRawUsage(rawUsage) {
120
+ if (rawUsage === undefined)
121
+ return;
122
+ if (!isPlainRecord(rawUsage)) {
123
+ throw new TypeError("[Sixb] AI usage rawUsage must be a JSON object.");
124
+ }
125
+ assertJsonValue(rawUsage, "AI usage rawUsage");
126
+ return structuredClone(rawUsage);
127
+ }
128
+ function assertNonBlank(value, field) {
129
+ if (typeof value !== "string" || value.trim().length === 0) {
130
+ throw new TypeError(`[Sixb] AI usage ${field} must be nonblank.`);
131
+ }
132
+ }
133
+ function assertPositiveSafeInteger(value, field) {
134
+ if (!Number.isSafeInteger(value) || value <= 0) {
135
+ throw new TypeError(`[Sixb] AI usage ${field} must be a positive safe integer.`);
136
+ }
137
+ }
138
+ function cloneValidDate(value, field) {
139
+ if (!(value instanceof Date) || !Number.isFinite(value.getTime())) {
140
+ throw new TypeError(`[Sixb] AI usage ${field} must be a valid Date.`);
141
+ }
142
+ return new Date(value);
143
+ }
144
+
145
+ // src/storage/ai-usage/in-memory.ts
146
+ class InMemoryAiUsageStorage {
147
+ executions;
148
+ records = new Map;
149
+ recordKeysByIdempotencyKey = new Map;
150
+ groupRows = new Map;
151
+ constructor(executions) {
152
+ this.executions = executions;
153
+ }
154
+ async recordModelCall(input) {
155
+ const record = normalizeAiModelCallRecord(input);
156
+ await this.assertExecutionExists(record.projectId, record.executionId);
157
+ const idempotencyKey = modelCallIdempotencyKey(record);
158
+ const existingRecordKey = this.recordKeysByIdempotencyKey.get(idempotencyKey);
159
+ if (existingRecordKey !== undefined) {
160
+ const existing = this.records.get(existingRecordKey);
161
+ if (!existing) {
162
+ throw new Error("[Sixb] In-memory AI usage idempotency index is inconsistent.");
163
+ }
164
+ return { record: structuredClone(existing), created: false };
165
+ }
166
+ const recordKey = modelCallRecordKey(record.projectId, record.id);
167
+ if (this.records.has(recordKey)) {
168
+ throw new AiUsageStorageError("duplicate_id", `[Sixb] AI usage record '${record.id}' already exists for project '${record.projectId}'.`);
169
+ }
170
+ this.records.set(recordKey, structuredClone(record));
171
+ this.recordKeysByIdempotencyKey.set(idempotencyKey, recordKey);
172
+ for (const groupId of record.requesterGroupIds) {
173
+ const row = {
174
+ projectId: record.projectId,
175
+ usageRecordId: record.id,
176
+ groupId,
177
+ occurredAt: record.occurredAt
178
+ };
179
+ this.groupRows.set(groupRowKey(row), row);
180
+ }
181
+ return { record: structuredClone(record), created: true };
182
+ }
183
+ async getLatestForExecution(input) {
184
+ assertAiUsageExecutionId(input.executionId);
185
+ if (typeof input.projectId !== "string" || input.projectId.trim().length === 0) {
186
+ throw new TypeError("[Sixb] AI usage projectId must be nonblank.");
187
+ }
188
+ let latest = null;
189
+ for (const record of this.records.values()) {
190
+ if (record.projectId !== input.projectId || record.executionId !== input.executionId)
191
+ continue;
192
+ if (!latest || record.occurredAt.getTime() > latest.occurredAt.getTime() || record.occurredAt.getTime() === latest.occurredAt.getTime() && record.id > latest.id) {
193
+ latest = record;
194
+ }
195
+ }
196
+ return latest ? structuredClone(latest) : null;
197
+ }
198
+ async summarizeExecution(input) {
199
+ const [summary] = await this.summarizeExecutions({
200
+ projectId: input.projectId,
201
+ executionIds: [input.executionId]
202
+ });
203
+ return summary;
204
+ }
205
+ async summarizeExecutions(input) {
206
+ if (typeof input.projectId !== "string" || input.projectId.trim().length === 0) {
207
+ throw new TypeError("[Sixb] AI usage projectId must be nonblank.");
208
+ }
209
+ const usageByExecutionId = new Map;
210
+ for (const executionId of input.executionIds) {
211
+ assertAiUsageExecutionId(executionId);
212
+ usageByExecutionId.set(executionId, []);
213
+ }
214
+ if (usageByExecutionId.size === 0)
215
+ return [];
216
+ for (const record of this.records.values()) {
217
+ if (record.projectId !== input.projectId)
218
+ continue;
219
+ usageByExecutionId.get(record.executionId)?.push(record.usage);
220
+ }
221
+ return input.executionIds.map((executionId) => {
222
+ const usages = usageByExecutionId.get(executionId) ?? [];
223
+ return {
224
+ modelCallCount: usages.length,
225
+ usage: aggregateAiModelCallUsage(usages)
226
+ };
227
+ });
228
+ }
229
+ snapshot() {
230
+ return structuredClone({
231
+ records: this.records,
232
+ recordKeysByIdempotencyKey: this.recordKeysByIdempotencyKey,
233
+ groupRows: this.groupRows
234
+ });
235
+ }
236
+ restore(snapshot) {
237
+ replaceMap(this.records, snapshot.records);
238
+ replaceMap(this.recordKeysByIdempotencyKey, snapshot.recordKeysByIdempotencyKey);
239
+ replaceMap(this.groupRows, snapshot.groupRows);
240
+ }
241
+ async assertExecutionExists(projectId, executionId) {
242
+ const execution = await this.executions.getById({ projectId, id: executionId });
243
+ if (execution)
244
+ return;
245
+ throw new AiUsageStorageError("missing_execution", `[Sixb] AI usage execution '${executionId}' does not exist in project '${projectId}'.`);
246
+ }
247
+ }
248
+ function modelCallRecordKey(projectId, id) {
249
+ return JSON.stringify([projectId, id]);
250
+ }
251
+ function modelCallIdempotencyKey(record) {
252
+ return JSON.stringify([
253
+ record.projectId,
254
+ record.executionId,
255
+ record.attempt,
256
+ record.callId,
257
+ record.responseId
258
+ ]);
259
+ }
260
+ function groupRowKey(row) {
261
+ return JSON.stringify([row.projectId, row.usageRecordId, row.groupId]);
262
+ }
263
+ function replaceMap(target, source) {
264
+ target.clear();
265
+ for (const [key, value] of structuredClone(source)) {
266
+ target.set(key, value);
267
+ }
268
+ }
269
+ // src/storage/ai-cost/analytics.ts
270
+ var DEFAULT_MODEL_CALL_PAGE_SIZE = 50;
271
+ var MAX_MODEL_CALL_PAGE_SIZE = 200;
272
+ var MAX_CHART_BUCKETS = 1e4;
273
+ function normalizeAiAccountingQuery(input) {
274
+ assertNonBlank2(input.projectId, "accounting projectId");
275
+ assertDate(input.from, "accounting from");
276
+ assertDate(input.to, "accounting to");
277
+ if (input.from.getTime() >= input.to.getTime()) {
278
+ throw new TypeError("[Sixb] AI accounting from must be before to.");
279
+ }
280
+ if (input.providerId !== undefined)
281
+ assertNonBlank2(input.providerId, "accounting providerId");
282
+ if (input.modelId !== undefined)
283
+ assertNonBlank2(input.modelId, "accounting modelId");
284
+ return {
285
+ projectId: input.projectId,
286
+ from: new Date(input.from),
287
+ to: new Date(input.to),
288
+ ...input.providerId === undefined ? {} : { providerId: input.providerId },
289
+ ...input.modelId === undefined ? {} : { modelId: input.modelId }
290
+ };
291
+ }
292
+ function normalizeAiModelCallAccountingQuery(input) {
293
+ const query = normalizeAiAccountingQuery(input);
294
+ if (input.executionId !== undefined) {
295
+ assertNonBlank2(input.executionId, "accounting executionId");
296
+ }
297
+ const { limit, offset } = normalizePage(input.limit, input.offset);
298
+ return {
299
+ ...query,
300
+ ...input.executionId === undefined ? {} : { executionId: input.executionId },
301
+ ...input.valuationStatus === undefined ? {} : { valuationStatus: input.valuationStatus },
302
+ limit,
303
+ offset
304
+ };
305
+ }
306
+ function aiAccountingItemMatchesQuery(item, query) {
307
+ const occurredAt = item.usage.occurredAt.getTime();
308
+ return item.usage.projectId === query.projectId && occurredAt >= query.from.getTime() && occurredAt < query.to.getTime() && (query.providerId === undefined || item.usage.providerId === query.providerId) && (query.modelId === undefined || item.usage.requestedModelId === query.modelId);
309
+ }
310
+ function buildAiAccountingOverview(input, source) {
311
+ const query = normalizeAiAccountingQuery(input);
312
+ assertAiAccountingBucket(input.bucket);
313
+ const items = Array.from(source).filter((item) => aiAccountingItemMatchesQuery(item, query));
314
+ const periods = accountingPeriods(query.from, query.to, input.bucket);
315
+ const periodItems = new Map(periods.map((period) => [period.start.getTime(), []]));
316
+ const modelItems = new Map;
317
+ const agentItems = new Map;
318
+ const workflowItems = new Map;
319
+ for (const item of items) {
320
+ const periodStart = aiAccountingBucketStart(item.usage.occurredAt, input.bucket).getTime();
321
+ periodItems.get(periodStart)?.push(item);
322
+ appendGrouped(modelItems, JSON.stringify([item.usage.providerId, item.usage.requestedModelId]), item);
323
+ if (item.attribution)
324
+ appendGrouped(agentItems, item.attribution.agentId, item);
325
+ if (item.attribution?.kind === "workflowAgent") {
326
+ appendGrouped(workflowItems, item.attribution.workflowId, item);
327
+ }
328
+ }
329
+ const series = periods.map((period) => ({
330
+ ...period,
331
+ ...aggregateAccountingItems(periodItems.get(period.start.getTime()) ?? [])
332
+ }));
333
+ const models = [...modelItems].map(([key, grouped]) => {
334
+ const [providerId, modelId] = JSON.parse(key);
335
+ return { providerId, modelId, ...aggregateAccountingItems(grouped) };
336
+ }).sort(compareModelBreakdowns);
337
+ const agents = [...agentItems].map(([agentId, grouped]) => ({ agentId, ...aggregateAccountingItems(grouped) })).sort(compareAgentBreakdowns);
338
+ const workflows = [...workflowItems].map(([workflowId, grouped]) => ({ workflowId, ...aggregateAccountingItems(grouped) })).sort(compareWorkflowBreakdowns);
339
+ return structuredClone({
340
+ range: { from: query.from, to: query.to },
341
+ bucket: input.bucket,
342
+ totals: aggregateAccountingItems(items),
343
+ series,
344
+ models,
345
+ agents,
346
+ workflows
347
+ });
348
+ }
349
+ function buildAiAccountingOverviewFromFragments(input, fragments) {
350
+ const query = normalizeAiAccountingQuery(input);
351
+ const periods = accountingPeriods(query.from, query.to, input.bucket);
352
+ const totals = aggregateFragmentAccumulator();
353
+ const series = new Map(periods.map((period) => [period.start.getTime(), aggregateFragmentAccumulator()]));
354
+ const models = new Map;
355
+ const agents = new Map;
356
+ const workflows = new Map;
357
+ for (const fragment of fragments) {
358
+ let target;
359
+ switch (fragment.dimension) {
360
+ case "totals":
361
+ target = totals;
362
+ break;
363
+ case "series": {
364
+ const start = requiredFragmentDate(fragment.start, "series start");
365
+ const existing = series.get(start.getTime());
366
+ if (!existing) {
367
+ throw new TypeError("[Sixb] AI accounting SQL series returned an unexpected bucket.");
368
+ }
369
+ target = existing;
370
+ break;
371
+ }
372
+ case "model":
373
+ target = getFragmentAccumulator(models, JSON.stringify([
374
+ requiredFragmentString(fragment.providerId, "providerId"),
375
+ requiredFragmentString(fragment.modelId, "modelId")
376
+ ]));
377
+ break;
378
+ case "agent":
379
+ target = getFragmentAccumulator(agents, requiredFragmentString(fragment.agentId, "agentId"));
380
+ break;
381
+ case "workflow":
382
+ target = getFragmentAccumulator(workflows, requiredFragmentString(fragment.workflowId, "workflowId"));
383
+ break;
384
+ }
385
+ appendAggregateFragment(target, fragment);
386
+ }
387
+ return structuredClone({
388
+ range: { from: query.from, to: query.to },
389
+ bucket: input.bucket,
390
+ totals: finishAggregateFragment(totals),
391
+ series: periods.map((period) => ({
392
+ ...period,
393
+ ...finishAggregateFragment(series.get(period.start.getTime()))
394
+ })),
395
+ models: [...models].map(([key, value]) => {
396
+ const [providerId, modelId] = JSON.parse(key);
397
+ return { providerId, modelId, ...finishAggregateFragment(value) };
398
+ }).sort(compareModelBreakdowns),
399
+ agents: [...agents].map(([agentId, value]) => ({ agentId, ...finishAggregateFragment(value) })).sort(compareAgentBreakdowns),
400
+ workflows: [...workflows].map(([workflowId, value]) => ({ workflowId, ...finishAggregateFragment(value) })).sort(compareWorkflowBreakdowns)
401
+ });
402
+ }
403
+ function buildAiModelCallAccountingList(input, source) {
404
+ const query = normalizeAiModelCallAccountingQuery(input);
405
+ const { limit, offset } = query;
406
+ const items = Array.from(source).filter((item) => aiAccountingItemMatchesQuery(item, query)).map(toAccountingItem).filter((item) => (input.executionId === undefined || item.usage.executionId === input.executionId) && (input.valuationStatus === undefined || item.valuationStatus === input.valuationStatus)).sort(compareAccountingItems);
407
+ const page = items.slice(offset, offset + limit);
408
+ return structuredClone({
409
+ items: page,
410
+ hasMore: offset + page.length < items.length,
411
+ total: items.length
412
+ });
413
+ }
414
+ function toAccountingItem(item) {
415
+ return {
416
+ usage: item.usage,
417
+ ...item.attribution === undefined ? {} : { attribution: item.attribution },
418
+ ...item.cost === undefined ? {} : { cost: item.cost },
419
+ valuationStatus: item.cost?.status ?? "unvalued"
420
+ };
421
+ }
422
+ function aiAccountingBucketStart(at, bucket) {
423
+ assertDate(at, "accounting bucket timestamp");
424
+ assertAiAccountingBucket(bucket);
425
+ const start = new Date(at);
426
+ start.setUTCMinutes(0, 0, 0);
427
+ if (bucket === "hour")
428
+ return start;
429
+ start.setUTCHours(0);
430
+ if (bucket === "day")
431
+ return start;
432
+ const mondayOffset = (start.getUTCDay() + 6) % 7;
433
+ start.setUTCDate(start.getUTCDate() - mondayOffset);
434
+ return start;
435
+ }
436
+ function aggregateAccountingItems(items) {
437
+ return {
438
+ modelCallCount: items.length,
439
+ usage: aggregateAiModelCallUsage(items.map((item) => item.usage.usage)),
440
+ costs: aggregateCosts(items)
441
+ };
442
+ }
443
+ function aggregateCosts(items) {
444
+ const amounts = new Map;
445
+ let ratedCallCount = 0;
446
+ let unpriceableCallCount = 0;
447
+ let unvaluedCallCount = 0;
448
+ for (const item of items) {
449
+ if (item.cost?.status === "rated") {
450
+ ratedCallCount += 1;
451
+ addAmount(amounts, item.cost.money.currency, item.cost.money.amountNanos);
452
+ } else if (item.cost?.status === "unpriceable") {
453
+ unpriceableCallCount += 1;
454
+ } else {
455
+ unvaluedCallCount += 1;
456
+ }
457
+ }
458
+ return {
459
+ amounts: [...amounts].sort(([left], [right]) => left.localeCompare(right)).map(([currency, amountNanos]) => ({ currency, amountNanos: amountNanos.toString() })),
460
+ ratedCallCount,
461
+ unpriceableCallCount,
462
+ unvaluedCallCount
463
+ };
464
+ }
465
+ var AGGREGATE_USAGE_FIELDS = [
466
+ "inputTokens",
467
+ "outputTokens",
468
+ "uncachedInputTokens",
469
+ "cacheReadInputTokens",
470
+ "cacheWriteInputTokens",
471
+ "textOutputTokens",
472
+ "reasoningOutputTokens"
473
+ ];
474
+ function aggregateFragmentAccumulator() {
475
+ return {
476
+ modelCallCount: 0n,
477
+ reportedUsageCallCount: 0n,
478
+ usage: Object.fromEntries(AGGREGATE_USAGE_FIELDS.map((field) => [field, { presentCallCount: 0n, total: 0n }])),
479
+ amounts: new Map,
480
+ ratedCallCount: 0n,
481
+ unpriceableCallCount: 0n,
482
+ unvaluedCallCount: 0n
483
+ };
484
+ }
485
+ function getFragmentAccumulator(values, key) {
486
+ const existing = values.get(key);
487
+ if (existing)
488
+ return existing;
489
+ const created = aggregateFragmentAccumulator();
490
+ values.set(key, created);
491
+ return created;
492
+ }
493
+ function appendAggregateFragment(target, fragment) {
494
+ target.modelCallCount += naturalBigInt(fragment.modelCallCount, "modelCallCount");
495
+ target.reportedUsageCallCount += naturalBigInt(fragment.usage.reportedCallCount, "reported usage call count");
496
+ for (const field of AGGREGATE_USAGE_FIELDS) {
497
+ const source = fragment.usage[field];
498
+ const presentCallCount = naturalBigInt(source.presentCallCount, `${field} call count`);
499
+ target.usage[field].presentCallCount += presentCallCount;
500
+ if (source.total !== null) {
501
+ target.usage[field].total += naturalBigInt(source.total, `${field} total`);
502
+ } else if (presentCallCount !== 0n) {
503
+ throw new TypeError(`[Sixb] AI accounting SQL ${field} total is missing.`);
504
+ }
505
+ }
506
+ target.ratedCallCount += naturalBigInt(fragment.costs.ratedCallCount, "rated call count");
507
+ target.unpriceableCallCount += naturalBigInt(fragment.costs.unpriceableCallCount, "unpriceable call count");
508
+ target.unvaluedCallCount += naturalBigInt(fragment.costs.unvaluedCallCount, "unvalued call count");
509
+ if (fragment.costs.amount) {
510
+ addAmount(target.amounts, fragment.costs.amount.currency, fragment.costs.amount.amountNanos);
511
+ }
512
+ }
513
+ function finishAggregateFragment(value) {
514
+ const classifiedCallCount = value.ratedCallCount + value.unpriceableCallCount + value.unvaluedCallCount;
515
+ if (classifiedCallCount !== value.modelCallCount || value.reportedUsageCallCount > value.modelCallCount || AGGREGATE_USAGE_FIELDS.some((field) => value.usage[field].presentCallCount > value.modelCallCount)) {
516
+ throw new TypeError("[Sixb] AI accounting SQL aggregate counts are inconsistent.");
517
+ }
518
+ const modelCallCount = safeAggregateNumber(value.modelCallCount, "model-call count");
519
+ const usageInput = {};
520
+ if (value.modelCallCount > 0n) {
521
+ for (const field of AGGREGATE_USAGE_FIELDS) {
522
+ const aggregate = value.usage[field];
523
+ if (aggregate.presentCallCount === value.modelCallCount) {
524
+ usageInput[field] = safeAggregateNumber(aggregate.total, field);
525
+ }
526
+ }
527
+ }
528
+ let usage = normalizeAiModelCallUsage(usageInput);
529
+ if (usage.reportingStatus === "unavailable" && value.reportedUsageCallCount > 0n) {
530
+ usage = { ...usage, reportingStatus: "partial" };
531
+ }
532
+ return {
533
+ modelCallCount,
534
+ usage,
535
+ costs: {
536
+ amounts: [...value.amounts].sort(([left], [right]) => left.localeCompare(right)).map(([currency, amountNanos]) => ({ currency, amountNanos: amountNanos.toString() })),
537
+ ratedCallCount: safeAggregateNumber(value.ratedCallCount, "rated call count"),
538
+ unpriceableCallCount: safeAggregateNumber(value.unpriceableCallCount, "unpriceable call count"),
539
+ unvaluedCallCount: safeAggregateNumber(value.unvaluedCallCount, "unvalued call count")
540
+ }
541
+ };
542
+ }
543
+ function naturalBigInt(value, field) {
544
+ if (!/^(0|[1-9]\d*)$/.test(value)) {
545
+ throw new TypeError(`[Sixb] AI accounting SQL ${field} must be a natural integer.`);
546
+ }
547
+ return BigInt(value);
548
+ }
549
+ function safeAggregateNumber(value, field) {
550
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
551
+ throw new TypeError(`[Sixb] AI accounting ${field} exceeds the safe integer range.`);
552
+ }
553
+ return Number(value);
554
+ }
555
+ function requiredFragmentString(value, field) {
556
+ if (value === undefined || value.length === 0) {
557
+ throw new TypeError(`[Sixb] AI accounting SQL ${field} is missing.`);
558
+ }
559
+ return value;
560
+ }
561
+ function requiredFragmentDate(value, field) {
562
+ if (value === undefined)
563
+ throw new TypeError(`[Sixb] AI accounting SQL ${field} is missing.`);
564
+ assertDate(value, field);
565
+ return value;
566
+ }
567
+ function accountingPeriods(from, to, bucket) {
568
+ const result = [];
569
+ let cursor = aiAccountingBucketStart(from, bucket);
570
+ while (cursor.getTime() < to.getTime()) {
571
+ if (result.length >= MAX_CHART_BUCKETS) {
572
+ throw new RangeError(`[Sixb] AI accounting query exceeds ${MAX_CHART_BUCKETS} chart buckets.`);
573
+ }
574
+ const next = nextBucket(cursor, bucket);
575
+ result.push({ start: new Date(cursor), end: next });
576
+ cursor = next;
577
+ }
578
+ return result;
579
+ }
580
+ function nextBucket(start, bucket) {
581
+ const next = new Date(start);
582
+ if (bucket === "hour")
583
+ next.setUTCHours(next.getUTCHours() + 1);
584
+ else if (bucket === "day")
585
+ next.setUTCDate(next.getUTCDate() + 1);
586
+ else
587
+ next.setUTCDate(next.getUTCDate() + 7);
588
+ return next;
589
+ }
590
+ function appendGrouped(groups, key, item) {
591
+ const existing = groups.get(key);
592
+ if (existing)
593
+ existing.push(item);
594
+ else
595
+ groups.set(key, [item]);
596
+ }
597
+ function addAmount(amounts, currency, amountNanos) {
598
+ amounts.set(currency, (amounts.get(currency) ?? 0n) + BigInt(amountNanos));
599
+ }
600
+ function normalizePage(requestedLimit, requestedOffset) {
601
+ const limit = requestedLimit ?? DEFAULT_MODEL_CALL_PAGE_SIZE;
602
+ const offset = requestedOffset ?? 0;
603
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_MODEL_CALL_PAGE_SIZE) {
604
+ throw new TypeError(`[Sixb] AI accounting list limit must be an integer between 1 and ${MAX_MODEL_CALL_PAGE_SIZE}.`);
605
+ }
606
+ if (!Number.isSafeInteger(offset) || offset < 0) {
607
+ throw new TypeError("[Sixb] AI accounting list offset must be a non-negative integer.");
608
+ }
609
+ return { limit, offset };
610
+ }
611
+ function compareAccountingItems(left, right) {
612
+ return right.usage.occurredAt.getTime() - left.usage.occurredAt.getTime() || left.usage.id.localeCompare(right.usage.id);
613
+ }
614
+ function compareAgentBreakdowns(left, right) {
615
+ return right.modelCallCount - left.modelCallCount || left.agentId.localeCompare(right.agentId);
616
+ }
617
+ function compareWorkflowBreakdowns(left, right) {
618
+ return right.modelCallCount - left.modelCallCount || left.workflowId.localeCompare(right.workflowId);
619
+ }
620
+ function compareModelBreakdowns(left, right) {
621
+ return right.modelCallCount - left.modelCallCount || left.providerId.localeCompare(right.providerId) || left.modelId.localeCompare(right.modelId);
622
+ }
623
+ function assertAiAccountingBucket(bucket) {
624
+ if (bucket !== "hour" && bucket !== "day" && bucket !== "week") {
625
+ throw new TypeError("[Sixb] AI accounting bucket must be hour, day, or week.");
626
+ }
627
+ }
628
+ function assertDate(value, label) {
629
+ if (!(value instanceof Date) || !Number.isFinite(value.getTime())) {
630
+ throw new TypeError(`[Sixb] AI ${label} must be a valid Date.`);
631
+ }
632
+ }
633
+ function assertNonBlank2(value, label) {
634
+ if (typeof value !== "string" || value.trim().length === 0) {
635
+ throw new TypeError(`[Sixb] AI ${label} must be nonblank.`);
636
+ }
637
+ }
638
+
639
+ // src/storage/ai-cost/validation.ts
640
+ var SIGNED_INT64_MAX = 9223372036854775807n;
641
+ var TOKENS_PER_MILLION = 1000000n;
642
+ var HALF_MILLION = TOKENS_PER_MILLION / 2n;
643
+ var MAX_NUMERIC_TEXT_LENGTH = 128;
644
+ var METER_ORDER = {
645
+ "tokens.input.total": 0,
646
+ "tokens.input.uncached": 1,
647
+ "tokens.input.cacheRead": 2,
648
+ "tokens.input.cacheWrite": 3,
649
+ "tokens.output.total": 4,
650
+ "tokens.output.text": 5,
651
+ "tokens.output.reasoning": 6
652
+ };
653
+ var METERS = new Set(Object.keys(METER_ORDER));
654
+ var UNPRICEABLE_REASONS = new Set([
655
+ "missingBillingIdentity",
656
+ "missingCatalogEntry",
657
+ "missingUsageMeter",
658
+ "unsupportedPricingDimension",
659
+ "invalidUsageForFormula"
660
+ ]);
661
+ var CONTEXT_STRING_FIELDS = [
662
+ "serviceTier",
663
+ "region",
664
+ "inferenceGeo",
665
+ "routedProviderId",
666
+ "deploymentId",
667
+ "inferenceProfileId",
668
+ "mode"
669
+ ];
670
+ function normalizeAiPricingContext(input) {
671
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
672
+ throw new TypeError("[Sixb] AI pricing context must be an object.");
673
+ }
674
+ const result = {};
675
+ for (const field of CONTEXT_STRING_FIELDS) {
676
+ const value = input[field];
677
+ if (value !== undefined) {
678
+ assertNonBlank3(value, `pricingContext.${field}`);
679
+ result[field] = value;
680
+ }
681
+ }
682
+ if (input.batch !== undefined) {
683
+ if (typeof input.batch !== "boolean") {
684
+ throw new TypeError("[Sixb] AI pricingContext.batch must be boolean.");
685
+ }
686
+ result.batch = input.batch;
687
+ }
688
+ if (input.cacheWriteTtlSeconds !== undefined) {
689
+ if (!Number.isSafeInteger(input.cacheWriteTtlSeconds) || input.cacheWriteTtlSeconds <= 0) {
690
+ throw new TypeError("[Sixb] AI pricingContext.cacheWriteTtlSeconds must be a positive safe integer.");
691
+ }
692
+ result.cacheWriteTtlSeconds = input.cacheWriteTtlSeconds;
693
+ }
694
+ return result;
695
+ }
696
+ function normalizeAiModelCallCostRecord(input) {
697
+ assertNonBlank3(input.projectId, "cost record projectId");
698
+ assertNonBlank3(input.usageRecordId, "cost record usageRecordId");
699
+ const base = {
700
+ projectId: input.projectId,
701
+ usageRecordId: input.usageRecordId,
702
+ pricingContext: normalizeAiPricingContext(input.pricingContext),
703
+ priceSource: normalizePriceSource(input.priceSource),
704
+ ratedAt: cloneDate(input.ratedAt, "cost record ratedAt")
705
+ };
706
+ if (input.status === "rated")
707
+ return normalizeRatedCost(input, base);
708
+ if (input.status === "unpriceable")
709
+ return normalizeUnpriceableCost(input, base);
710
+ throw new TypeError("[Sixb] AI cost status is invalid.");
711
+ }
712
+ function aiModelCallCostMatchesUsage(record, usageRecord) {
713
+ if (record.projectId !== usageRecord.projectId || record.usageRecordId !== usageRecord.id) {
714
+ return false;
715
+ }
716
+ if (record.status === "unpriceable")
717
+ return true;
718
+ const usage = normalizeAiModelCallUsage(usageRecord.usage);
719
+ const components = new Map(record.components.map((component) => [component.meter, component]));
720
+ return inputComponentsMatchUsage(components, usage) && outputComponentsMatchUsage(components, usage);
721
+ }
722
+ function inputComponentsMatchUsage(components, usage) {
723
+ if (usage.inputTokens === undefined)
724
+ return false;
725
+ const total = components.get("tokens.input.total");
726
+ const partitions = [
727
+ ["tokens.input.uncached", usage.uncachedInputTokens],
728
+ ["tokens.input.cacheRead", usage.cacheReadInputTokens],
729
+ ["tokens.input.cacheWrite", usage.cacheWriteInputTokens]
730
+ ];
731
+ const presentPartitions = partitions.filter(([meter]) => components.has(meter));
732
+ if (total) {
733
+ return presentPartitions.length === 0 && BigInt(total.quantity) === BigInt(usage.inputTokens);
734
+ }
735
+ if (presentPartitions.length === 0)
736
+ return false;
737
+ let quantity = 0n;
738
+ for (const [meter, expected] of presentPartitions) {
739
+ if (expected === undefined)
740
+ return false;
741
+ const component = components.get(meter);
742
+ if (BigInt(component.quantity) !== BigInt(expected))
743
+ return false;
744
+ quantity += BigInt(component.quantity);
745
+ }
746
+ return quantity === BigInt(usage.inputTokens);
747
+ }
748
+ function outputComponentsMatchUsage(components, usage) {
749
+ if (usage.outputTokens === undefined)
750
+ return false;
751
+ const total = components.get("tokens.output.total");
752
+ const partitions = [
753
+ ["tokens.output.text", usage.textOutputTokens],
754
+ ["tokens.output.reasoning", usage.reasoningOutputTokens]
755
+ ];
756
+ const presentPartitions = partitions.filter(([meter]) => components.has(meter));
757
+ if (total) {
758
+ return presentPartitions.length === 0 && BigInt(total.quantity) === BigInt(usage.outputTokens);
759
+ }
760
+ if (presentPartitions.length === 0)
761
+ return false;
762
+ let quantity = 0n;
763
+ for (const [meter, expected] of presentPartitions) {
764
+ if (expected === undefined)
765
+ return false;
766
+ const component = components.get(meter);
767
+ if (BigInt(component.quantity) !== BigInt(expected))
768
+ return false;
769
+ quantity += BigInt(component.quantity);
770
+ }
771
+ return quantity === BigInt(usage.outputTokens);
772
+ }
773
+ function normalizeRatedCost(input, base) {
774
+ const billingIdentity = normalizeBillingIdentity(input.billingIdentity);
775
+ const components = input.components.map(normalizeCostComponent).sort(compareComponents);
776
+ if (components.length === 0)
777
+ throw new TypeError("[Sixb] AI rated cost requires components.");
778
+ if (new Set(components.map((component) => component.meter)).size !== components.length) {
779
+ throw new TypeError("[Sixb] AI rated cost cannot contain duplicate meters.");
780
+ }
781
+ const amountNanos = parseNonnegativeInt64(input.money.amountNanos, "money amountNanos").toString();
782
+ if (amountNanos !== sumComponents(components)) {
783
+ throw new TypeError("[Sixb] AI cost total does not equal its component charges.");
784
+ }
785
+ return {
786
+ ...base,
787
+ status: "rated",
788
+ billingIdentity,
789
+ money: { currency: normalizeCurrency(input.money.currency), amountNanos },
790
+ components
791
+ };
792
+ }
793
+ function normalizeUnpriceableCost(input, base) {
794
+ if (!UNPRICEABLE_REASONS.has(input.reason)) {
795
+ throw new TypeError(`[Sixb] AI unpriceable reason '${String(input.reason)}' is invalid.`);
796
+ }
797
+ const billingIdentity = input.billingIdentity ? normalizeBillingIdentity(input.billingIdentity) : undefined;
798
+ if (input.reason === "missingBillingIdentity" && billingIdentity !== undefined) {
799
+ throw new TypeError("[Sixb] AI missingBillingIdentity cannot contain a billing identity.");
800
+ }
801
+ if (input.reason !== "missingBillingIdentity" && billingIdentity === undefined) {
802
+ throw new TypeError(`[Sixb] AI ${input.reason} requires a billing identity.`);
803
+ }
804
+ const missingMeters = normalizeMissingMeters(input.missingMeters);
805
+ if (input.reason === "missingUsageMeter" && !missingMeters) {
806
+ throw new TypeError("[Sixb] AI missingUsageMeter requires missingMeters.");
807
+ }
808
+ return {
809
+ ...base,
810
+ status: "unpriceable",
811
+ ...billingIdentity ? { billingIdentity } : {},
812
+ reason: input.reason,
813
+ ...missingMeters ? { missingMeters } : {}
814
+ };
815
+ }
816
+ function normalizeCostComponent(input) {
817
+ if (!METERS.has(input.meter)) {
818
+ throw new TypeError(`[Sixb] AI cost meter '${String(input.meter)}' is invalid.`);
819
+ }
820
+ const expected = calculateComponent(input.meter, input.quantity, input.rateAmountNanosPerMillion);
821
+ if (expected.chargeAmountNanos !== input.chargeAmountNanos) {
822
+ throw new TypeError(`[Sixb] AI cost component '${input.meter}' charge is invalid.`);
823
+ }
824
+ return expected;
825
+ }
826
+ function calculateComponent(meter, quantity, rateAmountNanosPerMillion) {
827
+ const normalizedQuantity = parseQuantity(quantity, `${meter} quantity`);
828
+ const rate = parseNonnegativeInt64(rateAmountNanosPerMillion, `${meter} rate`);
829
+ const charge = (normalizedQuantity * rate + HALF_MILLION) / TOKENS_PER_MILLION;
830
+ assertSignedInt64(charge, `${meter} charge`);
831
+ return {
832
+ meter,
833
+ quantity: normalizedQuantity.toString(),
834
+ rateAmountNanosPerMillion: rate.toString(),
835
+ chargeAmountNanos: charge.toString()
836
+ };
837
+ }
838
+ function normalizePriceSource(input) {
839
+ assertNonBlank3(input.sourceId, "price sourceId");
840
+ assertNonBlank3(input.sourceEntryId, "price sourceEntryId");
841
+ assertNonBlank3(input.sourceVersion, "price sourceVersion");
842
+ assertNonBlank3(input.sourceUrl, "price sourceUrl");
843
+ return { ...input, observedAt: cloneDate(input.observedAt, "price source observedAt") };
844
+ }
845
+ function normalizeBillingIdentity(input) {
846
+ assertNonBlank3(input.providerId, "billingIdentity.providerId");
847
+ assertNonBlank3(input.modelId, "billingIdentity.modelId");
848
+ return { providerId: input.providerId, modelId: input.modelId };
849
+ }
850
+ function normalizeMissingMeters(input) {
851
+ if (!input?.length)
852
+ return;
853
+ const result = [...new Set(input)];
854
+ for (const meter of result) {
855
+ if (!METERS.has(meter))
856
+ throw new TypeError(`[Sixb] AI missing meter '${meter}' is invalid.`);
857
+ }
858
+ return result.sort((left, right) => METER_ORDER[left] - METER_ORDER[right]);
859
+ }
860
+ function sumComponents(components) {
861
+ let total = 0n;
862
+ for (const component of components) {
863
+ total += parseNonnegativeInt64(component.chargeAmountNanos, "component charge");
864
+ assertSignedInt64(total, "cost total");
865
+ }
866
+ return total.toString();
867
+ }
868
+ function parseQuantity(value, field) {
869
+ if (typeof value === "number") {
870
+ if (!Number.isSafeInteger(value) || value < 0) {
871
+ throw new TypeError(`[Sixb] AI ${field} must be a non-negative safe integer.`);
872
+ }
873
+ return BigInt(value);
874
+ }
875
+ return parseNonnegativeInt64(value, field);
876
+ }
877
+ function parseNonnegativeInt64(value, field) {
878
+ if (typeof value !== "string" || value.length === 0 || value.length > MAX_NUMERIC_TEXT_LENGTH || !/^\d+$/.test(value)) {
879
+ throw new TypeError(`[Sixb] AI ${field} must be a non-negative integer string.`);
880
+ }
881
+ const parsed = BigInt(value);
882
+ assertSignedInt64(parsed, field);
883
+ return parsed;
884
+ }
885
+ function compareComponents(left, right) {
886
+ return METER_ORDER[left.meter] - METER_ORDER[right.meter];
887
+ }
888
+ function normalizeCurrency(value) {
889
+ if (!/^[A-Z]{3}$/.test(value)) {
890
+ throw new TypeError("[Sixb] AI currency must be a three-letter uppercase code.");
891
+ }
892
+ return value;
893
+ }
894
+ function assertSignedInt64(value, field) {
895
+ if (value < 0n || value > SIGNED_INT64_MAX) {
896
+ throw new TypeError(`[Sixb] AI ${field} exceeds the signed 64-bit range.`);
897
+ }
898
+ }
899
+ function assertNonBlank3(value, field) {
900
+ if (typeof value !== "string" || value.trim().length === 0) {
901
+ throw new TypeError(`[Sixb] AI ${field} must be nonblank.`);
902
+ }
903
+ }
904
+ function cloneDate(value, field) {
905
+ if (!(value instanceof Date) || !Number.isFinite(value.getTime())) {
906
+ throw new TypeError(`[Sixb] AI ${field} must be a valid Date.`);
907
+ }
908
+ return new Date(value);
909
+ }
910
+
911
+ export { AiUsageStorageError, normalizeAiModelCallUsage, aggregateAiModelCallUsage, normalizeAiModelCallRecord, assertAiUsageExecutionId, InMemoryAiUsageStorage, normalizeAiAccountingQuery, normalizeAiModelCallAccountingQuery, buildAiAccountingOverview, buildAiAccountingOverviewFromFragments, buildAiModelCallAccountingList, toAccountingItem, normalizeAiPricingContext, normalizeAiModelCallCostRecord, aiModelCallCostMatchesUsage };
912
+
913
+ //# debugId=084861E374895B3F64756E2164756E21