@sixb/core 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/index.js +37 -33
- package/dist/actions/index.js.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.js +7 -7
- 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-1g8negke.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-dy311asx.js → chunk-2b5qtban.js} +12 -12
- package/dist/{chunk-dy311asx.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-md8k0r54.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-t624af60.js → chunk-6ed5bwnd.js} +646 -67
- package/dist/{chunk-t624af60.js.map → chunk-6ed5bwnd.js.map} +10 -9
- 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-nkbfrt0c.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-0hc5j867.js → chunk-d2ndstdf.js} +8 -6
- package/dist/{chunk-0hc5j867.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-5sxb1168.js → chunk-e4rvtvpw.js} +13 -11
- package/dist/{chunk-5sxb1168.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-nva1xkjz.js → chunk-h0knpbz5.js} +468 -1236
- package/dist/chunk-h0knpbz5.js.map +38 -0
- package/dist/{chunk-tg5mee00.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-znagycq7.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-n4spznws.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-5gynx4xn.js → chunk-qv38twt8.js} +50 -69
- package/dist/{chunk-5gynx4xn.js.map → chunk-qv38twt8.js.map} +8 -8
- package/dist/{chunk-bhxaq2nn.js → chunk-qw9gvjv5.js} +1 -1
- package/dist/{chunk-8gv5z0zm.js → chunk-rp1mvzb4.js} +6 -6
- package/dist/{chunk-1e8m6yn3.js → chunk-rre42skh.js} +182 -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-e42bc6m3.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-a44d5zgd.js → chunk-y35ma3mj.js} +11 -16
- package/dist/{chunk-a44d5zgd.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 +7 -4
- 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/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 +3637 -1962
- package/dist/testing/index.js.map +14 -12
- 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/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/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 +51 -1
- 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/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-1e8m6yn3.js.map +0 -37
- package/dist/chunk-1g8negke.js.map +0 -11
- package/dist/chunk-6gjqgd3d.js.map +0 -11
- package/dist/chunk-dm72y8wt.js.map +0 -10
- package/dist/chunk-drjqm1aa.js.map +0 -15
- package/dist/chunk-fe5ev6mr.js +0 -55
- package/dist/chunk-fe5ev6mr.js.map +0 -11
- package/dist/chunk-h9kxd41f.js.map +0 -11
- package/dist/chunk-hceck7dq.js +0 -137
- package/dist/chunk-hceck7dq.js.map +0 -10
- package/dist/chunk-n4spznws.js.map +0 -11
- package/dist/chunk-nva1xkjz.js.map +0 -46
- package/dist/chunk-t0jjkep3.js.map +0 -10
- package/dist/chunk-t8t39h7v.js.map +0 -10
- /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-md8k0r54.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-72q2y8hn.js.map → chunk-8tsf6dmc.js.map} +0 -0
- /package/dist/{chunk-nkbfrt0c.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-tg5mee00.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-znagycq7.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-8gv5z0zm.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-e42bc6m3.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
|
@@ -3,11 +3,17 @@ import {
|
|
|
3
3
|
SyncValidationError,
|
|
4
4
|
createConnectorRuntime,
|
|
5
5
|
requestSyncRun
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ha58tjtt.js";
|
|
7
|
+
import {
|
|
8
|
+
aiLimitSubjectsFromAttribution,
|
|
9
|
+
aiUsageLimitExceededError,
|
|
10
|
+
aiUsageLimitUnavailableError,
|
|
11
|
+
applicableAiLimitPolicyStatuses
|
|
12
|
+
} from "./chunk-c15dr03f.js";
|
|
7
13
|
import {
|
|
8
14
|
PipelineError,
|
|
9
15
|
requestPipelineRun
|
|
10
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-rp1mvzb4.js";
|
|
11
17
|
import {
|
|
12
18
|
appendTelemetry,
|
|
13
19
|
createObjectSet,
|
|
@@ -18,7 +24,7 @@ import {
|
|
|
18
24
|
upsertLinkBatch1 as upsertLinkBatch,
|
|
19
25
|
upsertObject1 as upsertObject,
|
|
20
26
|
upsertObjectBatch1 as upsertObjectBatch
|
|
21
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-e4rvtvpw.js";
|
|
22
28
|
import {
|
|
23
29
|
shareOntologyMutationRuntime
|
|
24
30
|
} from "./chunk-xhy826cz.js";
|
|
@@ -28,12 +34,7 @@ import {
|
|
|
28
34
|
executeObjectQueryLinks,
|
|
29
35
|
existsObjects,
|
|
30
36
|
facetObjects
|
|
31
|
-
} from "./chunk-
|
|
32
|
-
import {
|
|
33
|
-
SIXB_API_ROUTES,
|
|
34
|
-
matchesPathPattern,
|
|
35
|
-
normalizeRoutePath
|
|
36
|
-
} from "./chunk-qewtks41.js";
|
|
37
|
+
} from "./chunk-3fqt22c4.js";
|
|
37
38
|
import {
|
|
38
39
|
registerConnectorConnectionsRuntime
|
|
39
40
|
} from "./chunk-nf4r78r4.js";
|
|
@@ -41,59 +42,60 @@ import {
|
|
|
41
42
|
isActionDefinition,
|
|
42
43
|
requestAction,
|
|
43
44
|
requestActionAndWait
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-y35ma3mj.js";
|
|
45
46
|
import {
|
|
46
47
|
createPrimitiveExecutionRecord,
|
|
47
48
|
ensureExecutionRecord,
|
|
48
49
|
executionRecordInputFromRuntime
|
|
49
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-hdz94br2.js";
|
|
50
51
|
import {
|
|
51
52
|
WORKFLOW_RUN_FAILURE_CODES
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import {
|
|
54
|
-
WorkflowRunError
|
|
55
|
-
} from "./chunk-fe5ev6mr.js";
|
|
56
|
-
import {
|
|
57
|
-
AgentStorageError
|
|
58
|
-
} from "./chunk-1g8negke.js";
|
|
53
|
+
} from "./chunk-6ed5bwnd.js";
|
|
59
54
|
import {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} from "./chunk-hceck7dq.js";
|
|
55
|
+
WorkflowRunError,
|
|
56
|
+
agentServiceAccountId
|
|
57
|
+
} from "./chunk-qjzp9xyb.js";
|
|
64
58
|
import {
|
|
65
59
|
ExecutionStorageError
|
|
66
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-gbrpsx4m.js";
|
|
61
|
+
import {
|
|
62
|
+
AGENT_REASONING_LEVELS,
|
|
63
|
+
AgentStorageError
|
|
64
|
+
} from "./chunk-08twe8m6.js";
|
|
67
65
|
import {
|
|
68
66
|
isObjectRefSchema,
|
|
69
67
|
validateSchemaOrRefValue
|
|
70
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-dqn23610.js";
|
|
69
|
+
import {
|
|
70
|
+
RuntimeError
|
|
71
|
+
} from "./chunk-p2vqaxkc.js";
|
|
72
|
+
import {
|
|
73
|
+
isModelReasoning
|
|
74
|
+
} from "./chunk-trxxmgnf.js";
|
|
71
75
|
import {
|
|
72
76
|
reportRunFailure
|
|
73
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-jq43kdvk.js";
|
|
74
78
|
import {
|
|
75
|
-
AgentDefinitionError,
|
|
76
|
-
AgentMessageAdapterError,
|
|
77
79
|
AgentRequestError,
|
|
78
|
-
AgentToolResultValidationError,
|
|
79
80
|
normalizeAgentContextEntries
|
|
80
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-atmkaf60.js";
|
|
81
82
|
import {
|
|
82
83
|
publishAgentRunActivity
|
|
83
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-7y0f6rf1.js";
|
|
84
85
|
import {
|
|
85
86
|
SYSTEM_PRINCIPAL,
|
|
86
87
|
principalsEqual
|
|
87
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-rre42skh.js";
|
|
88
89
|
import {
|
|
89
90
|
snapshotRequesterGroupIds
|
|
90
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-4a849fr1.js";
|
|
91
92
|
import {
|
|
92
93
|
AuthorizationError,
|
|
93
94
|
assertAuthorized,
|
|
94
95
|
assertCanManageConnector,
|
|
95
96
|
assertPrivileged,
|
|
96
97
|
assertProviderAccess,
|
|
98
|
+
assertRuntimeAuthorizationBound,
|
|
97
99
|
canViewActionRun,
|
|
98
100
|
canViewEvent,
|
|
99
101
|
canViewPipelineRun,
|
|
@@ -102,31 +104,23 @@ import {
|
|
|
102
104
|
canViewWorkflowIntervention,
|
|
103
105
|
canViewWorkflowRun,
|
|
104
106
|
createAgentRuntimeAuthorization,
|
|
107
|
+
getAuthorizationRef,
|
|
105
108
|
isAllowed,
|
|
106
109
|
resolveExecutionScopeAuthorization
|
|
107
|
-
} from "./chunk-
|
|
108
|
-
import {
|
|
109
|
-
assertObjectTypeRegistered,
|
|
110
|
-
normalizeSchemaValue,
|
|
111
|
-
validateSchemaValue
|
|
112
|
-
} from "./chunk-rnshztfq.js";
|
|
110
|
+
} from "./chunk-37wk412q.js";
|
|
113
111
|
import {
|
|
114
|
-
|
|
115
|
-
} from "./chunk-
|
|
112
|
+
assertObjectTypeRegistered
|
|
113
|
+
} from "./chunk-d63tybny.js";
|
|
116
114
|
import {
|
|
117
|
-
isFileRef,
|
|
118
115
|
supportsDirectUpload,
|
|
119
116
|
supportsRangeRead
|
|
120
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-08m3b6w8.js";
|
|
121
118
|
import {
|
|
122
119
|
captureSixbFailure
|
|
123
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-2xns679x.js";
|
|
124
121
|
import {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
isPlainRecord,
|
|
128
|
-
stableJsonStringify
|
|
129
|
-
} from "./chunk-t8t39h7v.js";
|
|
122
|
+
isPlainRecord
|
|
123
|
+
} from "./chunk-n6jxh8sw.js";
|
|
130
124
|
|
|
131
125
|
// src/actions/execution.ts
|
|
132
126
|
function createActionsRuntime(runtime, execution) {
|
|
@@ -197,13 +191,20 @@ async function resolveExecutionUsage(input) {
|
|
|
197
191
|
}
|
|
198
192
|
|
|
199
193
|
// src/agents/ids.ts
|
|
200
|
-
import { randomUUID } from "crypto";
|
|
194
|
+
import { createHash, randomUUID } from "crypto";
|
|
201
195
|
function createAgentThreadId() {
|
|
202
196
|
return `agt_thr_${randomUUID()}`;
|
|
203
197
|
}
|
|
204
198
|
function createAgentRunId() {
|
|
205
199
|
return `agt_run_${randomUUID()}`;
|
|
206
200
|
}
|
|
201
|
+
function createSubagentRunId(parentRunId, spawnKey) {
|
|
202
|
+
const digest = createHash("sha256").update(parentRunId).update("\x00").update(spawnKey).digest("hex");
|
|
203
|
+
return `agt_run_child_${digest}`;
|
|
204
|
+
}
|
|
205
|
+
function createSubagentExecutionId(runId) {
|
|
206
|
+
return `exec_${runId}`;
|
|
207
|
+
}
|
|
207
208
|
function createAgentMessageId() {
|
|
208
209
|
return `agt_msg_${randomUUID()}`;
|
|
209
210
|
}
|
|
@@ -249,6 +250,9 @@ function invalidContext(message) {
|
|
|
249
250
|
function agentRunQueueJobId(runId) {
|
|
250
251
|
return `agt_job_${runId}`;
|
|
251
252
|
}
|
|
253
|
+
function subagentRunQueueJobId(runId) {
|
|
254
|
+
return `agt_child_job_${runId}`;
|
|
255
|
+
}
|
|
252
256
|
function workflowAgentNodeQueueJobId(nodeRunId) {
|
|
253
257
|
return `wfa_job_${nodeRunId}`;
|
|
254
258
|
}
|
|
@@ -259,11 +263,12 @@ async function dispatchQueuedAgentRuns(input) {
|
|
|
259
263
|
ids: [...new Set(input.runIds)].slice(0, limit)
|
|
260
264
|
}) : (await input.storage.runs.list({
|
|
261
265
|
projectId: input.projectId,
|
|
266
|
+
kinds: ["conversation"],
|
|
262
267
|
statuses: ["queued"],
|
|
263
268
|
order: "asc",
|
|
264
269
|
limit
|
|
265
270
|
})).runs;
|
|
266
|
-
const queued = runs.filter((run) => run.status === "queued");
|
|
271
|
+
const queued = runs.filter((run) => run.kind === "conversation" && run.status === "queued");
|
|
267
272
|
if (queued.length === 0) {
|
|
268
273
|
return { scanned: 0, dispatched: [], failures: [] };
|
|
269
274
|
}
|
|
@@ -293,6 +298,47 @@ async function dispatchQueuedAgentRuns(input) {
|
|
|
293
298
|
};
|
|
294
299
|
}
|
|
295
300
|
}
|
|
301
|
+
async function dispatchQueuedSubagentRuns(input) {
|
|
302
|
+
const limit = normalizeLimit(input.limit);
|
|
303
|
+
const runs = input.runIds ? await input.storage.runs.getByIds({
|
|
304
|
+
projectId: input.projectId,
|
|
305
|
+
ids: [...new Set(input.runIds)].slice(0, limit)
|
|
306
|
+
}) : (await input.storage.runs.list({
|
|
307
|
+
projectId: input.projectId,
|
|
308
|
+
kinds: ["subagent"],
|
|
309
|
+
statuses: ["queued"],
|
|
310
|
+
order: "asc",
|
|
311
|
+
limit
|
|
312
|
+
})).runs;
|
|
313
|
+
const queued = runs.filter((run) => run.kind === "subagent" && run.status === "queued");
|
|
314
|
+
if (queued.length === 0)
|
|
315
|
+
return { scanned: 0, dispatched: [], failures: [] };
|
|
316
|
+
try {
|
|
317
|
+
const jobs = await input.queue.enqueue({
|
|
318
|
+
projectId: input.projectId,
|
|
319
|
+
jobs: queued.map((run) => ({
|
|
320
|
+
id: subagentRunQueueJobId(run.id),
|
|
321
|
+
type: "agent.subagent-run.requested",
|
|
322
|
+
payload: { runId: run.id }
|
|
323
|
+
}))
|
|
324
|
+
});
|
|
325
|
+
const jobsById = new Set(jobs.map((job) => job.id));
|
|
326
|
+
const dispatched = queued.map((run) => {
|
|
327
|
+
const jobId = subagentRunQueueJobId(run.id);
|
|
328
|
+
if (!jobsById.has(jobId)) {
|
|
329
|
+
throw new Error(`[Sixb] Subagent queue did not return job '${jobId}'.`);
|
|
330
|
+
}
|
|
331
|
+
return { runId: run.id, jobId };
|
|
332
|
+
});
|
|
333
|
+
return { scanned: queued.length, dispatched, failures: [] };
|
|
334
|
+
} catch (error) {
|
|
335
|
+
return {
|
|
336
|
+
scanned: queued.length,
|
|
337
|
+
dispatched: [],
|
|
338
|
+
failures: queued.map((run) => ({ runId: run.id, error }))
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
}
|
|
296
342
|
function normalizeLimit(value) {
|
|
297
343
|
if (value === undefined)
|
|
298
344
|
return 100;
|
|
@@ -302,16 +348,38 @@ function normalizeLimit(value) {
|
|
|
302
348
|
return Math.floor(value);
|
|
303
349
|
}
|
|
304
350
|
|
|
351
|
+
// src/agents/retired-config.ts
|
|
352
|
+
function assertNoAgentDefinitions(input) {
|
|
353
|
+
if ("agents" in input) {
|
|
354
|
+
throw new RuntimeError("[Sixb] Agent definitions are no longer supported. Configure 'models' and 'tools' on createSixb() instead.");
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function assertNoAgentSelector(input) {
|
|
358
|
+
if ("agentId" in input || "agentIds" in input) {
|
|
359
|
+
throw new AgentRequestError("agent_selector_removed", "[Sixb] There is one project Agent. Remove the agentId selector and use sixb.agent.");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
305
363
|
// src/agents/request.ts
|
|
306
|
-
async function requestAgentRun(runtime, execution,
|
|
307
|
-
|
|
364
|
+
async function requestAgentRun(runtime, execution, models, input) {
|
|
365
|
+
assertNoAgentSelector(input);
|
|
366
|
+
assertAuthorized(runtime, { kind: "agent.run" });
|
|
367
|
+
assertRequestAuthorityCanRunAgent(runtime);
|
|
368
|
+
const spec = resolveConversationRunSpec({ models, input });
|
|
308
369
|
const contextParts = await resolveAgentContextParts(runtime, input.context);
|
|
309
370
|
const agents = requireAgentStorage(runtime);
|
|
310
371
|
const projectId = runtime.projectId;
|
|
311
372
|
const principal = runtime.authorization?.principal ?? input.principal ?? SYSTEM_PRINCIPAL;
|
|
373
|
+
const runId = createAgentRunId();
|
|
374
|
+
const durableExecution = await prepareDurableAgentExecution(runtime, execution, runId);
|
|
375
|
+
const requesterGroupIds = durableExecution.requestedBy ? await snapshotRequesterGroupIds({
|
|
376
|
+
auth: runtime.storage.auth,
|
|
377
|
+
projectId,
|
|
378
|
+
principal: durableExecution.requestedBy
|
|
379
|
+
}) : [];
|
|
380
|
+
await assertAiLimitPreflight(runtime, durableExecution, requesterGroupIds);
|
|
312
381
|
const { thread, createdThread } = await resolveThread(agents, {
|
|
313
382
|
projectId,
|
|
314
|
-
agentId: agent.id,
|
|
315
383
|
threadId: input.threadId,
|
|
316
384
|
title: input.title,
|
|
317
385
|
principal
|
|
@@ -319,13 +387,6 @@ async function requestAgentRun(runtime, execution, security, agent, input) {
|
|
|
319
387
|
if (thread.activeRunId !== null) {
|
|
320
388
|
throw new AgentRequestError("active_run_exists", `[Sixb] Agent thread '${thread.id}' already has an active run '${thread.activeRunId}'.`);
|
|
321
389
|
}
|
|
322
|
-
const runId = createAgentRunId();
|
|
323
|
-
const durableExecution = await prepareDurableAgentExecution(runtime, execution, security, agent, runId);
|
|
324
|
-
const requesterGroupIds = durableExecution.requestedBy ? await snapshotRequesterGroupIds({
|
|
325
|
-
auth: runtime.storage.auth,
|
|
326
|
-
projectId,
|
|
327
|
-
principal: durableExecution.requestedBy
|
|
328
|
-
}) : [];
|
|
329
390
|
const triggerMessageId = input.messageId ?? createAgentMessageId();
|
|
330
391
|
let run;
|
|
331
392
|
try {
|
|
@@ -353,8 +414,8 @@ async function requestAgentRun(runtime, execution, security, agent, input) {
|
|
|
353
414
|
projectId,
|
|
354
415
|
executionId: durableExecution.id,
|
|
355
416
|
threadId: thread.id,
|
|
356
|
-
agentId: agent.id,
|
|
357
417
|
triggerMessageId,
|
|
418
|
+
spec,
|
|
358
419
|
requesterGroupIds
|
|
359
420
|
});
|
|
360
421
|
});
|
|
@@ -372,22 +433,28 @@ async function requestAgentRun(runtime, execution, security, agent, input) {
|
|
|
372
433
|
createdThread
|
|
373
434
|
};
|
|
374
435
|
}
|
|
375
|
-
async function retryAgentRun(runtime, execution,
|
|
376
|
-
assertAuthorized(runtime, { kind: "agent.run"
|
|
377
|
-
|
|
378
|
-
throw new AgentRequestError("agent_not_found", `[Sixb] Agent run '${failedRun.id}' does not belong to agent '${agent.id}'.`);
|
|
379
|
-
}
|
|
436
|
+
async function retryAgentRun(runtime, execution, models, failedRun) {
|
|
437
|
+
assertAuthorized(runtime, { kind: "agent.run" });
|
|
438
|
+
assertRequestAuthorityCanRunAgent(runtime);
|
|
380
439
|
if (failedRun.status !== "failed") {
|
|
381
440
|
throw new AgentRequestError("run_not_retryable", `[Sixb] Only failed Agent runs can be retried.`);
|
|
382
441
|
}
|
|
383
442
|
const agents = requireAgentStorage(runtime);
|
|
443
|
+
const thread = await agents.threads.getById({
|
|
444
|
+
projectId: runtime.projectId,
|
|
445
|
+
id: failedRun.threadId
|
|
446
|
+
});
|
|
447
|
+
if (!thread) {
|
|
448
|
+
throw new AgentRequestError("thread_not_found", `[Sixb] Agent thread '${failedRun.threadId}' was not found.`);
|
|
449
|
+
}
|
|
384
450
|
const runId = createAgentRunId();
|
|
385
|
-
const durableExecution = await prepareDurableAgentExecution(runtime, execution,
|
|
451
|
+
const durableExecution = await prepareDurableAgentExecution(runtime, execution, runId);
|
|
386
452
|
const requesterGroupIds = durableExecution.requestedBy ? await snapshotRequesterGroupIds({
|
|
387
453
|
auth: runtime.storage.auth,
|
|
388
454
|
projectId: runtime.projectId,
|
|
389
455
|
principal: durableExecution.requestedBy
|
|
390
456
|
}) : [];
|
|
457
|
+
await assertAiLimitPreflight(runtime, durableExecution, requesterGroupIds);
|
|
391
458
|
const run = await runtime.storage.transaction(async (tx) => {
|
|
392
459
|
const agents2 = tx.agents;
|
|
393
460
|
if (!agents2) {
|
|
@@ -404,8 +471,11 @@ async function retryAgentRun(runtime, execution, security, agent, failedRun) {
|
|
|
404
471
|
projectId: runtime.projectId,
|
|
405
472
|
executionId: durableExecution.id,
|
|
406
473
|
threadId: failedRun.threadId,
|
|
407
|
-
agentId: agent.id,
|
|
408
474
|
triggerMessageId: failedRun.triggerMessageId,
|
|
475
|
+
spec: failedRun.spec ?? resolveConversationRunSpec({
|
|
476
|
+
models,
|
|
477
|
+
input: {}
|
|
478
|
+
}),
|
|
409
479
|
requesterGroupIds
|
|
410
480
|
});
|
|
411
481
|
});
|
|
@@ -413,31 +483,61 @@ async function retryAgentRun(runtime, execution, security, agent, failedRun) {
|
|
|
413
483
|
const jobId = await dispatchAgentRun(runtime, agents, runId);
|
|
414
484
|
return { run, ...jobId ? { jobId } : {}, createdThread: false };
|
|
415
485
|
}
|
|
416
|
-
async function
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
486
|
+
async function assertAiLimitPreflight(runtime, execution, requesterGroupIds) {
|
|
487
|
+
const limits = runtime.storage.aiLimits;
|
|
488
|
+
if (!limits)
|
|
489
|
+
throw aiUsageLimitUnavailableError(["limitStorageUnavailable"]);
|
|
490
|
+
const subjects = aiLimitSubjectsFromAttribution(execution.requestedBy, requesterGroupIds);
|
|
491
|
+
let applicable;
|
|
492
|
+
try {
|
|
493
|
+
applicable = applicableAiLimitPolicyStatuses(await limits.listPolicyStatuses({ projectId: runtime.projectId }), subjects);
|
|
494
|
+
} catch {
|
|
495
|
+
throw aiUsageLimitUnavailableError(["limitStorageUnavailable"]);
|
|
496
|
+
}
|
|
497
|
+
const unavailable = applicable.filter((status) => status.accountingStatus === "unavailable");
|
|
498
|
+
if (unavailable.length > 0) {
|
|
499
|
+
throw aiUsageLimitUnavailableError(["incompleteAccounting"]);
|
|
500
|
+
}
|
|
501
|
+
const exhausted = applicable.filter((status) => status.exhausted);
|
|
502
|
+
if (exhausted.length > 0) {
|
|
503
|
+
const resetAt = new Date(Math.min(...exhausted.map((status) => status.period.resetAt.getTime())));
|
|
504
|
+
throw aiUsageLimitExceededError(resetAt);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function resolveConversationRunSpec(input) {
|
|
508
|
+
if (!input.models) {
|
|
509
|
+
throw new AgentRequestError("model_not_found", "[Sixb] Configure models.language before starting the Agent.");
|
|
510
|
+
}
|
|
511
|
+
const selected = input.input.model ?? input.models.default;
|
|
512
|
+
const model = input.models.getByRef(selected);
|
|
513
|
+
if (model === null) {
|
|
514
|
+
throw new AgentRequestError("model_not_found", `[Sixb] Language model '${selected.provider}/${selected.modelId}' is not in the project model catalog.`);
|
|
515
|
+
}
|
|
516
|
+
const reasoning = input.input.reasoning;
|
|
517
|
+
if (reasoning !== undefined && !isModelReasoning(reasoning)) {
|
|
518
|
+
throw new AgentRequestError("invalid_model_selection", `[Sixb] Agent reasoning must be one of: ${AGENT_REASONING_LEVELS.join(", ")}, or a nonnegative budgetTokens object.`);
|
|
519
|
+
}
|
|
520
|
+
return Object.freeze({
|
|
521
|
+
model: Object.freeze({ provider: selected.provider, modelId: selected.modelId }),
|
|
522
|
+
...reasoning === undefined ? {} : { reasoning }
|
|
428
523
|
});
|
|
524
|
+
}
|
|
525
|
+
async function prepareDurableAgentExecution(runtime, execution, runId) {
|
|
429
526
|
const parent = await ensureExecutionRecord(runtime.storage.executions, executionRecordInputFromRuntime({
|
|
430
527
|
execution,
|
|
431
528
|
runtimeAuthorization: runtime.runtimeAuthorization
|
|
432
529
|
}));
|
|
433
|
-
return
|
|
530
|
+
return createInheritedAgentExecutionRecord({
|
|
434
531
|
id: `exec_${randomUUID2()}`,
|
|
435
532
|
parent,
|
|
436
|
-
|
|
437
|
-
runId,
|
|
438
|
-
principal: resolved.identity.principal
|
|
533
|
+
runId
|
|
439
534
|
});
|
|
440
535
|
}
|
|
536
|
+
function assertRequestAuthorityCanRunAgent(runtime) {
|
|
537
|
+
if (!canInheritAgentRequestAuthorization(runtime.runtimeAuthorization)) {
|
|
538
|
+
throw new AgentRequestError("authority_not_inheritable", "[Sixb] The Agent requires an authenticated user request or disabled authorization.");
|
|
539
|
+
}
|
|
540
|
+
}
|
|
441
541
|
async function dispatchAgentRun(runtime, agents, runId) {
|
|
442
542
|
try {
|
|
443
543
|
const dispatch = await dispatchQueuedAgentRuns({
|
|
@@ -470,16 +570,12 @@ async function resolveThread(agents, params) {
|
|
|
470
570
|
id: params.threadId
|
|
471
571
|
});
|
|
472
572
|
if (existing) {
|
|
473
|
-
if (existing.agentId !== params.agentId) {
|
|
474
|
-
throw new AgentRequestError("thread_agent_mismatch", `[Sixb] Agent thread '${existing.id}' belongs to agent '${existing.agentId}', not '${params.agentId}'.`);
|
|
475
|
-
}
|
|
476
573
|
return { thread: existing, createdThread: false };
|
|
477
574
|
}
|
|
478
575
|
}
|
|
479
576
|
const thread = await agents.threads.create({
|
|
480
577
|
id: params.threadId ?? createAgentThreadId(),
|
|
481
578
|
projectId: params.projectId,
|
|
482
|
-
agentId: params.agentId,
|
|
483
579
|
ownerPrincipal: params.principal,
|
|
484
580
|
...params.title === undefined ? {} : { title: params.title }
|
|
485
581
|
});
|
|
@@ -494,44 +590,49 @@ function requireAgentStorage(runtime) {
|
|
|
494
590
|
}
|
|
495
591
|
|
|
496
592
|
// src/agents/execution.ts
|
|
497
|
-
function
|
|
593
|
+
function createAgentRuntime(runtime, execution, models) {
|
|
498
594
|
const principal = runtime.authorization?.principal ?? SYSTEM_PRINCIPAL;
|
|
499
|
-
const allowed = (
|
|
500
|
-
const
|
|
595
|
+
const allowed = () => isAllowed(runtime.authorization, { kind: "agent.run" });
|
|
596
|
+
const getVisibleThreadRecord = async (threadId) => {
|
|
501
597
|
const thread = await runtime.storage.agents?.threads.getById({
|
|
502
598
|
projectId: runtime.projectId,
|
|
503
599
|
id: threadId
|
|
504
600
|
}) ?? null;
|
|
505
|
-
if (!thread || !allowed(
|
|
601
|
+
if (!thread || !allowed())
|
|
506
602
|
return null;
|
|
507
603
|
return runtime.authorization && !principalsEqual(principal, thread.ownerPrincipal) ? null : thread;
|
|
508
604
|
};
|
|
509
|
-
const getAgent = (
|
|
510
|
-
const
|
|
511
|
-
|
|
605
|
+
const getAgent = () => {
|
|
606
|
+
const model = models?.language.default;
|
|
607
|
+
if (!model || !allowed())
|
|
608
|
+
return null;
|
|
609
|
+
return {
|
|
610
|
+
name: "Sixb",
|
|
611
|
+
model: { provider: model.provider, modelId: model.modelId }
|
|
612
|
+
};
|
|
512
613
|
};
|
|
513
614
|
const getVisibleRunRecord = async (runId) => {
|
|
514
615
|
const run = await runtime.storage.agents?.runs.getById({
|
|
515
616
|
projectId: runtime.projectId,
|
|
516
617
|
id: runId
|
|
517
618
|
}) ?? null;
|
|
518
|
-
if (!run)
|
|
619
|
+
if (!run || run.kind !== "conversation")
|
|
519
620
|
return null;
|
|
520
|
-
const thread = await
|
|
521
|
-
return thread
|
|
621
|
+
const thread = await getVisibleThreadRecord(run.threadId);
|
|
622
|
+
return thread ? run : null;
|
|
522
623
|
};
|
|
523
624
|
const getRun = async (runId) => {
|
|
524
625
|
const run = await getVisibleRunRecord(runId);
|
|
525
626
|
return run ? attachRunView(runtime, run) : null;
|
|
526
627
|
};
|
|
527
628
|
return {
|
|
528
|
-
|
|
529
|
-
getById: getAgent,
|
|
629
|
+
get: getAgent,
|
|
530
630
|
threads: {
|
|
531
631
|
create: async (input) => {
|
|
532
|
-
|
|
632
|
+
assertNoAgentSelector(input);
|
|
633
|
+
const agent = getAgent();
|
|
533
634
|
if (!agent) {
|
|
534
|
-
throw new AgentRequestError("agent_not_found",
|
|
635
|
+
throw new AgentRequestError("agent_not_found", "[Sixb] The project Agent is unavailable.");
|
|
535
636
|
}
|
|
536
637
|
const storage = runtime.storage.agents;
|
|
537
638
|
if (!storage) {
|
|
@@ -540,35 +641,35 @@ function createAgentsRuntime(runtime, execution, source, security) {
|
|
|
540
641
|
return storage.threads.create({
|
|
541
642
|
id: input.id ?? createAgentThreadId(),
|
|
542
643
|
projectId: runtime.projectId,
|
|
543
|
-
agentId: agent.id,
|
|
544
644
|
ownerPrincipal: principal,
|
|
545
645
|
...input.title === undefined ? {} : { title: input.title }
|
|
546
646
|
});
|
|
547
647
|
},
|
|
548
|
-
getById:
|
|
549
|
-
list: (input = {}) => {
|
|
648
|
+
getById: getVisibleThreadRecord,
|
|
649
|
+
list: async (input = {}) => {
|
|
650
|
+
assertNoAgentSelector(input);
|
|
550
651
|
const storage = runtime.storage.agents;
|
|
551
|
-
if (!storage)
|
|
552
|
-
return
|
|
652
|
+
if (!storage || !allowed())
|
|
653
|
+
return { threads: [], hasMore: false, total: 0 };
|
|
553
654
|
return storage.threads.list({
|
|
554
|
-
projectId: runtime.projectId,
|
|
555
655
|
...input,
|
|
556
|
-
|
|
656
|
+
projectId: runtime.projectId,
|
|
557
657
|
ownerPrincipal: runtime.authorization ? principal : undefined
|
|
558
658
|
});
|
|
559
659
|
}
|
|
560
660
|
},
|
|
561
661
|
runs: {
|
|
562
662
|
request: async (input) => {
|
|
563
|
-
|
|
663
|
+
assertNoAgentSelector(input);
|
|
664
|
+
const agent = getAgent();
|
|
564
665
|
if (!agent) {
|
|
565
|
-
throw new AgentRequestError("agent_not_found",
|
|
666
|
+
throw new AgentRequestError("agent_not_found", "[Sixb] The project Agent is unavailable.");
|
|
566
667
|
}
|
|
567
|
-
assertAuthorized(runtime, { kind: "agent.run"
|
|
568
|
-
if (input.threadId && !await
|
|
668
|
+
assertAuthorized(runtime, { kind: "agent.run" });
|
|
669
|
+
if (input.threadId && !await getVisibleThreadRecord(input.threadId)) {
|
|
569
670
|
throw new AgentRequestError("thread_not_found", `[Sixb] Agent thread '${input.threadId}' not found.`);
|
|
570
671
|
}
|
|
571
|
-
const result = await requestAgentRun(runtime, execution,
|
|
672
|
+
const result = await requestAgentRun(runtime, execution, models?.language, {
|
|
572
673
|
...input,
|
|
573
674
|
principal
|
|
574
675
|
});
|
|
@@ -579,26 +680,27 @@ function createAgentsRuntime(runtime, execution, source, security) {
|
|
|
579
680
|
if (!failedRun) {
|
|
580
681
|
throw new AgentRequestError("run_not_found", `[Sixb] Agent run '${runId}' was not found.`);
|
|
581
682
|
}
|
|
582
|
-
const agent = getAgent(
|
|
683
|
+
const agent = getAgent();
|
|
583
684
|
if (!agent) {
|
|
584
|
-
throw new AgentRequestError("agent_not_found",
|
|
685
|
+
throw new AgentRequestError("agent_not_found", "[Sixb] The project Agent is unavailable.");
|
|
585
686
|
}
|
|
586
|
-
const result = await retryAgentRun(runtime, execution,
|
|
687
|
+
const result = await retryAgentRun(runtime, execution, models?.language, failedRun);
|
|
587
688
|
return { ...result, run: await attachRunView(runtime, result.run) };
|
|
588
689
|
},
|
|
589
690
|
getById: getRun,
|
|
590
691
|
listForThread: async (threadId, input = {}) => {
|
|
692
|
+
assertNoAgentSelector(input);
|
|
591
693
|
const storage = runtime.storage.agents;
|
|
592
|
-
if (!storage || !await
|
|
694
|
+
if (!storage || !await getVisibleThreadRecord(threadId))
|
|
593
695
|
return null;
|
|
594
696
|
const result = await storage.runs.list({
|
|
595
|
-
projectId: runtime.projectId,
|
|
596
697
|
...input,
|
|
698
|
+
projectId: runtime.projectId,
|
|
597
699
|
threadId
|
|
598
700
|
});
|
|
599
701
|
return {
|
|
600
702
|
...result,
|
|
601
|
-
runs: await attachRunViews(runtime, result.runs)
|
|
703
|
+
runs: await attachRunViews(runtime, result.runs.filter((run) => run.kind === "conversation"))
|
|
602
704
|
};
|
|
603
705
|
}
|
|
604
706
|
}
|
|
@@ -644,6 +746,110 @@ async function attachRunViews(runtime, runs) {
|
|
|
644
746
|
});
|
|
645
747
|
}
|
|
646
748
|
|
|
749
|
+
// src/ai-usage/execution.ts
|
|
750
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
751
|
+
function createAiUsageRuntime(runtime, security) {
|
|
752
|
+
const assertObservable = () => assertAuthorized(runtime, { kind: "aiUsage.observe" });
|
|
753
|
+
const assertManageable = () => assertAuthorized(runtime, { kind: "aiUsage.manage" });
|
|
754
|
+
const assertPolicyReadable = () => {
|
|
755
|
+
const resolved = assertRuntimeAuthorizationBound(runtime);
|
|
756
|
+
if (resolved.type === "principal" && !isAllowed(resolved.context, { kind: "aiUsage.observe" }) && !isAllowed(resolved.context, { kind: "aiUsage.manage" })) {
|
|
757
|
+
assertObservable();
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
const requireCosts = () => {
|
|
761
|
+
if (!runtime.storage.aiCosts) {
|
|
762
|
+
throw new Error("[Sixb] AI cost storage is not configured.");
|
|
763
|
+
}
|
|
764
|
+
return runtime.storage.aiCosts;
|
|
765
|
+
};
|
|
766
|
+
const requireLimits = () => {
|
|
767
|
+
if (!runtime.storage.aiLimits) {
|
|
768
|
+
throw new Error("[Sixb] AI limit storage is not configured.");
|
|
769
|
+
}
|
|
770
|
+
return runtime.storage.aiLimits;
|
|
771
|
+
};
|
|
772
|
+
return {
|
|
773
|
+
accountingConfigured: runtime.storage.aiCosts !== undefined,
|
|
774
|
+
limitsConfigured: runtime.storage.aiLimits !== undefined,
|
|
775
|
+
assertObservable,
|
|
776
|
+
assertManageable,
|
|
777
|
+
canManageLimits: () => {
|
|
778
|
+
const resolved = assertRuntimeAuthorizationBound(runtime);
|
|
779
|
+
return resolved.type !== "principal" || isAllowed(resolved.context, { kind: "aiUsage.manage" });
|
|
780
|
+
},
|
|
781
|
+
queryOverview: (input) => {
|
|
782
|
+
assertObservable();
|
|
783
|
+
return requireCosts().queryProjectOverview({ ...input, projectId: runtime.projectId });
|
|
784
|
+
},
|
|
785
|
+
listModelCalls: (input) => {
|
|
786
|
+
assertObservable();
|
|
787
|
+
return requireCosts().listModelCalls({ ...input, projectId: runtime.projectId });
|
|
788
|
+
},
|
|
789
|
+
listModelCallGroups: (input) => {
|
|
790
|
+
assertObservable();
|
|
791
|
+
return requireCosts().listModelCallGroups({ ...input, projectId: runtime.projectId });
|
|
792
|
+
},
|
|
793
|
+
listLimitPolicies: (input = {}) => {
|
|
794
|
+
assertPolicyReadable();
|
|
795
|
+
return requireLimits().listPolicies({ ...input, projectId: runtime.projectId });
|
|
796
|
+
},
|
|
797
|
+
listLimitStatuses: (input = {}) => {
|
|
798
|
+
assertObservable();
|
|
799
|
+
return requireLimits().listPolicyStatuses({
|
|
800
|
+
...input.includeDisabled === undefined ? {} : { includeDisabled: input.includeDisabled },
|
|
801
|
+
projectId: runtime.projectId,
|
|
802
|
+
existingGroupIds: security.listGroups().map((group) => group.id)
|
|
803
|
+
});
|
|
804
|
+
},
|
|
805
|
+
listLimitSubjectOptions: async () => {
|
|
806
|
+
assertManageable();
|
|
807
|
+
const groups = security.listGroups().map((group) => ({
|
|
808
|
+
id: group.id,
|
|
809
|
+
...group.label === undefined ? {} : { label: group.label },
|
|
810
|
+
...group.description === undefined ? {} : { description: group.description }
|
|
811
|
+
}));
|
|
812
|
+
const auth = runtime.storage.auth;
|
|
813
|
+
if (!auth)
|
|
814
|
+
return { groups, users: [], serviceAccounts: [] };
|
|
815
|
+
const [users, serviceAccounts] = await Promise.all([
|
|
816
|
+
auth.users.list({ projectId: runtime.projectId, order: "asc" }),
|
|
817
|
+
auth.serviceAccounts.list({ projectId: runtime.projectId, order: "asc" })
|
|
818
|
+
]);
|
|
819
|
+
return {
|
|
820
|
+
groups,
|
|
821
|
+
users: users.users.map((user) => ({
|
|
822
|
+
id: user.id,
|
|
823
|
+
email: user.email,
|
|
824
|
+
...user.displayName === undefined ? {} : { displayName: user.displayName },
|
|
825
|
+
status: user.status
|
|
826
|
+
})),
|
|
827
|
+
serviceAccounts: serviceAccounts.serviceAccounts.map((serviceAccount) => ({
|
|
828
|
+
id: serviceAccount.id,
|
|
829
|
+
name: serviceAccount.name,
|
|
830
|
+
...serviceAccount.description === undefined ? {} : { description: serviceAccount.description },
|
|
831
|
+
status: serviceAccount.status
|
|
832
|
+
}))
|
|
833
|
+
};
|
|
834
|
+
},
|
|
835
|
+
createLimitPolicy: (input) => {
|
|
836
|
+
assertManageable();
|
|
837
|
+
return requireLimits().createPolicy({
|
|
838
|
+
...input,
|
|
839
|
+
id: input.id ?? `ailim_${randomUUID3()}`,
|
|
840
|
+
projectId: runtime.projectId
|
|
841
|
+
});
|
|
842
|
+
},
|
|
843
|
+
updateLimitPolicy: (input) => {
|
|
844
|
+
assertManageable();
|
|
845
|
+
return requireLimits().updatePolicy({ ...input, projectId: runtime.projectId });
|
|
846
|
+
},
|
|
847
|
+
deleteLimitPolicy: (id) => {
|
|
848
|
+
assertManageable();
|
|
849
|
+
return requireLimits().deletePolicy({ id, projectId: runtime.projectId });
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
}
|
|
647
853
|
// src/blob-storage/execution.ts
|
|
648
854
|
function createBlobsRuntime(runtime, execution, blobStorage) {
|
|
649
855
|
const assertAccess = () => assertProviderAccess(runtime, execution, "blobs.access");
|
|
@@ -1086,1112 +1292,32 @@ class WorkflowValidationError extends Error {
|
|
|
1086
1292
|
}
|
|
1087
1293
|
|
|
1088
1294
|
// src/workflows/run-dispatch.ts
|
|
1089
|
-
import { randomUUID as
|
|
1295
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
1090
1296
|
import { isDeepStrictEqual } from "util";
|
|
1091
1297
|
|
|
1092
|
-
// src/agents/context-model.ts
|
|
1093
|
-
function serializeAgentContextForModel(parts) {
|
|
1094
|
-
if (parts.length === 0)
|
|
1095
|
-
return;
|
|
1096
|
-
const lines = ["<sixb_user_context>"];
|
|
1097
|
-
for (const part of parts) {
|
|
1098
|
-
if (part.context.kind === "object") {
|
|
1099
|
-
lines.push(" <object_context>", ` <object_type_id>${escapeXml(part.context.ref.objectTypeId)}</object_type_id>`, ` <primary_id>${escapeXml(part.context.ref.primaryId)}</primary_id>`, " </object_context>");
|
|
1100
|
-
continue;
|
|
1101
|
-
}
|
|
1102
|
-
lines.push(" <app_state_context>", ` <id>${escapeXml(part.context.id)}</id>`, ` <description>${escapeXml(part.context.description)}</description>`, ` <value format="json">${escapeXml(stableJsonStringify(part.context.value))}</value>`, " </app_state_context>");
|
|
1103
|
-
}
|
|
1104
|
-
lines.push("</sixb_user_context>");
|
|
1105
|
-
return lines.join(`
|
|
1106
|
-
`);
|
|
1107
|
-
}
|
|
1108
|
-
function escapeXml(value) {
|
|
1109
|
-
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
// src/agents/tool-result.ts
|
|
1113
|
-
function isAgentToolResult(value) {
|
|
1114
|
-
return isPlainRecord(value) && value.kind === "agentToolResult" && getInvalidAgentToolResultReason(value) === undefined;
|
|
1115
|
-
}
|
|
1116
|
-
function getInvalidAgentToolResultReason(value) {
|
|
1117
|
-
if (!isPlainRecord(value) || value.kind !== "agentToolResult") {
|
|
1118
|
-
return;
|
|
1119
|
-
}
|
|
1120
|
-
if (!Array.isArray(value.content)) {
|
|
1121
|
-
return "result.content must be an array";
|
|
1122
|
-
}
|
|
1123
|
-
const unsupportedKey = Object.keys(value).find((key) => key !== "kind" && key !== "content");
|
|
1124
|
-
if (unsupportedKey) {
|
|
1125
|
-
return `result.${unsupportedKey} is not supported`;
|
|
1126
|
-
}
|
|
1127
|
-
if (value.content.length === 0) {
|
|
1128
|
-
return "result.content must contain at least one content part";
|
|
1129
|
-
}
|
|
1130
|
-
for (let index = 0;index < value.content.length; index += 1) {
|
|
1131
|
-
const part = value.content[index];
|
|
1132
|
-
const path = `result.content[${index}]`;
|
|
1133
|
-
if (!isPlainRecord(part)) {
|
|
1134
|
-
return `${path} must be a text or file content part`;
|
|
1135
|
-
}
|
|
1136
|
-
if (part.type === "text") {
|
|
1137
|
-
if (typeof part.text !== "string") {
|
|
1138
|
-
return `${path}.text must be a string`;
|
|
1139
|
-
}
|
|
1140
|
-
const unsupportedKey2 = Object.keys(part).find((key) => key !== "type" && key !== "text");
|
|
1141
|
-
if (unsupportedKey2) {
|
|
1142
|
-
return `${path}.${unsupportedKey2} is not supported`;
|
|
1143
|
-
}
|
|
1144
|
-
continue;
|
|
1145
|
-
}
|
|
1146
|
-
if (part.type === "file") {
|
|
1147
|
-
if (!isFileRef(part.fileRef)) {
|
|
1148
|
-
return `${path}.fileRef must be a valid FileRef`;
|
|
1149
|
-
}
|
|
1150
|
-
const unsupportedKey2 = Object.keys(part).find((key) => key !== "type" && key !== "fileRef");
|
|
1151
|
-
if (unsupportedKey2) {
|
|
1152
|
-
return `${path}.${unsupportedKey2} is not supported`;
|
|
1153
|
-
}
|
|
1154
|
-
continue;
|
|
1155
|
-
}
|
|
1156
|
-
return `${path}.type must be 'text' or 'file'`;
|
|
1157
|
-
}
|
|
1158
|
-
return;
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
// src/agents/adapters.ts
|
|
1162
|
-
var TOOL_TYPE_PREFIX = "tool-";
|
|
1163
|
-
function assertAdapter(condition, message) {
|
|
1164
|
-
if (!condition) {
|
|
1165
|
-
throw new AgentMessageAdapterError(`[Sixb] ${message}`);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
function requireJson(value, label) {
|
|
1169
|
-
const reason = getInvalidJsonValueReason(value, label);
|
|
1170
|
-
assertAdapter(reason === undefined, `agent message ${label} must be a JSON value; ${reason}`);
|
|
1171
|
-
return value;
|
|
1172
|
-
}
|
|
1173
|
-
function optionalJson(value, label) {
|
|
1174
|
-
if (value === undefined)
|
|
1175
|
-
return;
|
|
1176
|
-
return requireJson(omitUndefinedObjectProperties(value), label);
|
|
1177
|
-
}
|
|
1178
|
-
function omitUndefinedObjectProperties(value) {
|
|
1179
|
-
return omitUndefinedObjectPropertiesInternal(value, new Set);
|
|
1180
|
-
}
|
|
1181
|
-
function omitUndefinedObjectPropertiesInternal(value, seen) {
|
|
1182
|
-
if (typeof value !== "object" || value === null)
|
|
1183
|
-
return value;
|
|
1184
|
-
if (seen.has(value))
|
|
1185
|
-
return value;
|
|
1186
|
-
seen.add(value);
|
|
1187
|
-
try {
|
|
1188
|
-
if (Array.isArray(value)) {
|
|
1189
|
-
return value.map((entry) => omitUndefinedObjectPropertiesInternal(entry, seen));
|
|
1190
|
-
}
|
|
1191
|
-
if (!isPlainRecord(value))
|
|
1192
|
-
return value;
|
|
1193
|
-
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined).map(([key, entry]) => [key, omitUndefinedObjectPropertiesInternal(entry, seen)]));
|
|
1194
|
-
} finally {
|
|
1195
|
-
seen.delete(value);
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
function isToolType(type) {
|
|
1199
|
-
return type === "dynamic-tool" || type.startsWith(TOOL_TYPE_PREFIX);
|
|
1200
|
-
}
|
|
1201
|
-
function toolNameFromInbound(part) {
|
|
1202
|
-
if (part.type === "dynamic-tool") {
|
|
1203
|
-
assertAdapter(typeof part.toolName === "string" && part.toolName.length > 0, "dynamic-tool part is missing a tool name");
|
|
1204
|
-
return part.toolName;
|
|
1205
|
-
}
|
|
1206
|
-
const name = part.type.slice(TOOL_TYPE_PREFIX.length);
|
|
1207
|
-
assertAdapter(name.length > 0, `tool part type '${part.type}' is missing a tool name`);
|
|
1208
|
-
return name;
|
|
1209
|
-
}
|
|
1210
|
-
function fromAiSdk(message) {
|
|
1211
|
-
const { role } = message;
|
|
1212
|
-
assertAdapter(role === "system" || role === "user" || role === "assistant", `unsupported message role '${role}'`);
|
|
1213
|
-
const parts = message.parts.map((part) => fromAiSdkPart(part));
|
|
1214
|
-
assertAdapter(role === "user" || !parts.some((part) => part.type === "context"), "context parts are only valid on user messages");
|
|
1215
|
-
const metadata = optionalJson(message.metadata, "metadata");
|
|
1216
|
-
return {
|
|
1217
|
-
role,
|
|
1218
|
-
parts,
|
|
1219
|
-
...metadata === undefined ? {} : { metadata }
|
|
1220
|
-
};
|
|
1221
|
-
}
|
|
1222
|
-
function fromAiSdkPart(part) {
|
|
1223
|
-
switch (part.type) {
|
|
1224
|
-
case "text":
|
|
1225
|
-
case "reasoning": {
|
|
1226
|
-
assertAdapter(typeof part.text === "string", `${part.type} part is missing text`);
|
|
1227
|
-
assertAdapter(part.state !== "streaming", `cannot persist a streaming ${part.type} part; messages are written only once finalized`);
|
|
1228
|
-
const providerMetadata = optionalJson(part.providerMetadata, `${part.type}.providerMetadata`);
|
|
1229
|
-
return {
|
|
1230
|
-
type: part.type,
|
|
1231
|
-
text: part.text,
|
|
1232
|
-
...providerMetadata === undefined ? {} : { providerMetadata }
|
|
1233
|
-
};
|
|
1234
|
-
}
|
|
1235
|
-
case "step-start":
|
|
1236
|
-
return { type: "step-start" };
|
|
1237
|
-
case "file": {
|
|
1238
|
-
assertAdapter(isFileRef(part.fileRef), "file part is missing a valid fileRef");
|
|
1239
|
-
const providerMetadata = optionalJson(part.providerMetadata, "file.providerMetadata");
|
|
1240
|
-
return {
|
|
1241
|
-
type: "file",
|
|
1242
|
-
fileRef: part.fileRef,
|
|
1243
|
-
...providerMetadata === undefined ? {} : { providerMetadata }
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
case "context":
|
|
1247
|
-
return fromUiContextPart(part);
|
|
1248
|
-
default: {
|
|
1249
|
-
assertAdapter(isToolType(part.type), `unsupported message part type '${part.type}'; extend the Sixb message part union to support it`);
|
|
1250
|
-
return fromAiSdkToolPart(part);
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
function fromUiContextPart(part) {
|
|
1255
|
-
try {
|
|
1256
|
-
const [entry] = normalizeAgentContextEntries([
|
|
1257
|
-
{ context: part.context, origin: part.origin }
|
|
1258
|
-
]);
|
|
1259
|
-
return { type: "context", ...entry };
|
|
1260
|
-
} catch (error) {
|
|
1261
|
-
throw new AgentMessageAdapterError(error instanceof Error ? error.message : "[Sixb] Invalid agent context part.");
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
function fromAiSdkToolPart(part) {
|
|
1265
|
-
const dynamic = part.type === "dynamic-tool";
|
|
1266
|
-
const toolName = toolNameFromInbound(part);
|
|
1267
|
-
assertAdapter(typeof part.toolCallId === "string" && part.toolCallId.length > 0, `tool part '${part.type}' is missing a toolCallId`);
|
|
1268
|
-
assertAdapter(part.state === "output-available" || part.state === "output-error", `cannot persist tool part '${part.toolCallId}' in transient state '${part.state}'; only terminal states are stored`);
|
|
1269
|
-
const input = part.input === undefined ? null : requireJson(part.input, "tool input");
|
|
1270
|
-
const providerMetadata = optionalJson(part.callProviderMetadata, "tool callProviderMetadata");
|
|
1271
|
-
const base = {
|
|
1272
|
-
type: "tool-call",
|
|
1273
|
-
toolCallId: part.toolCallId,
|
|
1274
|
-
toolName,
|
|
1275
|
-
input,
|
|
1276
|
-
...dynamic ? { dynamic: true } : {},
|
|
1277
|
-
...part.providerExecuted === undefined ? {} : { providerExecuted: part.providerExecuted },
|
|
1278
|
-
...providerMetadata === undefined ? {} : { providerMetadata }
|
|
1279
|
-
};
|
|
1280
|
-
if (part.state === "output-available") {
|
|
1281
|
-
return { ...base, state: "output-available", output: requireJson(part.output, "tool output") };
|
|
1282
|
-
}
|
|
1283
|
-
assertAdapter(typeof part.errorText === "string", `tool part '${part.toolCallId}' is missing errorText`);
|
|
1284
|
-
return { ...base, state: "output-error", errorText: part.errorText };
|
|
1285
|
-
}
|
|
1286
|
-
function toUiMessage(message) {
|
|
1287
|
-
return {
|
|
1288
|
-
role: message.role,
|
|
1289
|
-
parts: message.parts.map((part) => toUiPart(part)),
|
|
1290
|
-
...message.metadata === undefined ? {} : { metadata: message.metadata }
|
|
1291
|
-
};
|
|
1292
|
-
}
|
|
1293
|
-
function toUiPart(part) {
|
|
1294
|
-
switch (part.type) {
|
|
1295
|
-
case "text":
|
|
1296
|
-
case "reasoning":
|
|
1297
|
-
return {
|
|
1298
|
-
type: part.type,
|
|
1299
|
-
text: part.text,
|
|
1300
|
-
...part.providerMetadata === undefined ? {} : { providerMetadata: part.providerMetadata }
|
|
1301
|
-
};
|
|
1302
|
-
case "step-start":
|
|
1303
|
-
return { type: "step-start" };
|
|
1304
|
-
case "file":
|
|
1305
|
-
return {
|
|
1306
|
-
type: "file",
|
|
1307
|
-
fileRef: part.fileRef,
|
|
1308
|
-
...part.providerMetadata === undefined ? {} : { providerMetadata: part.providerMetadata }
|
|
1309
|
-
};
|
|
1310
|
-
case "context":
|
|
1311
|
-
return { type: "context", context: part.context, origin: part.origin };
|
|
1312
|
-
case "tool-call":
|
|
1313
|
-
return toUiToolPart(part);
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
function toUiToolPart(part) {
|
|
1317
|
-
const body = {
|
|
1318
|
-
toolCallId: part.toolCallId,
|
|
1319
|
-
...part.providerExecuted === undefined ? {} : { providerExecuted: part.providerExecuted },
|
|
1320
|
-
...part.providerMetadata === undefined ? {} : { callProviderMetadata: part.providerMetadata }
|
|
1321
|
-
};
|
|
1322
|
-
const state = part.state === "output-available" ? { state: "output-available", input: part.input, output: part.output } : { state: "output-error", input: part.input, errorText: part.errorText };
|
|
1323
|
-
if (part.dynamic) {
|
|
1324
|
-
return { type: "dynamic-tool", toolName: part.toolName, ...body, ...state };
|
|
1325
|
-
}
|
|
1326
|
-
return { type: `tool-${part.toolName}`, ...body, ...state };
|
|
1327
|
-
}
|
|
1328
|
-
function toModelMessages(messages, options = {}) {
|
|
1329
|
-
const result = [];
|
|
1330
|
-
for (const message of messages) {
|
|
1331
|
-
switch (message.role) {
|
|
1332
|
-
case "system":
|
|
1333
|
-
result.push(systemModelMessage(message));
|
|
1334
|
-
break;
|
|
1335
|
-
case "user":
|
|
1336
|
-
result.push(userModelMessage(message, options));
|
|
1337
|
-
break;
|
|
1338
|
-
case "assistant":
|
|
1339
|
-
appendAssistantModelMessages(result, message, options);
|
|
1340
|
-
break;
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
return result;
|
|
1344
|
-
}
|
|
1345
|
-
function systemModelMessage(message) {
|
|
1346
|
-
const textParts = message.parts.filter(isTextPart);
|
|
1347
|
-
const providerOptions = mergeProviderMetadata(textParts);
|
|
1348
|
-
return {
|
|
1349
|
-
role: "system",
|
|
1350
|
-
content: textParts.map((part) => part.text).join(""),
|
|
1351
|
-
...providerOptions === undefined ? {} : { providerOptions }
|
|
1352
|
-
};
|
|
1353
|
-
}
|
|
1354
|
-
function mergeProviderMetadata(parts) {
|
|
1355
|
-
let merged;
|
|
1356
|
-
for (const part of parts) {
|
|
1357
|
-
const meta = part.providerMetadata;
|
|
1358
|
-
if (meta !== undefined && typeof meta === "object" && meta !== null && !Array.isArray(meta)) {
|
|
1359
|
-
merged = { ...merged ?? {}, ...meta };
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
return merged;
|
|
1363
|
-
}
|
|
1364
|
-
function userModelMessage(message, options) {
|
|
1365
|
-
const content = [];
|
|
1366
|
-
const serializedContext = serializeAgentContextForModel(message.parts.filter((part) => part.type === "context"));
|
|
1367
|
-
if (serializedContext) {
|
|
1368
|
-
content.push({ type: "text", text: `${serializedContext}
|
|
1369
|
-
|
|
1370
|
-
` });
|
|
1371
|
-
}
|
|
1372
|
-
message.parts.forEach((part, partIndex) => {
|
|
1373
|
-
if (part.type === "text") {
|
|
1374
|
-
content.push({
|
|
1375
|
-
type: "text",
|
|
1376
|
-
text: part.text,
|
|
1377
|
-
...part.providerMetadata === undefined ? {} : { providerOptions: part.providerMetadata }
|
|
1378
|
-
});
|
|
1379
|
-
return;
|
|
1380
|
-
}
|
|
1381
|
-
if (part.type === "file") {
|
|
1382
|
-
const fileContext = options.fileText?.({ message, part, partIndex });
|
|
1383
|
-
if (fileContext) {
|
|
1384
|
-
content.push({ type: "text", text: fileContext });
|
|
1385
|
-
}
|
|
1386
|
-
const resolved = options.fileData?.({ message, part, partIndex });
|
|
1387
|
-
if (resolved) {
|
|
1388
|
-
const projection = resolved instanceof URL ? { data: resolved } : resolved;
|
|
1389
|
-
content.push({
|
|
1390
|
-
type: "file",
|
|
1391
|
-
data: projection.data,
|
|
1392
|
-
mediaType: projection.mediaType ?? part.fileRef.mediaType ?? "application/octet-stream",
|
|
1393
|
-
...projection.filename !== undefined ? { filename: projection.filename } : part.fileRef.fileName === undefined ? {} : { filename: part.fileRef.fileName },
|
|
1394
|
-
...part.providerMetadata === undefined ? {} : { providerOptions: part.providerMetadata }
|
|
1395
|
-
});
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
return { role: "user", content };
|
|
1400
|
-
}
|
|
1401
|
-
function appendAssistantModelMessages(result, message, options) {
|
|
1402
|
-
let block = [];
|
|
1403
|
-
const flush = () => {
|
|
1404
|
-
if (block.length === 0) {
|
|
1405
|
-
return;
|
|
1406
|
-
}
|
|
1407
|
-
const current = block;
|
|
1408
|
-
block = [];
|
|
1409
|
-
const content = [];
|
|
1410
|
-
for (const { part, partIndex } of current) {
|
|
1411
|
-
if (part.type === "text") {
|
|
1412
|
-
content.push({
|
|
1413
|
-
type: "text",
|
|
1414
|
-
text: part.text,
|
|
1415
|
-
...part.providerMetadata === undefined ? {} : { providerOptions: part.providerMetadata }
|
|
1416
|
-
});
|
|
1417
|
-
} else if (part.type === "reasoning") {
|
|
1418
|
-
content.push({
|
|
1419
|
-
type: "reasoning",
|
|
1420
|
-
text: part.text,
|
|
1421
|
-
...part.providerMetadata === undefined ? {} : { providerOptions: part.providerMetadata }
|
|
1422
|
-
});
|
|
1423
|
-
} else if (part.type === "file") {
|
|
1424
|
-
const fileContext = options.fileText?.({ message, part, partIndex });
|
|
1425
|
-
if (fileContext) {
|
|
1426
|
-
content.push({ type: "text", text: fileContext });
|
|
1427
|
-
}
|
|
1428
|
-
} else if (part.type === "tool-call") {
|
|
1429
|
-
content.push(toolCallModelPart(part));
|
|
1430
|
-
if (part.providerExecuted === true) {
|
|
1431
|
-
content.push(toolResultModelPart(message, part, partIndex, "json", options));
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
result.push({ role: "assistant", content });
|
|
1436
|
-
const toolResults = current.flatMap(({ part, partIndex }) => part.type === "tool-call" && part.providerExecuted !== true ? [toolResultModelPart(message, part, partIndex, "text", options)] : []);
|
|
1437
|
-
if (toolResults.length > 0) {
|
|
1438
|
-
result.push({ role: "tool", content: toolResults });
|
|
1439
|
-
}
|
|
1440
|
-
};
|
|
1441
|
-
message.parts.forEach((part, partIndex) => {
|
|
1442
|
-
if (part.type === "step-start") {
|
|
1443
|
-
flush();
|
|
1444
|
-
} else {
|
|
1445
|
-
block.push({ part, partIndex });
|
|
1446
|
-
}
|
|
1447
|
-
});
|
|
1448
|
-
flush();
|
|
1449
|
-
}
|
|
1450
|
-
function toolCallModelPart(part) {
|
|
1451
|
-
return {
|
|
1452
|
-
type: "tool-call",
|
|
1453
|
-
toolCallId: part.toolCallId,
|
|
1454
|
-
toolName: part.toolName,
|
|
1455
|
-
input: part.input,
|
|
1456
|
-
...part.providerExecuted === undefined ? {} : { providerExecuted: part.providerExecuted },
|
|
1457
|
-
...part.providerMetadata === undefined ? {} : { providerOptions: part.providerMetadata }
|
|
1458
|
-
};
|
|
1459
|
-
}
|
|
1460
|
-
function toolResultModelPart(message, part, partIndex, errorMode, options) {
|
|
1461
|
-
return {
|
|
1462
|
-
type: "tool-result",
|
|
1463
|
-
toolCallId: part.toolCallId,
|
|
1464
|
-
toolName: part.toolName,
|
|
1465
|
-
output: toolResultOutput(message, part, partIndex, errorMode, options),
|
|
1466
|
-
...part.providerMetadata === undefined ? {} : { providerOptions: part.providerMetadata }
|
|
1467
|
-
};
|
|
1468
|
-
}
|
|
1469
|
-
function toolResultOutput(message, part, partIndex, errorMode, options) {
|
|
1470
|
-
if (part.state === "output-error") {
|
|
1471
|
-
return errorMode === "json" ? { type: "error-json", value: part.errorText } : { type: "error-text", value: part.errorText };
|
|
1472
|
-
}
|
|
1473
|
-
if (isAgentToolResult(part.output)) {
|
|
1474
|
-
const value = [];
|
|
1475
|
-
part.output.content.forEach((contentPart, contentIndex) => {
|
|
1476
|
-
if (contentPart.type === "text") {
|
|
1477
|
-
value.push(contentPart.text);
|
|
1478
|
-
return;
|
|
1479
|
-
}
|
|
1480
|
-
const resolverInput = { message, part, partIndex, contentPart, contentIndex };
|
|
1481
|
-
const fileContext = options.toolResultFileText?.(resolverInput);
|
|
1482
|
-
if (fileContext) {
|
|
1483
|
-
value.push(fileContext);
|
|
1484
|
-
} else {
|
|
1485
|
-
value.push(toolResultFileFallbackText(contentPart));
|
|
1486
|
-
}
|
|
1487
|
-
});
|
|
1488
|
-
return { type: "text", value: value.join(`
|
|
1489
|
-
`) };
|
|
1490
|
-
}
|
|
1491
|
-
return typeof part.output === "string" ? { type: "text", value: part.output } : { type: "json", value: part.output };
|
|
1492
|
-
}
|
|
1493
|
-
function toolResultFileFallbackText(part) {
|
|
1494
|
-
const attributes = [
|
|
1495
|
-
part.fileRef.fileName ? `name=${JSON.stringify(part.fileRef.fileName)}` : undefined,
|
|
1496
|
-
part.fileRef.mediaType ? `mediaType=${JSON.stringify(part.fileRef.mediaType)}` : undefined,
|
|
1497
|
-
`sizeBytes=${part.fileRef.sizeBytes}`
|
|
1498
|
-
].filter((value) => value !== undefined);
|
|
1499
|
-
return `[Tool-created file: ${attributes.join(" ")}. Contents are not available inline.]`;
|
|
1500
|
-
}
|
|
1501
|
-
function isTextPart(part) {
|
|
1502
|
-
return part.type === "text";
|
|
1503
|
-
}
|
|
1504
|
-
// src/agents/api-gateway.ts
|
|
1505
|
-
import { createHmac, timingSafeEqual } from "crypto";
|
|
1506
|
-
var AGENT_API_GATEWAY_PREFIX = "/__sixb/agent-api";
|
|
1507
|
-
var AGENT_API_GATEWAY_CAPABILITY_PREFIX = "sixb_agw_v1_";
|
|
1508
|
-
var AGENT_API_ROUTES = SIXB_API_ROUTES.filter((route) => route.agentApi).map((route) => ({ method: route.method, path: route.path }));
|
|
1509
|
-
function createAgentApiGatewayCapability(input) {
|
|
1510
|
-
return `${AGENT_API_GATEWAY_CAPABILITY_PREFIX}${capabilityDigest(input)}`;
|
|
1511
|
-
}
|
|
1512
|
-
function isValidAgentApiGatewayCapability(input) {
|
|
1513
|
-
const expected = createAgentApiGatewayCapability(input);
|
|
1514
|
-
const actual = input.capability;
|
|
1515
|
-
const expectedBuffer = Buffer.from(expected);
|
|
1516
|
-
const actualBuffer = Buffer.from(actual);
|
|
1517
|
-
return expectedBuffer.byteLength === actualBuffer.byteLength && timingSafeEqual(expectedBuffer, actualBuffer);
|
|
1518
|
-
}
|
|
1519
|
-
function isAllowedAgentApiRequest(method, pathname) {
|
|
1520
|
-
const normalizedMethod = method.toUpperCase();
|
|
1521
|
-
const normalizedPath = normalizeRoutePath(pathname);
|
|
1522
|
-
return AGENT_API_ROUTES.some((route) => route.method === normalizedMethod && matchesPathPattern(normalizedPath, route.path));
|
|
1523
|
-
}
|
|
1524
|
-
function capabilityDigest(input) {
|
|
1525
|
-
return createHmac("sha256", input.executionToken).update(`agent-api-gateway:${input.projectId}:${input.runId}`).digest("base64url");
|
|
1526
|
-
}
|
|
1527
|
-
// src/agents/types.ts
|
|
1528
|
-
var AGENT_REASONING_LEVELS = [
|
|
1529
|
-
"provider-default",
|
|
1530
|
-
"none",
|
|
1531
|
-
"minimal",
|
|
1532
|
-
"low",
|
|
1533
|
-
"medium",
|
|
1534
|
-
"high",
|
|
1535
|
-
"xhigh"
|
|
1536
|
-
];
|
|
1537
|
-
|
|
1538
|
-
// src/agents/validation.ts
|
|
1539
|
-
var AGENT_TOOL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]{0,63}$/;
|
|
1540
|
-
var AGENT_TOOL_PRIMITIVE_SCHEMAS = new Set([
|
|
1541
|
-
"string",
|
|
1542
|
-
"integer",
|
|
1543
|
-
"double",
|
|
1544
|
-
"decimal",
|
|
1545
|
-
"boolean",
|
|
1546
|
-
"date",
|
|
1547
|
-
"timestamp",
|
|
1548
|
-
"uuid",
|
|
1549
|
-
"fileRef"
|
|
1550
|
-
]);
|
|
1551
|
-
var AGENT_RESERVED_TOOL_NAMES = ["bash", "read", "view_file"];
|
|
1552
|
-
function assertNonEmpty(value, field) {
|
|
1553
|
-
if (!value.trim()) {
|
|
1554
|
-
throw new AgentDefinitionError(`[Sixb] Agent ${field} must not be empty.`);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
function isAgentDefinition(value) {
|
|
1558
|
-
return isRecord(value) && value.kind === "agent" && typeof value.id === "string" && typeof value.name === "string" && typeof value.instructions === "string" && (value.reasoning === undefined || isAgentReasoningLevel(value.reasoning)) && (value.providerOptions === undefined || isProviderOptions(value.providerOptions)) && Array.isArray(value.groupIds) && isAgentToolDefinitionArray(value.tools);
|
|
1559
|
-
}
|
|
1560
|
-
function isAgentToolDefinition(value) {
|
|
1561
|
-
return isRecord(value) && value.kind === "agentTool" && typeof value.name === "string" && typeof value.description === "string" && isPlainRecord(value.input) && typeof value.handler === "function";
|
|
1562
|
-
}
|
|
1563
|
-
function assertValidAgentToolName(name) {
|
|
1564
|
-
if (typeof name !== "string" || !AGENT_TOOL_NAME_PATTERN.test(name)) {
|
|
1565
|
-
throw new AgentDefinitionError("[Sixb] Agent tool name must be 1-64 characters, start with a letter or underscore, and contain only letters, numbers, underscores, or hyphens.");
|
|
1566
|
-
}
|
|
1567
|
-
if (AGENT_RESERVED_TOOL_NAMES.includes(name)) {
|
|
1568
|
-
throw new AgentDefinitionError(`[Sixb] Agent tool name '${name}' is reserved by the framework.`);
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
function assertValidAgentToolDescription(name, description) {
|
|
1572
|
-
if (typeof description !== "string" || !description.trim()) {
|
|
1573
|
-
throw new AgentDefinitionError(`[Sixb] Agent tool '${name}' description must not be empty.`);
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
function assertValidAgentToolInput(name, input) {
|
|
1577
|
-
if (!isPlainRecord(input)) {
|
|
1578
|
-
throw new AgentDefinitionError(`[Sixb] Agent tool '${name}' input must be a schema object.`);
|
|
1579
|
-
}
|
|
1580
|
-
for (const [field, schema] of Object.entries(input)) {
|
|
1581
|
-
if (!field.trim()) {
|
|
1582
|
-
throw new AgentDefinitionError(`[Sixb] Agent tool '${name}' input field names must not be empty.`);
|
|
1583
|
-
}
|
|
1584
|
-
assertValidAgentToolSchema(name, schema, `input.${field}`, new Set);
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
function validateAndSnapshotAgentToolInput(toolName, input) {
|
|
1588
|
-
assertValidAgentToolInput(toolName, input);
|
|
1589
|
-
try {
|
|
1590
|
-
return deepFreeze(structuredClone(input));
|
|
1591
|
-
} catch {
|
|
1592
|
-
throw new AgentDefinitionError(`[Sixb] Agent tool '${toolName}' input must be safely snapshot-compatible.`);
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
function validateAndNormalizeAgentToolInput(toolName, shape, value, valueTypesById) {
|
|
1596
|
-
const label = `Agent tool '${toolName}' input`;
|
|
1597
|
-
if (!isPlainRecord(value)) {
|
|
1598
|
-
throw new OntologyValidationError(`[Sixb] ${label} must be a JSON object.`);
|
|
1599
|
-
}
|
|
1600
|
-
const reason = getInvalidJsonValueReason(value, label);
|
|
1601
|
-
if (reason) {
|
|
1602
|
-
throw new OntologyValidationError(`[Sixb] ${label} must be JSON-compatible; ${reason}.`);
|
|
1603
|
-
}
|
|
1604
|
-
const schema = {
|
|
1605
|
-
type: "object",
|
|
1606
|
-
properties: Object.fromEntries(Object.entries(shape).map(([field, fieldSchema]) => [
|
|
1607
|
-
field,
|
|
1608
|
-
{ schema: fieldSchema, required: true }
|
|
1609
|
-
]))
|
|
1610
|
-
};
|
|
1611
|
-
validateSchemaValue(schema, value, label, valueTypesById);
|
|
1612
|
-
return deepFreeze(normalizeSchemaValue(schema, value, label, valueTypesById));
|
|
1613
|
-
}
|
|
1614
|
-
function validateAgentToolsAtStartup(agents) {
|
|
1615
|
-
for (const agent of agents) {
|
|
1616
|
-
if (!isAgentDefinition(agent)) {
|
|
1617
|
-
throw new AgentDefinitionError("[Sixb] Agents must contain only valid agent definitions.");
|
|
1618
|
-
}
|
|
1619
|
-
assertValidAgentToolDefinitions(agent.id, agent.tools);
|
|
1620
|
-
for (const tool of agent.tools) {
|
|
1621
|
-
deepFreeze(tool.input);
|
|
1622
|
-
Object.freeze(tool);
|
|
1623
|
-
}
|
|
1624
|
-
Object.freeze(agent.tools);
|
|
1625
|
-
Object.freeze(agent);
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
function resolveAgentLoopConfig(loop) {
|
|
1629
|
-
if (loop === undefined)
|
|
1630
|
-
return;
|
|
1631
|
-
const maxSteps = loop?.stopWhen?.maxSteps;
|
|
1632
|
-
if (maxSteps !== undefined && (!Number.isSafeInteger(maxSteps) || maxSteps <= 0)) {
|
|
1633
|
-
throw new AgentDefinitionError("[Sixb] Agent loop.stopWhen.maxSteps must be a positive safe integer.");
|
|
1634
|
-
}
|
|
1635
|
-
if (loop.caching !== undefined && loop.caching !== "auto" && loop.caching !== "off") {
|
|
1636
|
-
throw new AgentDefinitionError("[Sixb] Agent loop.caching must be 'auto' or 'off'.");
|
|
1637
|
-
}
|
|
1638
|
-
const context = loop.context ? snapshotAgentContextConfig(loop.context) : undefined;
|
|
1639
|
-
return Object.freeze({
|
|
1640
|
-
...loop.stopWhen === undefined ? {} : { stopWhen: Object.freeze({ ...maxSteps === undefined ? {} : { maxSteps } }) },
|
|
1641
|
-
...context === undefined ? {} : { context },
|
|
1642
|
-
...loop.caching === undefined ? {} : { caching: loop.caching }
|
|
1643
|
-
});
|
|
1644
|
-
}
|
|
1645
|
-
function snapshotAgentContextConfig(context) {
|
|
1646
|
-
const snapshot = {};
|
|
1647
|
-
for (const field of ["windowTokens", "reserveTokens", "keepRecentTokens"]) {
|
|
1648
|
-
const value = context[field];
|
|
1649
|
-
if (value === undefined)
|
|
1650
|
-
continue;
|
|
1651
|
-
assertPositiveSafeInteger(value, field);
|
|
1652
|
-
snapshot[field] = value;
|
|
1653
|
-
}
|
|
1654
|
-
return Object.freeze(snapshot);
|
|
1655
|
-
}
|
|
1656
|
-
function assertPositiveSafeInteger(value, field) {
|
|
1657
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
|
|
1658
|
-
throw new AgentDefinitionError(`[Sixb] Agent loop.context.${field} must be a positive safe integer.`);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
function assertValidReasoningLevel(reasoning) {
|
|
1662
|
-
if (reasoning === undefined) {
|
|
1663
|
-
return;
|
|
1664
|
-
}
|
|
1665
|
-
if (!isAgentReasoningLevel(reasoning)) {
|
|
1666
|
-
throw new AgentDefinitionError(`[Sixb] Agent reasoning must be one of: ${AGENT_REASONING_LEVELS.join(", ")}.`);
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
function assertValidProviderOptions(providerOptions) {
|
|
1670
|
-
if (providerOptions === undefined) {
|
|
1671
|
-
return;
|
|
1672
|
-
}
|
|
1673
|
-
const reason = getInvalidJsonValueReason(providerOptions, "providerOptions");
|
|
1674
|
-
if (!isRecord(providerOptions) || reason) {
|
|
1675
|
-
throw new AgentDefinitionError(`[Sixb] Agent providerOptions must be a provider-keyed JSON object${reason ? `; ${reason}` : "."}`);
|
|
1676
|
-
}
|
|
1677
|
-
for (const [provider, options] of Object.entries(providerOptions)) {
|
|
1678
|
-
if (!provider.trim()) {
|
|
1679
|
-
throw new AgentDefinitionError("[Sixb] Agent providerOptions provider names must not be empty.");
|
|
1680
|
-
}
|
|
1681
|
-
const optionsReason = getInvalidJsonValueReason(options, `providerOptions.${provider}`);
|
|
1682
|
-
if (!isRecord(options) || optionsReason) {
|
|
1683
|
-
throw new AgentDefinitionError(`[Sixb] Agent providerOptions.${provider} must be a JSON object${optionsReason ? `; ${optionsReason}` : "."}`);
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
function groupIdsFromDefinitions(agentId, groups) {
|
|
1688
|
-
const groupIds = (groups ?? []).map((group) => {
|
|
1689
|
-
if (!isRecord(group) || group.kind !== "group") {
|
|
1690
|
-
throw new AgentDefinitionError(`[Sixb] Agent '${agentId}' groups must contain only group definitions.`);
|
|
1691
|
-
}
|
|
1692
|
-
assertNonEmpty(group.id, `Agent '${agentId}' group id`);
|
|
1693
|
-
return group.id;
|
|
1694
|
-
});
|
|
1695
|
-
assertNoDuplicateGroupIds(agentId, groupIds);
|
|
1696
|
-
return Object.freeze(groupIds);
|
|
1697
|
-
}
|
|
1698
|
-
function validateAgentGroupReferences(agents, security) {
|
|
1699
|
-
for (const agent of agents) {
|
|
1700
|
-
assertNoDuplicateGroupIds(agent.id, agent.groupIds);
|
|
1701
|
-
for (const groupId of agent.groupIds) {
|
|
1702
|
-
if (!security.getGroupById(groupId)) {
|
|
1703
|
-
throw new AgentDefinitionError(`[Sixb] Agent '${agent.id}' groups references unknown group '${groupId}'. Add it to 'security/groups/' or pass it to createSixb({ groups }).`);
|
|
1704
|
-
}
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
function assertNoDuplicateGroupIds(agentId, groupIds) {
|
|
1709
|
-
const seen = new Set;
|
|
1710
|
-
for (const groupId of groupIds) {
|
|
1711
|
-
assertNonEmpty(groupId, `Agent '${agentId}' group id`);
|
|
1712
|
-
if (seen.has(groupId)) {
|
|
1713
|
-
throw new AgentDefinitionError(`[Sixb] Agent '${agentId}' groups contains duplicate group id '${groupId}'.`);
|
|
1714
|
-
}
|
|
1715
|
-
seen.add(groupId);
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
function isAgentReasoningLevel(value) {
|
|
1719
|
-
return typeof value === "string" && AGENT_REASONING_LEVELS.includes(value);
|
|
1720
|
-
}
|
|
1721
|
-
function isProviderOptions(value) {
|
|
1722
|
-
if (!isRecord(value) || getInvalidJsonValueReason(value) !== undefined) {
|
|
1723
|
-
return false;
|
|
1724
|
-
}
|
|
1725
|
-
return Object.entries(value).every(([provider, options]) => provider.trim().length > 0 && isRecord(options) && getInvalidJsonValueReason(options) === undefined);
|
|
1726
|
-
}
|
|
1727
|
-
function assertValidAgentToolSchema(toolName, schema, path, visiting) {
|
|
1728
|
-
if (typeof schema === "string") {
|
|
1729
|
-
if (AGENT_TOOL_PRIMITIVE_SCHEMAS.has(schema)) {
|
|
1730
|
-
return;
|
|
1731
|
-
}
|
|
1732
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1733
|
-
}
|
|
1734
|
-
if (!isPlainRecord(schema) || typeof schema.type !== "string" || visiting.has(schema)) {
|
|
1735
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1736
|
-
}
|
|
1737
|
-
visiting.add(schema);
|
|
1738
|
-
switch (schema.type) {
|
|
1739
|
-
case "enum": {
|
|
1740
|
-
const values = schema.values;
|
|
1741
|
-
const validValues = isValidAgentToolEnumValues(values, schema.valueType);
|
|
1742
|
-
if (!validValues || new Set(values).size !== values.length) {
|
|
1743
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1744
|
-
}
|
|
1745
|
-
break;
|
|
1746
|
-
}
|
|
1747
|
-
case "array":
|
|
1748
|
-
assertValidAgentToolSchema(toolName, schema.items, `${path}.items`, visiting);
|
|
1749
|
-
break;
|
|
1750
|
-
case "map":
|
|
1751
|
-
if (schema.keySchema !== "string") {
|
|
1752
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1753
|
-
}
|
|
1754
|
-
assertValidAgentToolSchema(toolName, schema.valueSchema, `${path}.valueSchema`, visiting);
|
|
1755
|
-
break;
|
|
1756
|
-
case "object": {
|
|
1757
|
-
if (!isPlainRecord(schema.properties)) {
|
|
1758
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1759
|
-
}
|
|
1760
|
-
for (const [fieldId, field] of Object.entries(schema.properties)) {
|
|
1761
|
-
if (!fieldId.trim() || !isPlainRecord(field) || !("schema" in field)) {
|
|
1762
|
-
throw invalidAgentToolSchema(toolName, `${path}.properties.${fieldId}`);
|
|
1763
|
-
}
|
|
1764
|
-
if (field.required !== undefined && typeof field.required !== "boolean" || field.nullable !== undefined && typeof field.nullable !== "boolean" || field.description !== undefined && (typeof field.description !== "string" || !field.description.trim())) {
|
|
1765
|
-
throw invalidAgentToolSchema(toolName, `${path}.properties.${fieldId}`);
|
|
1766
|
-
}
|
|
1767
|
-
assertValidAgentToolSchema(toolName, field.schema, `${path}.properties.${fieldId}.schema`, visiting);
|
|
1768
|
-
}
|
|
1769
|
-
break;
|
|
1770
|
-
}
|
|
1771
|
-
case "valueTypeRef":
|
|
1772
|
-
if (typeof schema.valueTypeId !== "string" || !schema.valueTypeId.trim()) {
|
|
1773
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1774
|
-
}
|
|
1775
|
-
if (schema._resolved !== undefined) {
|
|
1776
|
-
assertValidAgentToolSchema(toolName, schema._resolved, `${path}._resolved`, visiting);
|
|
1777
|
-
}
|
|
1778
|
-
break;
|
|
1779
|
-
default:
|
|
1780
|
-
throw invalidAgentToolSchema(toolName, path);
|
|
1781
|
-
}
|
|
1782
|
-
visiting.delete(schema);
|
|
1783
|
-
}
|
|
1784
|
-
function invalidAgentToolSchema(toolName, path) {
|
|
1785
|
-
return new AgentDefinitionError(`[Sixb] Agent tool '${toolName}' ${path} must be a valid Sixb schema.`);
|
|
1786
|
-
}
|
|
1787
|
-
function isAgentToolDefinitionArray(value) {
|
|
1788
|
-
if (!Array.isArray(value)) {
|
|
1789
|
-
return false;
|
|
1790
|
-
}
|
|
1791
|
-
for (let index = 0;index < value.length; index += 1) {
|
|
1792
|
-
if (!Object.hasOwn(value, index) || !isAgentToolDefinition(value[index])) {
|
|
1793
|
-
return false;
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
return true;
|
|
1797
|
-
}
|
|
1798
|
-
function assertValidAgentToolDefinitions(agentId, tools) {
|
|
1799
|
-
const seen = new Set;
|
|
1800
|
-
for (let index = 0;index < tools.length; index += 1) {
|
|
1801
|
-
const tool = tools[index];
|
|
1802
|
-
if (!Object.hasOwn(tools, index) || !isAgentToolDefinition(tool)) {
|
|
1803
|
-
throw new AgentDefinitionError(`[Sixb] Agent '${agentId}' tools must contain only agent tool definitions.`);
|
|
1804
|
-
}
|
|
1805
|
-
assertValidAgentToolName(tool.name);
|
|
1806
|
-
assertValidAgentToolDescription(tool.name, tool.description);
|
|
1807
|
-
assertValidAgentToolInput(tool.name, tool.input);
|
|
1808
|
-
if (seen.has(tool.name)) {
|
|
1809
|
-
throw new AgentDefinitionError(`[Sixb] Agent '${agentId}' tools contains duplicate tool name '${tool.name}'.`);
|
|
1810
|
-
}
|
|
1811
|
-
seen.add(tool.name);
|
|
1812
|
-
}
|
|
1813
|
-
}
|
|
1814
|
-
function isValidAgentToolEnumValues(values, valueType) {
|
|
1815
|
-
if (!Array.isArray(values) || values.length === 0) {
|
|
1816
|
-
return false;
|
|
1817
|
-
}
|
|
1818
|
-
for (let index = 0;index < values.length; index += 1) {
|
|
1819
|
-
if (!Object.hasOwn(values, index)) {
|
|
1820
|
-
return false;
|
|
1821
|
-
}
|
|
1822
|
-
const value = values[index];
|
|
1823
|
-
if (valueType === "string" ? typeof value !== "string" : valueType !== "integer" || typeof value !== "number" || !Number.isInteger(value)) {
|
|
1824
|
-
return false;
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
return true;
|
|
1828
|
-
}
|
|
1829
|
-
function deepFreeze(value, seen = new Set) {
|
|
1830
|
-
if (value === null || typeof value !== "object" || seen.has(value)) {
|
|
1831
|
-
return value;
|
|
1832
|
-
}
|
|
1833
|
-
seen.add(value);
|
|
1834
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
1835
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
1836
|
-
if (descriptor && "value" in descriptor) {
|
|
1837
|
-
deepFreeze(descriptor.value, seen);
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
return Object.freeze(value);
|
|
1841
|
-
}
|
|
1842
|
-
function isRecord(value) {
|
|
1843
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1844
|
-
}
|
|
1845
|
-
|
|
1846
|
-
// src/agents/tool-definition.ts
|
|
1847
|
-
var EMPTY_AGENT_TOOLS = Object.freeze([]);
|
|
1848
|
-
var normalizedAgentTools = new WeakSet;
|
|
1849
|
-
function createAgentToolDefinition(definition) {
|
|
1850
|
-
assertValidAgentToolName(definition.name);
|
|
1851
|
-
assertValidAgentToolDescription(definition.name, definition.description);
|
|
1852
|
-
if (typeof definition.handler !== "function") {
|
|
1853
|
-
throw new AgentDefinitionError(`[Sixb] Agent tool '${definition.name}' handler must be a function.`);
|
|
1854
|
-
}
|
|
1855
|
-
const input = validateAndSnapshotAgentToolInput(definition.name, definition.input);
|
|
1856
|
-
const tool = {
|
|
1857
|
-
kind: "agentTool",
|
|
1858
|
-
name: definition.name,
|
|
1859
|
-
description: definition.description,
|
|
1860
|
-
input,
|
|
1861
|
-
handler: async (context) => {
|
|
1862
|
-
const result = await definition.handler(context);
|
|
1863
|
-
let snapshot;
|
|
1864
|
-
try {
|
|
1865
|
-
snapshot = cloneJsonValue(result, "result");
|
|
1866
|
-
} catch (cause) {
|
|
1867
|
-
throw new AgentToolResultValidationError(definition.name, getInvalidJsonValueReason(result, "result") ?? "result could not be cloned safely", { cause });
|
|
1868
|
-
}
|
|
1869
|
-
const richResultReason = getInvalidAgentToolResultReason(snapshot);
|
|
1870
|
-
if (richResultReason) {
|
|
1871
|
-
throw new AgentToolResultValidationError(definition.name, richResultReason);
|
|
1872
|
-
}
|
|
1873
|
-
return snapshot;
|
|
1874
|
-
}
|
|
1875
|
-
};
|
|
1876
|
-
normalizedAgentTools.add(tool);
|
|
1877
|
-
return Object.freeze(tool);
|
|
1878
|
-
}
|
|
1879
|
-
function toolsFromDefinitions(agentId, tools) {
|
|
1880
|
-
if (tools === undefined) {
|
|
1881
|
-
return EMPTY_AGENT_TOOLS;
|
|
1882
|
-
}
|
|
1883
|
-
if (!Array.isArray(tools)) {
|
|
1884
|
-
throw new AgentDefinitionError(`[Sixb] Agent '${agentId}' tools must be an array of agent tool definitions.`);
|
|
1885
|
-
}
|
|
1886
|
-
assertValidAgentToolDefinitions(agentId, tools);
|
|
1887
|
-
const normalized = [];
|
|
1888
|
-
for (const tool of tools) {
|
|
1889
|
-
normalized.push(normalizeAgentToolDefinition(tool));
|
|
1890
|
-
}
|
|
1891
|
-
return Object.freeze(normalized);
|
|
1892
|
-
}
|
|
1893
|
-
function normalizeAgentToolDefinition(tool) {
|
|
1894
|
-
if (normalizedAgentTools.has(tool)) {
|
|
1895
|
-
return tool;
|
|
1896
|
-
}
|
|
1897
|
-
return createAgentToolDefinition({
|
|
1898
|
-
name: tool.name,
|
|
1899
|
-
description: tool.description,
|
|
1900
|
-
input: tool.input,
|
|
1901
|
-
handler: (context) => tool.handler(context)
|
|
1902
|
-
});
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
// src/agents/builders.ts
|
|
1906
|
-
function defineAgentTool(name) {
|
|
1907
|
-
assertValidAgentToolName(name);
|
|
1908
|
-
return {
|
|
1909
|
-
description(description) {
|
|
1910
|
-
assertValidAgentToolDescription(name, description);
|
|
1911
|
-
return {
|
|
1912
|
-
input(input) {
|
|
1913
|
-
assertValidAgentToolInput(name, input);
|
|
1914
|
-
return {
|
|
1915
|
-
run(handler) {
|
|
1916
|
-
return createAgentToolDefinition({ name, description, input, handler });
|
|
1917
|
-
}
|
|
1918
|
-
};
|
|
1919
|
-
}
|
|
1920
|
-
};
|
|
1921
|
-
}
|
|
1922
|
-
};
|
|
1923
|
-
}
|
|
1924
|
-
function defineAgent(id, config) {
|
|
1925
|
-
assertNonEmpty(id, "id");
|
|
1926
|
-
assertNonEmpty(config.name, "name");
|
|
1927
|
-
assertNonEmpty(config.instructions, "instructions");
|
|
1928
|
-
if (config.model === undefined || config.model === null) {
|
|
1929
|
-
throw new AgentDefinitionError("[Sixb] Agent model is required.");
|
|
1930
|
-
}
|
|
1931
|
-
assertValidReasoningLevel(config.reasoning);
|
|
1932
|
-
assertValidProviderOptions(config.providerOptions);
|
|
1933
|
-
const loop = resolveAgentLoopConfig(config.loop);
|
|
1934
|
-
const groupIds = groupIdsFromDefinitions(id, config.groups);
|
|
1935
|
-
const tools = toolsFromDefinitions(id, config.tools);
|
|
1936
|
-
return Object.freeze({
|
|
1937
|
-
kind: "agent",
|
|
1938
|
-
id,
|
|
1939
|
-
name: config.name,
|
|
1940
|
-
model: config.model,
|
|
1941
|
-
...config.reasoning !== undefined ? { reasoning: config.reasoning } : {},
|
|
1942
|
-
...config.providerOptions !== undefined ? { providerOptions: config.providerOptions } : {},
|
|
1943
|
-
instructions: config.instructions,
|
|
1944
|
-
groupIds,
|
|
1945
|
-
tools,
|
|
1946
|
-
...config.description !== undefined ? { description: config.description } : {},
|
|
1947
|
-
...loop !== undefined ? { loop } : {}
|
|
1948
|
-
});
|
|
1949
|
-
}
|
|
1950
|
-
// src/agents/context-compaction.ts
|
|
1951
|
-
var AGENT_CONTEXT_ESTIMATOR_VERSION = 1;
|
|
1952
|
-
var CHARS_PER_TOKEN = 4;
|
|
1953
|
-
var REQUEST_OVERHEAD_TOKENS = 8;
|
|
1954
|
-
var MESSAGE_OVERHEAD_TOKENS = 8;
|
|
1955
|
-
var TOOL_OVERHEAD_TOKENS = 16;
|
|
1956
|
-
var STEP_OVERHEAD_TOKENS = 2;
|
|
1957
|
-
var IMAGE_ALLOWANCE_TOKENS = 1200;
|
|
1958
|
-
var FILE_TEXT_INLINE_MAX_BYTES = 50 * 1024;
|
|
1959
|
-
var FILE_TEXT_INLINE_TOTAL_MAX_BYTES = 200 * 1024;
|
|
1960
|
-
var TOOL_RESULT_SUMMARY_MAX_CHARS = 2000;
|
|
1961
|
-
function shouldCompactAgentContext(input) {
|
|
1962
|
-
return input.estimatedInputTokens > input.inputBudgetTokens;
|
|
1963
|
-
}
|
|
1964
|
-
function estimateAgentContextRequestTokens(input) {
|
|
1965
|
-
const toolTokens = input.tools.reduce((total, tool) => total + TOOL_OVERHEAD_TOKENS + textTokens(tool.name) + textTokens(tool.description) + textTokens(tool.inputSchema), 0);
|
|
1966
|
-
return {
|
|
1967
|
-
tokens: REQUEST_OVERHEAD_TOKENS + textTokens(input.systemPrompt) + toolTokens + estimateAgentContextMessagesTokens(input.messages).tokens,
|
|
1968
|
-
estimatorVersion: AGENT_CONTEXT_ESTIMATOR_VERSION
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
1971
|
-
function estimateAgentContextMessagesTokens(messages) {
|
|
1972
|
-
const attachments = { textBytesRemaining: FILE_TEXT_INLINE_TOTAL_MAX_BYTES };
|
|
1973
|
-
let tokens = 0;
|
|
1974
|
-
for (const message of messages) {
|
|
1975
|
-
tokens += estimateMessageTokens(message, attachments);
|
|
1976
|
-
}
|
|
1977
|
-
return { tokens, estimatorVersion: AGENT_CONTEXT_ESTIMATOR_VERSION };
|
|
1978
|
-
}
|
|
1979
|
-
function selectAgentContextCompactionBoundary(input) {
|
|
1980
|
-
if (input.messages.length < 2)
|
|
1981
|
-
return null;
|
|
1982
|
-
let retainedTokens = 0;
|
|
1983
|
-
let boundaryIndex = null;
|
|
1984
|
-
let closestDistance = Number.POSITIVE_INFINITY;
|
|
1985
|
-
for (let index = input.messages.length - 1;index > 0; index -= 1) {
|
|
1986
|
-
retainedTokens += estimateAgentContextMessagesTokens([input.messages[index]]).tokens;
|
|
1987
|
-
if (input.messages[index]?.role !== "user")
|
|
1988
|
-
continue;
|
|
1989
|
-
const distance = Math.abs(input.keepRecentTokens - retainedTokens);
|
|
1990
|
-
if (distance <= closestDistance) {
|
|
1991
|
-
boundaryIndex = index;
|
|
1992
|
-
closestDistance = distance;
|
|
1993
|
-
}
|
|
1994
|
-
if (retainedTokens >= input.keepRecentTokens)
|
|
1995
|
-
break;
|
|
1996
|
-
}
|
|
1997
|
-
if (boundaryIndex === null)
|
|
1998
|
-
return null;
|
|
1999
|
-
const summarizedThroughSeq = input.messages[boundaryIndex - 1]?.seq;
|
|
2000
|
-
if (summarizedThroughSeq === undefined)
|
|
2001
|
-
return null;
|
|
2002
|
-
return {
|
|
2003
|
-
messagesToSummarize: input.messages.slice(0, boundaryIndex),
|
|
2004
|
-
retainedMessages: input.messages.slice(boundaryIndex),
|
|
2005
|
-
summarizedThroughSeq
|
|
2006
|
-
};
|
|
2007
|
-
}
|
|
2008
|
-
function serializeAgentMessagesForSummary(messages) {
|
|
2009
|
-
const lines = ["<sixb_conversation_history>"];
|
|
2010
|
-
for (const message of messages) {
|
|
2011
|
-
lines.push(` <message id="${escapeXml2(message.id)}" seq="${message.seq}" role="${message.role}">`);
|
|
2012
|
-
message.parts.forEach((part, partIndex) => {
|
|
2013
|
-
lines.push(...serializeSummaryPart(message, part, partIndex));
|
|
2014
|
-
});
|
|
2015
|
-
lines.push(" </message>");
|
|
2016
|
-
}
|
|
2017
|
-
lines.push("</sixb_conversation_history>");
|
|
2018
|
-
return lines.join(`
|
|
2019
|
-
`);
|
|
2020
|
-
}
|
|
2021
|
-
function estimateMessageTokens(message, attachments) {
|
|
2022
|
-
let tokens = MESSAGE_OVERHEAD_TOKENS;
|
|
2023
|
-
for (const part of message.parts) {
|
|
2024
|
-
switch (part.type) {
|
|
2025
|
-
case "text":
|
|
2026
|
-
case "reasoning":
|
|
2027
|
-
tokens += textTokens(part.text);
|
|
2028
|
-
break;
|
|
2029
|
-
case "step-start":
|
|
2030
|
-
tokens += STEP_OVERHEAD_TOKENS;
|
|
2031
|
-
break;
|
|
2032
|
-
case "context":
|
|
2033
|
-
tokens += textTokens(stableJsonStringify(part.context));
|
|
2034
|
-
break;
|
|
2035
|
-
case "tool-call":
|
|
2036
|
-
tokens += TOOL_OVERHEAD_TOKENS + textTokens(part.toolName) + textTokens(stableJsonStringify(part.input)) + (part.state === "output-available" ? textTokens(stableJsonStringify(part.output)) : textTokens(part.errorText));
|
|
2037
|
-
break;
|
|
2038
|
-
case "file": {
|
|
2039
|
-
const file = part.fileRef;
|
|
2040
|
-
tokens += textTokens([file.blobId, file.digest, file.fileName, file.mediaType, file.logicalPath].filter((value) => value !== undefined).join(" "));
|
|
2041
|
-
if (message.role !== "assistant") {
|
|
2042
|
-
if (looksLikeImage(file.mediaType, file.fileName)) {
|
|
2043
|
-
tokens += IMAGE_ALLOWANCE_TOKENS;
|
|
2044
|
-
} else {
|
|
2045
|
-
const inlineBytes = Math.min(file.sizeBytes, FILE_TEXT_INLINE_MAX_BYTES, attachments.textBytesRemaining);
|
|
2046
|
-
attachments.textBytesRemaining -= inlineBytes;
|
|
2047
|
-
tokens += Math.ceil(inlineBytes / CHARS_PER_TOKEN);
|
|
2048
|
-
}
|
|
2049
|
-
}
|
|
2050
|
-
break;
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
return tokens;
|
|
2055
|
-
}
|
|
2056
|
-
function serializeSummaryPart(message, part, partIndex) {
|
|
2057
|
-
const indent = " ";
|
|
2058
|
-
switch (part.type) {
|
|
2059
|
-
case "text":
|
|
2060
|
-
return [`${indent}<text>${escapeXml2(part.text)}</text>`];
|
|
2061
|
-
case "reasoning":
|
|
2062
|
-
case "step-start":
|
|
2063
|
-
return [];
|
|
2064
|
-
case "context":
|
|
2065
|
-
return part.context.kind === "object" ? [
|
|
2066
|
-
`${indent}<object_context origin="${part.origin}" object_type_id="${escapeXml2(part.context.ref.objectTypeId)}" primary_id="${escapeXml2(part.context.ref.primaryId)}" />`
|
|
2067
|
-
] : [
|
|
2068
|
-
`${indent}<app_context origin="${part.origin}" id="${escapeXml2(part.context.id)}" label="${escapeXml2(part.context.label)}">`,
|
|
2069
|
-
`${indent} <description>${escapeXml2(part.context.description)}</description>`,
|
|
2070
|
-
`${indent} <value format="json">${escapeXml2(stableJsonStringify(part.context.value))}</value>`,
|
|
2071
|
-
`${indent}</app_context>`
|
|
2072
|
-
];
|
|
2073
|
-
case "file": {
|
|
2074
|
-
const file = part.fileRef;
|
|
2075
|
-
const attributes = [
|
|
2076
|
-
`message_id="${escapeXml2(message.id)}"`,
|
|
2077
|
-
`part_index="${partIndex}"`,
|
|
2078
|
-
`blob_id="${escapeXml2(file.blobId)}"`,
|
|
2079
|
-
`digest="${escapeXml2(file.digest)}"`,
|
|
2080
|
-
`size_bytes="${file.sizeBytes}"`,
|
|
2081
|
-
...file.fileName === undefined ? [] : [`file_name="${escapeXml2(file.fileName)}"`],
|
|
2082
|
-
...file.mediaType === undefined ? [] : [`media_type="${escapeXml2(file.mediaType)}"`],
|
|
2083
|
-
...file.logicalPath === undefined ? [] : [`logical_path="${escapeXml2(file.logicalPath)}"`]
|
|
2084
|
-
];
|
|
2085
|
-
return [`${indent}<file ${attributes.join(" ")} />`];
|
|
2086
|
-
}
|
|
2087
|
-
case "tool-call": {
|
|
2088
|
-
const output = part.state === "output-available" ? truncateToolResult(stableJsonStringify(part.output)) : truncateToolResult(part.errorText);
|
|
2089
|
-
return [
|
|
2090
|
-
`${indent}<tool_call id="${escapeXml2(part.toolCallId)}" name="${escapeXml2(part.toolName)}" state="${part.state}">`,
|
|
2091
|
-
`${indent} <input format="json">${escapeXml2(stableJsonStringify(part.input))}</input>`,
|
|
2092
|
-
`${indent} <result>${escapeXml2(output)}</result>`,
|
|
2093
|
-
`${indent}</tool_call>`
|
|
2094
|
-
];
|
|
2095
|
-
}
|
|
2096
|
-
}
|
|
2097
|
-
}
|
|
2098
|
-
function truncateToolResult(value) {
|
|
2099
|
-
if (value.length <= TOOL_RESULT_SUMMARY_MAX_CHARS)
|
|
2100
|
-
return value;
|
|
2101
|
-
return `${value.slice(0, TOOL_RESULT_SUMMARY_MAX_CHARS)}
|
|
2102
|
-
[truncated ${value.length - TOOL_RESULT_SUMMARY_MAX_CHARS} characters]`;
|
|
2103
|
-
}
|
|
2104
|
-
function looksLikeImage(mediaType, fileName) {
|
|
2105
|
-
if (mediaType?.toLowerCase().startsWith("image/"))
|
|
2106
|
-
return true;
|
|
2107
|
-
return /\.(?:avif|gif|jpe?g|png|webp)$/i.test(fileName ?? "");
|
|
2108
|
-
}
|
|
2109
|
-
function textTokens(value) {
|
|
2110
|
-
return Math.ceil(new TextEncoder().encode(value).byteLength / CHARS_PER_TOKEN);
|
|
2111
|
-
}
|
|
2112
|
-
function escapeXml2(value) {
|
|
2113
|
-
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2114
|
-
}
|
|
2115
|
-
// src/agents/thread-context-projection.ts
|
|
2116
|
-
function projectAgentThreadModelContext(input) {
|
|
2117
|
-
const { checkpoint, messages } = input;
|
|
2118
|
-
if (!checkpoint)
|
|
2119
|
-
return messages;
|
|
2120
|
-
assertConsistentCheckpointProjection(checkpoint, messages);
|
|
2121
|
-
return [
|
|
2122
|
-
{
|
|
2123
|
-
role: "user",
|
|
2124
|
-
parts: [{ type: "text", text: serializeThreadSummary(checkpoint.summary) }]
|
|
2125
|
-
},
|
|
2126
|
-
...messages
|
|
2127
|
-
];
|
|
2128
|
-
}
|
|
2129
|
-
function assertConsistentCheckpointProjection(checkpoint, messages) {
|
|
2130
|
-
if (checkpoint.summaryFormatVersion !== 1 || checkpoint.summary.trim().length === 0) {
|
|
2131
|
-
throw projectionError(checkpoint, "has an invalid summary");
|
|
2132
|
-
}
|
|
2133
|
-
if (checkpoint.summarizedThroughSeq >= checkpoint.observedHeadSeq) {
|
|
2134
|
-
throw projectionError(checkpoint, "does not retain its observed head");
|
|
2135
|
-
}
|
|
2136
|
-
if (messages.length === 0) {
|
|
2137
|
-
throw projectionError(checkpoint, "has no retained messages");
|
|
2138
|
-
}
|
|
2139
|
-
let expectedSeq = checkpoint.summarizedThroughSeq + 1;
|
|
2140
|
-
for (const message of messages) {
|
|
2141
|
-
if (message.projectId !== checkpoint.projectId || message.threadId !== checkpoint.threadId) {
|
|
2142
|
-
throw projectionError(checkpoint, "contains a message from another thread");
|
|
2143
|
-
}
|
|
2144
|
-
if (message.seq !== expectedSeq) {
|
|
2145
|
-
throw projectionError(checkpoint, `has a sequence gap before message '${message.id}'`);
|
|
2146
|
-
}
|
|
2147
|
-
expectedSeq += 1;
|
|
2148
|
-
}
|
|
2149
|
-
if (messages[0]?.role !== "user") {
|
|
2150
|
-
throw projectionError(checkpoint, "does not begin at a user turn boundary");
|
|
2151
|
-
}
|
|
2152
|
-
if ((messages.at(-1)?.seq ?? 0) < checkpoint.observedHeadSeq) {
|
|
2153
|
-
throw projectionError(checkpoint, "ends before the checkpoint's observed head");
|
|
2154
|
-
}
|
|
2155
|
-
}
|
|
2156
|
-
function serializeThreadSummary(summary) {
|
|
2157
|
-
return [
|
|
2158
|
-
"The earlier conversation was compacted into this continuation summary.",
|
|
2159
|
-
"",
|
|
2160
|
-
"<sixb_thread_summary>",
|
|
2161
|
-
escapeXml3(summary),
|
|
2162
|
-
"</sixb_thread_summary>"
|
|
2163
|
-
].join(`
|
|
2164
|
-
`);
|
|
2165
|
-
}
|
|
2166
|
-
function projectionError(checkpoint, detail) {
|
|
2167
|
-
return new Error(`[Sixb] Agent context checkpoint '${checkpoint.id}' for thread '${checkpoint.threadId}' ${detail}.`);
|
|
2168
|
-
}
|
|
2169
|
-
function escapeXml3(value) {
|
|
2170
|
-
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2171
|
-
}
|
|
2172
1298
|
// src/workflows/validation.ts
|
|
2173
|
-
function
|
|
1299
|
+
function assertNonEmpty(value, subject, field) {
|
|
2174
1300
|
if (!value.trim()) {
|
|
2175
1301
|
throw new WorkflowDefinitionError(`${subject} ${field} must not be empty.`);
|
|
2176
1302
|
}
|
|
2177
1303
|
}
|
|
2178
1304
|
function isStepDefinition(value) {
|
|
2179
|
-
return
|
|
1305
|
+
return isRecord(value) && value.kind === "step" && typeof value.id === "string" && isRecord(value.input) && isRecord(value.output) && typeof value.handler === "function";
|
|
2180
1306
|
}
|
|
2181
1307
|
function isAgentStepDefinition(value) {
|
|
2182
|
-
return
|
|
1308
|
+
return isRecord(value) && value.kind === "agentStep" && typeof value.id === "string" && (value.model === undefined || isLanguageModel(value.model)) && (value.reasoning === undefined || isModelReasoning(value.reasoning)) && typeof value.instructions === "string" && isStringArray(value.groupIds) && isStringArray(value.toolNames) && isRecord(value.input) && isRecord(value.output) && typeof value.prompt === "function";
|
|
2183
1309
|
}
|
|
2184
1310
|
function isInterventionDefinition(value) {
|
|
2185
|
-
return
|
|
1311
|
+
return isRecord(value) && value.kind === "intervention" && typeof value.id === "string" && isRecord(value.input) && isRecord(value.response) && (value.defaults === undefined || typeof value.defaults === "function");
|
|
2186
1312
|
}
|
|
2187
1313
|
function isWorkflowDefinition(value) {
|
|
2188
|
-
return
|
|
1314
|
+
return isRecord(value) && value.kind === "workflow" && typeof value.id === "string" && isRecord(value.input) && Array.isArray(value.triggers) && Array.isArray(value.nodes);
|
|
2189
1315
|
}
|
|
2190
1316
|
function validateWorkflowDefinition(value) {
|
|
2191
1317
|
if (!isWorkflowDefinition(value)) {
|
|
2192
1318
|
throw new WorkflowDefinitionError("Invalid workflow definition.");
|
|
2193
1319
|
}
|
|
2194
|
-
|
|
1320
|
+
assertNonEmpty(value.id, "Workflow", "id");
|
|
2195
1321
|
if (value.nodes.length === 0) {
|
|
2196
1322
|
throw new WorkflowDefinitionError(`Workflow "${value.id}" must contain at least one node.`);
|
|
2197
1323
|
}
|
|
@@ -2219,13 +1345,42 @@ function validateWorkflowsAtStartup(options) {
|
|
|
2219
1345
|
if (node.type === "action" && !options.registeredActionIds.has(node.action.id)) {
|
|
2220
1346
|
throw new WorkflowDefinitionError(`Workflow "${workflow.id}" references unknown action "${node.action.id}". Add it to 'actions' in createSixb() or export it from 'actions/'.`);
|
|
2221
1347
|
}
|
|
2222
|
-
if (node.type === "agent"
|
|
2223
|
-
|
|
1348
|
+
if (node.type === "agent") {
|
|
1349
|
+
validateWorkflowAgentStepRuntimeReferences(workflow.id, node.agentStep, options);
|
|
2224
1350
|
}
|
|
2225
1351
|
}
|
|
2226
1352
|
}
|
|
2227
1353
|
return options.workflows;
|
|
2228
1354
|
}
|
|
1355
|
+
function validateWorkflowAgentStepGroupReferences(workflows, security) {
|
|
1356
|
+
for (const workflow of workflows) {
|
|
1357
|
+
for (const node of workflow.nodes) {
|
|
1358
|
+
if (node.type !== "agent")
|
|
1359
|
+
continue;
|
|
1360
|
+
for (const groupId of node.agentStep.groupIds) {
|
|
1361
|
+
if (!security.getGroupById(groupId)) {
|
|
1362
|
+
throw new WorkflowDefinitionError(`Workflow "${workflow.id}" agent step "${node.id}" references unknown group "${groupId}". Add it to 'security/groups/' or pass it to createSixb({ groups }).`);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
function validateWorkflowAgentStepRuntimeReferences(workflowId, step, options) {
|
|
1369
|
+
if (step.model === undefined && options.models === undefined) {
|
|
1370
|
+
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent step "${step.id}" needs a model. Configure 'models.language' or pass 'model' to defineAgentStep().`);
|
|
1371
|
+
}
|
|
1372
|
+
if (step.model !== undefined && options.models !== undefined) {
|
|
1373
|
+
const ref = { provider: step.model.providerId, modelId: step.model.modelId };
|
|
1374
|
+
if (options.models.language.getByRef(ref) === null) {
|
|
1375
|
+
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent step "${step.id}" uses unknown language model "${ref.provider}/${ref.modelId}". Add it to 'models.language' in createSixb().`);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
for (const toolName of step.toolNames) {
|
|
1379
|
+
if (options.tools.getByName(toolName) === null) {
|
|
1380
|
+
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent step "${step.id}" uses unknown project tool "${toolName}". Add it to 'tools' in createSixb().`);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
2229
1384
|
function validateWorkflowInput(params) {
|
|
2230
1385
|
return validateWorkflowContractRecord({
|
|
2231
1386
|
shape: params.workflow.input,
|
|
@@ -2277,7 +1432,7 @@ function validateWorkflowInterventionDefaultResponse(params) {
|
|
|
2277
1432
|
});
|
|
2278
1433
|
}
|
|
2279
1434
|
function validateWorkflowTriggerAtStartup(workflowId, trigger, registeredSchedules, inputFields) {
|
|
2280
|
-
if (!
|
|
1435
|
+
if (!isRecord(trigger) || trigger.type !== "schedule") {
|
|
2281
1436
|
throw new WorkflowDefinitionError(`Workflow "${workflowId}" contains an unsupported trigger.`);
|
|
2282
1437
|
}
|
|
2283
1438
|
validateScheduleWorkflowTrigger(workflowId, trigger, registeredSchedules, inputFields);
|
|
@@ -2301,7 +1456,7 @@ function validateScheduleWorkflowTrigger(workflowId, trigger, registeredSchedule
|
|
|
2301
1456
|
}
|
|
2302
1457
|
}
|
|
2303
1458
|
function validateWorkflowNodeDefinition(workflowId, node) {
|
|
2304
|
-
if (!
|
|
1459
|
+
if (!isRecord(node)) {
|
|
2305
1460
|
throw new WorkflowDefinitionError(`Workflow "${workflowId}" contains an invalid node.`);
|
|
2306
1461
|
}
|
|
2307
1462
|
if (node.type === "step") {
|
|
@@ -2335,10 +1490,39 @@ function validateAgentNodeDefinition(workflowId, node) {
|
|
|
2335
1490
|
if (node.id !== node.agentStep.id) {
|
|
2336
1491
|
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent node id "${node.id}" does not match agent step definition id "${node.agentStep.id}".`);
|
|
2337
1492
|
}
|
|
1493
|
+
if (!node.agentStep.instructions.trim()) {
|
|
1494
|
+
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent step "${node.id}" instructions must not be empty.`);
|
|
1495
|
+
}
|
|
1496
|
+
assertUniqueNonEmptyAgentStepValues(workflowId, node.id, "group", node.agentStep.groupIds);
|
|
1497
|
+
assertUniqueNonEmptyAgentStepValues(workflowId, node.id, "tool", node.agentStep.toolNames);
|
|
2338
1498
|
if (node.mapper !== undefined && typeof node.mapper !== "function") {
|
|
2339
1499
|
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent node "${node.id}" mapper must be a function.`);
|
|
2340
1500
|
}
|
|
2341
1501
|
}
|
|
1502
|
+
function assertUniqueNonEmptyAgentStepValues(workflowId, stepId, kind, values) {
|
|
1503
|
+
const seen = new Set;
|
|
1504
|
+
for (const value of values) {
|
|
1505
|
+
if (!value.trim()) {
|
|
1506
|
+
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent step "${stepId}" has an empty ${kind} id.`);
|
|
1507
|
+
}
|
|
1508
|
+
if (seen.has(value)) {
|
|
1509
|
+
throw new WorkflowDefinitionError(`Workflow "${workflowId}" agent step "${stepId}" has duplicate ${kind} '${value}'.`);
|
|
1510
|
+
}
|
|
1511
|
+
seen.add(value);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
function isLanguageModel(value) {
|
|
1515
|
+
return (typeof value === "object" || typeof value === "function") && value !== null;
|
|
1516
|
+
}
|
|
1517
|
+
function isStringArray(value) {
|
|
1518
|
+
if (!Array.isArray(value))
|
|
1519
|
+
return false;
|
|
1520
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
1521
|
+
if (!Object.hasOwn(value, index) || typeof value[index] !== "string")
|
|
1522
|
+
return false;
|
|
1523
|
+
}
|
|
1524
|
+
return true;
|
|
1525
|
+
}
|
|
2342
1526
|
function validateWorkflowAgentStepInput(params) {
|
|
2343
1527
|
return validateWorkflowContractRecord({
|
|
2344
1528
|
shape: params.agentStep.input,
|
|
@@ -2407,7 +1591,7 @@ function validateActionNodeDefinition(workflowId, node) {
|
|
|
2407
1591
|
}
|
|
2408
1592
|
}
|
|
2409
1593
|
function validateWorkflowContractRecord(params) {
|
|
2410
|
-
if (!
|
|
1594
|
+
if (!isRecord(params.value)) {
|
|
2411
1595
|
throw new WorkflowValidationError(`[Sixb] ${params.path} must be an object`);
|
|
2412
1596
|
}
|
|
2413
1597
|
const fieldIds = new Set(Object.keys(params.shape));
|
|
@@ -2430,7 +1614,7 @@ function validateWorkflowContractRecord(params) {
|
|
|
2430
1614
|
return params.value;
|
|
2431
1615
|
}
|
|
2432
1616
|
function validateWorkflowInterventionResponseRecord(params) {
|
|
2433
|
-
if (!
|
|
1617
|
+
if (!isRecord(params.value)) {
|
|
2434
1618
|
throw new WorkflowValidationError(`[Sixb] ${params.path} must be an object`);
|
|
2435
1619
|
}
|
|
2436
1620
|
const fieldIds = new Set(Object.keys(params.response));
|
|
@@ -2456,7 +1640,7 @@ function validateWorkflowInterventionResponseRecord(params) {
|
|
|
2456
1640
|
return params.value;
|
|
2457
1641
|
}
|
|
2458
1642
|
function isInterventionFieldConfig(value) {
|
|
2459
|
-
return
|
|
1643
|
+
return isRecord(value) && "schema" in value;
|
|
2460
1644
|
}
|
|
2461
1645
|
function interventionResponseFieldSchema(field) {
|
|
2462
1646
|
return isInterventionFieldConfig(field) ? field.schema : field;
|
|
@@ -2473,7 +1657,7 @@ function toWorkflowValidationError(error) {
|
|
|
2473
1657
|
}
|
|
2474
1658
|
return new WorkflowValidationError(String(error), { cause: error });
|
|
2475
1659
|
}
|
|
2476
|
-
function
|
|
1660
|
+
function isRecord(value) {
|
|
2477
1661
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2478
1662
|
}
|
|
2479
1663
|
|
|
@@ -2588,7 +1772,7 @@ function snapshotWorkflowInterventionResponseRecord(params) {
|
|
|
2588
1772
|
}
|
|
2589
1773
|
function snapshotSchemaOrRefValue(params) {
|
|
2590
1774
|
if (isObjectRefSchema(params.schema)) {
|
|
2591
|
-
if (!
|
|
1775
|
+
if (!isRecord2(params.value)) {
|
|
2592
1776
|
throw cannotSerialize(params.path);
|
|
2593
1777
|
}
|
|
2594
1778
|
return {
|
|
@@ -2629,7 +1813,7 @@ function snapshotSchemaValue(params) {
|
|
|
2629
1813
|
}));
|
|
2630
1814
|
}
|
|
2631
1815
|
if (schema.type === "map") {
|
|
2632
|
-
if (!
|
|
1816
|
+
if (!isRecord2(value)) {
|
|
2633
1817
|
throw cannotSerialize(path);
|
|
2634
1818
|
}
|
|
2635
1819
|
const snapshot = {};
|
|
@@ -2644,7 +1828,7 @@ function snapshotSchemaValue(params) {
|
|
|
2644
1828
|
return snapshot;
|
|
2645
1829
|
}
|
|
2646
1830
|
if (schema.type === "object") {
|
|
2647
|
-
if (!
|
|
1831
|
+
if (!isRecord2(value)) {
|
|
2648
1832
|
throw cannotSerialize(path);
|
|
2649
1833
|
}
|
|
2650
1834
|
const snapshot = {};
|
|
@@ -2714,7 +1898,7 @@ function snapshotDate(value, path) {
|
|
|
2714
1898
|
function cannotSerialize(path) {
|
|
2715
1899
|
return new WorkflowValidationError(`[Sixb] ${path} cannot be serialized as workflow IO`);
|
|
2716
1900
|
}
|
|
2717
|
-
function
|
|
1901
|
+
function isRecord2(value) {
|
|
2718
1902
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2719
1903
|
}
|
|
2720
1904
|
|
|
@@ -2797,7 +1981,7 @@ async function persistWorkflowRun(input, request) {
|
|
|
2797
1981
|
assertExistingWorkflowRun(existing, input.workflow.id, request.snapshot);
|
|
2798
1982
|
return { run: existing, created: false };
|
|
2799
1983
|
}
|
|
2800
|
-
const execution = await input.createExecution(`exec_${
|
|
1984
|
+
const execution = await input.createExecution(`exec_${randomUUID4()}`, request.runId);
|
|
2801
1985
|
const queuedAt = new Date;
|
|
2802
1986
|
try {
|
|
2803
1987
|
return await input.storage.transaction(async (tx) => {
|
|
@@ -2904,7 +2088,7 @@ async function failWorkflowRunPublication(input, run, error) {
|
|
|
2904
2088
|
}
|
|
2905
2089
|
function resolveWorkflowRunId(runId) {
|
|
2906
2090
|
if (runId === undefined)
|
|
2907
|
-
return `run_${
|
|
2091
|
+
return `run_${randomUUID4()}`;
|
|
2908
2092
|
if (!runId.trim()) {
|
|
2909
2093
|
throw new WorkflowValidationError("[Sixb] Workflow run id must not be empty");
|
|
2910
2094
|
}
|
|
@@ -3121,7 +2305,6 @@ function toWorkflowAgentNodeRunView(execution, usage, cost) {
|
|
|
3121
2305
|
projectId: execution.projectId,
|
|
3122
2306
|
nodeRunId: execution.nodeRunId,
|
|
3123
2307
|
executionId: execution.executionId,
|
|
3124
|
-
agentId: execution.agentId,
|
|
3125
2308
|
status: execution.status,
|
|
3126
2309
|
prompt: execution.prompt,
|
|
3127
2310
|
modelId: execution.modelId,
|
|
@@ -3178,7 +2361,8 @@ function createExecutionFacades(runtime, execution, dependencies) {
|
|
|
3178
2361
|
pipelines: createPipelinesRuntime(runtime, execution, dependencies.definitions.pipelines),
|
|
3179
2362
|
projections: createProjectionsRuntime(runtime, dependencies.definitions.projections),
|
|
3180
2363
|
rules: createRulesRuntime(runtime, dependencies.definitions.rules),
|
|
3181
|
-
|
|
2364
|
+
agent: createAgentRuntime(runtime, execution, dependencies.definitions.models),
|
|
2365
|
+
aiUsage: createAiUsageRuntime(runtime, dependencies.definitions.security),
|
|
3182
2366
|
events: createEventsRuntime(runtime),
|
|
3183
2367
|
logs: createLogsRuntime(runtime, dependencies.logging),
|
|
3184
2368
|
schedules: createSchedulesRuntime(dependencies.definitions.schedules),
|
|
@@ -3186,10 +2370,13 @@ function createExecutionFacades(runtime, execution, dependencies) {
|
|
|
3186
2370
|
blobs: createBlobsRuntime(runtime, execution, dependencies.blobStorage)
|
|
3187
2371
|
};
|
|
3188
2372
|
}
|
|
3189
|
-
|
|
3190
2373
|
// src/execution/agent.ts
|
|
2374
|
+
function canInheritAgentRequestAuthorization(authorization) {
|
|
2375
|
+
const ref = getAuthorizationRef(authorization);
|
|
2376
|
+
return ref.type === "disabled" || ref.type === "principal" && ref.principal.type === "user" && ref.credential !== undefined;
|
|
2377
|
+
}
|
|
3191
2378
|
function createAgentExecutionRecord(input) {
|
|
3192
|
-
assertAgentPrincipal(input.
|
|
2379
|
+
assertAgentPrincipal(input.actorId, input.principal);
|
|
3193
2380
|
return {
|
|
3194
2381
|
id: input.id,
|
|
3195
2382
|
projectId: input.parent.projectId,
|
|
@@ -3203,6 +2390,21 @@ function createAgentExecutionRecord(input) {
|
|
|
3203
2390
|
}
|
|
3204
2391
|
};
|
|
3205
2392
|
}
|
|
2393
|
+
function createInheritedAgentExecutionRecord(input) {
|
|
2394
|
+
const authority = input.parent.authorizationRef;
|
|
2395
|
+
if (authority.type !== "disabled" && !(authority.type === "principal" && authority.principal.type === "user" && authority.credential !== undefined)) {
|
|
2396
|
+
throw new ExecutionStorageError("invalid_input", `[Sixb] Agent run '${input.runId}' requires inheritable user or auth-disabled authority.`);
|
|
2397
|
+
}
|
|
2398
|
+
return {
|
|
2399
|
+
id: input.id,
|
|
2400
|
+
projectId: input.parent.projectId,
|
|
2401
|
+
...input.parent.requestedBy === undefined ? {} : { requestedBy: structuredClone(input.parent.requestedBy) },
|
|
2402
|
+
executor: { type: "agent", runId: input.runId },
|
|
2403
|
+
source: { type: "execution", executionId: input.parent.id },
|
|
2404
|
+
correlationId: input.parent.correlationId,
|
|
2405
|
+
authorizationRef: structuredClone(authority)
|
|
2406
|
+
};
|
|
2407
|
+
}
|
|
3206
2408
|
function bindDurableAgentExecution(host, input) {
|
|
3207
2409
|
const scope = restoreAgentExecutionScope(input);
|
|
3208
2410
|
const sixb = host.withScope(scope);
|
|
@@ -3217,7 +2419,11 @@ function restoreAgentExecutionScope(input) {
|
|
|
3217
2419
|
id: input.execution.id,
|
|
3218
2420
|
projectId: input.execution.projectId,
|
|
3219
2421
|
...input.execution.requestedBy === undefined ? {} : { requestedBy: Object.freeze(structuredClone(input.execution.requestedBy)) },
|
|
3220
|
-
executor: Object.freeze({
|
|
2422
|
+
executor: Object.freeze({
|
|
2423
|
+
type: "agent",
|
|
2424
|
+
...input.actorId === undefined ? {} : { actorId: input.actorId },
|
|
2425
|
+
runId: input.runId
|
|
2426
|
+
}),
|
|
3221
2427
|
source: Object.freeze(structuredClone(input.execution.source)),
|
|
3222
2428
|
correlationId: input.execution.correlationId
|
|
3223
2429
|
});
|
|
@@ -3225,30 +2431,56 @@ function restoreAgentExecutionScope(input) {
|
|
|
3225
2431
|
execution: context,
|
|
3226
2432
|
authorization: createAgentRuntimeAuthorization({
|
|
3227
2433
|
projectId: input.execution.projectId,
|
|
3228
|
-
context: input.authorization,
|
|
3229
2434
|
executionId: input.execution.id,
|
|
3230
|
-
|
|
3231
|
-
runId: input.runId
|
|
2435
|
+
...input.actorId === undefined ? {} : { actorId: input.actorId },
|
|
2436
|
+
runId: input.runId,
|
|
2437
|
+
authority: input.authorization.type === "principal" ? {
|
|
2438
|
+
type: "principal",
|
|
2439
|
+
context: input.authorization.context,
|
|
2440
|
+
...input.execution.authorizationRef.type === "principal" && input.execution.authorizationRef.credential !== undefined ? { credential: input.execution.authorizationRef.credential } : {}
|
|
2441
|
+
} : { type: "disabled" }
|
|
3232
2442
|
})
|
|
3233
2443
|
});
|
|
3234
2444
|
}
|
|
3235
2445
|
function assertAgentExecutionRecord(input) {
|
|
3236
2446
|
const authority = input.execution.authorizationRef;
|
|
3237
|
-
if (input.execution.executor.type !== "agent" || input.execution.executor.runId !== input.runId || input.execution.source.type !== "execution"
|
|
2447
|
+
if (input.execution.executor.type !== "agent" || input.execution.executor.runId !== input.runId || input.execution.source.type !== "execution") {
|
|
2448
|
+
invalidAgentExecution(input.execution.id, input.runId);
|
|
2449
|
+
}
|
|
2450
|
+
if (input.authorization.type === "disabled" || input.authorization.context.principal.type === "user") {
|
|
2451
|
+
assertInheritedAgentAuthority(input.execution, input.runId, input.authorization);
|
|
2452
|
+
return;
|
|
2453
|
+
}
|
|
2454
|
+
if (input.authorization.type !== "principal" || authority.type !== "principal" || authority.principal.type !== "serviceAccount" || input.authorization.context.principal.type !== "serviceAccount" || authority.principal.id !== input.authorization.context.principal.id || authority.credential !== undefined) {
|
|
2455
|
+
invalidAgentExecution(input.execution.id, input.runId);
|
|
2456
|
+
}
|
|
2457
|
+
if (input.actorId === undefined) {
|
|
3238
2458
|
invalidAgentExecution(input.execution.id, input.runId);
|
|
3239
2459
|
}
|
|
3240
|
-
assertAgentPrincipal(input.
|
|
2460
|
+
assertAgentPrincipal(input.actorId, authority.principal);
|
|
2461
|
+
}
|
|
2462
|
+
function assertInheritedAgentAuthority(execution, runId, authorization) {
|
|
2463
|
+
const authority = execution.authorizationRef;
|
|
2464
|
+
if (authorization.type === "disabled") {
|
|
2465
|
+
if (authority.type !== "disabled")
|
|
2466
|
+
invalidAgentExecution(execution.id, runId);
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2469
|
+
const principal = authorization.context.principal;
|
|
2470
|
+
if (authority.type !== "principal" || authority.principal.type !== "user" || principal.type !== "user" || authority.principal.id !== principal.id || authority.credential === undefined || (authority.credential.type === "session" ? authorization.context.sessionId !== authority.credential.id : authorization.context.sessionId !== undefined)) {
|
|
2471
|
+
invalidAgentExecution(execution.id, runId);
|
|
2472
|
+
}
|
|
3241
2473
|
}
|
|
3242
|
-
function assertAgentPrincipal(
|
|
3243
|
-
const expectedId = agentServiceAccountId(
|
|
2474
|
+
function assertAgentPrincipal(actorId, principal) {
|
|
2475
|
+
const expectedId = agentServiceAccountId(actorId);
|
|
3244
2476
|
if (principal.id !== expectedId) {
|
|
3245
|
-
throw new ExecutionStorageError("invalid_input", `[Sixb] Agent '${
|
|
2477
|
+
throw new ExecutionStorageError("invalid_input", `[Sixb] Agent '${actorId}' execution authority must reference service account '${expectedId}'.`);
|
|
3246
2478
|
}
|
|
3247
2479
|
}
|
|
3248
2480
|
function invalidAgentExecution(executionId, runId) {
|
|
3249
2481
|
throw new ExecutionStorageError("invalid_input", `[Sixb] Execution '${executionId}' does not authorize Agent run '${runId}'.`);
|
|
3250
2482
|
}
|
|
3251
2483
|
|
|
3252
|
-
export {
|
|
2484
|
+
export { resolveAgentContextParts, agentRunQueueJobId, subagentRunQueueJobId, workflowAgentNodeQueueJobId, dispatchQueuedAgentRuns, dispatchQueuedSubagentRuns, createAgentThreadId, createAgentRunId, createSubagentRunId, createSubagentExecutionId, createAgentMessageId, agentContextCheckpointId, createAgentRunExecutionToken, assertNoAgentDefinitions, WorkflowDefinitionError, WorkflowValidationError, assertNonEmpty, isStepDefinition, isAgentStepDefinition, isInterventionDefinition, isWorkflowDefinition, validateWorkflowDefinition, validateWorkflowsAtStartup, validateWorkflowAgentStepGroupReferences, validateWorkflowInput, validateWorkflowStepInput, validateWorkflowStepOutput, validateWorkflowInterventionInput, validateWorkflowInterventionResponse, validateWorkflowInterventionDefaultResponse, validateWorkflowAgentStepInput, validateWorkflowAgentStepOutput, snapshotWorkflowAgentStepInput, snapshotWorkflowAgentStepOutput, snapshotWorkflowInput, snapshotWorkflowStepInput, snapshotWorkflowStepOutput, snapshotWorkflowInterventionInput, snapshotWorkflowInterventionResponse, snapshotWorkflowInterventionDefaultResponse, snapshotWorkflowActionInput, WorkflowRunDispatcher, requestWorkflowRun, createBoundSixb, isBoundSixb, canInheritAgentRequestAuthorization, createAgentExecutionRecord, createInheritedAgentExecutionRecord, bindDurableAgentExecution, restoreAgentExecutionScope, assertAgentExecutionRecord, requestAgentRun, retryAgentRun };
|
|
3253
2485
|
|
|
3254
|
-
//# debugId=
|
|
2486
|
+
//# debugId=00C5E0281CC5D43264756E2164756E21
|