@kindgi/api 0.1.4 → 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 +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 +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 +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/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 +15385 -8788
- 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 +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 +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 +142 -3
- 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
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
|
|
4
|
+
import type { EvalRun, EvalRunStatus } from './eval-run-binding.js';
|
|
5
|
+
import type { JudgedComparisonSummary } from './judged-dispatcher.js';
|
|
6
|
+
import type { Promotion } from './live-version-binding.js';
|
|
7
|
+
import type { ProposalObjective, StoredProposal } from './supervisor-binding.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Where an improvement proposal stands. Never stored: it follows from the
|
|
11
|
+
* proposal's own steps, its comparison eval run and its promotion.
|
|
12
|
+
*
|
|
13
|
+
* - `draft`: not evaluated yet.
|
|
14
|
+
* - `evaluating`: its comparison is queued or running.
|
|
15
|
+
* - `evaluated`: the comparison finished and the candidate beat the
|
|
16
|
+
* recorded outputs on the objective metric by more than the noise.
|
|
17
|
+
* - `not-better`: the comparison finished; the candidate didn't.
|
|
18
|
+
* - `evaluation-failed`: the comparison failed or was cancelled.
|
|
19
|
+
* - `in-review`: requested; the gate passed and an approval is open.
|
|
20
|
+
* - `promoted`: the candidate went live for the scope.
|
|
21
|
+
* - `refused`: requested; the gate refused it.
|
|
22
|
+
* - `rejected`: the reviewer rejected it.
|
|
23
|
+
* - `expired`: the approval expired undecided.
|
|
24
|
+
* - `superseded`: approved after the scope's live version or policy changed.
|
|
25
|
+
* - `rolled-back`: rolled back through the proposal.
|
|
26
|
+
* - `withdrawn`: withdrawn.
|
|
27
|
+
*/
|
|
28
|
+
export type FixProposalStatus =
|
|
29
|
+
| 'draft'
|
|
30
|
+
| 'evaluating'
|
|
31
|
+
| 'evaluated'
|
|
32
|
+
| 'not-better'
|
|
33
|
+
| 'evaluation-failed'
|
|
34
|
+
| 'in-review'
|
|
35
|
+
| 'promoted'
|
|
36
|
+
| 'refused'
|
|
37
|
+
| 'rejected'
|
|
38
|
+
| 'expired'
|
|
39
|
+
| 'superseded'
|
|
40
|
+
| 'rolled-back'
|
|
41
|
+
| 'withdrawn';
|
|
42
|
+
|
|
43
|
+
export const FIX_PROPOSAL_STATUSES: readonly FixProposalStatus[] = [
|
|
44
|
+
'draft',
|
|
45
|
+
'evaluating',
|
|
46
|
+
'evaluated',
|
|
47
|
+
'not-better',
|
|
48
|
+
'evaluation-failed',
|
|
49
|
+
'in-review',
|
|
50
|
+
'promoted',
|
|
51
|
+
'refused',
|
|
52
|
+
'rejected',
|
|
53
|
+
'expired',
|
|
54
|
+
'superseded',
|
|
55
|
+
'rolled-back',
|
|
56
|
+
'withdrawn',
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
/** What a finished comparison says about the candidate, on the proposal's objective. */
|
|
60
|
+
export interface ProposalEvaluationOutcome {
|
|
61
|
+
readonly runStatus: EvalRunStatus;
|
|
62
|
+
readonly objective: ProposalObjective;
|
|
63
|
+
/** The recorded (judged) outputs' score. `null` without judged evidence. */
|
|
64
|
+
readonly baseline?: number | null;
|
|
65
|
+
readonly candidate?: number | null;
|
|
66
|
+
readonly delta?: number | null;
|
|
67
|
+
/** With more than one repetition: the candidate's max − min. The noise a delta must beat. */
|
|
68
|
+
readonly spread?: number;
|
|
69
|
+
readonly cases?: number;
|
|
70
|
+
/** Set once the comparison finished. */
|
|
71
|
+
readonly better?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Room for float rounding. */
|
|
75
|
+
const EPSILON = 1e-9;
|
|
76
|
+
|
|
77
|
+
/** A finished comparison's summary, or `null` for any other eval run. */
|
|
78
|
+
export function comparisonSummaryOf(run: EvalRun): JudgedComparisonSummary | null {
|
|
79
|
+
const summary = run.result?.summary;
|
|
80
|
+
return run.kind === 'judged' && summary !== null && typeof summary === 'object'
|
|
81
|
+
? (summary as JudgedComparisonSummary)
|
|
82
|
+
: null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The proposal's evaluation, read off its eval run. */
|
|
86
|
+
export function evaluationOutcome(
|
|
87
|
+
objective: ProposalObjective,
|
|
88
|
+
run: EvalRun,
|
|
89
|
+
): ProposalEvaluationOutcome {
|
|
90
|
+
const summary = run.status === 'completed' ? comparisonSummaryOf(run) : null;
|
|
91
|
+
if (summary === null) return { runStatus: run.status, objective };
|
|
92
|
+
const metric = summary.metrics[objective];
|
|
93
|
+
const noise = metric.spread ?? 0;
|
|
94
|
+
return {
|
|
95
|
+
runStatus: run.status,
|
|
96
|
+
objective,
|
|
97
|
+
baseline: metric.baseline,
|
|
98
|
+
candidate: metric.candidate,
|
|
99
|
+
delta: metric.delta,
|
|
100
|
+
...(metric.spread !== undefined && { spread: metric.spread }),
|
|
101
|
+
cases: summary.cases,
|
|
102
|
+
better: metric.delta !== null && metric.delta > noise + EPSILON,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const PROMOTION_STATUS: Readonly<Record<NonNullable<Promotion['status']>, FixProposalStatus>> = {
|
|
107
|
+
'pending-approval': 'in-review',
|
|
108
|
+
promoted: 'promoted',
|
|
109
|
+
refused: 'refused',
|
|
110
|
+
rejected: 'rejected',
|
|
111
|
+
expired: 'expired',
|
|
112
|
+
superseded: 'superseded',
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* A proposal's status from what's recorded: its own steps first
|
|
117
|
+
* (withdrawn, rolled back), then its promotion, then its comparison.
|
|
118
|
+
* `promotion` and `evaluation` are what the proposal's ids resolve to
|
|
119
|
+
* (`undefined` when it has none).
|
|
120
|
+
*/
|
|
121
|
+
export function proposalStatus(
|
|
122
|
+
proposal: StoredProposal,
|
|
123
|
+
promotion: Promotion | null | undefined,
|
|
124
|
+
evaluation: ProposalEvaluationOutcome | null | undefined,
|
|
125
|
+
): FixProposalStatus {
|
|
126
|
+
if (proposal.withdrawn !== undefined) return 'withdrawn';
|
|
127
|
+
if (proposal.rolledBack !== undefined) return 'rolled-back';
|
|
128
|
+
if (promotion !== undefined && promotion !== null) {
|
|
129
|
+
return PROMOTION_STATUS[promotion.status ?? 'promoted'];
|
|
130
|
+
}
|
|
131
|
+
if (evaluation === undefined || evaluation === null) {
|
|
132
|
+
return proposal.evaluation === undefined ? 'draft' : 'evaluation-failed';
|
|
133
|
+
}
|
|
134
|
+
switch (evaluation.runStatus) {
|
|
135
|
+
case 'pending':
|
|
136
|
+
case 'running':
|
|
137
|
+
return 'evaluating';
|
|
138
|
+
case 'failed':
|
|
139
|
+
case 'cancelled':
|
|
140
|
+
return 'evaluation-failed';
|
|
141
|
+
case 'completed':
|
|
142
|
+
return evaluation.better === true ? 'evaluated' : 'not-better';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** The lifecycle calls, and the statuses each starts from. */
|
|
147
|
+
export const PROPOSAL_ACTIONS = {
|
|
148
|
+
evaluate: [
|
|
149
|
+
'draft',
|
|
150
|
+
'evaluated',
|
|
151
|
+
'not-better',
|
|
152
|
+
'evaluation-failed',
|
|
153
|
+
'refused',
|
|
154
|
+
'superseded',
|
|
155
|
+
'expired',
|
|
156
|
+
],
|
|
157
|
+
// The gate decides what goes live: a candidate that isn't measurably
|
|
158
|
+
// better (a wording change) can still be requested through it.
|
|
159
|
+
request: ['evaluated', 'not-better', 'refused', 'superseded', 'expired'],
|
|
160
|
+
rollback: ['promoted'],
|
|
161
|
+
withdraw: [
|
|
162
|
+
'draft',
|
|
163
|
+
'evaluated',
|
|
164
|
+
'not-better',
|
|
165
|
+
'evaluation-failed',
|
|
166
|
+
'refused',
|
|
167
|
+
'superseded',
|
|
168
|
+
'expired',
|
|
169
|
+
],
|
|
170
|
+
} as const satisfies Readonly<Record<string, readonly FixProposalStatus[]>>;
|
|
171
|
+
|
|
172
|
+
export type ProposalAction = keyof typeof PROPOSAL_ACTIONS;
|
|
173
|
+
|
|
174
|
+
export function proposalActionAllowed(action: ProposalAction, status: FixProposalStatus): boolean {
|
|
175
|
+
return (PROPOSAL_ACTIONS[action] as readonly FixProposalStatus[]).includes(status);
|
|
176
|
+
}
|
package/src/provider-binding.ts
CHANGED
|
@@ -131,6 +131,14 @@ export interface ProviderRegisterInput {
|
|
|
131
131
|
* to the runtime, never returned by `list` / `get`.
|
|
132
132
|
*/
|
|
133
133
|
readonly adapterConfig?: AdapterConfig;
|
|
134
|
+
/**
|
|
135
|
+
* Whether the runtime sends each model call's W3C `traceparent` to this
|
|
136
|
+
* provider (as a header; ids only, never content), so the vendor's
|
|
137
|
+
* request logs can be matched to the run. Opt-in: absent or `false`
|
|
138
|
+
* sends none. The runtime enforces it, not the adapter: it sets
|
|
139
|
+
* `ModelCallInput.traceparent` only for a provider that opted in.
|
|
140
|
+
*/
|
|
141
|
+
readonly sendTraceparent?: boolean;
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
export interface ProviderSecretRef {
|
|
@@ -152,6 +160,8 @@ export interface ProviderRuntimeEntry {
|
|
|
152
160
|
readonly adapterId: string;
|
|
153
161
|
readonly secretRef?: ProviderSecretRef;
|
|
154
162
|
readonly adapterConfig?: AdapterConfig;
|
|
163
|
+
/** `ProviderRegisterInput.sendTraceparent`: absent is `false`. */
|
|
164
|
+
readonly sendTraceparent?: boolean;
|
|
155
165
|
}
|
|
156
166
|
|
|
157
167
|
export interface ProviderResolveForRuntimeInput {
|
package/src/publish-refused.ts
CHANGED
|
@@ -1,31 +1,60 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
|
+
import type { ProjectId } from '@kindgi/types';
|
|
5
|
+
|
|
4
6
|
import type { AgentRegistryBinding } from './agent-binding.js';
|
|
5
7
|
import type { FlowRegistryBinding } from './flow-binding.js';
|
|
6
8
|
import type { GuardrailRegistryBinding } from './guardrail-binding.js';
|
|
7
9
|
import type { ToolRegistryBinding } from './tool-binding.js';
|
|
8
10
|
|
|
11
|
+
type PublishedPrimitive = 'tool' | 'guardrail' | 'agent' | 'flow';
|
|
12
|
+
|
|
13
|
+
/** A registry's answer to a deploy's publish, other than `ok` or `already-registered`. */
|
|
14
|
+
type RefusedOutcome = Exclude<
|
|
15
|
+
| Awaited<ReturnType<ToolRegistryBinding['publish']>>
|
|
16
|
+
| Awaited<ReturnType<GuardrailRegistryBinding['register']>>
|
|
17
|
+
| Awaited<ReturnType<AgentRegistryBinding['publish']>>
|
|
18
|
+
| Awaited<ReturnType<FlowRegistryBinding['publish']>>,
|
|
19
|
+
{ readonly kind: 'ok' | 'already-registered' }
|
|
20
|
+
>;
|
|
21
|
+
|
|
9
22
|
/**
|
|
10
23
|
* A deploy's primitive came back from its registry with an outcome other
|
|
11
24
|
* than `ok` or `already-registered` (e.g. `project-not-found`): the deploy
|
|
12
25
|
* stops, what it published is rolled back, and the route answers with
|
|
13
26
|
* that outcome's own status and code (T205). Before, such an outcome was
|
|
14
27
|
* skipped, and the deployment was recorded without that primitive.
|
|
28
|
+
*
|
|
29
|
+
* A primitive whose id belongs to another project answers
|
|
30
|
+
* `<primitive>-project-mismatch`, as publishing it on its own does: a
|
|
31
|
+
* deploy never moves it. The project it belongs to (`projectId`) is for
|
|
32
|
+
* the log, never the answer.
|
|
15
33
|
*/
|
|
16
34
|
export class PublishRefused extends Error {
|
|
35
|
+
/** The code the deploy answers with. */
|
|
36
|
+
readonly code:
|
|
37
|
+
| Exclude<RefusedOutcome['kind'], 'project-mismatch'>
|
|
38
|
+
| `${PublishedPrimitive}-project-mismatch`;
|
|
39
|
+
/** With `…-project-mismatch`: the project the primitive belongs to, for the log only. */
|
|
40
|
+
readonly projectId?: ProjectId;
|
|
41
|
+
|
|
17
42
|
constructor(
|
|
18
|
-
readonly primitive:
|
|
43
|
+
readonly primitive: PublishedPrimitive,
|
|
19
44
|
readonly id: string,
|
|
20
|
-
|
|
21
|
-
| Awaited<ReturnType<ToolRegistryBinding['publish']>>['kind']
|
|
22
|
-
| Awaited<ReturnType<GuardrailRegistryBinding['register']>>['kind']
|
|
23
|
-
| Awaited<ReturnType<AgentRegistryBinding['publish']>>['kind']
|
|
24
|
-
| Awaited<ReturnType<FlowRegistryBinding['publish']>>['kind'],
|
|
25
|
-
'ok' | 'already-registered'
|
|
26
|
-
>,
|
|
45
|
+
outcome: RefusedOutcome,
|
|
27
46
|
) {
|
|
28
|
-
|
|
47
|
+
const code =
|
|
48
|
+
outcome.kind === 'project-mismatch'
|
|
49
|
+
? (`${primitive}-project-mismatch` as const)
|
|
50
|
+
: outcome.kind;
|
|
51
|
+
super(
|
|
52
|
+
outcome.kind === 'project-mismatch'
|
|
53
|
+
? `The ${primitive} ${id} wasn't published: it belongs to another project`
|
|
54
|
+
: `The ${primitive} ${id} wasn't published: ${code}`,
|
|
55
|
+
);
|
|
29
56
|
this.name = 'PublishRefused';
|
|
57
|
+
this.code = code;
|
|
58
|
+
if (outcome.kind === 'project-mismatch') this.projectId = outcome.projectId;
|
|
30
59
|
}
|
|
31
60
|
}
|
package/src/routes/adapters.ts
CHANGED
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
type AdapterTestOutcome,
|
|
18
18
|
} from '../adapter-binding.js';
|
|
19
19
|
import { statusFor, toWireError } from '../errors.js';
|
|
20
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
20
21
|
import type { AppEnv } from '../types.js';
|
|
21
22
|
import { clampLimit } from './pagination.js';
|
|
23
|
+
import { tenantResourceAccess } from './tenant-access.js';
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* Adapters resource routes — part of the admin control plane. Unified
|
|
@@ -46,8 +48,10 @@ import { clampLimit } from './pagination.js';
|
|
|
46
48
|
export function adaptersRouter(
|
|
47
49
|
binding: AdapterRegistryBinding,
|
|
48
50
|
factories?: AdapterFactoryRegistry,
|
|
51
|
+
authorizer?: Authorizer,
|
|
49
52
|
): Hono<AppEnv> {
|
|
50
53
|
const r = new Hono<AppEnv>();
|
|
54
|
+
r.use('*', tenantResourceAccess(authorizer));
|
|
51
55
|
|
|
52
56
|
// ---------- GET / (list, cursor-paginated) ----------
|
|
53
57
|
r.get('/', async (c) => {
|
|
@@ -12,11 +12,12 @@ import type { AgentRegistryBinding } from '../agent-binding.js';
|
|
|
12
12
|
import { statusFor, toWireError } from '../errors.js';
|
|
13
13
|
import type { EvalRun, EvalRunBinding } from '../eval-run-binding.js';
|
|
14
14
|
import type { GatePolicy } from '../gate-policy-binding.js';
|
|
15
|
-
import { type GateResult, evaluateGate } from '../gate.js';
|
|
15
|
+
import { type GateApproval, type GateCheck, type GateResult, evaluateGate } from '../gate.js';
|
|
16
16
|
import type { JudgedComparisonSummary } from '../judged-dispatcher.js';
|
|
17
17
|
import type {
|
|
18
18
|
AgentReleaseBindings,
|
|
19
19
|
LiveResolveInput,
|
|
20
|
+
PromoteInput,
|
|
20
21
|
Promotion,
|
|
21
22
|
PromotionActor,
|
|
22
23
|
} from '../live-version-binding.js';
|
|
@@ -137,79 +138,17 @@ export function mountAgentReleaseRoutes(
|
|
|
137
138
|
const requestId = c.get('requestId');
|
|
138
139
|
const parsed = await readPromotionBody(c);
|
|
139
140
|
if (parsed.kind === 'err') return badInput(c, requestId, parsed.message);
|
|
140
|
-
const tenantId = c.get('tenantId') as TenantId;
|
|
141
141
|
const agentId = c.req.param('agentId');
|
|
142
|
-
const
|
|
143
|
-
tenantId,
|
|
142
|
+
const outcome = await requestPromotion(registry, releases, deps, {
|
|
143
|
+
tenantId: c.get('tenantId') as TenantId,
|
|
144
144
|
agentId,
|
|
145
145
|
version: parsed.value.version,
|
|
146
146
|
scope: parsed.value.scope,
|
|
147
147
|
requestedBy: actorOf(c),
|
|
148
148
|
...(parsed.value.reason !== undefined && { reason: parsed.value.reason }),
|
|
149
149
|
...(parsed.value.evalRunId !== undefined && { evalRunId: parsed.value.evalRunId }),
|
|
150
|
-
};
|
|
151
|
-
const policy = await policyFor(releases, tenantId, agentId, parsed.value.scope);
|
|
152
|
-
if (releases.promotions.request === undefined) {
|
|
153
|
-
if (policy !== null) {
|
|
154
|
-
c.status(statusFor('promotion-gate-unsupported') as never);
|
|
155
|
-
return c.json(
|
|
156
|
-
toWireError(
|
|
157
|
-
{
|
|
158
|
-
code: 'promotion-gate-unsupported',
|
|
159
|
-
message: `Gate policy ${policy.id} ${policy.version} applies to this promotion, and this deployment can't record a gated promotion yet.`,
|
|
160
|
-
},
|
|
161
|
-
requestId,
|
|
162
|
-
),
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
// No gate, and a binding from before gates: promote as before.
|
|
166
|
-
const outcome = await releases.promotions.promote(input);
|
|
167
|
-
if (outcome.kind === 'err') return failed(c, requestId, outcome.error);
|
|
168
|
-
c.status(201);
|
|
169
|
-
return c.json(serializePromotion(outcome.value));
|
|
170
|
-
}
|
|
171
|
-
const gate = await runGate(
|
|
172
|
-
registry,
|
|
173
|
-
releases,
|
|
174
|
-
deps,
|
|
175
|
-
{ ...parsed.value, tenantId, agentId },
|
|
176
|
-
policy,
|
|
177
|
-
);
|
|
178
|
-
if (gate.kind === 'err') return failed(c, requestId, gate.error);
|
|
179
|
-
const outcome = await releases.promotions.request({
|
|
180
|
-
...input,
|
|
181
|
-
gate: {
|
|
182
|
-
policy: policy === null ? null : { id: policy.id, version: policy.version },
|
|
183
|
-
checks: gate.result.checks,
|
|
184
|
-
passed: gate.result.passed,
|
|
185
|
-
...(gate.result.approval !== undefined && { approval: gate.result.approval }),
|
|
186
|
-
servingVersion: gate.servingVersion as Semver,
|
|
187
|
-
...(gate.pinInPlace && { pinInPlace: true }),
|
|
188
|
-
},
|
|
189
150
|
});
|
|
190
|
-
|
|
191
|
-
const promotion = outcome.value;
|
|
192
|
-
if (promotion.status === 'refused') {
|
|
193
|
-
const checks = promotion.checks ?? gate.result.checks;
|
|
194
|
-
c.status(statusFor('gate-failed') as never);
|
|
195
|
-
return c.json(
|
|
196
|
-
toWireError(
|
|
197
|
-
{
|
|
198
|
-
code: 'gate-failed',
|
|
199
|
-
message: `The gate refused ${agentId} ${parsed.value.version}: ${checks
|
|
200
|
-
.filter((check) => !check.passed)
|
|
201
|
-
.map((check) => check.message)
|
|
202
|
-
.join(' ')}`,
|
|
203
|
-
promotionId: promotion.id,
|
|
204
|
-
policy: promotion.policy ?? null,
|
|
205
|
-
checks,
|
|
206
|
-
},
|
|
207
|
-
requestId,
|
|
208
|
-
),
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
c.status(promotion.status === 'pending-approval' ? 202 : 201);
|
|
212
|
-
return c.json(serializePromotion(promotion));
|
|
151
|
+
return promotionResponse(c, outcome);
|
|
213
152
|
});
|
|
214
153
|
|
|
215
154
|
r.post('/:agentId/promotions/check', async (c) => {
|
|
@@ -341,6 +280,119 @@ export function mountAgentReleaseRoutes(
|
|
|
341
280
|
|
|
342
281
|
type Ctx = Context<AppEnv>;
|
|
343
282
|
|
|
283
|
+
/** A promotion request's outcome: recorded, refused before recording, or unsupported here. */
|
|
284
|
+
export type PromotionRequestOutcome =
|
|
285
|
+
| {
|
|
286
|
+
readonly kind: 'ok';
|
|
287
|
+
readonly promotion: Promotion;
|
|
288
|
+
/** The gate's checks as they ran (a binding may not echo them on the row). */
|
|
289
|
+
readonly checks?: readonly GateCheck[];
|
|
290
|
+
}
|
|
291
|
+
| { readonly kind: 'err'; readonly error: { code: string; message: string } }
|
|
292
|
+
| { readonly kind: 'gate-unsupported'; readonly policy: GatePolicy };
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Request that `version` go live for `scope`, through the scope's gate:
|
|
296
|
+
* the binding records it as promoted, waiting for approval, or refused
|
|
297
|
+
* (`promotion.status`). Without gated requests in this deployment, an
|
|
298
|
+
* ungated scope promotes as before and a gated one is unsupported.
|
|
299
|
+
*/
|
|
300
|
+
export async function requestPromotion(
|
|
301
|
+
registry: AgentRegistryBinding,
|
|
302
|
+
releases: AgentReleaseBindings,
|
|
303
|
+
deps: AgentReleaseGateDeps,
|
|
304
|
+
input: PromoteInput,
|
|
305
|
+
options: {
|
|
306
|
+
/** An approval the promotion waits for even when the scope's policy asks for none. */
|
|
307
|
+
readonly requireApproval?: GateApproval;
|
|
308
|
+
} = {},
|
|
309
|
+
): Promise<PromotionRequestOutcome> {
|
|
310
|
+
const policy = await policyFor(releases, input.tenantId, input.agentId, input.scope);
|
|
311
|
+
if (releases.promotions.request === undefined) {
|
|
312
|
+
if (policy !== null) return { kind: 'gate-unsupported', policy };
|
|
313
|
+
if (options.requireApproval !== undefined) {
|
|
314
|
+
return {
|
|
315
|
+
kind: 'err',
|
|
316
|
+
error: {
|
|
317
|
+
code: 'promotion-gate-unsupported',
|
|
318
|
+
message:
|
|
319
|
+
"This promotion waits for a reviewer's approval, and this deployment can't record a gated promotion yet.",
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
// No gate, and a binding from before gates: promote as before.
|
|
324
|
+
const outcome = await releases.promotions.promote(input);
|
|
325
|
+
return outcome.kind === 'err'
|
|
326
|
+
? { kind: 'err', error: outcome.error }
|
|
327
|
+
: { kind: 'ok', promotion: outcome.value };
|
|
328
|
+
}
|
|
329
|
+
const gate = await runGate(registry, releases, deps, input, policy);
|
|
330
|
+
if (gate.kind === 'err') return gate;
|
|
331
|
+
const approval = gate.result.approval ?? options.requireApproval;
|
|
332
|
+
const outcome = await releases.promotions.request({
|
|
333
|
+
...input,
|
|
334
|
+
gate: {
|
|
335
|
+
policy: policy === null ? null : { id: policy.id, version: policy.version },
|
|
336
|
+
checks: gate.result.checks,
|
|
337
|
+
passed: gate.result.passed,
|
|
338
|
+
...(approval !== undefined && { approval }),
|
|
339
|
+
servingVersion: gate.servingVersion as Semver,
|
|
340
|
+
...(gate.pinInPlace && { pinInPlace: true }),
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
return outcome.kind === 'err'
|
|
344
|
+
? { kind: 'err', error: outcome.error }
|
|
345
|
+
: { kind: 'ok', promotion: outcome.value, checks: gate.result.checks };
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* The answer to a promotion request: 201 promoted, 202 waiting for
|
|
350
|
+
* approval, 422 `gate-failed` with the checks, or the error.
|
|
351
|
+
*/
|
|
352
|
+
export function promotionResponse(
|
|
353
|
+
c: Ctx,
|
|
354
|
+
outcome: PromotionRequestOutcome,
|
|
355
|
+
extra: Readonly<Record<string, unknown>> = {},
|
|
356
|
+
) {
|
|
357
|
+
const requestId = c.get('requestId');
|
|
358
|
+
if (outcome.kind === 'gate-unsupported') {
|
|
359
|
+
c.status(statusFor('promotion-gate-unsupported') as never);
|
|
360
|
+
return c.json(
|
|
361
|
+
toWireError(
|
|
362
|
+
{
|
|
363
|
+
code: 'promotion-gate-unsupported',
|
|
364
|
+
message: `Gate policy ${outcome.policy.id} ${outcome.policy.version} applies to this promotion, and this deployment can't record a gated promotion yet.`,
|
|
365
|
+
},
|
|
366
|
+
requestId,
|
|
367
|
+
),
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
if (outcome.kind === 'err') return failed(c, requestId, outcome.error);
|
|
371
|
+
const { promotion } = outcome;
|
|
372
|
+
if (promotion.status === 'refused') {
|
|
373
|
+
const checks = promotion.checks ?? outcome.checks ?? [];
|
|
374
|
+
c.status(statusFor('gate-failed') as never);
|
|
375
|
+
return c.json(
|
|
376
|
+
toWireError(
|
|
377
|
+
{
|
|
378
|
+
code: 'gate-failed',
|
|
379
|
+
message: `The gate refused ${promotion.agentId} ${promotion.toVersion as unknown as string}: ${checks
|
|
380
|
+
.filter((check) => !check.passed)
|
|
381
|
+
.map((check) => check.message)
|
|
382
|
+
.join(' ')}`,
|
|
383
|
+
promotionId: promotion.id,
|
|
384
|
+
policy: promotion.policy ?? null,
|
|
385
|
+
checks,
|
|
386
|
+
...extra,
|
|
387
|
+
},
|
|
388
|
+
requestId,
|
|
389
|
+
),
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
c.status(promotion.status === 'pending-approval' ? 202 : 201);
|
|
393
|
+
return c.json({ ...serializePromotion(promotion), ...extra });
|
|
394
|
+
}
|
|
395
|
+
|
|
344
396
|
async function readBody(c: Ctx): Promise<Record<string, unknown> | undefined> {
|
|
345
397
|
try {
|
|
346
398
|
const body: unknown = await c.req.json();
|
|
@@ -409,7 +461,7 @@ async function readPromotionBody(c: Ctx): Promise<
|
|
|
409
461
|
}
|
|
410
462
|
|
|
411
463
|
/** The gate policy for a promotion of `agentId` for `scope`; `null` when none applies. */
|
|
412
|
-
async function policyFor(
|
|
464
|
+
export async function policyFor(
|
|
413
465
|
releases: AgentReleaseBindings,
|
|
414
466
|
tenantId: TenantId,
|
|
415
467
|
agentId: string,
|
|
@@ -421,7 +473,7 @@ async function policyFor(
|
|
|
421
473
|
}
|
|
422
474
|
|
|
423
475
|
/** The scope's coordinates, as a run in it would resolve its version. */
|
|
424
|
-
function coordinatesOf(scope: LiveScope): Omit<LiveResolveInput, 'tenantId' | 'agentId'> {
|
|
476
|
+
export function coordinatesOf(scope: LiveScope): Omit<LiveResolveInput, 'tenantId' | 'agentId'> {
|
|
425
477
|
switch (scope.kind) {
|
|
426
478
|
case 'tenant':
|
|
427
479
|
return {};
|
|
@@ -566,7 +618,7 @@ async function runGate(
|
|
|
566
618
|
}
|
|
567
619
|
|
|
568
620
|
/** Who asked, from the request's principal. */
|
|
569
|
-
function actorOf(c: Ctx): PromotionActor {
|
|
621
|
+
export function actorOf(c: Ctx): PromotionActor {
|
|
570
622
|
const actor = c.get('principal')?.actor;
|
|
571
623
|
if (actor === undefined) return { kind: 'service', id: 'unknown' };
|
|
572
624
|
return { kind: actor.kind === 'user' ? 'user' : 'service', id: actor.id };
|