@kindgi/api 0.1.4 → 0.1.5
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/cost-binding.d.ts +19 -0
- package/dist/cost-binding.d.ts.map +1 -1
- package/dist/cost-binding.js.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 +75 -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 +9 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +122 -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 +919 -140
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +90 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2081 -359
- 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 +28 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +24 -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 +12 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +74 -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 +10 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +171 -13
- 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 +66 -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 +28 -2
- 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 +114 -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 +110 -3
- 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/readable-projects.d.ts +26 -0
- package/dist/routes/readable-projects.d.ts.map +1 -0
- package/dist/routes/readable-projects.js +39 -0
- package/dist/routes/readable-projects.js.map +1 -0
- 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 +15387 -8789
- 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/cost-binding.ts +19 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +75 -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 +155 -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 +1060 -143
- package/src/openapi/schemas.ts +2387 -469
- 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 +56 -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 +110 -4
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +210 -17
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +89 -6
- package/src/routes/eval-suites.ts +32 -2
- 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 +160 -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 +142 -3
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/readable-projects.ts +66 -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,6 +5,8 @@ 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,
|
|
@@ -16,9 +18,15 @@ import type { Cursor, TenantId } from '@kindgi/types';
|
|
|
16
18
|
|
|
17
19
|
import type { CapabilityDescriptor } from '../capability-binding.js';
|
|
18
20
|
import { statusFor, toWireError } from '../errors.js';
|
|
19
|
-
import type {
|
|
21
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
22
|
+
import type {
|
|
23
|
+
ProviderRegistryBinding,
|
|
24
|
+
ProviderRuntimeEntry,
|
|
25
|
+
ProviderSecretRef,
|
|
26
|
+
} from '../provider-binding.js';
|
|
20
27
|
import type { AppEnv } from '../types.js';
|
|
21
28
|
import { clampLimit } from './pagination.js';
|
|
29
|
+
import { tenantResourceAccess } from './tenant-access.js';
|
|
22
30
|
|
|
23
31
|
/**
|
|
24
32
|
* Providers resource routes — part of the admin control plane. Full
|
|
@@ -47,11 +55,20 @@ export type ProviderWriteHook = (params: {
|
|
|
47
55
|
readonly kind: 'register' | 'unregister';
|
|
48
56
|
}) => void | Promise<void>;
|
|
49
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
|
+
*/
|
|
50
64
|
export function providersRouter(
|
|
51
65
|
binding: ProviderRegistryBinding,
|
|
52
66
|
onWrite?: ProviderWriteHook,
|
|
67
|
+
factories?: AdapterFactoryRegistry,
|
|
68
|
+
authorizer?: Authorizer,
|
|
53
69
|
): Hono<AppEnv> {
|
|
54
70
|
const r = new Hono<AppEnv>();
|
|
71
|
+
r.use('*', tenantResourceAccess(authorizer));
|
|
55
72
|
|
|
56
73
|
// ---------- GET / (list, cursor-paginated) ----------
|
|
57
74
|
r.get('/', async (c) => {
|
|
@@ -152,12 +169,15 @@ export function providersRouter(
|
|
|
152
169
|
// runtime bridge),
|
|
153
170
|
// "adapter_config": { … } (optional — the adapter's flat,
|
|
154
171
|
// non-secret connection settings)
|
|
172
|
+
// "send_traceparent": boolean (optional — send each call's
|
|
173
|
+
// traceparent to the provider)
|
|
155
174
|
// }
|
|
156
175
|
const bodyObj = body as {
|
|
157
176
|
readonly metadata?: unknown;
|
|
158
177
|
readonly adapter_id?: unknown;
|
|
159
178
|
readonly secret_ref?: unknown;
|
|
160
179
|
readonly adapter_config?: unknown;
|
|
180
|
+
readonly send_traceparent?: unknown;
|
|
161
181
|
};
|
|
162
182
|
if (bodyObj.metadata === undefined) {
|
|
163
183
|
c.status(statusFor('bad-input') as never);
|
|
@@ -217,12 +237,38 @@ export function providersRouter(
|
|
|
217
237
|
);
|
|
218
238
|
}
|
|
219
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
|
+
|
|
220
265
|
const outcome = await binding.register({
|
|
221
266
|
tenantId,
|
|
222
267
|
metadata: validation.value,
|
|
223
268
|
adapterId: bodyObj.adapter_id,
|
|
224
269
|
...(secretRefResult.value !== undefined && { secretRef: secretRefResult.value }),
|
|
225
270
|
...(adapterConfigResult.value !== undefined && { adapterConfig: adapterConfigResult.value }),
|
|
271
|
+
...(typeof sendTraceparent === 'boolean' && { sendTraceparent }),
|
|
226
272
|
});
|
|
227
273
|
if (outcome.kind === 'already-registered') {
|
|
228
274
|
c.status(statusFor('provider-already-registered') as never);
|
|
@@ -265,6 +311,31 @@ export function providersRouter(
|
|
|
265
311
|
return c.json({ providerId: outcome.providerId });
|
|
266
312
|
});
|
|
267
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
|
+
|
|
268
339
|
// ---------- POST /:providerId/unregister ----------
|
|
269
340
|
r.post('/:providerId/unregister', async (c) => {
|
|
270
341
|
const requestId = c.get('requestId');
|
|
@@ -330,6 +401,9 @@ function serializeCapability(d: CapabilityDescriptor): Record<string, unknown> {
|
|
|
330
401
|
description: d.description,
|
|
331
402
|
...(d.kind !== undefined && { kind: d.kind }),
|
|
332
403
|
...(d.paramsSchema !== undefined && { paramsSchema: d.paramsSchema }),
|
|
404
|
+
...(d.providers !== undefined && {
|
|
405
|
+
providers: d.providers.map((p) => ({ providerId: p.providerId, models: [...p.models] })),
|
|
406
|
+
}),
|
|
333
407
|
};
|
|
334
408
|
}
|
|
335
409
|
|
|
@@ -653,11 +727,76 @@ function costExtraRates(
|
|
|
653
727
|
return out;
|
|
654
728
|
}
|
|
655
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
|
+
|
|
656
795
|
/**
|
|
657
796
|
* Parse the optional `adapter_config` on the register request body: a
|
|
658
797
|
* flat object of string, number or boolean values. Credentials don't
|
|
659
|
-
* belong here (they ride on `secret_ref`); the adapter
|
|
660
|
-
*
|
|
798
|
+
* belong here (they ride on `secret_ref`); the adapter checks its own keys
|
|
799
|
+
* (`configProblems`).
|
|
661
800
|
*/
|
|
662
801
|
function parseAdapterConfig(
|
|
663
802
|
raw: unknown,
|
|
@@ -9,6 +9,7 @@ import type { RunId, TenantId } from '@kindgi/types';
|
|
|
9
9
|
|
|
10
10
|
import { statusFor, toWireError } from '../errors.js';
|
|
11
11
|
import type { Authorizer } from '../middleware/authorize.js';
|
|
12
|
+
import { withholdFromReplay } from '../middleware/idempotency.js';
|
|
12
13
|
import { MAX_PUBLIC_RUN_TOKEN_RUNS, type MintPublicRunTokenResult } from '../public-run-token.js';
|
|
13
14
|
import type { AppEnv } from '../types.js';
|
|
14
15
|
|
|
@@ -92,6 +93,8 @@ export function publicRunTokensRouter(
|
|
|
92
93
|
|
|
93
94
|
const minted = issuer.mint(tenantId, unique, ttl as number);
|
|
94
95
|
if (minted.kind === 'err') return error('token-mint-failed', minted.message);
|
|
96
|
+
// The token is shown once: an Idempotency-Key repeat doesn't get it.
|
|
97
|
+
withholdFromReplay(c);
|
|
95
98
|
c.status(201);
|
|
96
99
|
return c.json({
|
|
97
100
|
token: minted.token,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The projects a caller may act on, for a route that hands them to its
|
|
6
|
+
* binding to apply inside the query (memory reads, the cost aggregate)
|
|
7
|
+
* rather than filtering a page after it: the authorizer's list when it can
|
|
8
|
+
* list (`listObjects`), else the tenant's projects checked one by one.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { Context } from 'hono';
|
|
12
|
+
|
|
13
|
+
import { type Action, ref } from '@kindgi/authz';
|
|
14
|
+
import type { ProjectBinding } from '@kindgi/platform';
|
|
15
|
+
import type { OrgId, ProjectId, TenantId } from '@kindgi/types';
|
|
16
|
+
|
|
17
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
18
|
+
import type { AppEnv } from '../types.js';
|
|
19
|
+
|
|
20
|
+
const PROJECT_PAGE = 200;
|
|
21
|
+
|
|
22
|
+
export type ProjectRow = { readonly id: ProjectId; readonly orgId?: OrgId };
|
|
23
|
+
|
|
24
|
+
/** The tenant's projects, every page; none without a project binding. */
|
|
25
|
+
export async function allProjects(
|
|
26
|
+
c: Context<AppEnv>,
|
|
27
|
+
projects: Pick<ProjectBinding, 'list'> | undefined,
|
|
28
|
+
): Promise<ProjectRow[]> {
|
|
29
|
+
if (projects === undefined) return [];
|
|
30
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
31
|
+
const all: ProjectRow[] = [];
|
|
32
|
+
let cursor: Parameters<ProjectBinding['list']>[1]['cursor'];
|
|
33
|
+
for (;;) {
|
|
34
|
+
const page = await projects.list(tenantId, {
|
|
35
|
+
limit: PROJECT_PAGE,
|
|
36
|
+
...(cursor !== undefined && { cursor }),
|
|
37
|
+
});
|
|
38
|
+
all.push(
|
|
39
|
+
...page.items.map((p) => ({ id: p.id, ...(p.orgId !== undefined && { orgId: p.orgId }) })),
|
|
40
|
+
);
|
|
41
|
+
if (page.nextCursor === undefined) break;
|
|
42
|
+
cursor = page.nextCursor;
|
|
43
|
+
}
|
|
44
|
+
return all;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The ids of the projects the caller may `action`: listed by the
|
|
49
|
+
* authorizer, else the tenant's projects checked one by one. `undefined`
|
|
50
|
+
* when neither can say (the authorizer can't list, and there's no project
|
|
51
|
+
* binding to check against).
|
|
52
|
+
*/
|
|
53
|
+
export async function projectIdsCallerMay(
|
|
54
|
+
c: Context<AppEnv>,
|
|
55
|
+
authorizer: Authorizer,
|
|
56
|
+
projects: Pick<ProjectBinding, 'list'> | undefined,
|
|
57
|
+
action: Action,
|
|
58
|
+
): Promise<ProjectId[] | undefined> {
|
|
59
|
+
const listed = await authorizer.listObjects?.(c, action, 'project');
|
|
60
|
+
if (listed !== undefined) return listed.map((id) => id as ProjectId);
|
|
61
|
+
if (projects === undefined) return undefined;
|
|
62
|
+
const may = await authorizer.filterByCan(c, action, await allProjects(c, projects), (p) =>
|
|
63
|
+
ref('project', p.id as unknown as string),
|
|
64
|
+
);
|
|
65
|
+
return may.map((p) => p.id);
|
|
66
|
+
}
|