@sixb/core 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/index.js +37 -33
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/types/definitions.d.ts +8 -2
- package/dist/actions/types/definitions.d.ts.map +1 -1
- package/dist/actions/worker.js +3 -3
- package/dist/agents/adapters.d.ts +33 -76
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/authority.d.ts +22 -6
- package/dist/agents/authority.d.ts.map +1 -1
- package/dist/agents/builders.d.ts +3 -11
- package/dist/agents/builders.d.ts.map +1 -1
- package/dist/agents/context.js +2 -2
- package/dist/agents/dispatch.d.ts +9 -1
- package/dist/agents/dispatch.d.ts.map +1 -1
- package/dist/agents/errors.d.ts +2 -2
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/execution.d.ts +9 -10
- package/dist/agents/execution.d.ts.map +1 -1
- package/dist/agents/ids.d.ts +4 -0
- package/dist/agents/ids.d.ts.map +1 -1
- package/dist/agents/index.d.ts +13 -9
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +80 -68
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/message.d.ts +17 -10
- package/dist/agents/message.d.ts.map +1 -1
- package/dist/agents/model-loop.d.ts +56 -0
- package/dist/agents/model-loop.d.ts.map +1 -0
- package/dist/agents/reference.d.ts +4 -0
- package/dist/agents/reference.d.ts.map +1 -0
- package/dist/agents/request.d.ts +10 -8
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/retired-config.d.ts +4 -0
- package/dist/agents/retired-config.d.ts.map +1 -0
- package/dist/agents/streams.d.ts +13 -8
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +7 -5
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/tool-catalog.d.ts +9 -0
- package/dist/agents/tool-catalog.d.ts.map +1 -0
- package/dist/agents/tool-definition.d.ts +1 -0
- package/dist/agents/tool-definition.d.ts.map +1 -1
- package/dist/agents/types.d.ts +31 -68
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +4 -10
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/ai-usage/execution.d.ts +53 -0
- package/dist/ai-usage/execution.d.ts.map +1 -0
- package/dist/ai-usage/index.d.ts +3 -0
- package/dist/ai-usage/index.d.ts.map +1 -0
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +7 -7
- package/dist/auth/runtime.d.ts.map +1 -1
- package/dist/auth/strategy.d.ts +1 -1
- package/dist/auth/strategy.d.ts.map +1 -1
- package/dist/auth/types.d.ts +13 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/authorization/decision.d.ts +5 -2
- package/dist/authorization/decision.d.ts.map +1 -1
- package/dist/authorization/grant-kinds.d.ts +24 -8
- package/dist/authorization/grant-kinds.d.ts.map +1 -1
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +8 -6
- package/dist/authorization/index.js.map +1 -1
- package/dist/authorization/resolve.d.ts +3 -3
- package/dist/authorization/resolve.d.ts.map +1 -1
- package/dist/authorization/types.d.ts +7 -5
- package/dist/authorization/types.d.ts.map +1 -1
- package/dist/blob-storage/browser.js +2 -2
- package/dist/blob-storage/index.js +3 -3
- package/dist/bootstrap/discovery.d.ts +1 -7
- package/dist/bootstrap/discovery.d.ts.map +1 -1
- package/dist/bootstrap/index.js +52 -48
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/broker/index.js +2 -2
- package/dist/{chunk-zqysyfjt.js → chunk-08m3b6w8.js} +1 -1
- package/dist/{chunk-xdf9yswn.js → chunk-08twe8m6.js} +93 -8
- package/dist/chunk-08twe8m6.js.map +12 -0
- package/dist/{chunk-xkthy56g.js → chunk-1kamz6j0.js} +1 -1
- package/dist/{chunk-h6h91mfy.js → chunk-2b5qtban.js} +12 -12
- package/dist/{chunk-h6h91mfy.js.map → chunk-2b5qtban.js.map} +3 -3
- package/dist/{chunk-0172wgm9.js → chunk-2xns679x.js} +10 -2
- package/dist/{chunk-0172wgm9.js.map → chunk-2xns679x.js.map} +3 -3
- package/dist/{chunk-f83ka50g.js → chunk-37wk412q.js} +86 -28
- package/dist/{chunk-f83ka50g.js.map → chunk-37wk412q.js.map} +8 -8
- package/dist/{chunk-6d5xdj1q.js → chunk-3fqt22c4.js} +4 -4
- package/dist/{chunk-t9xghkva.js → chunk-3kv70xwp.js} +3 -2
- package/dist/{chunk-t9xghkva.js.map → chunk-3kv70xwp.js.map} +3 -3
- package/dist/{chunk-z3zp0bj1.js → chunk-407j3msh.js} +1 -1
- package/dist/{chunk-rhrbz7d4.js → chunk-4a849fr1.js} +1 -1
- package/dist/{chunk-62c7t4jc.js → chunk-4nxeacx7.js} +1 -1
- package/dist/{chunk-cy0n5dms.js → chunk-5jcdmjam.js} +1 -1
- package/dist/{chunk-819wnjz8.js → chunk-64sr682n.js} +7 -7
- package/dist/{chunk-v0egge8b.js → chunk-6ed5bwnd.js} +666 -81
- package/dist/chunk-6ed5bwnd.js.map +57 -0
- package/dist/{chunk-x2yw73hy.js → chunk-7ds9620f.js} +1 -1
- package/dist/{chunk-dm72y8wt.js → chunk-7y0f6rf1.js} +29 -16
- package/dist/chunk-7y0f6rf1.js.map +10 -0
- package/dist/{chunk-72q2y8hn.js → chunk-8tsf6dmc.js} +2 -2
- package/dist/{chunk-72q2y8hn.js.map → chunk-8tsf6dmc.js.map} +3 -3
- package/dist/{chunk-tbv03sx2.js → chunk-9aehf39w.js} +7 -7
- package/dist/{chunk-ezake7g1.js → chunk-agsvg9ar.js} +1 -1
- package/dist/{chunk-rdeagz6b.js → chunk-atmkaf60.js} +1 -1
- package/dist/{chunk-rdeagz6b.js.map → chunk-atmkaf60.js.map} +2 -2
- package/dist/chunk-c15dr03f.js +43 -0
- package/dist/chunk-c15dr03f.js.map +10 -0
- package/dist/{chunk-78c6xvyr.js → chunk-d2ndstdf.js} +8 -6
- package/dist/{chunk-78c6xvyr.js.map → chunk-d2ndstdf.js.map} +2 -2
- package/dist/{chunk-rnshztfq.js → chunk-d63tybny.js} +2 -2
- package/dist/{chunk-t0jjkep3.js → chunk-d8qkxt2v.js} +4 -2
- package/dist/chunk-d8qkxt2v.js.map +10 -0
- package/dist/{chunk-vybf6pkp.js → chunk-dbc80ad7.js} +1 -1
- package/dist/{chunk-4gz41why.js → chunk-dqn23610.js} +1 -1
- package/dist/{chunk-z3ga9q5m.js → chunk-e4rvtvpw.js} +13 -11
- package/dist/{chunk-z3ga9q5m.js.map → chunk-e4rvtvpw.js.map} +2 -2
- package/dist/{chunk-h9kxd41f.js → chunk-gbrpsx4m.js} +19 -6
- package/dist/chunk-gbrpsx4m.js.map +11 -0
- package/dist/{chunk-84h6qhmp.js → chunk-h0knpbz5.js} +468 -1236
- package/dist/chunk-h0knpbz5.js.map +38 -0
- package/dist/{chunk-zp2v2rv6.js → chunk-ha58tjtt.js} +6 -6
- package/dist/{chunk-f6erf2vv.js → chunk-hdz94br2.js} +2 -2
- package/dist/chunk-jecn6t54.js +307 -0
- package/dist/chunk-jecn6t54.js.map +12 -0
- package/dist/{chunk-dsrkgtnh.js → chunk-jq43kdvk.js} +1 -1
- package/dist/{chunk-wtmzkcht.js → chunk-k34z5rvh.js} +1 -1
- package/dist/{chunk-htq0qh7z.js → chunk-ka3a2ft3.js} +2 -2
- package/dist/{chunk-4h947jd8.js → chunk-kt81c11h.js} +2 -2
- package/dist/chunk-n2arzn6e.js +1745 -0
- package/dist/chunk-n2arzn6e.js.map +20 -0
- package/dist/{chunk-f2rt4vkh.js → chunk-n2w475r0.js} +3 -3
- package/dist/{chunk-t8t39h7v.js → chunk-n6jxh8sw.js} +10 -2
- package/dist/chunk-n6jxh8sw.js.map +10 -0
- package/dist/{chunk-drjqm1aa.js → chunk-p03r0h5s.js} +310 -28
- package/dist/chunk-p03r0h5s.js.map +16 -0
- package/dist/chunk-p2vqaxkc.js +528 -0
- package/dist/chunk-p2vqaxkc.js.map +15 -0
- package/dist/{chunk-gadsm794.js → chunk-qjycjdj6.js} +84 -11
- package/dist/chunk-qjycjdj6.js.map +12 -0
- package/dist/chunk-qjzp9xyb.js +286 -0
- package/dist/chunk-qjzp9xyb.js.map +12 -0
- package/dist/{chunk-am6eczah.js → chunk-qv38twt8.js} +50 -69
- package/dist/{chunk-am6eczah.js.map → chunk-qv38twt8.js.map} +8 -8
- package/dist/{chunk-bhxaq2nn.js → chunk-qw9gvjv5.js} +1 -1
- package/dist/{chunk-r0rry8dn.js → chunk-rp1mvzb4.js} +6 -6
- package/dist/{chunk-tkdscva6.js → chunk-rre42skh.js} +187 -18
- package/dist/chunk-rre42skh.js.map +39 -0
- package/dist/{chunk-ghteq96b.js → chunk-s5y30bc9.js} +2 -2
- package/dist/{chunk-a31h57d5.js → chunk-tn7xcs2n.js} +2 -2
- package/dist/{chunk-6gjqgd3d.js → chunk-tpnd31c1.js} +2 -1
- package/dist/chunk-tpnd31c1.js.map +11 -0
- package/dist/chunk-trxxmgnf.js +68 -0
- package/dist/chunk-trxxmgnf.js.map +11 -0
- package/dist/{chunk-ea73pzk7.js → chunk-vjjv9mrb.js} +2 -2
- package/dist/{chunk-8b55ygje.js → chunk-w3e09qqk.js} +1 -1
- package/dist/{chunk-ckxfnx7f.js → chunk-wjgm6jjt.js} +2 -2
- package/dist/{chunk-3j7573mj.js → chunk-x0qhkqje.js} +2 -2
- package/dist/{chunk-dysw7nsm.js → chunk-xdpwpkha.js} +2 -2
- package/dist/{chunk-1q02e95s.js → chunk-y35ma3mj.js} +11 -16
- package/dist/{chunk-1q02e95s.js.map → chunk-y35ma3mj.js.map} +3 -4
- package/dist/{chunk-qewtks41.js → chunk-z2sery1b.js} +64 -1
- package/dist/{chunk-qewtks41.js.map → chunk-z2sery1b.js.map} +3 -3
- package/dist/error-reporting/internal.js +4 -4
- package/dist/error-reporting/types.d.ts +7 -2
- package/dist/error-reporting/types.d.ts.map +1 -1
- package/dist/errors/catalog.d.ts +8 -0
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/internal.js +2 -2
- package/dist/events/index.js +4 -4
- package/dist/execution/agent.d.ts +18 -9
- package/dist/execution/agent.d.ts.map +1 -1
- package/dist/execution/agent.js +52 -43
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/authorization.d.ts +14 -4
- package/dist/execution/authorization.d.ts.map +1 -1
- package/dist/execution/primitive.js +45 -43
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.d.ts +3 -1
- package/dist/execution/request.d.ts.map +1 -1
- package/dist/execution/request.js +46 -44
- package/dist/execution/request.js.map +3 -3
- package/dist/execution/types.d.ts +1 -1
- package/dist/execution/types.d.ts.map +1 -1
- package/dist/http/api-routes.d.ts.map +1 -1
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -77
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +2 -0
- package/dist/json.d.ts.map +1 -1
- package/dist/lake-storage/index.js +5 -5
- package/dist/logging/index.js +3 -3
- package/dist/logging/types.js +2 -2
- package/dist/materialization/index.js +2 -2
- package/dist/materializer/index.js +33 -29
- package/dist/materializer/index.js.map +1 -1
- package/dist/models/catalog.d.ts +40 -0
- package/dist/models/catalog.d.ts.map +1 -0
- package/dist/models/definitions.d.ts +25 -0
- package/dist/models/definitions.d.ts.map +1 -0
- package/dist/models/errors.d.ts +52 -0
- package/dist/models/errors.d.ts.map +1 -0
- package/dist/models/events.d.ts +192 -0
- package/dist/models/events.d.ts.map +1 -0
- package/dist/models/index.d.ts +17 -39
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +50 -0
- package/dist/models/index.js.map +9 -0
- package/dist/models/language-model.d.ts +90 -0
- package/dist/models/language-model.d.ts.map +1 -0
- package/dist/models/messages.d.ts +74 -0
- package/dist/models/messages.d.ts.map +1 -0
- package/dist/models/pricing.d.ts +69 -0
- package/dist/models/pricing.d.ts.map +1 -0
- package/dist/models/rate-card.d.ts +24 -0
- package/dist/models/rate-card.d.ts.map +1 -0
- package/dist/models/tools.d.ts +24 -0
- package/dist/models/tools.d.ts.map +1 -0
- package/dist/objects/index.js +38 -34
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/query/index.js +32 -28
- package/dist/objects/query/index.js.map +1 -1
- package/dist/ontology/index.js +5 -5
- package/dist/ontology/internal.js +4 -4
- package/dist/pipelines/index.js +37 -35
- package/dist/pipelines/index.js.map +1 -1
- package/dist/projections/internal.js +35 -31
- package/dist/projections/internal.js.map +1 -1
- package/dist/queues/in-memory.d.ts +3 -2
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.d.ts +3 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/index.js +1 -1
- package/dist/queues/types.d.ts +15 -3
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/runtime/create.d.ts +4 -4
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +2 -2
- package/dist/runtime/definitions.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +3 -2
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +2 -2
- package/dist/runtime/resolve-definitions.d.ts.map +1 -1
- package/dist/runtime/sixb.d.ts +4 -2
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/security/every.d.ts +1 -4
- package/dist/security/every.d.ts.map +1 -1
- package/dist/security/grants.d.ts +6 -5
- package/dist/security/grants.d.ts.map +1 -1
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/registry.d.ts +1 -1
- package/dist/security/registry.d.ts.map +1 -1
- package/dist/security/types.d.ts +13 -5
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/validation.d.ts +4 -2
- package/dist/security/validation.d.ts.map +1 -1
- package/dist/storage/action-runs/failure.js +3 -3
- package/dist/storage/action-runs/provider.js +2 -2
- package/dist/storage/agents/errors.d.ts +1 -1
- package/dist/storage/agents/errors.d.ts.map +1 -1
- package/dist/storage/agents/in-memory.d.ts +3 -2
- 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 +11 -4
- package/dist/storage/agents/provider.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +18 -15
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +65 -17
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/analytics.d.ts +2 -1
- package/dist/storage/ai-cost/analytics.d.ts.map +1 -1
- package/dist/storage/ai-cost/codec.d.ts +3 -2
- package/dist/storage/ai-cost/codec.d.ts.map +1 -1
- package/dist/storage/ai-cost/groups.d.ts +51 -0
- package/dist/storage/ai-cost/groups.d.ts.map +1 -0
- package/dist/storage/ai-cost/in-memory.d.ts +11 -1
- package/dist/storage/ai-cost/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-cost/index.d.ts +1 -1
- package/dist/storage/ai-cost/index.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.d.ts +2 -0
- package/dist/storage/ai-cost/provider.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.js +29 -13
- package/dist/storage/ai-cost/provider.js.map +3 -3
- package/dist/storage/ai-cost/types.d.ts +64 -15
- package/dist/storage/ai-cost/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/validation.d.ts +2 -1
- package/dist/storage/ai-cost/validation.d.ts.map +1 -1
- package/dist/storage/ai-limits/enforcement.d.ts +14 -0
- package/dist/storage/ai-limits/enforcement.d.ts.map +1 -0
- package/dist/storage/ai-limits/enforcement.js +21 -0
- package/dist/storage/ai-limits/enforcement.js.map +9 -0
- package/dist/storage/ai-limits/errors.d.ts +8 -0
- package/dist/storage/ai-limits/errors.d.ts.map +1 -0
- package/dist/storage/ai-limits/in-memory.d.ts +78 -0
- package/dist/storage/ai-limits/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-limits/index.d.ts +7 -0
- package/dist/storage/ai-limits/index.d.ts.map +1 -0
- package/dist/storage/ai-limits/period.d.ts +4 -0
- package/dist/storage/ai-limits/period.d.ts.map +1 -0
- package/dist/storage/ai-limits/provider.d.ts +85 -0
- package/dist/storage/ai-limits/provider.d.ts.map +1 -0
- package/dist/storage/ai-limits/provider.js +62 -0
- package/dist/storage/ai-limits/provider.js.map +9 -0
- package/dist/storage/ai-limits/types.d.ts +175 -0
- package/dist/storage/ai-limits/types.d.ts.map +1 -0
- package/dist/storage/ai-usage/in-memory.d.ts +4 -0
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-usage/record.d.ts.map +1 -1
- package/dist/storage/ai-usage/types.d.ts +6 -2
- package/dist/storage/ai-usage/types.d.ts.map +1 -1
- package/dist/storage/auth/errors.d.ts +1 -1
- package/dist/storage/auth/errors.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts +4 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/device-authorizations.d.ts +29 -0
- package/dist/storage/auth/in-memory/device-authorizations.d.ts.map +1 -0
- package/dist/storage/auth/in-memory/shared.d.ts +3 -1
- package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
- package/dist/storage/auth/index.d.ts +2 -1
- package/dist/storage/auth/index.d.ts.map +1 -1
- package/dist/storage/auth/types.d.ts +66 -0
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +2 -2
- package/dist/storage/executions/provider.js +1 -1
- package/dist/storage/executions/run-link.d.ts +7 -2
- package/dist/storage/executions/run-link.d.ts.map +1 -1
- package/dist/storage/executions/validation.d.ts.map +1 -1
- package/dist/storage/in-memory/index.d.ts +4 -0
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +8 -5
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +51 -38
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts +4 -3
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/index.d.ts +1 -1
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/materializations.d.ts +7 -3
- package/dist/storage/ontology/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +2 -2
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +3 -3
- package/dist/storage/pipeline-runs/provider.js +2 -2
- package/dist/storage/projection-runs/provider.js +4 -4
- package/dist/storage/sync-runs/provider.js +2 -2
- package/dist/storage/types.d.ts +5 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/webhook-runs/provider.js +2 -2
- package/dist/storage/workflow-runs/provider.d.ts +1 -1
- package/dist/storage/workflow-runs/provider.js +10 -11
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/storage/workflow-runs/types.d.ts +5 -4
- package/dist/storage/workflow-runs/types.d.ts.map +1 -1
- package/dist/syncs/index.js +37 -35
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/agent-execution.d.ts +3 -1
- package/dist/testing/agent-execution.d.ts.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-limit-storage-contract.d.ts +18 -0
- package/dist/testing/ai-limit-storage-contract.d.ts.map +1 -0
- package/dist/testing/ai-model-call-groups-contract.d.ts +6 -0
- package/dist/testing/ai-model-call-groups-contract.d.ts.map +1 -0
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +3758 -1945
- package/dist/testing/index.js.map +15 -13
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/queues-contract.d.ts.map +1 -1
- package/dist/webhooks/internal.js +32 -28
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workers/index.js +2 -2
- package/dist/workflows/agent-step-identity.d.ts +3 -0
- package/dist/workflows/agent-step-identity.d.ts.map +1 -0
- package/dist/workflows/builders.d.ts +2 -3
- package/dist/workflows/builders.d.ts.map +1 -1
- package/dist/workflows/execution.d.ts +1 -1
- package/dist/workflows/execution.d.ts.map +1 -1
- package/dist/workflows/failure.d.ts +1 -1
- package/dist/workflows/failure.d.ts.map +1 -1
- package/dist/workflows/index.d.ts +3 -2
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +53 -45
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/types.d.ts +26 -11
- package/dist/workflows/types.d.ts.map +1 -1
- package/dist/workflows/validation.d.ts +7 -1
- package/dist/workflows/validation.d.ts.map +1 -1
- package/package.json +19 -4
- package/src/actions/types/definitions.ts +24 -2
- package/src/agents/adapters.ts +109 -115
- package/src/agents/authority.ts +214 -32
- package/src/agents/builders.ts +3 -50
- package/src/agents/context-compaction.ts +4 -0
- package/src/agents/dispatch.ts +59 -2
- package/src/agents/errors.ts +5 -2
- package/src/agents/execution.ts +53 -52
- package/src/agents/ids.ts +16 -1
- package/src/agents/index.ts +23 -11
- package/src/agents/message.ts +18 -9
- package/src/agents/model-loop.ts +1023 -0
- package/src/agents/reference.ts +7 -0
- package/src/agents/request.ts +141 -74
- package/src/agents/retired-config.ts +20 -0
- package/src/agents/streams.ts +45 -19
- package/src/agents/tool-catalog.ts +21 -0
- package/src/agents/tool-definition.ts +23 -0
- package/src/agents/types.ts +39 -81
- package/src/agents/validation.ts +34 -180
- package/src/ai-usage/execution.ts +196 -0
- package/src/ai-usage/index.ts +15 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/runtime.ts +8 -0
- package/src/auth/strategy.ts +1 -0
- package/src/auth/types.ts +14 -0
- package/src/authorization/decision.ts +27 -10
- package/src/authorization/grant-kinds.ts +62 -15
- package/src/authorization/index.ts +1 -0
- package/src/authorization/resolve.ts +12 -5
- package/src/authorization/types.ts +7 -5
- package/src/bootstrap/discovery.ts +0 -3
- package/src/error-reporting/types.ts +4 -2
- package/src/errors/catalog.ts +8 -0
- package/src/execution/agent.ts +129 -22
- package/src/execution/authorization.ts +48 -18
- package/src/execution/request.ts +4 -1
- package/src/execution/types.ts +1 -1
- package/src/http/api-routes.ts +63 -0
- package/src/index.ts +36 -7
- package/src/json.ts +9 -0
- package/src/models/catalog.ts +137 -0
- package/src/models/definitions.ts +202 -0
- package/src/models/errors.ts +83 -0
- package/src/models/events.ts +198 -0
- package/src/models/index.ts +89 -71
- package/src/models/language-model.ts +143 -0
- package/src/models/messages.ts +78 -0
- package/src/models/pricing.ts +390 -0
- package/src/models/rate-card.ts +101 -0
- package/src/models/tools.ts +29 -0
- package/src/queues/in-memory.ts +5 -0
- package/src/queues/index.ts +11 -0
- package/src/queues/types.ts +20 -3
- package/src/runtime/create.ts +7 -5
- package/src/runtime/definitions.ts +2 -2
- package/src/runtime/host.ts +3 -2
- package/src/runtime/resolve-definitions.ts +13 -36
- package/src/runtime/sixb.ts +6 -8
- package/src/security/every.ts +0 -4
- package/src/security/grants.ts +55 -11
- package/src/security/index.ts +2 -0
- package/src/security/registry.ts +6 -5
- package/src/security/types.ts +15 -4
- package/src/security/validation.ts +30 -9
- package/src/storage/agents/errors.ts +1 -0
- package/src/storage/agents/in-memory.ts +121 -11
- package/src/storage/agents/index.ts +7 -0
- package/src/storage/agents/provider.ts +150 -6
- package/src/storage/agents/types.ts +73 -16
- package/src/storage/ai-cost/analytics.ts +63 -6
- package/src/storage/ai-cost/codec.ts +37 -12
- package/src/storage/ai-cost/groups.ts +248 -0
- package/src/storage/ai-cost/in-memory.ts +42 -0
- package/src/storage/ai-cost/index.ts +6 -0
- package/src/storage/ai-cost/provider.ts +7 -0
- package/src/storage/ai-cost/types.ts +76 -14
- package/src/storage/ai-cost/validation.ts +147 -17
- package/src/storage/ai-limits/enforcement.ts +68 -0
- package/src/storage/ai-limits/errors.ts +23 -0
- package/src/storage/ai-limits/in-memory.ts +671 -0
- package/src/storage/ai-limits/index.ts +31 -0
- package/src/storage/ai-limits/period.ts +11 -0
- package/src/storage/ai-limits/provider.ts +430 -0
- package/src/storage/ai-limits/types.ts +195 -0
- package/src/storage/ai-usage/in-memory.ts +13 -0
- package/src/storage/ai-usage/record.ts +17 -0
- package/src/storage/ai-usage/types.ts +6 -2
- package/src/storage/auth/errors.ts +6 -0
- package/src/storage/auth/in-memory/auth-storage.ts +69 -0
- package/src/storage/auth/in-memory/device-authorizations.ts +145 -0
- package/src/storage/auth/in-memory/shared.ts +7 -0
- package/src/storage/auth/index.ts +7 -0
- package/src/storage/auth/types.ts +73 -0
- package/src/storage/executions/run-link.ts +16 -6
- package/src/storage/executions/validation.ts +36 -6
- package/src/storage/in-memory/index.ts +48 -4
- package/src/storage/index.ts +52 -1
- package/src/storage/ontology/in-memory/materializations.ts +34 -22
- package/src/storage/ontology/index.ts +1 -0
- package/src/storage/ontology/materializations.ts +8 -3
- package/src/storage/ontology/provider.ts +2 -2
- package/src/storage/types.ts +37 -0
- package/src/storage/workflow-runs/in-memory.ts +3 -3
- package/src/storage/workflow-runs/provider.ts +2 -2
- package/src/storage/workflow-runs/types.ts +6 -3
- package/src/testing/agent-execution.ts +40 -28
- package/src/testing/agent-storage-contract.ts +249 -28
- package/src/testing/ai-cost-storage-contract.ts +96 -8
- package/src/testing/ai-limit-storage-contract.ts +1134 -0
- package/src/testing/ai-model-call-groups-contract.ts +353 -0
- package/src/testing/ai-usage-storage-contract.ts +31 -0
- package/src/testing/auth-storage-contract.ts +85 -0
- package/src/testing/execution-storage-contract.ts +2 -2
- package/src/testing/index.ts +10 -0
- package/src/testing/materializer-storage-contract.ts +170 -2
- package/src/testing/queues-contract.ts +36 -1
- package/src/workflows/agent-step-identity.ts +4 -0
- package/src/workflows/builders.ts +95 -9
- package/src/workflows/execution.ts +2 -2
- package/src/workflows/failure.ts +2 -2
- package/src/workflows/index.ts +3 -0
- package/src/workflows/types.ts +23 -11
- package/src/workflows/validation.ts +100 -7
- package/dist/chunk-6gjqgd3d.js.map +0 -11
- package/dist/chunk-84h6qhmp.js.map +0 -46
- package/dist/chunk-a09jx26t.js +0 -55
- package/dist/chunk-a09jx26t.js.map +0 -11
- package/dist/chunk-dm72y8wt.js.map +0 -10
- package/dist/chunk-drjqm1aa.js.map +0 -15
- package/dist/chunk-gadsm794.js.map +0 -11
- package/dist/chunk-h9kxd41f.js.map +0 -11
- package/dist/chunk-nzw7sm3b.js +0 -137
- package/dist/chunk-nzw7sm3b.js.map +0 -10
- package/dist/chunk-t0jjkep3.js.map +0 -10
- package/dist/chunk-t8t39h7v.js.map +0 -10
- package/dist/chunk-tkdscva6.js.map +0 -37
- package/dist/chunk-v0egge8b.js.map +0 -56
- package/dist/chunk-xdf9yswn.js.map +0 -11
- /package/dist/{chunk-zqysyfjt.js.map → chunk-08m3b6w8.js.map} +0 -0
- /package/dist/{chunk-xkthy56g.js.map → chunk-1kamz6j0.js.map} +0 -0
- /package/dist/{chunk-6d5xdj1q.js.map → chunk-3fqt22c4.js.map} +0 -0
- /package/dist/{chunk-z3zp0bj1.js.map → chunk-407j3msh.js.map} +0 -0
- /package/dist/{chunk-rhrbz7d4.js.map → chunk-4a849fr1.js.map} +0 -0
- /package/dist/{chunk-62c7t4jc.js.map → chunk-4nxeacx7.js.map} +0 -0
- /package/dist/{chunk-cy0n5dms.js.map → chunk-5jcdmjam.js.map} +0 -0
- /package/dist/{chunk-819wnjz8.js.map → chunk-64sr682n.js.map} +0 -0
- /package/dist/{chunk-x2yw73hy.js.map → chunk-7ds9620f.js.map} +0 -0
- /package/dist/{chunk-tbv03sx2.js.map → chunk-9aehf39w.js.map} +0 -0
- /package/dist/{chunk-ezake7g1.js.map → chunk-agsvg9ar.js.map} +0 -0
- /package/dist/{chunk-rnshztfq.js.map → chunk-d63tybny.js.map} +0 -0
- /package/dist/{chunk-vybf6pkp.js.map → chunk-dbc80ad7.js.map} +0 -0
- /package/dist/{chunk-4gz41why.js.map → chunk-dqn23610.js.map} +0 -0
- /package/dist/{chunk-zp2v2rv6.js.map → chunk-ha58tjtt.js.map} +0 -0
- /package/dist/{chunk-f6erf2vv.js.map → chunk-hdz94br2.js.map} +0 -0
- /package/dist/{chunk-dsrkgtnh.js.map → chunk-jq43kdvk.js.map} +0 -0
- /package/dist/{chunk-wtmzkcht.js.map → chunk-k34z5rvh.js.map} +0 -0
- /package/dist/{chunk-htq0qh7z.js.map → chunk-ka3a2ft3.js.map} +0 -0
- /package/dist/{chunk-4h947jd8.js.map → chunk-kt81c11h.js.map} +0 -0
- /package/dist/{chunk-f2rt4vkh.js.map → chunk-n2w475r0.js.map} +0 -0
- /package/dist/{chunk-bhxaq2nn.js.map → chunk-qw9gvjv5.js.map} +0 -0
- /package/dist/{chunk-r0rry8dn.js.map → chunk-rp1mvzb4.js.map} +0 -0
- /package/dist/{chunk-ghteq96b.js.map → chunk-s5y30bc9.js.map} +0 -0
- /package/dist/{chunk-a31h57d5.js.map → chunk-tn7xcs2n.js.map} +0 -0
- /package/dist/{chunk-ea73pzk7.js.map → chunk-vjjv9mrb.js.map} +0 -0
- /package/dist/{chunk-8b55ygje.js.map → chunk-w3e09qqk.js.map} +0 -0
- /package/dist/{chunk-ckxfnx7f.js.map → chunk-wjgm6jjt.js.map} +0 -0
- /package/dist/{chunk-3j7573mj.js.map → chunk-x0qhkqje.js.map} +0 -0
- /package/dist/{chunk-dysw7nsm.js.map → chunk-xdpwpkha.js.map} +0 -0
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto"
|
|
2
|
+
import { assertJsonObject, assertJsonValue, isJsonValue, type JsonValue } from "../json"
|
|
3
|
+
import { ModelProviderError, ModelStreamError, StructuredOutputError } from "../models/errors"
|
|
4
|
+
import type {
|
|
5
|
+
LanguageModelStreamEvent,
|
|
6
|
+
ModelCallEndEvent,
|
|
7
|
+
ModelFinishReason,
|
|
8
|
+
ModelStep,
|
|
9
|
+
ModelUiChunk,
|
|
10
|
+
ModelUsage,
|
|
11
|
+
} from "../models/events"
|
|
12
|
+
import type {
|
|
13
|
+
LanguageModel,
|
|
14
|
+
ModelReasoning,
|
|
15
|
+
ModelToolSpecification,
|
|
16
|
+
} from "../models/language-model"
|
|
17
|
+
import type {
|
|
18
|
+
ModelAssistantPart,
|
|
19
|
+
ModelMessage,
|
|
20
|
+
ModelProviderStatePart,
|
|
21
|
+
ModelTextPart,
|
|
22
|
+
ModelToolCallPart,
|
|
23
|
+
ModelToolOutput,
|
|
24
|
+
ModelToolResultPart,
|
|
25
|
+
ProviderData,
|
|
26
|
+
} from "../models/messages"
|
|
27
|
+
import {
|
|
28
|
+
estimateModelCall,
|
|
29
|
+
type ModelCallCost,
|
|
30
|
+
type ModelReportedCost,
|
|
31
|
+
rateModelCall,
|
|
32
|
+
} from "../models/pricing"
|
|
33
|
+
import type { ModelOutput, ModelTool } from "../models/tools"
|
|
34
|
+
|
|
35
|
+
const MAX_PROVIDER_DATA_BYTES = 256 * 1024
|
|
36
|
+
|
|
37
|
+
interface ModelLoopOptions {
|
|
38
|
+
readonly model: LanguageModel
|
|
39
|
+
readonly messages: readonly ModelMessage[]
|
|
40
|
+
readonly tools?: readonly ModelTool[]
|
|
41
|
+
readonly reasoning?: ModelReasoning
|
|
42
|
+
readonly maxOutputTokens?: number
|
|
43
|
+
readonly caching?: "auto" | "off"
|
|
44
|
+
readonly maxSteps: number
|
|
45
|
+
readonly signal: AbortSignal
|
|
46
|
+
/** Reserve the final provider call for a tool-free synthesis response. */
|
|
47
|
+
readonly finalStepInstruction?: string
|
|
48
|
+
readonly prepareStep?: (
|
|
49
|
+
input: PrepareModelStepInput
|
|
50
|
+
) => PrepareModelStepResult | undefined | Promise<PrepareModelStepResult | undefined>
|
|
51
|
+
readonly onEvent?: (event: ModelUiChunk) => void | Promise<void>
|
|
52
|
+
readonly onModelCallEnd?: (event: ModelCallEndEvent) => void | Promise<void>
|
|
53
|
+
readonly onStepEnd?: (step: ModelStep) => void | Promise<void>
|
|
54
|
+
readonly generateCallId?: () => string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Non-text output requires a validator; unvalidated text can only inhabit types accepting string. */
|
|
58
|
+
export type RunModelLoopInput<TOutput = string> = ModelLoopOptions &
|
|
59
|
+
(
|
|
60
|
+
| { readonly output: ModelOutput<TOutput> }
|
|
61
|
+
| (string extends TOutput ? { readonly output?: undefined } : never)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
export interface PrepareModelStepInput {
|
|
65
|
+
readonly stepIndex: number
|
|
66
|
+
readonly messages: readonly ModelMessage[]
|
|
67
|
+
readonly model: LanguageModel
|
|
68
|
+
readonly signal: AbortSignal
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface PrepareModelStepResult {
|
|
72
|
+
/** Replacement history retained for this request and subsequent steps. */
|
|
73
|
+
readonly messages?: readonly ModelMessage[]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type ModelLoopResult<TOutput = string> =
|
|
77
|
+
| {
|
|
78
|
+
readonly status: "completed"
|
|
79
|
+
readonly output: TOutput
|
|
80
|
+
readonly steps: readonly ModelStep[]
|
|
81
|
+
readonly finishReason: ModelFinishReason
|
|
82
|
+
}
|
|
83
|
+
| {
|
|
84
|
+
readonly status: "aborted"
|
|
85
|
+
readonly steps: readonly ModelStep[]
|
|
86
|
+
readonly partialContent: readonly ModelAssistantPart[]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface CompletedResponse {
|
|
90
|
+
readonly providerIds?: import("../models/events").ModelProviderIds
|
|
91
|
+
readonly content: readonly ModelAssistantPart[]
|
|
92
|
+
readonly toolCalls: readonly ParsedToolCall[]
|
|
93
|
+
readonly finishReason: ModelFinishReason
|
|
94
|
+
readonly rawFinishReason?: string
|
|
95
|
+
readonly usage: ModelUsage
|
|
96
|
+
readonly responseId?: string
|
|
97
|
+
readonly responseModelId?: string
|
|
98
|
+
readonly projectionError?: Error
|
|
99
|
+
readonly reportedCost?: ModelReportedCost
|
|
100
|
+
readonly route?: import("../models/events").ModelRoute
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface ParsedToolCall {
|
|
104
|
+
readonly part: ModelToolCallPart
|
|
105
|
+
readonly inputError?: Error
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Run a provider-neutral, streaming model/tool loop.
|
|
110
|
+
*
|
|
111
|
+
* One step is exactly one provider call. Lifecycle and stream callbacks are awaited so the caller
|
|
112
|
+
* controls backpressure and can fail closed before another billable call starts.
|
|
113
|
+
*/
|
|
114
|
+
export function runModelLoop<TOutput = string>(
|
|
115
|
+
input: RunModelLoopInput<TOutput>
|
|
116
|
+
): Promise<ModelLoopResult<TOutput>>
|
|
117
|
+
export async function runModelLoop(
|
|
118
|
+
input: RunModelLoopInput<unknown>
|
|
119
|
+
): Promise<ModelLoopResult<unknown>> {
|
|
120
|
+
assertLoopInput(input)
|
|
121
|
+
const tools = indexTools(input.tools ?? [])
|
|
122
|
+
const toolSpecifications = [...tools.values()].map<ModelToolSpecification>((tool) => ({
|
|
123
|
+
name: tool.name,
|
|
124
|
+
description: tool.description,
|
|
125
|
+
inputSchema: tool.inputSchema,
|
|
126
|
+
}))
|
|
127
|
+
let messages: readonly ModelMessage[] = [...input.messages]
|
|
128
|
+
const steps: ModelStep[] = []
|
|
129
|
+
const generateCallId = input.generateCallId ?? (() => `model_call_${randomUUID()}`)
|
|
130
|
+
const callIds = new Set<string>()
|
|
131
|
+
|
|
132
|
+
for (let stepIndex = 0; stepIndex < input.maxSteps; stepIndex += 1) {
|
|
133
|
+
if (input.signal.aborted) {
|
|
134
|
+
return { status: "aborted", steps, partialContent: [] }
|
|
135
|
+
}
|
|
136
|
+
await input.onEvent?.({ type: "start-step" })
|
|
137
|
+
|
|
138
|
+
let requestMessages: readonly ModelMessage[]
|
|
139
|
+
try {
|
|
140
|
+
const prepared = await input.prepareStep?.({
|
|
141
|
+
stepIndex,
|
|
142
|
+
messages,
|
|
143
|
+
model: input.model,
|
|
144
|
+
signal: input.signal,
|
|
145
|
+
})
|
|
146
|
+
requestMessages = prepared?.messages ?? messages
|
|
147
|
+
} catch (error) {
|
|
148
|
+
if (!input.signal.aborted && !isAbortError(error)) throw error
|
|
149
|
+
return { status: "aborted", steps, partialContent: [] }
|
|
150
|
+
}
|
|
151
|
+
if (input.signal.aborted) {
|
|
152
|
+
return { status: "aborted", steps, partialContent: [] }
|
|
153
|
+
}
|
|
154
|
+
let requestTools: readonly ModelToolSpecification[] = toolSpecifications
|
|
155
|
+
if (input.finalStepInstruction !== undefined && stepIndex === input.maxSteps - 1) {
|
|
156
|
+
requestMessages = [
|
|
157
|
+
...requestMessages,
|
|
158
|
+
{ role: "user", content: [{ type: "text", text: input.finalStepInstruction }] },
|
|
159
|
+
]
|
|
160
|
+
requestTools = []
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const callId = generateCallId()
|
|
164
|
+
if (!callId || callIds.has(callId)) {
|
|
165
|
+
throw new ModelStreamError(`[SixbModels] Model call IDs must be nonempty and unique.`)
|
|
166
|
+
}
|
|
167
|
+
callIds.add(callId)
|
|
168
|
+
const accumulator = new StreamAccumulator(input.onEvent)
|
|
169
|
+
let accepted = false
|
|
170
|
+
let cost: ModelCallCost = { status: "unpriceable", reason: "missing-usage" }
|
|
171
|
+
let terminalStreamError: { readonly error: unknown } | undefined
|
|
172
|
+
try {
|
|
173
|
+
const stream = await input.model.stream({
|
|
174
|
+
callId,
|
|
175
|
+
messages: requestMessages,
|
|
176
|
+
tools: requestTools,
|
|
177
|
+
...(input.reasoning === undefined ? {} : { reasoning: input.reasoning }),
|
|
178
|
+
...(input.maxOutputTokens === undefined ? {} : { maxOutputTokens: input.maxOutputTokens }),
|
|
179
|
+
...(input.caching === undefined ? {} : { caching: input.caching }),
|
|
180
|
+
...(input.output === undefined
|
|
181
|
+
? {}
|
|
182
|
+
: {
|
|
183
|
+
responseFormat: {
|
|
184
|
+
type: "json" as const,
|
|
185
|
+
name: input.output.name,
|
|
186
|
+
...(input.output.description === undefined
|
|
187
|
+
? {}
|
|
188
|
+
: { description: input.output.description }),
|
|
189
|
+
schema: input.output.schema,
|
|
190
|
+
},
|
|
191
|
+
}),
|
|
192
|
+
signal: input.signal,
|
|
193
|
+
})
|
|
194
|
+
accepted = true
|
|
195
|
+
for await (const event of stream.events) {
|
|
196
|
+
await accumulator.accept(event)
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
const aborted = input.signal.aborted || isAbortError(error)
|
|
200
|
+
if (accumulator.isFinished()) {
|
|
201
|
+
if (!aborted) terminalStreamError = { error }
|
|
202
|
+
} else if (!aborted) {
|
|
203
|
+
throw error
|
|
204
|
+
} else {
|
|
205
|
+
return {
|
|
206
|
+
status: "aborted",
|
|
207
|
+
steps,
|
|
208
|
+
partialContent: accumulator.partialContent(),
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
} finally {
|
|
212
|
+
// Once a stream is accepted, cancellation or protocol failure cannot erase the call.
|
|
213
|
+
// Only a finish event establishes final meters; interrupted calls remain explicitly unknown.
|
|
214
|
+
if (accepted) {
|
|
215
|
+
const facts = accumulator.accounting()
|
|
216
|
+
const estimate = accumulator.isFinished() ? estimateModelCall(input.model, facts) : cost
|
|
217
|
+
cost = facts.reportedCost
|
|
218
|
+
? rateModelCall({ usage: facts.usage, reported: facts.reportedCost })
|
|
219
|
+
: estimate
|
|
220
|
+
await input.onModelCallEnd?.({
|
|
221
|
+
callId,
|
|
222
|
+
providerId: input.model.providerId,
|
|
223
|
+
modelId: input.model.modelId,
|
|
224
|
+
responseId: facts.responseId ?? `${callId}:response`,
|
|
225
|
+
providerIds: facts.providerIds,
|
|
226
|
+
responseModelId: facts.responseModelId,
|
|
227
|
+
usage: facts.usage,
|
|
228
|
+
cost,
|
|
229
|
+
...(facts.reportedCost === undefined ? {} : { estimate }),
|
|
230
|
+
...(input.reasoning === undefined ? {} : { requestedReasoning: input.reasoning }),
|
|
231
|
+
...(facts.route === undefined ? {} : { route: facts.route }),
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (input.signal.aborted && !accumulator.isFinished()) {
|
|
237
|
+
return { status: "aborted", steps, partialContent: accumulator.partialContent() }
|
|
238
|
+
}
|
|
239
|
+
const response = accumulator.complete()
|
|
240
|
+
const responseId = response.responseId ?? `${callId}:response`
|
|
241
|
+
if (terminalStreamError) throw terminalStreamError.error
|
|
242
|
+
if (response.projectionError) throw response.projectionError
|
|
243
|
+
if (input.signal.aborted) {
|
|
244
|
+
return { status: "aborted", steps, partialContent: response.content }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const localCalls = response.toolCalls.filter((call) => call.part.providerExecuted !== true)
|
|
248
|
+
if (response.finishReason === "pause" && localCalls.length === 0) {
|
|
249
|
+
const step = modelStep(response, responseId, response.content, cost)
|
|
250
|
+
steps.push(step)
|
|
251
|
+
await input.onStepEnd?.(step)
|
|
252
|
+
messages = [...requestMessages, { role: "assistant", content: response.content }]
|
|
253
|
+
if (stepIndex + 1 === input.maxSteps) {
|
|
254
|
+
throw new ModelStreamError(
|
|
255
|
+
"[SixbModels] Model reached the step limit while a provider continuation was pending."
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
continue
|
|
259
|
+
}
|
|
260
|
+
if (localCalls.length === 0) {
|
|
261
|
+
const step = modelStep(response, responseId, response.content, cost)
|
|
262
|
+
steps.push(step)
|
|
263
|
+
await input.onStepEnd?.(step)
|
|
264
|
+
if (input.output) {
|
|
265
|
+
const text = responseText(response)
|
|
266
|
+
if (response.finishReason !== "stop") {
|
|
267
|
+
throw new StructuredOutputError(
|
|
268
|
+
`[SixbModels] Structured output did not complete successfully (${response.finishReason}).`,
|
|
269
|
+
structuredOutputErrorContext(input, response, responseId, cost, text)
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
let raw: unknown
|
|
273
|
+
try {
|
|
274
|
+
raw = JSON.parse(text)
|
|
275
|
+
} catch (error) {
|
|
276
|
+
throw new StructuredOutputError("[SixbModels] Model did not produce valid JSON output.", {
|
|
277
|
+
cause: error,
|
|
278
|
+
...structuredOutputErrorContext(input, response, responseId, cost, text),
|
|
279
|
+
})
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
return {
|
|
283
|
+
status: "completed",
|
|
284
|
+
output: input.output.validate(raw),
|
|
285
|
+
steps,
|
|
286
|
+
finishReason: response.finishReason,
|
|
287
|
+
}
|
|
288
|
+
} catch (error) {
|
|
289
|
+
throw new StructuredOutputError("[SixbModels] Structured output validation failed.", {
|
|
290
|
+
cause: error,
|
|
291
|
+
...structuredOutputErrorContext(input, response, responseId, cost, text),
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const output = responseText(response)
|
|
296
|
+
return { status: "completed", output, steps, finishReason: response.finishReason }
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const toolResults = await Promise.all(
|
|
300
|
+
localCalls.map((call) => executeToolCall(call, tools, callId, input.signal, input.onEvent))
|
|
301
|
+
)
|
|
302
|
+
const step = modelStep(response, responseId, [...response.content, ...toolResults], cost)
|
|
303
|
+
steps.push(step)
|
|
304
|
+
await input.onStepEnd?.(step)
|
|
305
|
+
|
|
306
|
+
if (input.signal.aborted) {
|
|
307
|
+
return {
|
|
308
|
+
status: "aborted",
|
|
309
|
+
steps,
|
|
310
|
+
partialContent: [],
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const assistantContent = response.content.filter(
|
|
315
|
+
(part) => part.type !== "tool-result" || part.providerExecuted === true
|
|
316
|
+
)
|
|
317
|
+
messages = [
|
|
318
|
+
...requestMessages,
|
|
319
|
+
{ role: "assistant", content: assistantContent },
|
|
320
|
+
{ role: "tool", content: toolResults },
|
|
321
|
+
]
|
|
322
|
+
|
|
323
|
+
if (stepIndex + 1 === input.maxSteps) {
|
|
324
|
+
if (input.output) {
|
|
325
|
+
throw new StructuredOutputError(
|
|
326
|
+
"[SixbModels] Model reached the step limit without structured output.",
|
|
327
|
+
structuredOutputErrorContext(input, response, responseId, cost, responseText(response))
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
const output = responseText(response)
|
|
331
|
+
return { status: "completed", output, steps, finishReason: response.finishReason }
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
throw new ModelStreamError("[SixbModels] Model loop exited without a terminal result.")
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function assertLoopInput(input: RunModelLoopInput<unknown>): void {
|
|
339
|
+
if (
|
|
340
|
+
input.maxOutputTokens !== undefined &&
|
|
341
|
+
(!Number.isSafeInteger(input.maxOutputTokens) || input.maxOutputTokens <= 0)
|
|
342
|
+
) {
|
|
343
|
+
throw new TypeError("[SixbModels] maxOutputTokens must be a positive safe integer.")
|
|
344
|
+
}
|
|
345
|
+
if (!Number.isInteger(input.maxSteps) || input.maxSteps <= 0) {
|
|
346
|
+
throw new TypeError("[SixbModels] maxSteps must be a positive integer.")
|
|
347
|
+
}
|
|
348
|
+
if (!input.model.providerId.trim() || !input.model.modelId.trim()) {
|
|
349
|
+
throw new TypeError("[SixbModels] Model providerId and modelId must not be empty.")
|
|
350
|
+
}
|
|
351
|
+
if (
|
|
352
|
+
input.model.definition.providerId !== input.model.providerId ||
|
|
353
|
+
input.model.definition.modelId !== input.model.modelId
|
|
354
|
+
) {
|
|
355
|
+
throw new TypeError(
|
|
356
|
+
`[SixbModels] Model definition for '${input.model.providerId}/${input.model.modelId}' has a different identity.`
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
if (input.output) {
|
|
360
|
+
if (!input.output.name.trim()) {
|
|
361
|
+
throw new TypeError("[SixbModels] Structured output names must not be empty.")
|
|
362
|
+
}
|
|
363
|
+
assertJsonObject(input.output.schema, "structured output schema")
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function indexTools(tools: readonly ModelTool[]): ReadonlyMap<string, ModelTool> {
|
|
368
|
+
const result = new Map<string, ModelTool>()
|
|
369
|
+
for (const tool of tools) {
|
|
370
|
+
if (!tool.name.trim()) throw new TypeError("[SixbModels] Tool names must not be empty.")
|
|
371
|
+
if (result.has(tool.name)) {
|
|
372
|
+
throw new TypeError(`[SixbModels] Duplicate tool name '${tool.name}'.`)
|
|
373
|
+
}
|
|
374
|
+
assertJsonObject(tool.inputSchema, `tool '${tool.name}' input schema`)
|
|
375
|
+
result.set(tool.name, tool)
|
|
376
|
+
}
|
|
377
|
+
return result
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function responseText(response: CompletedResponse): string {
|
|
381
|
+
return response.content
|
|
382
|
+
.filter((part): part is ModelTextPart => part.type === "text")
|
|
383
|
+
.map((part) => part.text)
|
|
384
|
+
.join("")
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function structuredOutputErrorContext(
|
|
388
|
+
input: RunModelLoopInput<unknown>,
|
|
389
|
+
response: CompletedResponse,
|
|
390
|
+
responseId: string,
|
|
391
|
+
cost: ModelCallCost,
|
|
392
|
+
text: string
|
|
393
|
+
) {
|
|
394
|
+
return {
|
|
395
|
+
text,
|
|
396
|
+
providerId: input.model.providerId,
|
|
397
|
+
modelId: input.model.modelId,
|
|
398
|
+
responseId,
|
|
399
|
+
...(response.responseModelId === undefined
|
|
400
|
+
? {}
|
|
401
|
+
: { responseModelId: response.responseModelId }),
|
|
402
|
+
finishReason: response.finishReason,
|
|
403
|
+
usage: response.usage,
|
|
404
|
+
cost,
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function modelStep(
|
|
409
|
+
response: CompletedResponse,
|
|
410
|
+
responseId: string,
|
|
411
|
+
content: readonly ModelAssistantPart[],
|
|
412
|
+
cost: import("../models/pricing").ModelCallCost
|
|
413
|
+
): ModelStep {
|
|
414
|
+
return {
|
|
415
|
+
content,
|
|
416
|
+
finishReason: response.finishReason,
|
|
417
|
+
...(response.rawFinishReason === undefined
|
|
418
|
+
? {}
|
|
419
|
+
: { rawFinishReason: response.rawFinishReason }),
|
|
420
|
+
usage: response.usage,
|
|
421
|
+
responseId,
|
|
422
|
+
...(response.responseModelId === undefined
|
|
423
|
+
? {}
|
|
424
|
+
: { responseModelId: response.responseModelId }),
|
|
425
|
+
cost,
|
|
426
|
+
...(response.route === undefined ? {} : { route: response.route }),
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async function executeToolCall(
|
|
431
|
+
call: ParsedToolCall,
|
|
432
|
+
tools: ReadonlyMap<string, ModelTool>,
|
|
433
|
+
callId: string,
|
|
434
|
+
signal: AbortSignal,
|
|
435
|
+
onEvent: RunModelLoopInput["onEvent"]
|
|
436
|
+
): Promise<ModelToolResultPart> {
|
|
437
|
+
const { part } = call
|
|
438
|
+
if (call.inputError) {
|
|
439
|
+
const errorText = `Tool input is not valid JSON: ${call.inputError.message}`
|
|
440
|
+
await onEvent?.({
|
|
441
|
+
type: "tool-input-error",
|
|
442
|
+
toolCallId: part.toolCallId,
|
|
443
|
+
toolName: part.toolName,
|
|
444
|
+
input: part.input,
|
|
445
|
+
errorText,
|
|
446
|
+
})
|
|
447
|
+
return toolErrorResult(part, errorText)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const tool = tools.get(part.toolName)
|
|
451
|
+
if (!tool) {
|
|
452
|
+
const errorText = `Tool '${part.toolName}' is not available.`
|
|
453
|
+
await onEvent?.({
|
|
454
|
+
type: "tool-output-error",
|
|
455
|
+
toolCallId: part.toolCallId,
|
|
456
|
+
toolName: part.toolName,
|
|
457
|
+
errorText,
|
|
458
|
+
})
|
|
459
|
+
return toolErrorResult(part, errorText)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
let parsed: unknown
|
|
463
|
+
try {
|
|
464
|
+
parsed = tool.parseInput(part.input)
|
|
465
|
+
} catch (error) {
|
|
466
|
+
const errorText = error instanceof Error ? error.message : "Tool input validation failed."
|
|
467
|
+
await onEvent?.({
|
|
468
|
+
type: "tool-input-error",
|
|
469
|
+
toolCallId: part.toolCallId,
|
|
470
|
+
toolName: part.toolName,
|
|
471
|
+
input: part.input,
|
|
472
|
+
errorText,
|
|
473
|
+
})
|
|
474
|
+
return toolErrorResult(part, errorText)
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
await onEvent?.({
|
|
478
|
+
type: "tool-input-available",
|
|
479
|
+
toolCallId: part.toolCallId,
|
|
480
|
+
toolName: part.toolName,
|
|
481
|
+
input: part.input,
|
|
482
|
+
})
|
|
483
|
+
let output: JsonValue
|
|
484
|
+
let modelOutput: ModelToolOutput
|
|
485
|
+
try {
|
|
486
|
+
const context = { signal, callId, toolCallId: part.toolCallId }
|
|
487
|
+
output = await tool.execute(parsed, context)
|
|
488
|
+
assertJsonValue(output, `tool '${part.toolName}' output`)
|
|
489
|
+
modelOutput = tool.toModelOutput
|
|
490
|
+
? await tool.toModelOutput(output, context)
|
|
491
|
+
: modelToolOutput(output)
|
|
492
|
+
validateModelToolOutput(modelOutput, part.toolName)
|
|
493
|
+
} catch (error) {
|
|
494
|
+
const errorText = tool.errorText(error)
|
|
495
|
+
await onEvent?.({
|
|
496
|
+
type: "tool-output-error",
|
|
497
|
+
toolCallId: part.toolCallId,
|
|
498
|
+
toolName: part.toolName,
|
|
499
|
+
errorText,
|
|
500
|
+
})
|
|
501
|
+
return toolErrorResult(part, errorText)
|
|
502
|
+
}
|
|
503
|
+
// Publication failures belong to the caller, not the tool's recoverable error channel.
|
|
504
|
+
await onEvent?.({
|
|
505
|
+
type: "tool-output-available",
|
|
506
|
+
toolCallId: part.toolCallId,
|
|
507
|
+
toolName: part.toolName,
|
|
508
|
+
output,
|
|
509
|
+
})
|
|
510
|
+
return {
|
|
511
|
+
type: "tool-result",
|
|
512
|
+
toolCallId: part.toolCallId,
|
|
513
|
+
toolName: part.toolName,
|
|
514
|
+
output: modelOutput,
|
|
515
|
+
...(modelOutputMatchesOriginal(modelOutput, output) ? {} : { originalOutput: output }),
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function validateModelToolOutput(output: ModelToolOutput, toolName: string): void {
|
|
520
|
+
if (output.type === "text" || output.type === "error-text") {
|
|
521
|
+
if (typeof output.value !== "string") {
|
|
522
|
+
throw new TypeError(`[SixbModels] Tool '${toolName}' model output must contain text.`)
|
|
523
|
+
}
|
|
524
|
+
return
|
|
525
|
+
}
|
|
526
|
+
assertJsonValue(output.value, `tool '${toolName}' model output`)
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function modelOutputMatchesOriginal(output: ModelToolOutput, original: JsonValue): boolean {
|
|
530
|
+
if (output.type === "text") return typeof original === "string" && output.value === original
|
|
531
|
+
if (output.type === "json") return output.value === original
|
|
532
|
+
return false
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function modelToolOutput(value: JsonValue): ModelToolOutput {
|
|
536
|
+
return typeof value === "string" ? { type: "text", value } : { type: "json", value }
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function toolErrorResult(part: ModelToolCallPart, errorText: string): ModelToolResultPart {
|
|
540
|
+
return {
|
|
541
|
+
type: "tool-result",
|
|
542
|
+
toolCallId: part.toolCallId,
|
|
543
|
+
toolName: part.toolName,
|
|
544
|
+
output: { type: "error-text", value: errorText },
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
type MutableTextPart = {
|
|
549
|
+
type: "text"
|
|
550
|
+
text: string
|
|
551
|
+
providerData?: ProviderData
|
|
552
|
+
complete: boolean
|
|
553
|
+
}
|
|
554
|
+
type MutableReasoningPart = {
|
|
555
|
+
type: "reasoning"
|
|
556
|
+
text: string
|
|
557
|
+
providerData?: ProviderData
|
|
558
|
+
complete: boolean
|
|
559
|
+
}
|
|
560
|
+
type MutableToolCall = {
|
|
561
|
+
type: "tool-call"
|
|
562
|
+
toolCallId: string
|
|
563
|
+
toolName: string
|
|
564
|
+
inputText: string
|
|
565
|
+
providerData?: ProviderData
|
|
566
|
+
providerExecuted?: boolean
|
|
567
|
+
dynamic?: boolean
|
|
568
|
+
complete: boolean
|
|
569
|
+
}
|
|
570
|
+
type MutablePart =
|
|
571
|
+
| MutableTextPart
|
|
572
|
+
| MutableReasoningPart
|
|
573
|
+
| MutableToolCall
|
|
574
|
+
| ModelToolResultPart
|
|
575
|
+
| ModelProviderStatePart
|
|
576
|
+
|
|
577
|
+
class StreamAccumulator {
|
|
578
|
+
private readonly parts: MutablePart[] = []
|
|
579
|
+
private readonly spans = new Map<string, MutableTextPart | MutableReasoningPart>()
|
|
580
|
+
private readonly toolCalls = new Map<string, MutableToolCall>()
|
|
581
|
+
private started = false
|
|
582
|
+
private finished = false
|
|
583
|
+
private finishReason: ModelFinishReason | undefined
|
|
584
|
+
private rawFinishReason: string | undefined
|
|
585
|
+
private usage: ModelUsage = {}
|
|
586
|
+
private responseId: string | undefined
|
|
587
|
+
private providerIds: import("../models/events").ModelProviderIds | undefined
|
|
588
|
+
private responseModelId: string | undefined
|
|
589
|
+
private projectionError: Error | undefined
|
|
590
|
+
private reportedCost: ModelReportedCost | undefined
|
|
591
|
+
private route: import("../models/events").ModelRoute | undefined
|
|
592
|
+
|
|
593
|
+
constructor(private readonly onEvent: RunModelLoopInput["onEvent"]) {}
|
|
594
|
+
|
|
595
|
+
isFinished(): boolean {
|
|
596
|
+
return this.finished
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
async accept(event: LanguageModelStreamEvent): Promise<void> {
|
|
600
|
+
if (this.finished) {
|
|
601
|
+
throw new ModelStreamError(`[SixbModels] Received '${event.type}' after stream finish.`)
|
|
602
|
+
}
|
|
603
|
+
switch (event.type) {
|
|
604
|
+
case "stream-start":
|
|
605
|
+
if (this.started) throw new ModelStreamError("[SixbModels] Duplicate stream-start event.")
|
|
606
|
+
this.started = true
|
|
607
|
+
return
|
|
608
|
+
case "response-metadata":
|
|
609
|
+
this.requireStarted(event.type)
|
|
610
|
+
this.responseId = event.id ?? this.responseId
|
|
611
|
+
if (event.providerIds) this.providerIds = { ...this.providerIds, ...event.providerIds }
|
|
612
|
+
this.responseModelId = event.modelId ?? this.responseModelId
|
|
613
|
+
return
|
|
614
|
+
case "text-start":
|
|
615
|
+
await this.startText(event)
|
|
616
|
+
return
|
|
617
|
+
case "text-delta":
|
|
618
|
+
await this.appendText(event, "text")
|
|
619
|
+
return
|
|
620
|
+
case "text-end":
|
|
621
|
+
await this.endText(event, "text")
|
|
622
|
+
return
|
|
623
|
+
case "reasoning-start":
|
|
624
|
+
await this.startReasoning(event)
|
|
625
|
+
return
|
|
626
|
+
case "reasoning-delta":
|
|
627
|
+
await this.appendText(event, "reasoning")
|
|
628
|
+
return
|
|
629
|
+
case "reasoning-end":
|
|
630
|
+
await this.endText(event, "reasoning")
|
|
631
|
+
return
|
|
632
|
+
case "tool-input-start":
|
|
633
|
+
await this.startTool(event)
|
|
634
|
+
return
|
|
635
|
+
case "tool-input-delta":
|
|
636
|
+
await this.appendTool(event)
|
|
637
|
+
return
|
|
638
|
+
case "tool-input-end":
|
|
639
|
+
this.endTool(event)
|
|
640
|
+
return
|
|
641
|
+
case "tool-call":
|
|
642
|
+
await this.completeTool(event)
|
|
643
|
+
return
|
|
644
|
+
case "tool-result":
|
|
645
|
+
this.addProviderToolResult(event)
|
|
646
|
+
return
|
|
647
|
+
case "provider-state":
|
|
648
|
+
if (this.captureProviderState(event.data)) {
|
|
649
|
+
this.parts.push({
|
|
650
|
+
type: "provider-state",
|
|
651
|
+
providerId: event.providerId,
|
|
652
|
+
data: event.data,
|
|
653
|
+
})
|
|
654
|
+
}
|
|
655
|
+
return
|
|
656
|
+
case "finish":
|
|
657
|
+
this.requireStarted(event.type)
|
|
658
|
+
validateUsage(event.usage)
|
|
659
|
+
this.captureProviderData(event.providerData)
|
|
660
|
+
this.finished = true
|
|
661
|
+
this.finishReason = event.finishReason
|
|
662
|
+
this.rawFinishReason = event.rawFinishReason
|
|
663
|
+
this.usage = event.usage
|
|
664
|
+
this.reportedCost = event.reportedCost
|
|
665
|
+
this.route = event.route
|
|
666
|
+
return
|
|
667
|
+
case "error":
|
|
668
|
+
throw event.error instanceof Error
|
|
669
|
+
? event.error
|
|
670
|
+
: new ModelProviderError("[SixbModels] Provider stream failed.", "unknown", "unknown", {
|
|
671
|
+
cause: event.error,
|
|
672
|
+
})
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
complete(): CompletedResponse {
|
|
677
|
+
if (!this.started) throw new ModelStreamError("[SixbModels] Stream did not start.")
|
|
678
|
+
if (!this.finished || !this.finishReason) {
|
|
679
|
+
throw new ModelStreamError("[SixbModels] Stream ended without a finish event.")
|
|
680
|
+
}
|
|
681
|
+
for (const part of this.parts) {
|
|
682
|
+
if ("complete" in part && !part.complete) {
|
|
683
|
+
throw new ModelStreamError(
|
|
684
|
+
`[SixbModels] Stream finished with incomplete ${part.type} content.`
|
|
685
|
+
)
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
const parsed = this.parseParts(false)
|
|
689
|
+
return {
|
|
690
|
+
content: parsed.content,
|
|
691
|
+
toolCalls: parsed.toolCalls,
|
|
692
|
+
finishReason: this.finishReason,
|
|
693
|
+
...(this.rawFinishReason === undefined ? {} : { rawFinishReason: this.rawFinishReason }),
|
|
694
|
+
...this.accounting(),
|
|
695
|
+
...(this.projectionError === undefined ? {} : { projectionError: this.projectionError }),
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
accounting() {
|
|
700
|
+
return {
|
|
701
|
+
usage: this.usage,
|
|
702
|
+
...(this.responseId === undefined ? {} : { responseId: this.responseId }),
|
|
703
|
+
...(this.providerIds === undefined ? {} : { providerIds: this.providerIds }),
|
|
704
|
+
...(this.responseModelId === undefined ? {} : { responseModelId: this.responseModelId }),
|
|
705
|
+
...(this.reportedCost === undefined ? {} : { reportedCost: this.reportedCost }),
|
|
706
|
+
...(this.route === undefined ? {} : { route: this.route }),
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
partialContent(): readonly ModelAssistantPart[] {
|
|
711
|
+
return this.parseParts(true).content
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
private parseParts(partial: boolean): {
|
|
715
|
+
readonly content: ModelAssistantPart[]
|
|
716
|
+
readonly toolCalls: ParsedToolCall[]
|
|
717
|
+
} {
|
|
718
|
+
const content: ModelAssistantPart[] = []
|
|
719
|
+
const toolCalls: ParsedToolCall[] = []
|
|
720
|
+
for (const part of this.parts) {
|
|
721
|
+
if (part.type === "text") {
|
|
722
|
+
if ((!partial || part.text.length > 0) && (part.complete || partial)) {
|
|
723
|
+
content.push({
|
|
724
|
+
type: "text",
|
|
725
|
+
text: part.text,
|
|
726
|
+
...(part.providerData === undefined ? {} : { providerData: part.providerData }),
|
|
727
|
+
})
|
|
728
|
+
}
|
|
729
|
+
} else if (part.type === "reasoning") {
|
|
730
|
+
if (part.complete) {
|
|
731
|
+
content.push({
|
|
732
|
+
type: "reasoning",
|
|
733
|
+
text: part.text,
|
|
734
|
+
...(part.providerData === undefined ? {} : { providerData: part.providerData }),
|
|
735
|
+
})
|
|
736
|
+
}
|
|
737
|
+
} else if (part.type === "tool-call") {
|
|
738
|
+
if (!part.complete) continue
|
|
739
|
+
let value: JsonValue = null
|
|
740
|
+
let inputError: Error | undefined
|
|
741
|
+
try {
|
|
742
|
+
const parsed: unknown = JSON.parse(part.inputText)
|
|
743
|
+
if (!isJsonValue(parsed)) throw new TypeError("input is not a JSON value")
|
|
744
|
+
value = parsed
|
|
745
|
+
} catch (error) {
|
|
746
|
+
inputError = error instanceof Error ? error : new Error(String(error))
|
|
747
|
+
}
|
|
748
|
+
const call: ModelToolCallPart = {
|
|
749
|
+
type: "tool-call",
|
|
750
|
+
toolCallId: part.toolCallId,
|
|
751
|
+
toolName: part.toolName,
|
|
752
|
+
input: value,
|
|
753
|
+
...(part.providerData === undefined ? {} : { providerData: part.providerData }),
|
|
754
|
+
...(part.providerExecuted === undefined
|
|
755
|
+
? {}
|
|
756
|
+
: { providerExecuted: part.providerExecuted }),
|
|
757
|
+
...(part.dynamic === undefined ? {} : { dynamic: part.dynamic }),
|
|
758
|
+
}
|
|
759
|
+
content.push(call)
|
|
760
|
+
toolCalls.push({ part: call, ...(inputError === undefined ? {} : { inputError }) })
|
|
761
|
+
} else {
|
|
762
|
+
content.push(part)
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return { content, toolCalls }
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private async startText(
|
|
769
|
+
event: Extract<LanguageModelStreamEvent, { type: "text-start" }>
|
|
770
|
+
): Promise<void> {
|
|
771
|
+
this.requireStarted(event.type)
|
|
772
|
+
this.assertNewSpan(event.id)
|
|
773
|
+
const providerData = this.captureProviderData(event.providerData)
|
|
774
|
+
const part: MutableTextPart = {
|
|
775
|
+
type: "text",
|
|
776
|
+
text: "",
|
|
777
|
+
complete: false,
|
|
778
|
+
...(providerData === undefined ? {} : { providerData }),
|
|
779
|
+
}
|
|
780
|
+
this.spans.set(event.id, part)
|
|
781
|
+
this.parts.push(part)
|
|
782
|
+
await this.onEvent?.({ type: "text-start", id: event.id })
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
private async startReasoning(
|
|
786
|
+
event: Extract<LanguageModelStreamEvent, { type: "reasoning-start" }>
|
|
787
|
+
): Promise<void> {
|
|
788
|
+
this.requireStarted(event.type)
|
|
789
|
+
this.assertNewSpan(event.id)
|
|
790
|
+
const providerData = this.captureProviderData(event.providerData)
|
|
791
|
+
const part: MutableReasoningPart = {
|
|
792
|
+
type: "reasoning",
|
|
793
|
+
text: "",
|
|
794
|
+
complete: false,
|
|
795
|
+
...(providerData === undefined ? {} : { providerData }),
|
|
796
|
+
}
|
|
797
|
+
this.spans.set(event.id, part)
|
|
798
|
+
this.parts.push(part)
|
|
799
|
+
await this.onEvent?.({ type: "reasoning-start", id: event.id })
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
private async appendText(
|
|
803
|
+
event: Extract<LanguageModelStreamEvent, { type: "text-delta" | "reasoning-delta" }>,
|
|
804
|
+
expected: "text" | "reasoning"
|
|
805
|
+
): Promise<void> {
|
|
806
|
+
const part = this.spans.get(event.id)
|
|
807
|
+
if (!part || part.type !== expected || part.complete) {
|
|
808
|
+
throw new ModelStreamError(
|
|
809
|
+
`[SixbModels] ${event.type} references unopened ${expected} span '${event.id}'.`
|
|
810
|
+
)
|
|
811
|
+
}
|
|
812
|
+
part.text += event.delta
|
|
813
|
+
await this.onEvent?.({ type: event.type, id: event.id, delta: event.delta })
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
private async endText(
|
|
817
|
+
event: Extract<LanguageModelStreamEvent, { type: "text-end" | "reasoning-end" }>,
|
|
818
|
+
expected: "text" | "reasoning"
|
|
819
|
+
): Promise<void> {
|
|
820
|
+
const part = this.spans.get(event.id)
|
|
821
|
+
if (!part || part.type !== expected || part.complete) {
|
|
822
|
+
throw new ModelStreamError(
|
|
823
|
+
`[SixbModels] ${event.type} references unopened ${expected} span '${event.id}'.`
|
|
824
|
+
)
|
|
825
|
+
}
|
|
826
|
+
part.providerData = mergeProviderData(
|
|
827
|
+
part.providerData,
|
|
828
|
+
this.captureProviderData(event.providerData)
|
|
829
|
+
)
|
|
830
|
+
part.complete = true
|
|
831
|
+
this.spans.delete(event.id)
|
|
832
|
+
await this.onEvent?.({ type: event.type, id: event.id })
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
private async startTool(
|
|
836
|
+
event: Extract<LanguageModelStreamEvent, { type: "tool-input-start" }>
|
|
837
|
+
): Promise<void> {
|
|
838
|
+
this.requireStarted(event.type)
|
|
839
|
+
if (!event.id || !event.toolName) {
|
|
840
|
+
throw new ModelStreamError("[SixbModels] Tool calls require nonempty IDs and names.")
|
|
841
|
+
}
|
|
842
|
+
if (this.toolCalls.has(event.id)) {
|
|
843
|
+
throw new ModelStreamError(`[SixbModels] Duplicate tool call ID '${event.id}'.`)
|
|
844
|
+
}
|
|
845
|
+
const providerData = this.captureProviderData(event.providerData)
|
|
846
|
+
const part: MutableToolCall = {
|
|
847
|
+
type: "tool-call",
|
|
848
|
+
toolCallId: event.id,
|
|
849
|
+
toolName: event.toolName,
|
|
850
|
+
inputText: "",
|
|
851
|
+
complete: false,
|
|
852
|
+
...(providerData === undefined ? {} : { providerData }),
|
|
853
|
+
...(event.providerExecuted === undefined ? {} : { providerExecuted: event.providerExecuted }),
|
|
854
|
+
...(event.dynamic === undefined ? {} : { dynamic: event.dynamic }),
|
|
855
|
+
}
|
|
856
|
+
this.toolCalls.set(event.id, part)
|
|
857
|
+
this.parts.push(part)
|
|
858
|
+
await this.onEvent?.({
|
|
859
|
+
type: "tool-input-start",
|
|
860
|
+
toolCallId: event.id,
|
|
861
|
+
toolName: event.toolName,
|
|
862
|
+
})
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
private async appendTool(
|
|
866
|
+
event: Extract<LanguageModelStreamEvent, { type: "tool-input-delta" }>
|
|
867
|
+
): Promise<void> {
|
|
868
|
+
const part = this.toolCalls.get(event.id)
|
|
869
|
+
if (!part || part.complete) {
|
|
870
|
+
throw new ModelStreamError(
|
|
871
|
+
`[SixbModels] tool-input-delta references unopened tool call '${event.id}'.`
|
|
872
|
+
)
|
|
873
|
+
}
|
|
874
|
+
part.inputText += event.delta
|
|
875
|
+
await this.onEvent?.({
|
|
876
|
+
type: "tool-input-delta",
|
|
877
|
+
toolCallId: event.id,
|
|
878
|
+
toolName: part.toolName,
|
|
879
|
+
inputTextDelta: event.delta,
|
|
880
|
+
})
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
private endTool(event: Extract<LanguageModelStreamEvent, { type: "tool-input-end" }>): void {
|
|
884
|
+
const part = this.toolCalls.get(event.id)
|
|
885
|
+
if (!part || part.complete) {
|
|
886
|
+
throw new ModelStreamError(
|
|
887
|
+
`[SixbModels] tool-input-end references unopened tool call '${event.id}'.`
|
|
888
|
+
)
|
|
889
|
+
}
|
|
890
|
+
part.providerData = mergeProviderData(
|
|
891
|
+
part.providerData,
|
|
892
|
+
this.captureProviderData(event.providerData)
|
|
893
|
+
)
|
|
894
|
+
part.complete = true
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
private async completeTool(
|
|
898
|
+
event: Extract<LanguageModelStreamEvent, { type: "tool-call" }>
|
|
899
|
+
): Promise<void> {
|
|
900
|
+
await this.startTool({
|
|
901
|
+
type: "tool-input-start",
|
|
902
|
+
id: event.toolCallId,
|
|
903
|
+
toolName: event.toolName,
|
|
904
|
+
...(event.providerData === undefined ? {} : { providerData: event.providerData }),
|
|
905
|
+
...(event.providerExecuted === undefined ? {} : { providerExecuted: event.providerExecuted }),
|
|
906
|
+
...(event.dynamic === undefined ? {} : { dynamic: event.dynamic }),
|
|
907
|
+
})
|
|
908
|
+
const part = this.toolCalls.get(event.toolCallId)
|
|
909
|
+
if (!part) throw new ModelStreamError("[SixbModels] Failed to index completed tool call.")
|
|
910
|
+
part.inputText = event.input
|
|
911
|
+
part.complete = true
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
private addProviderToolResult(
|
|
915
|
+
event: Extract<LanguageModelStreamEvent, { type: "tool-result" }>
|
|
916
|
+
): void {
|
|
917
|
+
if (!this.captureJsonValue(event.output, "provider tool result")) return
|
|
918
|
+
const providerData = this.captureProviderData(event.providerData)
|
|
919
|
+
this.parts.push({
|
|
920
|
+
type: "tool-result",
|
|
921
|
+
toolCallId: event.toolCallId,
|
|
922
|
+
toolName: event.toolName,
|
|
923
|
+
output: event.isError
|
|
924
|
+
? { type: "error-json", value: event.output }
|
|
925
|
+
: modelToolOutput(event.output),
|
|
926
|
+
providerExecuted: event.providerExecuted ?? true,
|
|
927
|
+
...(event.dynamic === undefined ? {} : { dynamic: event.dynamic }),
|
|
928
|
+
...(providerData === undefined ? {} : { providerData }),
|
|
929
|
+
})
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
private captureProviderData(data: ProviderData | undefined): ProviderData | undefined {
|
|
933
|
+
if (data === undefined) return undefined
|
|
934
|
+
try {
|
|
935
|
+
validateProviderData(data)
|
|
936
|
+
return data
|
|
937
|
+
} catch (error) {
|
|
938
|
+
this.captureProjectionError(error)
|
|
939
|
+
return undefined
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
private captureProviderState(value: unknown): value is JsonValue {
|
|
944
|
+
if (!this.captureJsonValue(value, "provider state")) return false
|
|
945
|
+
if (JSON.stringify(value).length > MAX_PROVIDER_DATA_BYTES) {
|
|
946
|
+
this.captureProjectionError(
|
|
947
|
+
new ModelStreamError(
|
|
948
|
+
`[SixbModels] Provider state exceeds the ${MAX_PROVIDER_DATA_BYTES}-byte response limit.`
|
|
949
|
+
)
|
|
950
|
+
)
|
|
951
|
+
return false
|
|
952
|
+
}
|
|
953
|
+
return true
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
private captureJsonValue(value: unknown, label: string): value is JsonValue {
|
|
957
|
+
try {
|
|
958
|
+
assertJsonValue(value, label)
|
|
959
|
+
return true
|
|
960
|
+
} catch (error) {
|
|
961
|
+
this.captureProjectionError(error)
|
|
962
|
+
return false
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
private captureProjectionError(error: unknown): void {
|
|
967
|
+
this.projectionError ??= error instanceof Error ? error : new Error(String(error))
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
private requireStarted(type: string): void {
|
|
971
|
+
if (!this.started) {
|
|
972
|
+
throw new ModelStreamError(`[SixbModels] Received '${type}' before stream-start.`)
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
private assertNewSpan(id: string): void {
|
|
977
|
+
if (!id) throw new ModelStreamError("[SixbModels] Content span IDs must not be empty.")
|
|
978
|
+
if (this.spans.has(id)) {
|
|
979
|
+
throw new ModelStreamError(`[SixbModels] Duplicate open content span '${id}'.`)
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
function validateUsage(usage: ModelUsage): void {
|
|
985
|
+
for (const [key, value] of Object.entries(usage)) {
|
|
986
|
+
if (key === "raw") {
|
|
987
|
+
if (value !== undefined) assertJsonValue(value, "raw model usage")
|
|
988
|
+
continue
|
|
989
|
+
}
|
|
990
|
+
if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
|
|
991
|
+
throw new ModelStreamError(`[SixbModels] Usage field '${key}' must be a nonnegative integer.`)
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
function validateProviderData(data: ProviderData | undefined): void {
|
|
997
|
+
if (data === undefined) return
|
|
998
|
+
assertJsonValue(data, "provider data")
|
|
999
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
1000
|
+
throw new TypeError("[SixbModels] provider data must be a JSON object.")
|
|
1001
|
+
}
|
|
1002
|
+
if (JSON.stringify(data).length > MAX_PROVIDER_DATA_BYTES) {
|
|
1003
|
+
throw new ModelStreamError(
|
|
1004
|
+
`[SixbModels] Provider data exceeds the ${MAX_PROVIDER_DATA_BYTES}-byte response limit.`
|
|
1005
|
+
)
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
function mergeProviderData(
|
|
1010
|
+
first: ProviderData | undefined,
|
|
1011
|
+
second: ProviderData | undefined
|
|
1012
|
+
): ProviderData | undefined {
|
|
1013
|
+
if (first === undefined) return second
|
|
1014
|
+
if (second === undefined) return first
|
|
1015
|
+
return { ...first, ...second }
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
function isAbortError(error: unknown): boolean {
|
|
1019
|
+
return (
|
|
1020
|
+
(error instanceof DOMException && error.name === "AbortError") ||
|
|
1021
|
+
(error instanceof Error && error.name === "AbortError")
|
|
1022
|
+
)
|
|
1023
|
+
}
|