@kindgi/api 0.1.4-rc.5 → 0.1.5-rc.0
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/agent-binding.d.ts +13 -0
- package/dist/agent-binding.d.ts.map +1 -1
- package/dist/agent-pins.d.ts.map +1 -1
- package/dist/agent-pins.js +18 -2
- package/dist/agent-pins.js.map +1 -1
- package/dist/app.d.ts +110 -17
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +163 -35
- package/dist/app.js.map +1 -1
- package/dist/block-publish.d.ts +56 -0
- package/dist/block-publish.d.ts.map +1 -0
- package/dist/block-publish.js +132 -0
- package/dist/block-publish.js.map +1 -0
- package/dist/caller.d.ts +24 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +47 -0
- package/dist/caller.js.map +1 -0
- package/dist/capability-binding.d.ts +11 -0
- package/dist/capability-binding.d.ts.map +1 -1
- package/dist/derive-agent-version.d.ts +7 -0
- package/dist/derive-agent-version.d.ts.map +1 -1
- package/dist/derive-agent-version.js +4 -0
- package/dist/derive-agent-version.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +73 -7
- package/dist/errors.js.map +1 -1
- package/dist/eval-case-binding.d.ts +16 -4
- package/dist/eval-case-binding.d.ts.map +1 -1
- package/dist/eval-run-binding.d.ts +31 -0
- package/dist/eval-run-binding.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.d.ts +7 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.js.map +1 -1
- package/dist/eval-sample.d.ts +11 -0
- package/dist/eval-sample.d.ts.map +1 -0
- package/dist/eval-sample.js +34 -0
- package/dist/eval-sample.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +13 -0
- package/dist/eval-suite-binding.d.ts.map +1 -1
- package/dist/eval-suite-binding.js.map +1 -1
- package/dist/flow-binding.d.ts +18 -0
- package/dist/flow-binding.d.ts.map +1 -1
- package/dist/flow-pins.d.ts.map +1 -1
- package/dist/flow-pins.js +18 -2
- package/dist/flow-pins.js.map +1 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +25 -0
- package/dist/gate.js.map +1 -1
- package/dist/handler-binding.d.ts +32 -0
- package/dist/handler-binding.d.ts.map +1 -1
- package/dist/hitl-binding.d.ts +23 -0
- package/dist/hitl-binding.d.ts.map +1 -1
- package/dist/identity-directory-binding.d.ts +82 -4
- package/dist/identity-directory-binding.d.ts.map +1 -1
- package/dist/identity-provider-binding.d.ts +197 -17
- package/dist/identity-provider-binding.d.ts.map +1 -1
- package/dist/improvement-pass-binding.d.ts +196 -0
- package/dist/improvement-pass-binding.d.ts.map +1 -0
- package/dist/improvement-pass-binding.js +9 -0
- package/dist/improvement-pass-binding.js.map +1 -0
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/judged-dispatcher.d.ts +25 -4
- package/dist/judged-dispatcher.d.ts.map +1 -1
- package/dist/judged-dispatcher.js +43 -6
- package/dist/judged-dispatcher.js.map +1 -1
- package/dist/judgment-binding.d.ts +25 -1
- package/dist/judgment-binding.d.ts.map +1 -1
- package/dist/mcp-endpoint-binding.d.ts +7 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -1
- package/dist/memory-binding.d.ts +124 -17
- package/dist/memory-binding.d.ts.map +1 -1
- package/dist/memory-erasure-binding.d.ts +145 -0
- package/dist/memory-erasure-binding.d.ts.map +1 -0
- package/dist/memory-erasure-binding.js +4 -0
- package/dist/memory-erasure-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +66 -13
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +150 -50
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/authorize.d.ts +6 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +113 -4
- package/dist/middleware/authorize.js.map +1 -1
- package/dist/middleware/error-mapper.d.ts +5 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -1
- package/dist/middleware/error-mapper.js +14 -1
- package/dist/middleware/error-mapper.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +70 -5
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +174 -41
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/key-project.d.ts +17 -0
- package/dist/middleware/key-project.d.ts.map +1 -0
- package/dist/middleware/key-project.js +75 -0
- package/dist/middleware/key-project.js.map +1 -0
- package/dist/middleware/principal.d.ts.map +1 -1
- package/dist/middleware/principal.js +9 -5
- package/dist/middleware/principal.js.map +1 -1
- package/dist/middleware/project-ref.d.ts.map +1 -1
- package/dist/middleware/project-ref.js +3 -0
- package/dist/middleware/project-ref.js.map +1 -1
- package/dist/openapi/generate.d.ts.map +1 -1
- package/dist/openapi/generate.js +5 -2
- package/dist/openapi/generate.js.map +1 -1
- package/dist/openapi/operations.d.ts.map +1 -1
- package/dist/openapi/operations.js +918 -139
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +92 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2122 -370
- package/dist/openapi/schemas.js.map +1 -1
- package/dist/person-grants-binding.d.ts +77 -0
- package/dist/person-grants-binding.d.ts.map +1 -0
- package/dist/person-grants-binding.js +4 -0
- package/dist/person-grants-binding.js.map +1 -0
- package/dist/proposal-service.d.ts +121 -0
- package/dist/proposal-service.d.ts.map +1 -0
- package/dist/proposal-service.js +447 -0
- package/dist/proposal-service.js.map +1 -0
- package/dist/proposal-status.d.ts +60 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +109 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/provider-binding.d.ts +10 -0
- package/dist/provider-binding.d.ts.map +1 -1
- package/dist/publish-refused.d.ts +18 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +18 -3
- package/dist/publish-refused.js.map +1 -1
- package/dist/routes/adapters.d.ts +2 -1
- package/dist/routes/adapters.d.ts.map +1 -1
- package/dist/routes/adapters.js +3 -1
- package/dist/routes/adapters.js.map +1 -1
- package/dist/routes/agent-releases.d.ts +55 -3
- package/dist/routes/agent-releases.d.ts.map +1 -1
- package/dist/routes/agent-releases.js +85 -55
- package/dist/routes/agent-releases.js.map +1 -1
- package/dist/routes/agents.d.ts +12 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +100 -2
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts +15 -3
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +133 -122
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/artifacts.d.ts +25 -3
- package/dist/routes/artifacts.d.ts.map +1 -1
- package/dist/routes/artifacts.js +116 -7
- package/dist/routes/artifacts.js.map +1 -1
- package/dist/routes/auth.d.ts +25 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +655 -281
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/blocks.d.ts.map +1 -1
- package/dist/routes/blocks.js +2 -42
- package/dist/routes/blocks.js.map +1 -1
- package/dist/routes/capabilities.d.ts +2 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +6 -1
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +9 -10
- package/dist/routes/compliance.d.ts.map +1 -1
- package/dist/routes/compliance.js +42 -61
- package/dist/routes/compliance.js.map +1 -1
- package/dist/routes/conversations.d.ts +8 -1
- package/dist/routes/conversations.d.ts.map +1 -1
- package/dist/routes/conversations.js +87 -8
- package/dist/routes/conversations.js.map +1 -1
- package/dist/routes/cost.d.ts +7 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +22 -3
- package/dist/routes/cost.js.map +1 -1
- package/dist/routes/denied.d.ts +11 -0
- package/dist/routes/denied.d.ts.map +1 -0
- package/dist/routes/denied.js +17 -0
- package/dist/routes/denied.js.map +1 -0
- package/dist/routes/deployments.d.ts +2 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +44 -12
- package/dist/routes/deployments.js.map +1 -1
- package/dist/routes/eval-comparison.d.ts.map +1 -1
- package/dist/routes/eval-comparison.js +69 -1
- package/dist/routes/eval-comparison.js.map +1 -1
- package/dist/routes/eval-overrides.d.ts +18 -0
- package/dist/routes/eval-overrides.d.ts.map +1 -0
- package/dist/routes/eval-overrides.js +81 -0
- package/dist/routes/eval-overrides.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +10 -1
- package/dist/routes/eval-runs.d.ts.map +1 -1
- package/dist/routes/eval-runs.js +63 -7
- package/dist/routes/eval-runs.js.map +1 -1
- package/dist/routes/eval-suites.d.ts.map +1 -1
- package/dist/routes/eval-suites.js +20 -1
- package/dist/routes/eval-suites.js.map +1 -1
- package/dist/routes/event-triggers.d.ts +5 -1
- package/dist/routes/event-triggers.d.ts.map +1 -1
- package/dist/routes/event-triggers.js +26 -3
- package/dist/routes/event-triggers.js.map +1 -1
- package/dist/routes/export-signing-keys.d.ts +12 -0
- package/dist/routes/export-signing-keys.d.ts.map +1 -0
- package/dist/routes/export-signing-keys.js +24 -0
- package/dist/routes/export-signing-keys.js.map +1 -0
- package/dist/routes/flows.d.ts.map +1 -1
- package/dist/routes/flows.js +9 -1
- package/dist/routes/flows.js.map +1 -1
- package/dist/routes/gate-policies.d.ts +4 -1
- package/dist/routes/gate-policies.d.ts.map +1 -1
- package/dist/routes/gate-policies.js +29 -5
- package/dist/routes/gate-policies.js.map +1 -1
- package/dist/routes/guardrails.d.ts +16 -14
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +39 -3
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/identity.d.ts +20 -4
- package/dist/routes/identity.d.ts.map +1 -1
- package/dist/routes/identity.js +246 -6
- package/dist/routes/identity.js.map +1 -1
- package/dist/routes/improvement-passes.d.ts +52 -0
- package/dist/routes/improvement-passes.d.ts.map +1 -0
- package/dist/routes/improvement-passes.js +449 -0
- package/dist/routes/improvement-passes.js.map +1 -0
- package/dist/routes/judged-suites.d.ts +50 -0
- package/dist/routes/judged-suites.d.ts.map +1 -1
- package/dist/routes/judged-suites.js +66 -27
- package/dist/routes/judged-suites.js.map +1 -1
- package/dist/routes/judgment-context.d.ts +18 -2
- package/dist/routes/judgment-context.d.ts.map +1 -1
- package/dist/routes/judgment-context.js +63 -5
- package/dist/routes/judgment-context.js.map +1 -1
- package/dist/routes/judgment-flow-context.d.ts.map +1 -1
- package/dist/routes/judgment-flow-context.js +14 -2
- package/dist/routes/judgment-flow-context.js.map +1 -1
- package/dist/routes/judgments.d.ts.map +1 -1
- package/dist/routes/judgments.js +8 -1
- package/dist/routes/judgments.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +26 -1
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/memory-access.d.ts +43 -0
- package/dist/routes/memory-access.d.ts.map +1 -0
- package/dist/routes/memory-access.js +129 -0
- package/dist/routes/memory-access.js.map +1 -0
- package/dist/routes/memory-erasures.d.ts +25 -0
- package/dist/routes/memory-erasures.d.ts.map +1 -0
- package/dist/routes/memory-erasures.js +214 -0
- package/dist/routes/memory-erasures.js.map +1 -0
- package/dist/routes/memory-parse.d.ts +38 -0
- package/dist/routes/memory-parse.d.ts.map +1 -0
- package/dist/routes/memory-parse.js +199 -0
- package/dist/routes/memory-parse.js.map +1 -0
- package/dist/routes/memory.d.ts +9 -4
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/memory.js +226 -234
- package/dist/routes/memory.js.map +1 -1
- package/dist/routes/observations.d.ts +4 -1
- package/dist/routes/observations.d.ts.map +1 -1
- package/dist/routes/observations.js +8 -2
- package/dist/routes/observations.js.map +1 -1
- package/dist/routes/pagination.d.ts +7 -0
- package/dist/routes/pagination.d.ts.map +1 -1
- package/dist/routes/pagination.js +10 -0
- package/dist/routes/pagination.js.map +1 -1
- package/dist/routes/policies.d.ts +2 -1
- package/dist/routes/policies.d.ts.map +1 -1
- package/dist/routes/policies.js +3 -1
- package/dist/routes/policies.js.map +1 -1
- package/dist/routes/project-mismatch.d.ts +22 -0
- package/dist/routes/project-mismatch.d.ts.map +1 -0
- package/dist/routes/project-mismatch.js +34 -0
- package/dist/routes/project-mismatch.js.map +1 -0
- package/dist/routes/projects.d.ts +15 -4
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +100 -9
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/proposals.d.ts +25 -17
- package/dist/routes/proposals.d.ts.map +1 -1
- package/dist/routes/proposals.js +340 -507
- package/dist/routes/proposals.js.map +1 -1
- package/dist/routes/provenance.d.ts +17 -3
- package/dist/routes/provenance.d.ts.map +1 -1
- package/dist/routes/provenance.js +79 -103
- package/dist/routes/provenance.js.map +1 -1
- package/dist/routes/providers.d.ts +17 -1
- package/dist/routes/providers.d.ts.map +1 -1
- package/dist/routes/providers.js +188 -8
- package/dist/routes/providers.js.map +1 -1
- package/dist/routes/public-run-tokens.d.ts.map +1 -1
- package/dist/routes/public-run-tokens.js +3 -0
- package/dist/routes/public-run-tokens.js.map +1 -1
- package/dist/routes/runs.d.ts +10 -0
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +92 -42
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/schedules.d.ts +21 -13
- package/dist/routes/schedules.d.ts.map +1 -1
- package/dist/routes/schedules.js +416 -55
- package/dist/routes/schedules.js.map +1 -1
- package/dist/routes/segments.d.ts +2 -0
- package/dist/routes/segments.d.ts.map +1 -1
- package/dist/routes/segments.js +5 -0
- package/dist/routes/segments.js.map +1 -1
- package/dist/routes/service-accounts.d.ts +17 -0
- package/dist/routes/service-accounts.d.ts.map +1 -0
- package/dist/routes/service-accounts.js +212 -0
- package/dist/routes/service-accounts.js.map +1 -0
- package/dist/routes/sign-in-options.d.ts +50 -0
- package/dist/routes/sign-in-options.d.ts.map +1 -0
- package/dist/routes/sign-in-options.js +98 -0
- package/dist/routes/sign-in-options.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +2 -1
- package/dist/routes/signing-keys.d.ts.map +1 -1
- package/dist/routes/signing-keys.js +3 -1
- package/dist/routes/signing-keys.js.map +1 -1
- package/dist/routes/tenant-access.d.ts +13 -0
- package/dist/routes/tenant-access.d.ts.map +1 -0
- package/dist/routes/tenant-access.js +26 -0
- package/dist/routes/tenant-access.js.map +1 -0
- package/dist/routes/tenant.d.ts.map +1 -1
- package/dist/routes/tenant.js +4 -0
- package/dist/routes/tenant.js.map +1 -1
- package/dist/routes/token-sign-in.d.ts +36 -0
- package/dist/routes/token-sign-in.d.ts.map +1 -0
- package/dist/routes/token-sign-in.js +101 -0
- package/dist/routes/token-sign-in.js.map +1 -0
- package/dist/routes/tokens.d.ts +15 -5
- package/dist/routes/tokens.d.ts.map +1 -1
- package/dist/routes/tokens.js +162 -43
- package/dist/routes/tokens.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +9 -1
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/trigger-access.d.ts +29 -0
- package/dist/routes/trigger-access.d.ts.map +1 -0
- package/dist/routes/trigger-access.js +33 -0
- package/dist/routes/trigger-access.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +2 -1
- package/dist/routes/webhook-endpoints.d.ts.map +1 -1
- package/dist/routes/webhook-endpoints.js +11 -3
- package/dist/routes/webhook-endpoints.js.map +1 -1
- package/dist/routes/webhooks.d.ts +5 -1
- package/dist/routes/webhooks.d.ts.map +1 -1
- package/dist/routes/webhooks.js +25 -2
- package/dist/routes/webhooks.js.map +1 -1
- package/dist/run-failure.d.ts +21 -0
- package/dist/run-failure.d.ts.map +1 -0
- package/dist/run-failure.js +29 -0
- package/dist/run-failure.js.map +1 -0
- package/dist/service-account-binding.d.ts +108 -0
- package/dist/service-account-binding.d.ts.map +1 -0
- package/dist/service-account-binding.js +4 -0
- package/dist/service-account-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +61 -13
- package/dist/session-store-binding.d.ts.map +1 -1
- package/dist/signed-export.d.ts +89 -0
- package/dist/signed-export.d.ts.map +1 -0
- package/dist/signed-export.js +149 -0
- package/dist/signed-export.js.map +1 -0
- package/dist/supervisor-binding.d.ts +186 -413
- package/dist/supervisor-binding.d.ts.map +1 -1
- package/dist/testing/app-bindings.d.ts +33 -0
- package/dist/testing/app-bindings.d.ts.map +1 -0
- package/dist/testing/app-bindings.js +112 -0
- package/dist/testing/app-bindings.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +13 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/stub-binding.d.ts +34 -0
- package/dist/testing/stub-binding.d.ts.map +1 -0
- package/dist/testing/stub-binding.js +42 -0
- package/dist/testing/stub-binding.js.map +1 -0
- package/dist/testing/trigger-registry.d.ts +21 -0
- package/dist/testing/trigger-registry.d.ts.map +1 -0
- package/dist/testing/trigger-registry.js +206 -0
- package/dist/testing/trigger-registry.js.map +1 -0
- package/dist/token-admin.d.ts +46 -8
- package/dist/token-admin.d.ts.map +1 -1
- package/dist/token-admin.js.map +1 -1
- package/dist/tool-binding.d.ts +13 -0
- package/dist/tool-binding.d.ts.map +1 -1
- package/dist/trigger-binding.d.ts +2 -2
- package/dist/trigger-binding.d.ts.map +1 -1
- package/dist/trigger-binding.js +1 -1
- package/dist/trigger-binding.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.d.ts +19 -3
- package/dist/webhook-endpoint-binding.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.js +1 -1
- package/dist/webhook-endpoint-binding.js.map +1 -1
- package/openapi.json +15286 -8653
- package/package.json +26 -22
- package/src/agent-binding.ts +14 -0
- package/src/agent-pins.ts +18 -2
- package/src/app.ts +366 -80
- package/src/block-publish.ts +181 -0
- package/src/caller.ts +62 -0
- package/src/capability-binding.ts +12 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +73 -7
- package/src/eval-case-binding.ts +17 -1
- package/src/eval-run-binding.ts +31 -0
- package/src/eval-run-dispatcher.ts +7 -0
- package/src/eval-sample.ts +42 -0
- package/src/eval-suite-binding.ts +14 -0
- package/src/flow-binding.ts +19 -0
- package/src/flow-pins.ts +18 -2
- package/src/gate.ts +26 -0
- package/src/handler-binding.ts +36 -1
- package/src/hitl-binding.ts +24 -0
- package/src/identity-directory-binding.ts +85 -4
- package/src/identity-provider-binding.ts +216 -21
- package/src/improvement-pass-binding.ts +193 -0
- package/src/index.ts +153 -31
- package/src/judged-dispatcher.ts +78 -11
- package/src/judgment-binding.ts +25 -1
- package/src/mcp-endpoint-binding.ts +7 -0
- package/src/memory-binding.ts +121 -17
- package/src/memory-erasure-binding.ts +156 -0
- package/src/middleware/auth.ts +228 -62
- package/src/middleware/authorize.ts +139 -3
- package/src/middleware/error-mapper.ts +15 -1
- package/src/middleware/idempotency.ts +230 -43
- package/src/middleware/key-project.ts +86 -0
- package/src/middleware/principal.ts +9 -5
- package/src/middleware/project-ref.ts +3 -0
- package/src/openapi/generate.ts +11 -2
- package/src/openapi/operations.ts +1059 -142
- package/src/openapi/schemas.ts +2438 -485
- package/src/person-grants-binding.ts +76 -0
- package/src/proposal-service.ts +640 -0
- package/src/proposal-status.ts +176 -0
- package/src/provider-binding.ts +10 -0
- package/src/publish-refused.ts +38 -9
- package/src/routes/adapters.ts +4 -0
- package/src/routes/agent-releases.ts +121 -69
- package/src/routes/agents.ts +128 -1
- package/src/routes/approvals.ts +164 -154
- package/src/routes/artifacts.ts +181 -11
- package/src/routes/auth.ts +804 -336
- package/src/routes/blocks.ts +2 -53
- package/src/routes/capabilities.ts +10 -1
- package/src/routes/compliance.ts +60 -99
- package/src/routes/conversations.ts +101 -7
- package/src/routes/cost.ts +32 -3
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +62 -16
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +86 -6
- package/src/routes/eval-suites.ts +25 -1
- package/src/routes/event-triggers.ts +27 -3
- package/src/routes/export-signing-keys.ts +31 -0
- package/src/routes/flows.ts +12 -1
- package/src/routes/gate-policies.ts +37 -6
- package/src/routes/guardrails.ts +61 -2
- package/src/routes/identity.ts +328 -10
- package/src/routes/improvement-passes.ts +541 -0
- package/src/routes/judged-suites.ts +113 -43
- package/src/routes/judgment-context.ts +76 -5
- package/src/routes/judgment-flow-context.ts +16 -2
- package/src/routes/judgments.ts +17 -3
- package/src/routes/mcp.ts +29 -1
- package/src/routes/memory-access.ts +179 -0
- package/src/routes/memory-erasures.ts +240 -0
- package/src/routes/memory-parse.ts +250 -0
- package/src/routes/memory.ts +244 -286
- package/src/routes/observations.ts +15 -2
- package/src/routes/pagination.ts +12 -0
- package/src/routes/policies.ts +7 -1
- package/src/routes/project-mismatch.ts +56 -0
- package/src/routes/projects.ts +107 -13
- package/src/routes/proposals.ts +370 -611
- package/src/routes/provenance.ts +99 -133
- package/src/routes/providers.ts +223 -8
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/runs.ts +119 -39
- package/src/routes/schedules.ts +472 -60
- package/src/routes/segments.ts +11 -0
- package/src/routes/service-accounts.ts +262 -0
- package/src/routes/sign-in-options.ts +168 -0
- package/src/routes/signing-keys.ts +7 -1
- package/src/routes/tenant-access.ts +37 -0
- package/src/routes/tenant.ts +6 -0
- package/src/routes/token-sign-in.ts +161 -0
- package/src/routes/tokens.ts +172 -46
- package/src/routes/tools.ts +12 -1
- package/src/routes/trigger-access.ts +72 -0
- package/src/routes/webhook-endpoints.ts +15 -3
- package/src/routes/webhooks.ts +26 -2
- package/src/run-failure.ts +42 -0
- package/src/service-account-binding.ts +113 -0
- package/src/session-store-binding.ts +65 -13
- package/src/signed-export.ts +250 -0
- package/src/supervisor-binding.ts +169 -409
- package/src/testing/app-bindings.ts +142 -0
- package/src/testing/index.ts +21 -0
- package/src/testing/stub-binding.ts +53 -0
- package/src/testing/trigger-registry.ts +259 -0
- package/src/token-admin.ts +40 -8
- package/src/tool-binding.ts +14 -0
- package/src/trigger-binding.ts +8 -1
- package/src/types.ts +16 -0
- package/src/webhook-endpoint-binding.ts +18 -3
package/src/routes/provenance.ts
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
+
import type { Context, Next } from 'hono';
|
|
5
6
|
|
|
6
7
|
import type { ConversationBinding } from '@kindgi/agents';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import type {
|
|
8
|
+
import type { AuditEventBinding } from '@kindgi/audit-events';
|
|
9
|
+
import { ref } from '@kindgi/authz';
|
|
10
|
+
import type { ExportSigningBinding } from '@kindgi/crypto';
|
|
11
|
+
import type { RunBinding } from '@kindgi/runtime';
|
|
12
|
+
import type { ConversationId, RunId, TenantId } from '@kindgi/types';
|
|
11
13
|
|
|
12
14
|
import { statusFor, toWireError } from '../errors.js';
|
|
13
15
|
|
|
16
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
14
17
|
import type {
|
|
15
18
|
CallUsageByCallId,
|
|
16
19
|
ProvenanceBinding,
|
|
@@ -18,9 +21,18 @@ import type {
|
|
|
18
21
|
ProvenanceListCursor,
|
|
19
22
|
ProvenanceRecordSummary,
|
|
20
23
|
} from '../provenance-binding.js';
|
|
24
|
+
import {
|
|
25
|
+
exportActor,
|
|
26
|
+
parseSigningKeyId,
|
|
27
|
+
readExportBody,
|
|
28
|
+
signExport,
|
|
29
|
+
signExportFailure,
|
|
30
|
+
signingNotConfigured,
|
|
31
|
+
} from '../signed-export.js';
|
|
21
32
|
import type { AppEnv } from '../types.js';
|
|
22
33
|
import { clampLimit, decodeCursor, encodeCursor } from './pagination.js';
|
|
23
34
|
import { parseListScope } from './scope-params.js';
|
|
35
|
+
import { UUID_RE } from './uuid-param.js';
|
|
24
36
|
|
|
25
37
|
/**
|
|
26
38
|
* Provenance resource routes.
|
|
@@ -41,25 +53,56 @@ import { parseListScope } from './scope-params.js';
|
|
|
41
53
|
* server round trip.
|
|
42
54
|
*/
|
|
43
55
|
export interface ProvenanceRouterOptions {
|
|
44
|
-
|
|
56
|
+
/** Signs provenance exports. Absent: `POST /:runId/export` answers `404 signing-not-configured`. */
|
|
57
|
+
readonly exportSigning?: ExportSigningBinding;
|
|
58
|
+
/** Records each signed export (`export-signed`). */
|
|
59
|
+
readonly auditEvents?: AuditEventBinding;
|
|
45
60
|
/**
|
|
46
61
|
* Conversation binding used by the signed-export path to read
|
|
47
62
|
* conversation transcripts (`readMessages`) alongside provenance
|
|
48
63
|
* DAGs. Absent = the export omits messages (empty array).
|
|
49
64
|
*/
|
|
50
65
|
readonly conversationBinding?: ConversationBinding;
|
|
66
|
+
/** Where a run's project is read, for the per-run checks (T243 A). */
|
|
67
|
+
readonly runBinding?: RunBinding;
|
|
51
68
|
}
|
|
52
69
|
|
|
53
70
|
/** Bundle schema version — bump when the wire shape of `bundle.body` changes. */
|
|
54
71
|
/** 1.1.0 adds `callUsage`: the model calls' usage from the cost ledger, when the run has any. */
|
|
55
|
-
|
|
72
|
+
/** 1.2.0: `exportedAt` is in the signed body (was the envelope's only). */
|
|
73
|
+
const BUNDLE_SCHEMA_VERSION = '1.2.0';
|
|
56
74
|
|
|
57
75
|
export function provenanceRouter(
|
|
58
76
|
binding: ProvenanceBinding,
|
|
59
77
|
options: ProvenanceRouterOptions = {},
|
|
78
|
+
/**
|
|
79
|
+
* With one (T243 A): a run's provenance (and its export) needs `read`
|
|
80
|
+
* on the run's project; the list holds only records whose project the
|
|
81
|
+
* caller may read (the tenant, for one with no project).
|
|
82
|
+
*/
|
|
83
|
+
authorizer?: Authorizer,
|
|
60
84
|
): Hono<AppEnv> {
|
|
61
85
|
const r = new Hono<AppEnv>();
|
|
62
|
-
|
|
86
|
+
if (authorizer !== undefined) {
|
|
87
|
+
// A run that isn't there is the handler's 404 (`read` on the tenant).
|
|
88
|
+
// An id that isn't a run id is never looked up (its uuid cast would
|
|
89
|
+
// fail the query as a 500).
|
|
90
|
+
const onRunProject = async (c: Context<AppEnv>, next: Next) => {
|
|
91
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
92
|
+
const runId = c.req.param('runId') ?? '';
|
|
93
|
+
const run = UUID_RE.test(runId)
|
|
94
|
+
? await options.runBinding?.getRun(tenantId, runId as RunId)
|
|
95
|
+
: undefined;
|
|
96
|
+
const at =
|
|
97
|
+
run === undefined || run === null
|
|
98
|
+
? ref('tenant', tenantId as unknown as string)
|
|
99
|
+
: ref('project', run.projectId as unknown as string);
|
|
100
|
+
return authorizer.authorize('read', () => at)(c, next);
|
|
101
|
+
};
|
|
102
|
+
r.use('/:runId', async (c, next) => (c.req.method === 'GET' ? onRunProject(c, next) : next()));
|
|
103
|
+
r.use('/:runId/export', onRunProject);
|
|
104
|
+
}
|
|
105
|
+
const exportSigning = options.exportSigning;
|
|
63
106
|
|
|
64
107
|
// ---------- GET / (list metadata, cursor-paginated) ----------
|
|
65
108
|
r.get('/', async (c) => {
|
|
@@ -125,8 +168,16 @@ export function provenanceRouter(
|
|
|
125
168
|
}
|
|
126
169
|
const { records, nextCursor } = result.value;
|
|
127
170
|
const hasMore = nextCursor !== undefined;
|
|
171
|
+
const visible =
|
|
172
|
+
authorizer === undefined
|
|
173
|
+
? records
|
|
174
|
+
: await authorizer.filterByCan(c, 'read', records, (rec) =>
|
|
175
|
+
rec.projectId !== undefined
|
|
176
|
+
? ref('project', rec.projectId as unknown as string)
|
|
177
|
+
: ref('tenant', tenantId as unknown as string),
|
|
178
|
+
);
|
|
128
179
|
return c.json({
|
|
129
|
-
data:
|
|
180
|
+
data: visible.map(serializeRecordMetadata),
|
|
130
181
|
hasMore,
|
|
131
182
|
...(nextCursor !== undefined && {
|
|
132
183
|
nextCursor: encodeCursor({ createdAt: nextCursor.createdAt, id: nextCursor.id }),
|
|
@@ -195,36 +246,10 @@ export function provenanceRouter(
|
|
|
195
246
|
const tenantId = c.get('tenantId') as TenantId;
|
|
196
247
|
const runId = c.req.param('runId') as RunId;
|
|
197
248
|
|
|
198
|
-
if (
|
|
199
|
-
c.status(statusFor('signing-not-configured') as never);
|
|
200
|
-
return c.json(
|
|
201
|
-
toWireError(
|
|
202
|
-
{
|
|
203
|
-
code: 'signing-not-configured',
|
|
204
|
-
message:
|
|
205
|
-
'This deployment does not have a `signingKey` binding mounted; signed provenance exports are unavailable.',
|
|
206
|
-
},
|
|
207
|
-
requestId,
|
|
208
|
-
),
|
|
209
|
-
);
|
|
210
|
-
}
|
|
249
|
+
if (exportSigning === undefined) return signingNotConfigured(c, 'signed provenance exports');
|
|
211
250
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
body = await c.req.json();
|
|
215
|
-
} catch {
|
|
216
|
-
c.status(statusFor('bad-input') as never);
|
|
217
|
-
return c.json(
|
|
218
|
-
toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
if (body === null || typeof body !== 'object' || Array.isArray(body)) {
|
|
222
|
-
c.status(statusFor('bad-input') as never);
|
|
223
|
-
return c.json(
|
|
224
|
-
toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
const parsed = parseExportBody(body as Record<string, unknown>);
|
|
251
|
+
const read = await readExportBody(c);
|
|
252
|
+
const parsed = read.kind === 'ok' ? parseExportBody(read.value) : read;
|
|
228
253
|
if (parsed.kind === 'err') {
|
|
229
254
|
c.status(statusFor('bad-input') as never);
|
|
230
255
|
return c.json(toWireError({ code: 'bad-input', message: parsed.message }, requestId));
|
|
@@ -282,94 +307,43 @@ export function provenanceRouter(
|
|
|
282
307
|
}
|
|
283
308
|
}
|
|
284
309
|
|
|
285
|
-
// 3.
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return c.json(
|
|
290
|
-
toWireError(
|
|
291
|
-
{
|
|
292
|
-
code: 'signing-key-not-found',
|
|
293
|
-
message: `No signing key registered with id "${signingKeyId as unknown as string}"`,
|
|
294
|
-
signingKeyId: signingKeyId as unknown as string,
|
|
295
|
-
},
|
|
296
|
-
requestId,
|
|
297
|
-
),
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
const publicKeyRaw = signingKey.getPublicKey(signingKeyId);
|
|
301
|
-
if (publicKeyRaw === null) {
|
|
302
|
-
// Contract: `getPublicKey` never returns null for a key that
|
|
303
|
-
// `getPrivateKey` resolved. Treat mismatch as a binding bug.
|
|
304
|
-
c.status(statusFor('signing-key-not-found') as never);
|
|
305
|
-
return c.json(
|
|
306
|
-
toWireError(
|
|
307
|
-
{
|
|
308
|
-
code: 'signing-key-not-found',
|
|
309
|
-
message: `Signing key "${signingKeyId as unknown as string}" resolved a private key but no public key`,
|
|
310
|
-
signingKeyId: signingKeyId as unknown as string,
|
|
311
|
-
},
|
|
312
|
-
requestId,
|
|
313
|
-
),
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// 4. Build the canonical bundle body. Bundle shape is v1.0.0 —
|
|
318
|
-
// ordering here is irrelevant for signing (canonicalize sorts
|
|
319
|
-
// keys) but declared explicitly for reviewer scanability.
|
|
320
|
-
const bundleBody = {
|
|
310
|
+
// 3. Sign the bundle body (and record the export).
|
|
311
|
+
const signed = await signExport({
|
|
312
|
+
signer: exportSigning,
|
|
313
|
+
kind: 'provenance',
|
|
321
314
|
bundleSchemaVersion: BUNDLE_SCHEMA_VERSION,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
315
|
+
...(signingKeyId !== undefined && { signingKeyId }),
|
|
316
|
+
body: {
|
|
317
|
+
provenanceId: provenance.id as unknown as string,
|
|
318
|
+
runId: provenance.runId as unknown as string,
|
|
319
|
+
tenantId: provenance.tenantId as unknown as string,
|
|
320
|
+
version: provenance.version,
|
|
321
|
+
createdAt: provenance.createdAt as unknown as string,
|
|
322
|
+
...(provenance.flowRef !== undefined && {
|
|
323
|
+
flowRef: {
|
|
324
|
+
id: provenance.flowRef.id as unknown as string,
|
|
325
|
+
version: provenance.flowRef.version,
|
|
326
|
+
},
|
|
327
|
+
}),
|
|
328
|
+
dag: {
|
|
329
|
+
nodes: provenance.nodes,
|
|
330
|
+
edges: provenance.edges,
|
|
331
331
|
},
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
nodes: provenance.nodes,
|
|
335
|
-
edges: provenance.edges,
|
|
332
|
+
...(messages !== undefined && { messages }),
|
|
333
|
+
...(callUsage.value !== undefined && { callUsage: callUsage.value }),
|
|
336
334
|
},
|
|
337
|
-
...(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return c.json(
|
|
347
|
-
toWireError(
|
|
348
|
-
{
|
|
349
|
-
code: 'export-key-error',
|
|
350
|
-
message: `Failed to sign provenance bundle: ${signResult.error.message}`,
|
|
351
|
-
},
|
|
352
|
-
requestId,
|
|
353
|
-
),
|
|
354
|
-
);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// 6. Emit the signed envelope. `bundle` is a base64 of the exact
|
|
358
|
-
// bytes that were signed — verifiers decode + re-canonicalize
|
|
359
|
-
// is unnecessary, they can verify against `atob(bundle)`
|
|
360
|
-
// directly.
|
|
361
|
-
const exportedAt = new Date().toISOString() as Timestamp;
|
|
362
|
-
return c.json({
|
|
363
|
-
runId: runId as unknown as string,
|
|
364
|
-
bundle: Buffer.from(canonicalBundleBytes).toString('base64'),
|
|
365
|
-
bundleSchemaVersion: BUNDLE_SCHEMA_VERSION,
|
|
366
|
-
algorithm: 'ed25519' as const,
|
|
367
|
-
signingKeyId: signingKeyId as unknown as string,
|
|
368
|
-
signature: Buffer.from(signResult.value).toString('base64'),
|
|
369
|
-
publicKey: serializePublicKeyPem(publicKeyRaw),
|
|
370
|
-
canonicalization: 'sorted-key-json' as const,
|
|
371
|
-
exportedAt: exportedAt as unknown as string,
|
|
335
|
+
...(options.auditEvents !== undefined && {
|
|
336
|
+
record: {
|
|
337
|
+
auditEvents: options.auditEvents,
|
|
338
|
+
tenantId,
|
|
339
|
+
runId: runId as unknown as string,
|
|
340
|
+
actor: exportActor(c),
|
|
341
|
+
subject: { runId: runId as unknown as string },
|
|
342
|
+
},
|
|
343
|
+
}),
|
|
372
344
|
});
|
|
345
|
+
if (signed.kind === 'err') return signExportFailure(c, signed.error, 'export-key-error');
|
|
346
|
+
return c.json({ runId: runId as unknown as string, ...signed.value });
|
|
373
347
|
});
|
|
374
348
|
|
|
375
349
|
return r;
|
|
@@ -407,7 +381,7 @@ function serializeRecordMetadata(row: ProvenanceRecordSummary): RecordMetadata {
|
|
|
407
381
|
}
|
|
408
382
|
|
|
409
383
|
interface ValidatedExportBody {
|
|
410
|
-
readonly signingKeyId:
|
|
384
|
+
readonly signingKeyId: string | undefined;
|
|
411
385
|
readonly includeMessages: boolean;
|
|
412
386
|
}
|
|
413
387
|
|
|
@@ -416,10 +390,8 @@ type ParseResult<T> =
|
|
|
416
390
|
| { readonly kind: 'err'; readonly message: string };
|
|
417
391
|
|
|
418
392
|
function parseExportBody(body: Record<string, unknown>): ParseResult<ValidatedExportBody> {
|
|
419
|
-
const
|
|
420
|
-
if (
|
|
421
|
-
return { kind: 'err', message: 'Field `signingKeyId` must be a non-empty string' };
|
|
422
|
-
}
|
|
393
|
+
const signingKeyId = parseSigningKeyId(body);
|
|
394
|
+
if (signingKeyId.kind === 'err') return signingKeyId;
|
|
423
395
|
let includeMessages = false;
|
|
424
396
|
if ('includeMessages' in body) {
|
|
425
397
|
const im = body.includeMessages;
|
|
@@ -428,13 +400,7 @@ function parseExportBody(body: Record<string, unknown>): ParseResult<ValidatedEx
|
|
|
428
400
|
}
|
|
429
401
|
includeMessages = im;
|
|
430
402
|
}
|
|
431
|
-
return {
|
|
432
|
-
kind: 'ok',
|
|
433
|
-
value: {
|
|
434
|
-
signingKeyId: raw as SigningKeyId,
|
|
435
|
-
includeMessages,
|
|
436
|
-
},
|
|
437
|
-
};
|
|
403
|
+
return { kind: 'ok', value: { signingKeyId: signingKeyId.value, includeMessages } };
|
|
438
404
|
}
|
|
439
405
|
|
|
440
406
|
/** The run's call usage, when the binding has a cost ledger and the run made calls. */
|
package/src/routes/providers.ts
CHANGED
|
@@ -5,19 +5,28 @@ import { Hono } from 'hono';
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
type AdapterConfig,
|
|
8
|
+
type AdapterConfigProblem,
|
|
9
|
+
type AdapterFactoryRegistry,
|
|
8
10
|
FEATURES,
|
|
9
11
|
type Feature,
|
|
10
12
|
type ModelInfo,
|
|
11
13
|
type ProviderMetadata,
|
|
14
|
+
isModelThinking,
|
|
12
15
|
validateProviderLabels,
|
|
13
16
|
} from '@kindgi/capabilities';
|
|
14
17
|
import type { Cursor, TenantId } from '@kindgi/types';
|
|
15
18
|
|
|
16
19
|
import type { CapabilityDescriptor } from '../capability-binding.js';
|
|
17
20
|
import { statusFor, toWireError } from '../errors.js';
|
|
18
|
-
import type {
|
|
21
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
22
|
+
import type {
|
|
23
|
+
ProviderRegistryBinding,
|
|
24
|
+
ProviderRuntimeEntry,
|
|
25
|
+
ProviderSecretRef,
|
|
26
|
+
} from '../provider-binding.js';
|
|
19
27
|
import type { AppEnv } from '../types.js';
|
|
20
28
|
import { clampLimit } from './pagination.js';
|
|
29
|
+
import { tenantResourceAccess } from './tenant-access.js';
|
|
21
30
|
|
|
22
31
|
/**
|
|
23
32
|
* Providers resource routes — part of the admin control plane. Full
|
|
@@ -46,11 +55,20 @@ export type ProviderWriteHook = (params: {
|
|
|
46
55
|
readonly kind: 'register' | 'unregister';
|
|
47
56
|
}) => void | Promise<void>;
|
|
48
57
|
|
|
58
|
+
/**
|
|
59
|
+
* `factories`: the deployment's in-process adapter factories. With them, a
|
|
60
|
+
* registration is checked against its adapter's `checkConfig` before it's
|
|
61
|
+
* stored, and `GET /:providerId/check` answers for a registered one.
|
|
62
|
+
* Without them, registration takes any flat `adapter_config`.
|
|
63
|
+
*/
|
|
49
64
|
export function providersRouter(
|
|
50
65
|
binding: ProviderRegistryBinding,
|
|
51
66
|
onWrite?: ProviderWriteHook,
|
|
67
|
+
factories?: AdapterFactoryRegistry,
|
|
68
|
+
authorizer?: Authorizer,
|
|
52
69
|
): Hono<AppEnv> {
|
|
53
70
|
const r = new Hono<AppEnv>();
|
|
71
|
+
r.use('*', tenantResourceAccess(authorizer));
|
|
54
72
|
|
|
55
73
|
// ---------- GET / (list, cursor-paginated) ----------
|
|
56
74
|
r.get('/', async (c) => {
|
|
@@ -151,12 +169,15 @@ export function providersRouter(
|
|
|
151
169
|
// runtime bridge),
|
|
152
170
|
// "adapter_config": { … } (optional — the adapter's flat,
|
|
153
171
|
// non-secret connection settings)
|
|
172
|
+
// "send_traceparent": boolean (optional — send each call's
|
|
173
|
+
// traceparent to the provider)
|
|
154
174
|
// }
|
|
155
175
|
const bodyObj = body as {
|
|
156
176
|
readonly metadata?: unknown;
|
|
157
177
|
readonly adapter_id?: unknown;
|
|
158
178
|
readonly secret_ref?: unknown;
|
|
159
179
|
readonly adapter_config?: unknown;
|
|
180
|
+
readonly send_traceparent?: unknown;
|
|
160
181
|
};
|
|
161
182
|
if (bodyObj.metadata === undefined) {
|
|
162
183
|
c.status(statusFor('bad-input') as never);
|
|
@@ -216,12 +237,38 @@ export function providersRouter(
|
|
|
216
237
|
);
|
|
217
238
|
}
|
|
218
239
|
|
|
240
|
+
// The registration's own fields first, then the adapter's check of what
|
|
241
|
+
// it'll be built from: refused now, naming the field, instead of skipped
|
|
242
|
+
// at the first model call. One answer lists them all.
|
|
243
|
+
const sendTraceparent = bodyObj.send_traceparent;
|
|
244
|
+
const adapterProblems = configProblems(factories, {
|
|
245
|
+
metadata: validation.value,
|
|
246
|
+
adapterId: bodyObj.adapter_id,
|
|
247
|
+
...(secretRefResult.value !== undefined && { secretRef: secretRefResult.value }),
|
|
248
|
+
...(adapterConfigResult.value !== undefined && { adapterConfig: adapterConfigResult.value }),
|
|
249
|
+
});
|
|
250
|
+
const problems = [...registrationProblems(bodyObj), ...(adapterProblems ?? [])];
|
|
251
|
+
if (problems.length > 0) {
|
|
252
|
+
c.status(statusFor('provider-config-invalid') as never);
|
|
253
|
+
return c.json(
|
|
254
|
+
toWireError(
|
|
255
|
+
{
|
|
256
|
+
code: 'provider-config-invalid',
|
|
257
|
+
message: refusalOf(validation.value.id, bodyObj.adapter_id, problems),
|
|
258
|
+
issues: problems,
|
|
259
|
+
},
|
|
260
|
+
requestId,
|
|
261
|
+
),
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
219
265
|
const outcome = await binding.register({
|
|
220
266
|
tenantId,
|
|
221
267
|
metadata: validation.value,
|
|
222
268
|
adapterId: bodyObj.adapter_id,
|
|
223
269
|
...(secretRefResult.value !== undefined && { secretRef: secretRefResult.value }),
|
|
224
270
|
...(adapterConfigResult.value !== undefined && { adapterConfig: adapterConfigResult.value }),
|
|
271
|
+
...(typeof sendTraceparent === 'boolean' && { sendTraceparent }),
|
|
225
272
|
});
|
|
226
273
|
if (outcome.kind === 'already-registered') {
|
|
227
274
|
c.status(statusFor('provider-already-registered') as never);
|
|
@@ -264,6 +311,31 @@ export function providersRouter(
|
|
|
264
311
|
return c.json({ providerId: outcome.providerId });
|
|
265
312
|
});
|
|
266
313
|
|
|
314
|
+
// ---------- GET /:providerId/check ----------
|
|
315
|
+
r.get('/:providerId/check', async (c) => {
|
|
316
|
+
const requestId = c.get('requestId');
|
|
317
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
318
|
+
const providerId = c.req.param('providerId');
|
|
319
|
+
const entries = await binding.resolveForRuntime({ tenantId });
|
|
320
|
+
const entry = entries.find((e) => e.metadata.id === providerId);
|
|
321
|
+
if (entry === undefined) {
|
|
322
|
+
c.status(statusFor('provider-not-found') as never);
|
|
323
|
+
return c.json(
|
|
324
|
+
toWireError(
|
|
325
|
+
{ code: 'provider-not-found', message: `Provider "${providerId}" not found`, providerId },
|
|
326
|
+
requestId,
|
|
327
|
+
),
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
const problems = configProblems(factories, entry);
|
|
331
|
+
return c.json({
|
|
332
|
+
providerId,
|
|
333
|
+
adapterId: entry.adapterId,
|
|
334
|
+
checked: problems !== undefined,
|
|
335
|
+
issues: problems ?? [],
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
267
339
|
// ---------- POST /:providerId/unregister ----------
|
|
268
340
|
r.post('/:providerId/unregister', async (c) => {
|
|
269
341
|
const requestId = c.get('requestId');
|
|
@@ -305,14 +377,15 @@ function serializeProvider(m: ProviderMetadata): Record<string, unknown> {
|
|
|
305
377
|
name: model.name,
|
|
306
378
|
contextWindow: model.contextWindow,
|
|
307
379
|
features: model.features,
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
completionUsdPer1kTokens: model.cost.completionUsdPer1kTokens,
|
|
311
|
-
},
|
|
380
|
+
// As stored: the base rates and any an adapter widens it with.
|
|
381
|
+
cost: { ...model.cost },
|
|
312
382
|
...(model.p95LatencyMs !== undefined && { p95LatencyMs: model.p95LatencyMs }),
|
|
313
383
|
...(model.maxOutputTokens !== undefined && { maxOutputTokens: model.maxOutputTokens }),
|
|
384
|
+
...(model.sampling !== undefined && { sampling: model.sampling }),
|
|
385
|
+
...(model.thinking !== undefined && { thinking: model.thinking }),
|
|
314
386
|
...(model.description !== undefined && { description: model.description }),
|
|
315
387
|
})),
|
|
388
|
+
...(m.defaultModel !== undefined && { defaultModel: m.defaultModel }),
|
|
316
389
|
...(m.attributes !== undefined && { attributes: m.attributes }),
|
|
317
390
|
...(m.description !== undefined && { description: m.description }),
|
|
318
391
|
...(m.capabilityKind !== undefined && { capabilityKind: m.capabilityKind }),
|
|
@@ -328,6 +401,9 @@ function serializeCapability(d: CapabilityDescriptor): Record<string, unknown> {
|
|
|
328
401
|
description: d.description,
|
|
329
402
|
...(d.kind !== undefined && { kind: d.kind }),
|
|
330
403
|
...(d.paramsSchema !== undefined && { paramsSchema: d.paramsSchema }),
|
|
404
|
+
...(d.providers !== undefined && {
|
|
405
|
+
providers: d.providers.map((p) => ({ providerId: p.providerId, models: [...p.models] })),
|
|
406
|
+
}),
|
|
331
407
|
};
|
|
332
408
|
}
|
|
333
409
|
|
|
@@ -436,10 +512,20 @@ function validateProviderMetadata(
|
|
|
436
512
|
}
|
|
437
513
|
const badLabels = validateProviderLabels(b.id, b.labels);
|
|
438
514
|
if (badLabels !== undefined) return { kind: 'err', error: badLabels };
|
|
515
|
+
if (b.defaultModel !== undefined && !seenNames.has(b.defaultModel as string)) {
|
|
516
|
+
return {
|
|
517
|
+
kind: 'err',
|
|
518
|
+
error: {
|
|
519
|
+
message: `provider "${b.id}" defaultModel must be one of its models (${[...seenNames].join(', ')}), got ${JSON.stringify(b.defaultModel)}`,
|
|
520
|
+
reason: 'unknown-default-model',
|
|
521
|
+
},
|
|
522
|
+
};
|
|
523
|
+
}
|
|
439
524
|
const value: ProviderMetadata = {
|
|
440
525
|
id: b.id,
|
|
441
526
|
region: b.region,
|
|
442
527
|
models: validatedModels,
|
|
528
|
+
...(b.defaultModel !== undefined && { defaultModel: b.defaultModel as string }),
|
|
443
529
|
...(b.attributes !== undefined && { attributes: b.attributes as readonly string[] }),
|
|
444
530
|
...(b.description !== undefined && { description: b.description }),
|
|
445
531
|
...(b.capabilityKind !== undefined && { capabilityKind: b.capabilityKind as string }),
|
|
@@ -527,6 +613,16 @@ function validateModelInfo(
|
|
|
527
613
|
},
|
|
528
614
|
};
|
|
529
615
|
}
|
|
616
|
+
const extraRates = costExtraRates(cost as unknown as Record<string, unknown>);
|
|
617
|
+
if (extraRates === undefined) {
|
|
618
|
+
return {
|
|
619
|
+
kind: 'err',
|
|
620
|
+
error: {
|
|
621
|
+
message: `provider "${providerId}" model "${m.name}" cost table's other rates must be non-negative numbers, or objects of them (e.g. longContext: { thresholdTokens, promptUsdPer1kTokens, completionUsdPer1kTokens })`,
|
|
622
|
+
reason: 'invalid-cost',
|
|
623
|
+
},
|
|
624
|
+
};
|
|
625
|
+
}
|
|
530
626
|
if (m.p95LatencyMs !== undefined) {
|
|
531
627
|
if (typeof m.p95LatencyMs !== 'number' || m.p95LatencyMs < 0) {
|
|
532
628
|
return {
|
|
@@ -553,6 +649,24 @@ function validateModelInfo(
|
|
|
553
649
|
};
|
|
554
650
|
}
|
|
555
651
|
}
|
|
652
|
+
if (m.sampling !== undefined && typeof m.sampling !== 'boolean') {
|
|
653
|
+
return {
|
|
654
|
+
kind: 'err',
|
|
655
|
+
error: {
|
|
656
|
+
message: `provider "${providerId}" model "${m.name}" sampling must be true or false`,
|
|
657
|
+
reason: 'invalid-sampling',
|
|
658
|
+
},
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
if (m.thinking !== undefined && !isModelThinking(m.thinking)) {
|
|
662
|
+
return {
|
|
663
|
+
kind: 'err',
|
|
664
|
+
error: {
|
|
665
|
+
message: `provider "${providerId}" model "${m.name}" thinking must be { mode: 'adaptive' | 'always', lowest: <the vendor's setting> }`,
|
|
666
|
+
reason: 'invalid-thinking',
|
|
667
|
+
},
|
|
668
|
+
};
|
|
669
|
+
}
|
|
556
670
|
if (m.description !== undefined && typeof m.description !== 'string') {
|
|
557
671
|
return {
|
|
558
672
|
kind: 'err',
|
|
@@ -567,21 +681,122 @@ function validateModelInfo(
|
|
|
567
681
|
contextWindow: m.contextWindow,
|
|
568
682
|
features: m.features as readonly Feature[],
|
|
569
683
|
cost: {
|
|
684
|
+
...extraRates,
|
|
570
685
|
promptUsdPer1kTokens: cost.promptUsdPer1kTokens,
|
|
571
686
|
completionUsdPer1kTokens: cost.completionUsdPer1kTokens,
|
|
572
|
-
},
|
|
687
|
+
} as ModelInfo['cost'],
|
|
573
688
|
...(m.p95LatencyMs !== undefined && { p95LatencyMs: m.p95LatencyMs }),
|
|
574
689
|
...(m.maxOutputTokens !== undefined && { maxOutputTokens: m.maxOutputTokens }),
|
|
690
|
+
...(m.sampling !== undefined && { sampling: m.sampling }),
|
|
691
|
+
...(m.thinking !== undefined && {
|
|
692
|
+
thinking: { mode: m.thinking.mode, lowest: m.thinking.lowest },
|
|
693
|
+
}),
|
|
575
694
|
...(m.description !== undefined && { description: m.description }),
|
|
576
695
|
};
|
|
577
696
|
return { kind: 'ok', value };
|
|
578
697
|
}
|
|
579
698
|
|
|
699
|
+
/**
|
|
700
|
+
* The rates a cost table carries beyond the two base ones: an adapter
|
|
701
|
+
* widens it with its own (Anthropic's prompt-cache multipliers, Gemini's
|
|
702
|
+
* cached-prompt share, a long-context tier), each a non-negative number
|
|
703
|
+
* or one level of an object of them. Returned as given, or `undefined`
|
|
704
|
+
* when one isn't, so a registration keeps what its adapter prices with.
|
|
705
|
+
*/
|
|
706
|
+
function costExtraRates(
|
|
707
|
+
cost: Readonly<Record<string, unknown>>,
|
|
708
|
+
): Record<string, number | Record<string, number>> | undefined {
|
|
709
|
+
const isRate = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0;
|
|
710
|
+
const out: Record<string, number | Record<string, number>> = {};
|
|
711
|
+
for (const [key, value] of Object.entries(cost)) {
|
|
712
|
+
if (key === 'promptUsdPer1kTokens' || key === 'completionUsdPer1kTokens') continue;
|
|
713
|
+
if (isRate(value)) {
|
|
714
|
+
out[key] = value;
|
|
715
|
+
} else if (
|
|
716
|
+
typeof value === 'object' &&
|
|
717
|
+
value !== null &&
|
|
718
|
+
!Array.isArray(value) &&
|
|
719
|
+
Object.keys(value).length > 0 &&
|
|
720
|
+
Object.values(value).every(isRate)
|
|
721
|
+
) {
|
|
722
|
+
out[key] = { ...(value as Record<string, number>) };
|
|
723
|
+
} else {
|
|
724
|
+
return undefined;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return out;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* What's wrong with a registration, by its adapter's own static check
|
|
732
|
+
* (`AdapterFactoryEntry.checkConfig`): no network, no secret read.
|
|
733
|
+
* `undefined` when there's nothing to check it with (no factories wired, or
|
|
734
|
+
* an adapter without a check). An adapter the deployment doesn't have is a
|
|
735
|
+
* problem: the runtime could never build the provider.
|
|
736
|
+
*/
|
|
737
|
+
function configProblems(
|
|
738
|
+
factories: AdapterFactoryRegistry | undefined,
|
|
739
|
+
registration: ProviderRuntimeEntry,
|
|
740
|
+
): readonly AdapterConfigProblem[] | undefined {
|
|
741
|
+
if (factories === undefined) return undefined;
|
|
742
|
+
const entry = factories.get(registration.adapterId);
|
|
743
|
+
if (entry === undefined) {
|
|
744
|
+
return [
|
|
745
|
+
{
|
|
746
|
+
path: '/adapter_id',
|
|
747
|
+
message: `This runtime has no adapter "${registration.adapterId}", so it can't build provider "${registration.metadata.id}".`,
|
|
748
|
+
},
|
|
749
|
+
];
|
|
750
|
+
}
|
|
751
|
+
return entry.checkConfig?.({
|
|
752
|
+
metadata: registration.metadata,
|
|
753
|
+
...(registration.adapterConfig !== undefined && { config: registration.adapterConfig }),
|
|
754
|
+
hasSecretRef: registration.secretRef !== undefined,
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* What's wrong with the registration's own fields, before its adapter's:
|
|
760
|
+
* `send_traceparent`, when present, is a boolean. The runtime, not the
|
|
761
|
+
* adapter, reads it.
|
|
762
|
+
*/
|
|
763
|
+
export function registrationProblems(body: {
|
|
764
|
+
readonly send_traceparent?: unknown;
|
|
765
|
+
}): readonly AdapterConfigProblem[] {
|
|
766
|
+
const value = body.send_traceparent;
|
|
767
|
+
return value === undefined || typeof value === 'boolean'
|
|
768
|
+
? []
|
|
769
|
+
: [{ path: '/send_traceparent', message: 'send_traceparent must be true or false.' }];
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* The 422's message: one sentence naming the provider, its adapter and the
|
|
774
|
+
* first problem, with a count of the rest (`details.issues` lists each).
|
|
775
|
+
* A problem with the registration's own fields names the provider alone.
|
|
776
|
+
*/
|
|
777
|
+
function refusalOf(
|
|
778
|
+
providerId: string,
|
|
779
|
+
adapterId: string,
|
|
780
|
+
problems: readonly AdapterConfigProblem[],
|
|
781
|
+
): string {
|
|
782
|
+
const [first, ...rest] = problems;
|
|
783
|
+
if (first === undefined) return `Provider "${providerId}" doesn't fit adapter ${adapterId}.`;
|
|
784
|
+
if (first.path === '/adapter_id') return first.message;
|
|
785
|
+
const more = rest.length > 0 ? ` (and ${rest.length} more)` : '';
|
|
786
|
+
const what = first.message.replace(/\.$/, '');
|
|
787
|
+
return REGISTRATION_PATHS.has(first.path)
|
|
788
|
+
? `Provider "${providerId}": ${what}${more}.`
|
|
789
|
+
: `Provider "${providerId}" doesn't fit adapter ${adapterId}: ${what}${more}.`;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/** The paths `registrationProblems` reports: the registration's own fields, not its adapter's. */
|
|
793
|
+
const REGISTRATION_PATHS: ReadonlySet<string> = new Set(['/send_traceparent']);
|
|
794
|
+
|
|
580
795
|
/**
|
|
581
796
|
* Parse the optional `adapter_config` on the register request body: a
|
|
582
797
|
* flat object of string, number or boolean values. Credentials don't
|
|
583
|
-
* belong here (they ride on `secret_ref`); the adapter
|
|
584
|
-
*
|
|
798
|
+
* belong here (they ride on `secret_ref`); the adapter checks its own keys
|
|
799
|
+
* (`configProblems`).
|
|
585
800
|
*/
|
|
586
801
|
function parseAdapterConfig(
|
|
587
802
|
raw: unknown,
|