@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.
- package/dist/actions/index.js +19 -17
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/worker.js +4 -4
- package/dist/actions/worker.js.map +1 -1
- package/dist/agents/adapters.d.ts +11 -1
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/context-compaction.d.ts +40 -0
- package/dist/agents/context-compaction.d.ts.map +1 -0
- package/dist/agents/context.js +1 -1
- package/dist/agents/errors.d.ts +1 -1
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/execution.d.ts +3 -0
- package/dist/agents/execution.d.ts.map +1 -1
- package/dist/agents/ids.d.ts +2 -0
- package/dist/agents/ids.d.ts.map +1 -1
- package/dist/agents/index.d.ts +10 -6
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +51 -35
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/streams.d.ts +17 -1
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +5 -3
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/thread-context-projection.d.ts +19 -0
- package/dist/agents/thread-context-projection.d.ts.map +1 -0
- package/dist/agents/tool-definition.d.ts.map +1 -1
- package/dist/agents/tool-result.d.ts +6 -0
- package/dist/agents/tool-result.d.ts.map +1 -0
- package/dist/agents/types.d.ts +46 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +2 -2
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/index.js +11 -5
- package/dist/auth/index.js.map +1 -1
- package/dist/authorization/index.js +6 -2
- package/dist/authorization/index.js.map +1 -1
- package/dist/bootstrap/index.js +33 -31
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/{chunk-ys1nse2v.js → chunk-1wk20wn3.js} +438 -246
- package/dist/{chunk-ys1nse2v.js.map → chunk-1wk20wn3.js.map} +11 -11
- package/dist/{chunk-sa4340y1.js → chunk-1yz3x65y.js} +7 -7
- package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
- package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
- package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +4 -4
- package/dist/{chunk-nnyp53zt.js → chunk-7gw7mepb.js} +259 -9
- package/dist/chunk-7gw7mepb.js.map +14 -0
- package/dist/{chunk-nten49ta.js → chunk-819wnjz8.js} +11 -5
- package/dist/chunk-819wnjz8.js.map +12 -0
- package/dist/chunk-96swp2wd.js +47 -0
- package/dist/chunk-96swp2wd.js.map +10 -0
- package/dist/{chunk-4x43bkbp.js → chunk-a09jx26t.js} +1 -1
- package/dist/{chunk-st4xgxey.js → chunk-afjpa2hs.js} +205 -48
- package/dist/chunk-afjpa2hs.js.map +45 -0
- package/dist/{chunk-0mbx247x.js → chunk-c43qr6s0.js} +427 -99
- package/dist/chunk-c43qr6s0.js.map +46 -0
- package/dist/{chunk-zg9yryhz.js → chunk-cbkm2vam.js} +3 -3
- package/dist/{chunk-57zpb99z.js → chunk-dm72y8wt.js} +26 -3
- package/dist/chunk-dm72y8wt.js.map +10 -0
- package/dist/chunk-drjqm1aa.js +913 -0
- package/dist/chunk-drjqm1aa.js.map +15 -0
- package/dist/chunk-dysw7nsm.js.map +1 -1
- package/dist/{chunk-8ryen3p3.js → chunk-f6erf2vv.js} +1 -1
- package/dist/{chunk-34bqh420.js → chunk-f83ka50g.js} +188 -44
- package/dist/chunk-f83ka50g.js.map +23 -0
- package/dist/{chunk-bct7hmfc.js → chunk-g13869yf.js} +3 -3
- package/dist/{chunk-0k4avqr2.js → chunk-hbeh8j9w.js} +2 -2
- package/dist/{chunk-qvybnnpe.js → chunk-nzw7sm3b.js} +2 -2
- package/dist/{chunk-k9pts48t.js → chunk-pn8n8sba.js} +16 -15
- package/dist/{chunk-k9pts48t.js.map → chunk-pn8n8sba.js.map} +3 -3
- package/dist/{chunk-63te770v.js → chunk-qewtks41.js} +8 -8
- package/dist/{chunk-63te770v.js.map → chunk-qewtks41.js.map} +2 -2
- package/dist/{chunk-85j5ybfj.js → chunk-rdeagz6b.js} +2 -2
- package/dist/{chunk-85j5ybfj.js.map → chunk-rdeagz6b.js.map} +3 -3
- package/dist/chunk-rhrbz7d4.js +36 -0
- package/dist/chunk-rhrbz7d4.js.map +10 -0
- package/dist/{chunk-bh6k3nc6.js → chunk-rs1wbvy6.js} +1 -1
- package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
- package/dist/chunk-rte5sm3z.js.map +12 -0
- package/dist/{chunk-n8herkry.js → chunk-s31d0qmq.js} +57 -20
- package/dist/{chunk-n8herkry.js.map → chunk-s31d0qmq.js.map} +8 -7
- package/dist/{chunk-7pc8b818.js → chunk-sxwk41qa.js} +1 -1
- package/dist/{chunk-663csy96.js → chunk-t0jjkep3.js} +2 -1
- package/dist/chunk-t0jjkep3.js.map +10 -0
- package/dist/{chunk-c6qd89g5.js → chunk-tek1qwgm.js} +6 -6
- package/dist/{chunk-c6qd89g5.js.map → chunk-tek1qwgm.js.map} +1 -1
- package/dist/{chunk-jaj13078.js → chunk-tkdscva6.js} +3 -33
- package/dist/{chunk-jaj13078.js.map → chunk-tkdscva6.js.map} +3 -4
- package/dist/{chunk-5egfka8j.js → chunk-tycbzedm.js} +2 -2
- package/dist/{chunk-g9t3kdtx.js → chunk-x2yw73hy.js} +1 -1
- package/dist/{chunk-57r1cpxx.js → chunk-xc7hq65b.js} +3 -2
- package/dist/{chunk-57r1cpxx.js.map → chunk-xc7hq65b.js.map} +3 -3
- package/dist/chunk-xdf9yswn.js +133 -0
- package/dist/chunk-xdf9yswn.js.map +11 -0
- package/dist/execution/agent.js +29 -27
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/primitive.js +29 -27
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +30 -28
- package/dist/execution/request.js.map +2 -2
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -58
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/types.d.ts +2 -1
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/materialization/model.d.ts +4 -0
- package/dist/materialization/model.d.ts.map +1 -1
- package/dist/materializer/edits/apply.d.ts +6 -1
- package/dist/materializer/edits/apply.d.ts.map +1 -1
- package/dist/materializer/edits/working-state.d.ts +2 -0
- package/dist/materializer/edits/working-state.d.ts.map +1 -1
- package/dist/materializer/effective/resolve.d.ts +3 -1
- package/dist/materializer/effective/resolve.d.ts.map +1 -1
- package/dist/materializer/execution/work-records.d.ts.map +1 -1
- package/dist/materializer/index.js +19 -17
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/shared/normalize.d.ts.map +1 -1
- package/dist/models/index.d.ts +40 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/objects/execution.d.ts +6 -1
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +21 -19
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/link/endpoints.d.ts.map +1 -1
- package/dist/objects/query/executor.d.ts +1 -0
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/explain.d.ts +1 -0
- package/dist/objects/query/explain.d.ts.map +1 -1
- package/dist/objects/query/index.d.ts +3 -1
- package/dist/objects/query/index.d.ts.map +1 -1
- package/dist/objects/query/index.js +30 -5
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/ir.d.ts +14 -1
- package/dist/objects/query/ir.d.ts.map +1 -1
- package/dist/objects/query/links.d.ts +25 -0
- package/dist/objects/query/links.d.ts.map +1 -0
- package/dist/objects/query/normalize.d.ts.map +1 -1
- package/dist/objects/query/planner.d.ts.map +1 -1
- package/dist/objects/query/validate.d.ts +1 -0
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/pipelines/index.js +16 -15
- package/dist/pipelines/index.js.map +1 -1
- package/dist/projections/builders.d.ts +52 -10
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/index.d.ts +2 -1
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/internal.d.ts +4 -1
- package/dist/projections/internal.d.ts.map +1 -1
- package/dist/projections/internal.js +22 -17
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/run-dispatch.d.ts +1 -0
- package/dist/projections/run-dispatch.d.ts.map +1 -1
- package/dist/projections/timestamp.d.ts +3 -0
- package/dist/projections/timestamp.d.ts.map +1 -0
- package/dist/projections/types.d.ts +21 -9
- package/dist/projections/types.d.ts.map +1 -1
- package/dist/projections/validation.d.ts +6 -5
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/query.d.ts +2 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +2 -2
- package/dist/queues/index.d.ts +1 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/types.d.ts +7 -0
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/runtime/ai-cost.d.ts +8 -0
- package/dist/runtime/ai-cost.d.ts.map +1 -0
- package/dist/runtime/create.d.ts +3 -0
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +3 -0
- package/dist/runtime/definitions.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +2 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +2 -0
- package/dist/runtime/resolve-definitions.d.ts.map +1 -1
- package/dist/storage/agents/in-memory.d.ts +22 -4
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/index.d.ts +1 -1
- package/dist/storage/agents/index.d.ts.map +1 -1
- package/dist/storage/agents/provider.d.ts +31 -0
- package/dist/storage/agents/provider.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +22 -7
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +75 -4
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/analytics.d.ts +61 -0
- package/dist/storage/ai-cost/analytics.d.ts.map +1 -0
- package/dist/storage/ai-cost/codec.d.ts +14 -0
- package/dist/storage/ai-cost/codec.d.ts.map +1 -0
- package/dist/storage/ai-cost/errors.d.ts +7 -0
- package/dist/storage/ai-cost/errors.d.ts.map +1 -0
- package/dist/storage/ai-cost/in-memory.d.ts +32 -0
- package/dist/storage/ai-cost/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-cost/index.d.ts +6 -0
- package/dist/storage/ai-cost/index.d.ts.map +1 -0
- package/dist/storage/ai-cost/provider.d.ts +7 -0
- package/dist/storage/ai-cost/provider.d.ts.map +1 -0
- package/dist/storage/ai-cost/provider.js +132 -0
- package/dist/storage/ai-cost/provider.js.map +10 -0
- package/dist/storage/ai-cost/types.d.ts +154 -0
- package/dist/storage/ai-cost/types.d.ts.map +1 -0
- package/dist/storage/ai-cost/validation.d.ts +7 -0
- package/dist/storage/ai-cost/validation.d.ts.map +1 -0
- package/dist/storage/ai-usage/in-memory.d.ts +2 -1
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-usage/index.d.ts +1 -1
- package/dist/storage/ai-usage/index.d.ts.map +1 -1
- package/dist/storage/ai-usage/types.d.ts +6 -0
- package/dist/storage/ai-usage/types.d.ts.map +1 -1
- package/dist/storage/in-memory/index.d.ts +5 -0
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +6 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +33 -21
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/objects/in-memory.d.ts +6 -3
- package/dist/storage/objects/in-memory.d.ts.map +1 -1
- package/dist/storage/objects/index.d.ts +3 -1
- package/dist/storage/objects/index.d.ts.map +1 -1
- package/dist/storage/objects/keys.d.ts +16 -0
- package/dist/storage/objects/keys.d.ts.map +1 -0
- package/dist/storage/objects/types.d.ts +33 -6
- package/dist/storage/objects/types.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/materializations.d.ts +3 -0
- package/dist/storage/ontology/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/types.d.ts +2 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +10 -5
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/syncs/index.js +16 -15
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts +3 -2
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-cost-storage-contract.d.ts +12 -0
- package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -0
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
- package/dist/testing/effective-storage-contract.d.ts +1 -1
- package/dist/testing/effective-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2525 -1480
- package/dist/testing/index.js.map +10 -9
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-query-contract.d.ts +1 -1
- package/dist/testing/object-query-contract.d.ts.map +1 -1
- package/dist/webhooks/internal.js +14 -13
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workers/index.js +12 -2
- package/dist/workers/index.js.map +3 -3
- package/dist/workers/queue-worker.d.ts +2 -0
- package/dist/workers/queue-worker.d.ts.map +1 -1
- package/dist/workflows/execution.d.ts +3 -0
- package/dist/workflows/execution.d.ts.map +1 -1
- package/dist/workflows/index.js +30 -28
- package/dist/workflows/index.js.map +1 -1
- package/package.json +7 -1
- package/src/agents/adapters.ts +64 -23
- package/src/agents/builders.ts +3 -3
- package/src/agents/context-compaction.ts +261 -0
- package/src/agents/errors.ts +2 -2
- package/src/agents/execution.ts +14 -2
- package/src/agents/ids.ts +5 -0
- package/src/agents/index.ts +32 -6
- package/src/agents/request.ts +5 -0
- package/src/agents/streams.ts +56 -0
- package/src/agents/thread-context-projection.ts +93 -0
- package/src/agents/tool-definition.ts +17 -2
- package/src/agents/tool-result.ts +61 -0
- package/src/agents/types.ts +57 -1
- package/src/agents/validation.ts +36 -6
- package/src/http/api-routes.ts +7 -7
- package/src/index.ts +27 -0
- package/src/lake-storage/types.ts +2 -1
- package/src/materialization/model.ts +4 -0
- package/src/materializer/edits/apply.ts +55 -2
- package/src/materializer/edits/operations.ts +8 -1
- package/src/materializer/edits/working-state.ts +7 -0
- package/src/materializer/effective/resolve.ts +78 -9
- package/src/materializer/execution/work-records.ts +3 -1
- package/src/materializer/projections/entry-validator.ts +23 -1
- package/src/materializer/projections/replacement-plan.ts +2 -0
- package/src/materializer/shared/normalize.ts +16 -0
- package/src/materializer/telemetry/append.ts +33 -16
- package/src/models/index.ts +71 -0
- package/src/objects/execution.ts +20 -0
- package/src/objects/link/endpoints.ts +2 -1
- package/src/objects/query/executor.ts +42 -11
- package/src/objects/query/explain.ts +11 -0
- package/src/objects/query/index.ts +6 -0
- package/src/objects/query/ir.ts +16 -0
- package/src/objects/query/links.ts +308 -0
- package/src/objects/query/normalize.ts +40 -1
- package/src/objects/query/planner.ts +5 -0
- package/src/objects/query/validate.ts +58 -2
- package/src/projections/builders.ts +320 -50
- package/src/projections/index.ts +7 -0
- package/src/projections/internal.ts +4 -1
- package/src/projections/ownership.ts +5 -5
- package/src/projections/registry.ts +16 -3
- package/src/projections/revision.ts +35 -5
- package/src/projections/run-dispatch.ts +10 -1
- package/src/projections/timestamp.ts +66 -0
- package/src/projections/types.ts +20 -9
- package/src/projections/validation.ts +85 -19
- package/src/query.ts +2 -0
- package/src/queues/index.ts +1 -0
- package/src/queues/types.ts +8 -0
- package/src/runtime/ai-cost.ts +15 -0
- package/src/runtime/create.ts +4 -0
- package/src/runtime/definitions.ts +3 -0
- package/src/runtime/host.ts +2 -0
- package/src/runtime/resolve-definitions.ts +28 -0
- package/src/storage/agents/in-memory.ts +186 -4
- package/src/storage/agents/index.ts +5 -0
- package/src/storage/agents/provider.ts +225 -0
- package/src/storage/agents/types.ts +82 -3
- package/src/storage/ai-cost/analytics.ts +602 -0
- package/src/storage/ai-cost/codec.ts +136 -0
- package/src/storage/ai-cost/errors.ts +12 -0
- package/src/storage/ai-cost/in-memory.ts +164 -0
- package/src/storage/ai-cost/index.ts +35 -0
- package/src/storage/ai-cost/provider.ts +20 -0
- package/src/storage/ai-cost/types.ts +193 -0
- package/src/storage/ai-cost/validation.ts +337 -0
- package/src/storage/ai-usage/in-memory.ts +23 -0
- package/src/storage/ai-usage/index.ts +1 -0
- package/src/storage/ai-usage/types.ts +10 -0
- package/src/storage/in-memory/index.ts +50 -0
- package/src/storage/index.ts +48 -0
- package/src/storage/objects/in-memory.ts +103 -16
- package/src/storage/objects/index.ts +9 -0
- package/src/storage/objects/keys.ts +36 -0
- package/src/storage/objects/types.ts +34 -6
- package/src/storage/ontology/in-memory/materializations.ts +1 -0
- package/src/storage/ontology/materializations.ts +3 -0
- package/src/storage/ontology/provider-header-validation.ts +2 -2
- package/src/storage/operation-scope.ts +1 -0
- package/src/storage/types.ts +2 -0
- package/src/testing/agent-storage-contract.ts +353 -2
- package/src/testing/ai-cost-storage-contract.ts +320 -0
- package/src/testing/ai-usage-storage-contract.ts +35 -0
- package/src/testing/effective-storage-contract.ts +194 -4
- package/src/testing/index.ts +5 -0
- package/src/testing/lake-storage-contract.ts +56 -0
- package/src/testing/materializer-storage-contract.ts +120 -2
- package/src/testing/object-query-contract.ts +208 -1
- package/src/workers/queue-worker.ts +14 -1
- package/src/workflows/execution.ts +31 -10
- package/dist/agents/prompt.d.ts +0 -15
- package/dist/agents/prompt.d.ts.map +0 -1
- package/dist/chunk-0mbx247x.js.map +0 -43
- package/dist/chunk-34bqh420.js.map +0 -23
- package/dist/chunk-57zpb99z.js.map +0 -10
- package/dist/chunk-663csy96.js.map +0 -10
- package/dist/chunk-6wetht33.js +0 -89
- package/dist/chunk-6wetht33.js.map +0 -10
- package/dist/chunk-88ppkr54.js.map +0 -12
- package/dist/chunk-nnyp53zt.js.map +0 -13
- package/dist/chunk-nten49ta.js.map +0 -12
- package/dist/chunk-st4xgxey.js.map +0 -45
- package/dist/chunk-vp1vc6ee.js +0 -35
- package/dist/chunk-vp1vc6ee.js.map +0 -11
- package/src/agents/prompt.ts +0 -57
- /package/dist/{chunk-sa4340y1.js.map → chunk-1yz3x65y.js.map} +0 -0
- /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
- /package/dist/{chunk-4x43bkbp.js.map → chunk-a09jx26t.js.map} +0 -0
- /package/dist/{chunk-zg9yryhz.js.map → chunk-cbkm2vam.js.map} +0 -0
- /package/dist/{chunk-8ryen3p3.js.map → chunk-f6erf2vv.js.map} +0 -0
- /package/dist/{chunk-bct7hmfc.js.map → chunk-g13869yf.js.map} +0 -0
- /package/dist/{chunk-0k4avqr2.js.map → chunk-hbeh8j9w.js.map} +0 -0
- /package/dist/{chunk-qvybnnpe.js.map → chunk-nzw7sm3b.js.map} +0 -0
- /package/dist/{chunk-bh6k3nc6.js.map → chunk-rs1wbvy6.js.map} +0 -0
- /package/dist/{chunk-7pc8b818.js.map → chunk-sxwk41qa.js.map} +0 -0
- /package/dist/{chunk-5egfka8j.js.map → chunk-tycbzedm.js.map} +0 -0
- /package/dist/{chunk-g9t3kdtx.js.map → chunk-x2yw73hy.js.map} +0 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import type { AiModelCallUsage, AiModelCallUsageRecord } from "../ai-usage"
|
|
2
|
+
import { normalizeAiModelCallUsage } from "../ai-usage"
|
|
3
|
+
import type {
|
|
4
|
+
AiBillableMeter,
|
|
5
|
+
AiBillingIdentity,
|
|
6
|
+
AiCostComponent,
|
|
7
|
+
AiModelCallCostRecord,
|
|
8
|
+
AiPriceSource,
|
|
9
|
+
AiPricingContext,
|
|
10
|
+
AiRatedModelCallCostRecord,
|
|
11
|
+
AiUnpriceableModelCallCostRecord,
|
|
12
|
+
AiUnpriceableReason,
|
|
13
|
+
} from "./types"
|
|
14
|
+
|
|
15
|
+
const SIGNED_INT64_MAX = 9_223_372_036_854_775_807n
|
|
16
|
+
const TOKENS_PER_MILLION = 1_000_000n
|
|
17
|
+
const HALF_MILLION = TOKENS_PER_MILLION / 2n
|
|
18
|
+
const MAX_NUMERIC_TEXT_LENGTH = 128
|
|
19
|
+
const METER_ORDER: Readonly<Record<AiBillableMeter, number>> = {
|
|
20
|
+
"tokens.input.total": 0,
|
|
21
|
+
"tokens.input.uncached": 1,
|
|
22
|
+
"tokens.input.cacheRead": 2,
|
|
23
|
+
"tokens.input.cacheWrite": 3,
|
|
24
|
+
"tokens.output.total": 4,
|
|
25
|
+
"tokens.output.text": 5,
|
|
26
|
+
"tokens.output.reasoning": 6,
|
|
27
|
+
}
|
|
28
|
+
const METERS = new Set(Object.keys(METER_ORDER))
|
|
29
|
+
const UNPRICEABLE_REASONS = new Set<AiUnpriceableReason>([
|
|
30
|
+
"missingBillingIdentity",
|
|
31
|
+
"missingCatalogEntry",
|
|
32
|
+
"missingUsageMeter",
|
|
33
|
+
"unsupportedPricingDimension",
|
|
34
|
+
"invalidUsageForFormula",
|
|
35
|
+
])
|
|
36
|
+
const CONTEXT_STRING_FIELDS = [
|
|
37
|
+
"serviceTier",
|
|
38
|
+
"region",
|
|
39
|
+
"inferenceGeo",
|
|
40
|
+
"routedProviderId",
|
|
41
|
+
"deploymentId",
|
|
42
|
+
"inferenceProfileId",
|
|
43
|
+
"mode",
|
|
44
|
+
] as const
|
|
45
|
+
|
|
46
|
+
export function normalizeAiPricingContext(input: AiPricingContext): AiPricingContext {
|
|
47
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
48
|
+
throw new TypeError("[Sixb] AI pricing context must be an object.")
|
|
49
|
+
}
|
|
50
|
+
const result: Record<string, string | boolean | number> = {}
|
|
51
|
+
for (const field of CONTEXT_STRING_FIELDS) {
|
|
52
|
+
const value = input[field]
|
|
53
|
+
if (value !== undefined) {
|
|
54
|
+
assertNonBlank(value, `pricingContext.${field}`)
|
|
55
|
+
result[field] = value
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (input.batch !== undefined) {
|
|
59
|
+
if (typeof input.batch !== "boolean") {
|
|
60
|
+
throw new TypeError("[Sixb] AI pricingContext.batch must be boolean.")
|
|
61
|
+
}
|
|
62
|
+
result.batch = input.batch
|
|
63
|
+
}
|
|
64
|
+
if (input.cacheWriteTtlSeconds !== undefined) {
|
|
65
|
+
if (!Number.isSafeInteger(input.cacheWriteTtlSeconds) || input.cacheWriteTtlSeconds <= 0) {
|
|
66
|
+
throw new TypeError(
|
|
67
|
+
"[Sixb] AI pricingContext.cacheWriteTtlSeconds must be a positive safe integer."
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
result.cacheWriteTtlSeconds = input.cacheWriteTtlSeconds
|
|
71
|
+
}
|
|
72
|
+
return result
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function normalizeAiModelCallCostRecord(
|
|
76
|
+
input: AiModelCallCostRecord
|
|
77
|
+
): AiModelCallCostRecord {
|
|
78
|
+
assertNonBlank(input.projectId, "cost record projectId")
|
|
79
|
+
assertNonBlank(input.usageRecordId, "cost record usageRecordId")
|
|
80
|
+
const base = {
|
|
81
|
+
projectId: input.projectId,
|
|
82
|
+
usageRecordId: input.usageRecordId,
|
|
83
|
+
pricingContext: normalizeAiPricingContext(input.pricingContext),
|
|
84
|
+
priceSource: normalizePriceSource(input.priceSource),
|
|
85
|
+
ratedAt: cloneDate(input.ratedAt, "cost record ratedAt"),
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (input.status === "rated") return normalizeRatedCost(input, base)
|
|
89
|
+
if (input.status === "unpriceable") return normalizeUnpriceableCost(input, base)
|
|
90
|
+
throw new TypeError("[Sixb] AI cost status is invalid.")
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Verify that a normalized valuation's billed quantities describe its usage record. */
|
|
94
|
+
export function aiModelCallCostMatchesUsage(
|
|
95
|
+
record: AiModelCallCostRecord,
|
|
96
|
+
usageRecord: AiModelCallUsageRecord
|
|
97
|
+
): boolean {
|
|
98
|
+
if (record.projectId !== usageRecord.projectId || record.usageRecordId !== usageRecord.id) {
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
if (record.status === "unpriceable") return true
|
|
102
|
+
|
|
103
|
+
const usage = normalizeAiModelCallUsage(usageRecord.usage)
|
|
104
|
+
const components = new Map(record.components.map((component) => [component.meter, component]))
|
|
105
|
+
return (
|
|
106
|
+
inputComponentsMatchUsage(components, usage) && outputComponentsMatchUsage(components, usage)
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function inputComponentsMatchUsage(
|
|
111
|
+
components: ReadonlyMap<AiBillableMeter, AiCostComponent>,
|
|
112
|
+
usage: AiModelCallUsage
|
|
113
|
+
): boolean {
|
|
114
|
+
if (usage.inputTokens === undefined) return false
|
|
115
|
+
const total = components.get("tokens.input.total")
|
|
116
|
+
const partitions = [
|
|
117
|
+
["tokens.input.uncached", usage.uncachedInputTokens],
|
|
118
|
+
["tokens.input.cacheRead", usage.cacheReadInputTokens],
|
|
119
|
+
["tokens.input.cacheWrite", usage.cacheWriteInputTokens],
|
|
120
|
+
] as const
|
|
121
|
+
const presentPartitions = partitions.filter(([meter]) => components.has(meter))
|
|
122
|
+
|
|
123
|
+
if (total) {
|
|
124
|
+
return presentPartitions.length === 0 && BigInt(total.quantity) === BigInt(usage.inputTokens)
|
|
125
|
+
}
|
|
126
|
+
if (presentPartitions.length === 0) return false
|
|
127
|
+
|
|
128
|
+
let quantity = 0n
|
|
129
|
+
for (const [meter, expected] of presentPartitions) {
|
|
130
|
+
if (expected === undefined) return false
|
|
131
|
+
const component = components.get(meter)!
|
|
132
|
+
if (BigInt(component.quantity) !== BigInt(expected)) return false
|
|
133
|
+
quantity += BigInt(component.quantity)
|
|
134
|
+
}
|
|
135
|
+
return quantity === BigInt(usage.inputTokens)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function outputComponentsMatchUsage(
|
|
139
|
+
components: ReadonlyMap<AiBillableMeter, AiCostComponent>,
|
|
140
|
+
usage: AiModelCallUsage
|
|
141
|
+
): boolean {
|
|
142
|
+
if (usage.outputTokens === undefined) return false
|
|
143
|
+
const total = components.get("tokens.output.total")
|
|
144
|
+
const partitions = [
|
|
145
|
+
["tokens.output.text", usage.textOutputTokens],
|
|
146
|
+
["tokens.output.reasoning", usage.reasoningOutputTokens],
|
|
147
|
+
] as const
|
|
148
|
+
const presentPartitions = partitions.filter(([meter]) => components.has(meter))
|
|
149
|
+
|
|
150
|
+
if (total) {
|
|
151
|
+
return presentPartitions.length === 0 && BigInt(total.quantity) === BigInt(usage.outputTokens)
|
|
152
|
+
}
|
|
153
|
+
if (presentPartitions.length === 0) return false
|
|
154
|
+
|
|
155
|
+
let quantity = 0n
|
|
156
|
+
for (const [meter, expected] of presentPartitions) {
|
|
157
|
+
if (expected === undefined) return false
|
|
158
|
+
const component = components.get(meter)!
|
|
159
|
+
if (BigInt(component.quantity) !== BigInt(expected)) return false
|
|
160
|
+
quantity += BigInt(component.quantity)
|
|
161
|
+
}
|
|
162
|
+
return quantity === BigInt(usage.outputTokens)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function normalizeRatedCost(
|
|
166
|
+
input: AiRatedModelCallCostRecord,
|
|
167
|
+
base: Pick<
|
|
168
|
+
AiRatedModelCallCostRecord,
|
|
169
|
+
"projectId" | "usageRecordId" | "pricingContext" | "priceSource" | "ratedAt"
|
|
170
|
+
>
|
|
171
|
+
): AiRatedModelCallCostRecord {
|
|
172
|
+
const billingIdentity = normalizeBillingIdentity(input.billingIdentity)
|
|
173
|
+
const components = input.components.map(normalizeCostComponent).sort(compareComponents)
|
|
174
|
+
if (components.length === 0) throw new TypeError("[Sixb] AI rated cost requires components.")
|
|
175
|
+
if (new Set(components.map((component) => component.meter)).size !== components.length) {
|
|
176
|
+
throw new TypeError("[Sixb] AI rated cost cannot contain duplicate meters.")
|
|
177
|
+
}
|
|
178
|
+
const amountNanos = parseNonnegativeInt64(input.money.amountNanos, "money amountNanos").toString()
|
|
179
|
+
if (amountNanos !== sumComponents(components)) {
|
|
180
|
+
throw new TypeError("[Sixb] AI cost total does not equal its component charges.")
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
...base,
|
|
184
|
+
status: "rated",
|
|
185
|
+
billingIdentity,
|
|
186
|
+
money: { currency: normalizeCurrency(input.money.currency), amountNanos },
|
|
187
|
+
components,
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function normalizeUnpriceableCost(
|
|
192
|
+
input: AiUnpriceableModelCallCostRecord,
|
|
193
|
+
base: Pick<
|
|
194
|
+
AiUnpriceableModelCallCostRecord,
|
|
195
|
+
"projectId" | "usageRecordId" | "pricingContext" | "priceSource" | "ratedAt"
|
|
196
|
+
>
|
|
197
|
+
): AiUnpriceableModelCallCostRecord {
|
|
198
|
+
if (!UNPRICEABLE_REASONS.has(input.reason)) {
|
|
199
|
+
throw new TypeError(`[Sixb] AI unpriceable reason '${String(input.reason)}' is invalid.`)
|
|
200
|
+
}
|
|
201
|
+
const billingIdentity = input.billingIdentity
|
|
202
|
+
? normalizeBillingIdentity(input.billingIdentity)
|
|
203
|
+
: undefined
|
|
204
|
+
if (input.reason === "missingBillingIdentity" && billingIdentity !== undefined) {
|
|
205
|
+
throw new TypeError("[Sixb] AI missingBillingIdentity cannot contain a billing identity.")
|
|
206
|
+
}
|
|
207
|
+
if (input.reason !== "missingBillingIdentity" && billingIdentity === undefined) {
|
|
208
|
+
throw new TypeError(`[Sixb] AI ${input.reason} requires a billing identity.`)
|
|
209
|
+
}
|
|
210
|
+
const missingMeters = normalizeMissingMeters(input.missingMeters)
|
|
211
|
+
if (input.reason === "missingUsageMeter" && !missingMeters) {
|
|
212
|
+
throw new TypeError("[Sixb] AI missingUsageMeter requires missingMeters.")
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
...base,
|
|
216
|
+
status: "unpriceable",
|
|
217
|
+
...(billingIdentity ? { billingIdentity } : {}),
|
|
218
|
+
reason: input.reason,
|
|
219
|
+
...(missingMeters ? { missingMeters } : {}),
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function normalizeCostComponent(input: AiCostComponent): AiCostComponent {
|
|
224
|
+
if (!METERS.has(input.meter)) {
|
|
225
|
+
throw new TypeError(`[Sixb] AI cost meter '${String(input.meter)}' is invalid.`)
|
|
226
|
+
}
|
|
227
|
+
const expected = calculateComponent(input.meter, input.quantity, input.rateAmountNanosPerMillion)
|
|
228
|
+
if (expected.chargeAmountNanos !== input.chargeAmountNanos) {
|
|
229
|
+
throw new TypeError(`[Sixb] AI cost component '${input.meter}' charge is invalid.`)
|
|
230
|
+
}
|
|
231
|
+
return expected
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function calculateComponent(
|
|
235
|
+
meter: AiBillableMeter,
|
|
236
|
+
quantity: number | string,
|
|
237
|
+
rateAmountNanosPerMillion: string
|
|
238
|
+
): AiCostComponent {
|
|
239
|
+
const normalizedQuantity = parseQuantity(quantity, `${meter} quantity`)
|
|
240
|
+
const rate = parseNonnegativeInt64(rateAmountNanosPerMillion, `${meter} rate`)
|
|
241
|
+
const charge = (normalizedQuantity * rate + HALF_MILLION) / TOKENS_PER_MILLION
|
|
242
|
+
assertSignedInt64(charge, `${meter} charge`)
|
|
243
|
+
return {
|
|
244
|
+
meter,
|
|
245
|
+
quantity: normalizedQuantity.toString(),
|
|
246
|
+
rateAmountNanosPerMillion: rate.toString(),
|
|
247
|
+
chargeAmountNanos: charge.toString(),
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function normalizePriceSource(input: AiPriceSource): AiPriceSource {
|
|
252
|
+
assertNonBlank(input.sourceId, "price sourceId")
|
|
253
|
+
assertNonBlank(input.sourceEntryId, "price sourceEntryId")
|
|
254
|
+
assertNonBlank(input.sourceVersion, "price sourceVersion")
|
|
255
|
+
assertNonBlank(input.sourceUrl, "price sourceUrl")
|
|
256
|
+
return { ...input, observedAt: cloneDate(input.observedAt, "price source observedAt") }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function normalizeBillingIdentity(input: AiBillingIdentity): AiBillingIdentity {
|
|
260
|
+
assertNonBlank(input.providerId, "billingIdentity.providerId")
|
|
261
|
+
assertNonBlank(input.modelId, "billingIdentity.modelId")
|
|
262
|
+
return { providerId: input.providerId, modelId: input.modelId }
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function normalizeMissingMeters(
|
|
266
|
+
input: readonly AiBillableMeter[] | undefined
|
|
267
|
+
): readonly AiBillableMeter[] | undefined {
|
|
268
|
+
if (!input?.length) return undefined
|
|
269
|
+
const result = [...new Set(input)]
|
|
270
|
+
for (const meter of result) {
|
|
271
|
+
if (!METERS.has(meter)) throw new TypeError(`[Sixb] AI missing meter '${meter}' is invalid.`)
|
|
272
|
+
}
|
|
273
|
+
return result.sort((left, right) => METER_ORDER[left] - METER_ORDER[right])
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function sumComponents(components: readonly AiCostComponent[]): string {
|
|
277
|
+
let total = 0n
|
|
278
|
+
for (const component of components) {
|
|
279
|
+
total += parseNonnegativeInt64(component.chargeAmountNanos, "component charge")
|
|
280
|
+
assertSignedInt64(total, "cost total")
|
|
281
|
+
}
|
|
282
|
+
return total.toString()
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function parseQuantity(value: number | string, field: string): bigint {
|
|
286
|
+
if (typeof value === "number") {
|
|
287
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
288
|
+
throw new TypeError(`[Sixb] AI ${field} must be a non-negative safe integer.`)
|
|
289
|
+
}
|
|
290
|
+
return BigInt(value)
|
|
291
|
+
}
|
|
292
|
+
return parseNonnegativeInt64(value, field)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function parseNonnegativeInt64(value: string, field: string): bigint {
|
|
296
|
+
if (
|
|
297
|
+
typeof value !== "string" ||
|
|
298
|
+
value.length === 0 ||
|
|
299
|
+
value.length > MAX_NUMERIC_TEXT_LENGTH ||
|
|
300
|
+
!/^\d+$/.test(value)
|
|
301
|
+
) {
|
|
302
|
+
throw new TypeError(`[Sixb] AI ${field} must be a non-negative integer string.`)
|
|
303
|
+
}
|
|
304
|
+
const parsed = BigInt(value)
|
|
305
|
+
assertSignedInt64(parsed, field)
|
|
306
|
+
return parsed
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function compareComponents(left: AiCostComponent, right: AiCostComponent): number {
|
|
310
|
+
return METER_ORDER[left.meter] - METER_ORDER[right.meter]
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function normalizeCurrency(value: string): string {
|
|
314
|
+
if (!/^[A-Z]{3}$/.test(value)) {
|
|
315
|
+
throw new TypeError("[Sixb] AI currency must be a three-letter uppercase code.")
|
|
316
|
+
}
|
|
317
|
+
return value
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function assertSignedInt64(value: bigint, field: string): void {
|
|
321
|
+
if (value < 0n || value > SIGNED_INT64_MAX) {
|
|
322
|
+
throw new TypeError(`[Sixb] AI ${field} exceeds the signed 64-bit range.`)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function assertNonBlank(value: string, field: string): void {
|
|
327
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
328
|
+
throw new TypeError(`[Sixb] AI ${field} must be nonblank.`)
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function cloneDate(value: Date, field: string): Date {
|
|
333
|
+
if (!(value instanceof Date) || !Number.isFinite(value.getTime())) {
|
|
334
|
+
throw new TypeError(`[Sixb] AI ${field} must be a valid Date.`)
|
|
335
|
+
}
|
|
336
|
+
return new Date(value)
|
|
337
|
+
}
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
AiModelCallUsageRecord,
|
|
6
6
|
AiUsageExecutionSummary,
|
|
7
7
|
AiUsageStorage,
|
|
8
|
+
GetLatestAiModelCallForExecutionInput,
|
|
8
9
|
RecordAiModelCallInput,
|
|
9
10
|
RecordAiModelCallResult,
|
|
10
11
|
SummarizeAiUsageExecutionInput,
|
|
@@ -69,6 +70,28 @@ export class InMemoryAiUsageStorage implements AiUsageStorage {
|
|
|
69
70
|
return { record: structuredClone(record), created: true }
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
async getLatestForExecution(
|
|
74
|
+
input: GetLatestAiModelCallForExecutionInput
|
|
75
|
+
): Promise<AiModelCallUsageRecord | null> {
|
|
76
|
+
assertAiUsageExecutionId(input.executionId)
|
|
77
|
+
if (typeof input.projectId !== "string" || input.projectId.trim().length === 0) {
|
|
78
|
+
throw new TypeError("[Sixb] AI usage projectId must be nonblank.")
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let latest: AiModelCallUsageRecord | null = null
|
|
82
|
+
for (const record of this.records.values()) {
|
|
83
|
+
if (record.projectId !== input.projectId || record.executionId !== input.executionId) continue
|
|
84
|
+
if (
|
|
85
|
+
!latest ||
|
|
86
|
+
record.occurredAt.getTime() > latest.occurredAt.getTime() ||
|
|
87
|
+
(record.occurredAt.getTime() === latest.occurredAt.getTime() && record.id > latest.id)
|
|
88
|
+
) {
|
|
89
|
+
latest = record
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return latest ? structuredClone(latest) : null
|
|
93
|
+
}
|
|
94
|
+
|
|
72
95
|
async summarizeExecution(
|
|
73
96
|
input: SummarizeAiUsageExecutionInput
|
|
74
97
|
): Promise<AiUsageExecutionSummary> {
|
|
@@ -80,6 +80,11 @@ export interface SummarizeAiUsageExecutionsInput {
|
|
|
80
80
|
readonly executionIds: readonly string[]
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
export interface GetLatestAiModelCallForExecutionInput {
|
|
84
|
+
readonly projectId: string
|
|
85
|
+
readonly executionId: string
|
|
86
|
+
}
|
|
87
|
+
|
|
83
88
|
/** Durable, provider-neutral accounting for completed language-model calls. */
|
|
84
89
|
export interface AiUsageStorage {
|
|
85
90
|
/**
|
|
@@ -88,6 +93,11 @@ export interface AiUsageStorage {
|
|
|
88
93
|
*/
|
|
89
94
|
recordModelCall(input: RecordAiModelCallInput): Promise<RecordAiModelCallResult>
|
|
90
95
|
|
|
96
|
+
/** Latest completed provider call for one execution, ordered by occurrence and stable id. */
|
|
97
|
+
getLatestForExecution(
|
|
98
|
+
input: GetLatestAiModelCallForExecutionInput
|
|
99
|
+
): Promise<AiModelCallUsageRecord | null>
|
|
100
|
+
|
|
91
101
|
/** Aggregate normalized usage and call presence across every attempt of one execution. */
|
|
92
102
|
summarizeExecution(input: SummarizeAiUsageExecutionInput): Promise<AiUsageExecutionSummary>
|
|
93
103
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks"
|
|
2
2
|
import { InMemoryActionRunStorage } from "../action-runs"
|
|
3
3
|
import { type AgentStorage, InMemoryAgentStorage } from "../agents"
|
|
4
|
+
import { type AiAccountingAttribution, type AiCostStorage, InMemoryAiCostStorage } from "../ai-cost"
|
|
4
5
|
import { type AiUsageStorage, InMemoryAiUsageStorage } from "../ai-usage"
|
|
5
6
|
import { type AuthStorage, InMemoryAuthStorage } from "../auth"
|
|
6
7
|
import {
|
|
@@ -67,6 +68,9 @@ export class InMemoryStorage implements Storage {
|
|
|
67
68
|
private readonly executionStorage = new InMemoryExecutionStorage(this.authStorage)
|
|
68
69
|
private readonly agentStorage = new InMemoryAgentStorage(this.executionStorage)
|
|
69
70
|
private readonly aiUsageStorage = new InMemoryAiUsageStorage(this.executionStorage)
|
|
71
|
+
private readonly aiCostStorage = new InMemoryAiCostStorage(this.aiUsageStorage, {
|
|
72
|
+
resolve: (input) => this.resolveAiAccountingAttribution(input),
|
|
73
|
+
})
|
|
70
74
|
private readonly actionRunStorage = new InMemoryActionRunStorage(this.executionStorage)
|
|
71
75
|
private readonly syncRunStorage = new InMemorySyncRunStorage(this.executionStorage)
|
|
72
76
|
private readonly pipelineRunStorage = new InMemoryPipelineRunStorage(this.executionStorage)
|
|
@@ -83,6 +87,7 @@ export class InMemoryStorage implements Storage {
|
|
|
83
87
|
readonly executions: ExecutionStorage
|
|
84
88
|
readonly agents: AgentStorage
|
|
85
89
|
readonly aiUsage: AiUsageStorage
|
|
90
|
+
readonly aiCosts: AiCostStorage
|
|
86
91
|
readonly actionRuns: InMemoryActionRunStorage
|
|
87
92
|
readonly syncRuns: SyncRunStorage
|
|
88
93
|
readonly pipelineRuns: PipelineRunStorage
|
|
@@ -108,6 +113,7 @@ export class InMemoryStorage implements Storage {
|
|
|
108
113
|
this.executions = createOperationScopedFacade(this.executionStorage, scope)
|
|
109
114
|
this.agents = createAgentOperationScope(this.agentStorage, scope)
|
|
110
115
|
this.aiUsage = createOperationScopedFacade(this.aiUsageStorage, scope)
|
|
116
|
+
this.aiCosts = createOperationScopedFacade(this.aiCostStorage, scope)
|
|
111
117
|
this.actionRuns = createOperationScopedFacade(this.actionRunStorage, scope)
|
|
112
118
|
this.syncRuns = createOperationScopedFacade(this.syncRunStorage, scope)
|
|
113
119
|
this.pipelineRuns = createOperationScopedFacade(this.pipelineRunStorage, scope)
|
|
@@ -135,6 +141,46 @@ export class InMemoryStorage implements Storage {
|
|
|
135
141
|
registerInMemoryStorageTestingAdapter(this, { snapshot: () => this.snapshot() })
|
|
136
142
|
}
|
|
137
143
|
|
|
144
|
+
private async resolveAiAccountingAttribution(input: {
|
|
145
|
+
readonly projectId: string
|
|
146
|
+
readonly executionId: string
|
|
147
|
+
}): Promise<AiAccountingAttribution | undefined> {
|
|
148
|
+
const execution = await this.executionStorage.getById({
|
|
149
|
+
projectId: input.projectId,
|
|
150
|
+
id: input.executionId,
|
|
151
|
+
})
|
|
152
|
+
if (!execution || execution.executor.type !== "agent") return undefined
|
|
153
|
+
const directRun = await this.agentStorage.runs.getById({
|
|
154
|
+
projectId: input.projectId,
|
|
155
|
+
id: execution.executor.runId,
|
|
156
|
+
})
|
|
157
|
+
if (directRun) {
|
|
158
|
+
return {
|
|
159
|
+
kind: "agent",
|
|
160
|
+
agentId: directRun.agentId,
|
|
161
|
+
agentRunId: directRun.id,
|
|
162
|
+
threadId: directRun.threadId,
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const agentRun = await this.workflowRunStorage.agentNodes.getByNodeRunId({
|
|
166
|
+
projectId: input.projectId,
|
|
167
|
+
nodeRunId: execution.executor.runId,
|
|
168
|
+
})
|
|
169
|
+
if (!agentRun) return undefined
|
|
170
|
+
const node = await this.workflowRunStorage.nodes.getById({
|
|
171
|
+
projectId: input.projectId,
|
|
172
|
+
id: agentRun.nodeRunId,
|
|
173
|
+
})
|
|
174
|
+
if (!node) return undefined
|
|
175
|
+
return {
|
|
176
|
+
kind: "workflowAgent",
|
|
177
|
+
agentId: agentRun.agentId,
|
|
178
|
+
nodeRunId: agentRun.nodeRunId,
|
|
179
|
+
workflowId: node.workflowId,
|
|
180
|
+
workflowRunId: node.workflowRunId,
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
138
184
|
private readonly transactionScope = new AsyncLocalStorage<object>()
|
|
139
185
|
private readonly activeTransactionTokens = new WeakSet<object>()
|
|
140
186
|
private readonly materializationLifecycles = new WeakMap<
|
|
@@ -250,6 +296,7 @@ export class InMemoryStorage implements Storage {
|
|
|
250
296
|
executions: this.executionStorage,
|
|
251
297
|
agents: this.agentStorage,
|
|
252
298
|
aiUsage: this.aiUsageStorage,
|
|
299
|
+
aiCosts: this.aiCostStorage,
|
|
253
300
|
actionRuns: this.actionRunStorage,
|
|
254
301
|
syncRuns: this.syncRunStorage,
|
|
255
302
|
pipelineRuns: this.pipelineRunStorage,
|
|
@@ -276,6 +323,7 @@ export class InMemoryStorage implements Storage {
|
|
|
276
323
|
executions: this.executionStorage.snapshot(),
|
|
277
324
|
agents: this.agentStorage.snapshot(),
|
|
278
325
|
aiUsage: this.aiUsageStorage.snapshot(),
|
|
326
|
+
aiCosts: this.aiCostStorage.snapshot(),
|
|
279
327
|
actionRuns: this.actionRunStorage.snapshot(),
|
|
280
328
|
syncRuns: this.syncRunStorage.snapshot(),
|
|
281
329
|
pipelineRuns: this.pipelineRunStorage.snapshot(),
|
|
@@ -297,6 +345,7 @@ export class InMemoryStorage implements Storage {
|
|
|
297
345
|
this.executionStorage.restore(snapshot.executions)
|
|
298
346
|
this.agentStorage.restore(snapshot.agents)
|
|
299
347
|
this.aiUsageStorage.restore(snapshot.aiUsage)
|
|
348
|
+
this.aiCostStorage.restore(snapshot.aiCosts)
|
|
300
349
|
this.actionRunStorage.restore(snapshot.actionRuns)
|
|
301
350
|
this.syncRunStorage.restore(snapshot.syncRuns)
|
|
302
351
|
this.pipelineRunStorage.restore(snapshot.pipelineRuns)
|
|
@@ -318,6 +367,7 @@ export interface InMemoryStorageSnapshot {
|
|
|
318
367
|
readonly executions: ReturnType<InMemoryExecutionStorage["snapshot"]>
|
|
319
368
|
readonly agents: ReturnType<InMemoryAgentStorage["snapshot"]>
|
|
320
369
|
readonly aiUsage: ReturnType<InMemoryAiUsageStorage["snapshot"]>
|
|
370
|
+
readonly aiCosts: ReturnType<InMemoryAiCostStorage["snapshot"]>
|
|
321
371
|
readonly actionRuns: ReturnType<InMemoryActionRunStorage["snapshot"]>
|
|
322
372
|
readonly syncRuns: ReturnType<InMemorySyncRunStorage["snapshot"]>
|
|
323
373
|
readonly pipelineRuns: ReturnType<InMemoryPipelineRunStorage["snapshot"]>
|
package/src/storage/index.ts
CHANGED
|
@@ -52,6 +52,9 @@ export {
|
|
|
52
52
|
isTerminalActionRun,
|
|
53
53
|
} from "./action-runs"
|
|
54
54
|
export type {
|
|
55
|
+
AgentContextCheckpointReason,
|
|
56
|
+
AgentContextCheckpointRecord,
|
|
57
|
+
AgentContextCheckpointStore,
|
|
55
58
|
AgentExecutionStatus,
|
|
56
59
|
AgentMessageRecord,
|
|
57
60
|
AgentMessageRole,
|
|
@@ -72,8 +75,10 @@ export type {
|
|
|
72
75
|
AgentThreadStore,
|
|
73
76
|
AppendAgentMessageInput,
|
|
74
77
|
ConfirmAgentRunExecutionOwnershipInput,
|
|
78
|
+
CreateAgentContextCheckpointInput,
|
|
75
79
|
CreateAgentRunInput,
|
|
76
80
|
CreateAgentThreadInput,
|
|
81
|
+
DeleteAgentMessagesByRunInput,
|
|
77
82
|
FinishAgentRunInput,
|
|
78
83
|
FinishQueuedAgentRunInput,
|
|
79
84
|
ListAgentMessagesInput,
|
|
@@ -93,6 +98,38 @@ export {
|
|
|
93
98
|
coerceAgentRunFinishReason,
|
|
94
99
|
InMemoryAgentStorage,
|
|
95
100
|
} from "./agents"
|
|
101
|
+
export type {
|
|
102
|
+
AiAccountingAgentBreakdown,
|
|
103
|
+
AiAccountingAggregate,
|
|
104
|
+
AiAccountingAttribution,
|
|
105
|
+
AiAccountingBucket,
|
|
106
|
+
AiAccountingModelBreakdown,
|
|
107
|
+
AiAccountingOverview,
|
|
108
|
+
AiAccountingRange,
|
|
109
|
+
AiAccountingTimeBucket,
|
|
110
|
+
AiAccountingWorkflowBreakdown,
|
|
111
|
+
AiBillableMeter,
|
|
112
|
+
AiBillingIdentity,
|
|
113
|
+
AiCostComponent,
|
|
114
|
+
AiCostStorage,
|
|
115
|
+
AiCostStorageErrorCode,
|
|
116
|
+
AiCostSummary,
|
|
117
|
+
AiModelCallAccountingItem,
|
|
118
|
+
AiModelCallCostRecord,
|
|
119
|
+
AiMoney,
|
|
120
|
+
AiPriceSource,
|
|
121
|
+
AiPricingContext,
|
|
122
|
+
AiRatedModelCallCostRecord,
|
|
123
|
+
AiUnpriceableModelCallCostRecord,
|
|
124
|
+
AiUnpriceableReason,
|
|
125
|
+
InMemoryAiAccountingAttributionSource,
|
|
126
|
+
InMemoryAiCostStorageSnapshot,
|
|
127
|
+
ListAiModelCallAccountingInput,
|
|
128
|
+
ListAiModelCallAccountingResult,
|
|
129
|
+
QueryAiAccountingOverviewInput,
|
|
130
|
+
SummarizeAiCostExecutionsInput,
|
|
131
|
+
} from "./ai-cost"
|
|
132
|
+
export { AiCostStorageError, InMemoryAiCostStorage } from "./ai-cost"
|
|
96
133
|
export type {
|
|
97
134
|
AiModelCallUsage,
|
|
98
135
|
AiModelCallUsageInput,
|
|
@@ -101,6 +138,7 @@ export type {
|
|
|
101
138
|
AiUsageReportingStatus,
|
|
102
139
|
AiUsageStorage,
|
|
103
140
|
AiUsageStorageErrorCode,
|
|
141
|
+
GetLatestAiModelCallForExecutionInput,
|
|
104
142
|
InMemoryAiUsageGroupRow,
|
|
105
143
|
InMemoryAiUsageStorageSnapshot,
|
|
106
144
|
RecordAiModelCallInput,
|
|
@@ -315,10 +353,13 @@ export type {
|
|
|
315
353
|
ExpandedObjectRow,
|
|
316
354
|
FacetObjectsInput,
|
|
317
355
|
FacetObjectsResult,
|
|
356
|
+
LinkBatchKey,
|
|
318
357
|
LinkDirection,
|
|
358
|
+
ObjectBatchKey,
|
|
319
359
|
ObjectFacetBucket,
|
|
320
360
|
ObjectFacetRequest,
|
|
321
361
|
ObjectFacetResult,
|
|
362
|
+
ObjectLinkCursor,
|
|
322
363
|
ObjectLinkRow,
|
|
323
364
|
ObjectQueryCapabilities,
|
|
324
365
|
ObjectQueryCapabilityMap,
|
|
@@ -327,9 +368,16 @@ export type {
|
|
|
327
368
|
ObjectRow,
|
|
328
369
|
ObjectRowLinks,
|
|
329
370
|
ObjectStorage,
|
|
371
|
+
QueryObjectLinksInput,
|
|
372
|
+
QueryObjectLinksResult,
|
|
330
373
|
QueryObjectsInput,
|
|
331
374
|
QueryObjectsResult,
|
|
332
375
|
} from "./objects"
|
|
376
|
+
export {
|
|
377
|
+
linkBatchKey,
|
|
378
|
+
objectBatchKey,
|
|
379
|
+
objectLinkCursor,
|
|
380
|
+
} from "./objects"
|
|
333
381
|
export type {
|
|
334
382
|
AbandonSourceMaterializationCandidateInput,
|
|
335
383
|
AbandonSourceMaterializationInput,
|