@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
|
@@ -9,7 +9,12 @@ import type { Agent, AgentId, AgentPins } from '@kindgi/agents';
|
|
|
9
9
|
import { tuplesForCreate } from '@kindgi/authz';
|
|
10
10
|
import { parsePublicKeyPem, verifyEd25519 } from '@kindgi/crypto';
|
|
11
11
|
import type { Flow, FlowPins } from '@kindgi/flow';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
GUARDRAIL_SPEC_KEYS,
|
|
14
|
+
type Guardrail,
|
|
15
|
+
createCheckRegistry,
|
|
16
|
+
validateGuardrailSpec,
|
|
17
|
+
} from '@kindgi/guardrails';
|
|
13
18
|
import type { ProjectBinding, Scope } from '@kindgi/platform';
|
|
14
19
|
import { validateToolManifest } from '@kindgi/tools';
|
|
15
20
|
import type {
|
|
@@ -42,6 +47,7 @@ import { type FlowPinsLive, publishDeployedFlow, resolveFlowPins } from '../flow
|
|
|
42
47
|
import type { GuardrailRegistryBinding } from '../guardrail-binding.js';
|
|
43
48
|
import type { ImageRegistryBinding } from '../image-registry-binding.js';
|
|
44
49
|
import type { LiveVersionBinding } from '../live-version-binding.js';
|
|
50
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
45
51
|
import { PublishRefused } from '../publish-refused.js';
|
|
46
52
|
import { type RegistryReadOnly, refuseReadOnly } from '../registry-read-only.js';
|
|
47
53
|
import type { SecretBinding } from '../secrets-binding.js';
|
|
@@ -51,6 +57,7 @@ import type { AppEnv } from '../types.js';
|
|
|
51
57
|
import { hasCapability, requireEnvName } from './env.js';
|
|
52
58
|
import type { GuardrailWriteHook } from './guardrails.js';
|
|
53
59
|
import { clampLimit } from './pagination.js';
|
|
60
|
+
import { tenantResourceAccess } from './tenant-access.js';
|
|
54
61
|
import type { ToolWriteHook } from './tools.js';
|
|
55
62
|
|
|
56
63
|
/**
|
|
@@ -167,8 +174,12 @@ export interface DeploymentsRouterBindings {
|
|
|
167
174
|
readonly onGuardrailWrite?: GuardrailWriteHook;
|
|
168
175
|
}
|
|
169
176
|
|
|
170
|
-
export function deploymentsRouter(
|
|
177
|
+
export function deploymentsRouter(
|
|
178
|
+
bindings: DeploymentsRouterBindings,
|
|
179
|
+
authorizer?: Authorizer,
|
|
180
|
+
): Hono<AppEnv> {
|
|
171
181
|
const r = new Hono<AppEnv>();
|
|
182
|
+
r.use('*', tenantResourceAccess(authorizer));
|
|
172
183
|
|
|
173
184
|
// ---------- GET / (list, cursor-paginated) ----------
|
|
174
185
|
r.get('/', async (c) => {
|
|
@@ -476,10 +487,11 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
|
|
|
476
487
|
}
|
|
477
488
|
|
|
478
489
|
// ---- Manifest validation ----
|
|
479
|
-
const validation = validatePrimitives(
|
|
480
|
-
|
|
481
|
-
artifactVersion: wire.artifactVersion,
|
|
482
|
-
|
|
490
|
+
const validation = validatePrimitives(
|
|
491
|
+
imageIndex,
|
|
492
|
+
{ imageRef: wire.imageRef, artifactVersion: wire.artifactVersion },
|
|
493
|
+
c.get('log'),
|
|
494
|
+
);
|
|
483
495
|
if (validation.kind === 'err') {
|
|
484
496
|
c.status(statusFor('deployment-validation-failed') as never);
|
|
485
497
|
return c.json(
|
|
@@ -580,7 +592,7 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
|
|
|
580
592
|
await bindings.toolRegistry?.unregister({ tenantId, toolId, version });
|
|
581
593
|
});
|
|
582
594
|
} else if (outcome.kind !== 'already-registered') {
|
|
583
|
-
throw new PublishRefused('tool', `${tool.id}@${tool.version}`, outcome
|
|
595
|
+
throw new PublishRefused('tool', `${tool.id}@${tool.version}`, outcome);
|
|
584
596
|
}
|
|
585
597
|
}
|
|
586
598
|
}
|
|
@@ -605,7 +617,7 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
|
|
|
605
617
|
await bindings.guardrailRegistry?.unregister({ tenantId, guardrailId });
|
|
606
618
|
});
|
|
607
619
|
} else if (outcome.kind !== 'already-registered') {
|
|
608
|
-
throw new PublishRefused('guardrail', guardrail.id, outcome
|
|
620
|
+
throw new PublishRefused('guardrail', guardrail.id, outcome);
|
|
609
621
|
}
|
|
610
622
|
}
|
|
611
623
|
}
|
|
@@ -645,6 +657,13 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
|
|
|
645
657
|
// A primitive refused with a typed outcome is the caller's to fix:
|
|
646
658
|
// that outcome's own status and code. Anything thrown is a 500.
|
|
647
659
|
if (cause instanceof PublishRefused) {
|
|
660
|
+
if (cause.projectId !== undefined) {
|
|
661
|
+
c.get('log').info(`${cause.message}: deploy refused`, {
|
|
662
|
+
primitive: cause.primitive,
|
|
663
|
+
id: cause.id,
|
|
664
|
+
ownerProjectId: cause.projectId as unknown as string,
|
|
665
|
+
});
|
|
666
|
+
}
|
|
648
667
|
c.status(statusFor(cause.code) as never);
|
|
649
668
|
return c.json(
|
|
650
669
|
toWireError(
|
|
@@ -1236,9 +1255,13 @@ function ociCodeArtifactRef(image: DeployedImage, modulePath: unknown) {
|
|
|
1236
1255
|
* a guardrail's `checkId` becomes its `check`, as `kindgi dev`'s disk
|
|
1237
1256
|
* registry maps it.
|
|
1238
1257
|
*/
|
|
1258
|
+
/** The built-in checks, for the config of a guardrail naming one. */
|
|
1259
|
+
const builtInChecks = createCheckRegistry();
|
|
1260
|
+
|
|
1239
1261
|
function validatePrimitives(
|
|
1240
1262
|
index: Readonly<Record<string, unknown>>,
|
|
1241
1263
|
image: DeployedImage,
|
|
1264
|
+
log?: { debug(message: string): void },
|
|
1242
1265
|
): ValidateResult {
|
|
1243
1266
|
const details: ValidationDetail[] = [];
|
|
1244
1267
|
|
|
@@ -1286,12 +1309,20 @@ function validatePrimitives(
|
|
|
1286
1309
|
details.push({ primitive: 'guardrail', index: i, path: '', message: 'must be an object' });
|
|
1287
1310
|
return;
|
|
1288
1311
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1312
|
+
// The rest is the guardrail as registered, its `configSchema` included:
|
|
1313
|
+
// the runtime checks a guardrail naming this check against it. A field
|
|
1314
|
+
// the guardrail spec doesn't have (an index from a newer CLI) is dropped,
|
|
1315
|
+
// never refused, so a newer CLI never breaks a deployment.
|
|
1316
|
+
const { checkModulePath, checkId, ...indexed } = raw as Record<string, unknown>;
|
|
1317
|
+
const dropped = Object.keys(indexed).filter((k) => !GUARDRAIL_SPEC_KEYS.includes(k));
|
|
1318
|
+
const rest = Object.fromEntries(
|
|
1319
|
+
Object.entries(indexed).filter(([k]) => GUARDRAIL_SPEC_KEYS.includes(k)),
|
|
1320
|
+
);
|
|
1321
|
+
if (dropped.length > 0) {
|
|
1322
|
+
log?.debug(
|
|
1323
|
+
`deployment: guardrail ${String(indexed.id)}: ignored index field(s) this runtime doesn't know: ${dropped.join(', ')}`,
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1295
1326
|
const r = validateGuardrailSpec({
|
|
1296
1327
|
...rest,
|
|
1297
1328
|
check: checkId ?? rest.check ?? rest.id,
|
|
@@ -1325,6 +1356,21 @@ function validatePrimitives(
|
|
|
1325
1356
|
}
|
|
1326
1357
|
return;
|
|
1327
1358
|
}
|
|
1359
|
+
// A guardrail naming a built-in check: its config against the built-in's.
|
|
1360
|
+
const builtIn = builtInChecks.get(r.value.check);
|
|
1361
|
+
const configProblems = builtIn?.configProblems?.(r.value.config) ?? [];
|
|
1362
|
+
if (configProblems.length > 0) {
|
|
1363
|
+
for (const problem of configProblems) {
|
|
1364
|
+
details.push({
|
|
1365
|
+
primitive: 'guardrail',
|
|
1366
|
+
index: i,
|
|
1367
|
+
id: r.value.id as unknown as string,
|
|
1368
|
+
path: problem.path,
|
|
1369
|
+
message: problem.message,
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1328
1374
|
validatedGuardrails.push(r.value);
|
|
1329
1375
|
});
|
|
1330
1376
|
|
|
@@ -1524,7 +1570,7 @@ async function registerAgents(input: {
|
|
|
1524
1570
|
const outcome = await agents.publish({ tenantId, projectId, agent, enqueueTuples });
|
|
1525
1571
|
if (outcome.kind === 'ok') written(outcome.agentId, outcome.version);
|
|
1526
1572
|
else if (outcome.kind !== 'already-registered') {
|
|
1527
|
-
throw new PublishRefused('agent', `${agent.id}@${agent.version}`, outcome
|
|
1573
|
+
throw new PublishRefused('agent', `${agent.id}@${agent.version}`, outcome);
|
|
1528
1574
|
}
|
|
1529
1575
|
}
|
|
1530
1576
|
return input.defined.map(deployedPrimitive);
|
|
@@ -1588,7 +1634,7 @@ async function registerFlows(input: {
|
|
|
1588
1634
|
const outcome = await flows.publish({ tenantId, projectId, flow, enqueueTuples });
|
|
1589
1635
|
if (outcome.kind === 'ok') written(outcome.flowId, outcome.version as unknown as string);
|
|
1590
1636
|
else if (outcome.kind !== 'already-registered') {
|
|
1591
|
-
throw new PublishRefused('flow', `${flow.id}@${flow.version}`, outcome
|
|
1637
|
+
throw new PublishRefused('flow', `${flow.id}@${flow.version}`, outcome);
|
|
1592
1638
|
}
|
|
1593
1639
|
}
|
|
1594
1640
|
return input.defined.map(deployedPrimitive);
|
|
@@ -5,12 +5,18 @@ import type { AgentId } from '@kindgi/agents';
|
|
|
5
5
|
import type { FlowVersionOverrides } from '@kindgi/flow';
|
|
6
6
|
import type { ProjectId, Semver } from '@kindgi/types';
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
EvalBaseline,
|
|
10
|
+
EvalComparison,
|
|
11
|
+
EvalOverrides,
|
|
12
|
+
EvalSample,
|
|
13
|
+
} from '../eval-run-binding.js';
|
|
9
14
|
import { DEFAULT_COMPARISON } from '../judged-dispatcher.js';
|
|
10
15
|
import { parseSegmentsBody } from './segments.js';
|
|
11
16
|
|
|
12
17
|
const MAX_REPETITIONS = 10;
|
|
13
18
|
const MAX_K = 100;
|
|
19
|
+
const MAX_OVERRIDDEN_BLOCKS = 20;
|
|
14
20
|
|
|
15
21
|
function obj(value: unknown): Record<string, unknown> | undefined {
|
|
16
22
|
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
@@ -84,6 +90,71 @@ function integerIn(raw: unknown, name: string, max: number): number | string {
|
|
|
84
90
|
: `\`${name}\` must be an integer from 1 to ${max}`;
|
|
85
91
|
}
|
|
86
92
|
|
|
93
|
+
/** `overrides: { settings?, prompts? }`; `undefined` when it names nothing. */
|
|
94
|
+
function parseOverrides(raw: unknown): EvalOverrides | undefined | string {
|
|
95
|
+
const o = obj(raw);
|
|
96
|
+
if (o === undefined) return '`overrides` must be an object: { settings?, prompts? }';
|
|
97
|
+
const extra = Object.keys(o).filter((key) => key !== 'settings' && key !== 'prompts');
|
|
98
|
+
if (extra.length > 0) {
|
|
99
|
+
return `\`overrides\` takes \`settings\` and \`prompts\`, not \`${extra[0]}\``;
|
|
100
|
+
}
|
|
101
|
+
const settings = o.settings === undefined ? {} : obj(o.settings);
|
|
102
|
+
const prompts = o.prompts === undefined ? {} : obj(o.prompts);
|
|
103
|
+
const settingsBlocks = settings === undefined ? [] : Object.entries(settings);
|
|
104
|
+
const promptBlocks = prompts === undefined ? [] : Object.entries(prompts);
|
|
105
|
+
if (
|
|
106
|
+
settings === undefined ||
|
|
107
|
+
settingsBlocks.length > MAX_OVERRIDDEN_BLOCKS ||
|
|
108
|
+
settingsBlocks.some(([id, values]) => id === '' || obj(values) === undefined)
|
|
109
|
+
) {
|
|
110
|
+
return `\`overrides.settings\` must be an object of { blockId: { …values } } (at most ${MAX_OVERRIDDEN_BLOCKS} blocks)`;
|
|
111
|
+
}
|
|
112
|
+
if (
|
|
113
|
+
prompts === undefined ||
|
|
114
|
+
promptBlocks.length > 1 ||
|
|
115
|
+
promptBlocks.some(([id, content]) => {
|
|
116
|
+
const c = obj(content);
|
|
117
|
+
return (
|
|
118
|
+
id === '' ||
|
|
119
|
+
c === undefined ||
|
|
120
|
+
typeof c.template !== 'string' ||
|
|
121
|
+
Object.keys(c).length !== 1
|
|
122
|
+
);
|
|
123
|
+
})
|
|
124
|
+
) {
|
|
125
|
+
return '`overrides.prompts` must be { blockId: { template } } for the prompt block (one)';
|
|
126
|
+
}
|
|
127
|
+
if (settingsBlocks.length === 0 && promptBlocks.length === 0) return undefined;
|
|
128
|
+
return {
|
|
129
|
+
...(settingsBlocks.length > 0 && {
|
|
130
|
+
settings: settings as Readonly<Record<string, Readonly<Record<string, unknown>>>>,
|
|
131
|
+
}),
|
|
132
|
+
...(promptBlocks.length > 0 && {
|
|
133
|
+
prompts: prompts as Readonly<Record<string, { readonly template: string }>>,
|
|
134
|
+
}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** `sample: { part, seed, holdOutShare }`, or an error message. */
|
|
139
|
+
function parseSample(raw: unknown): EvalSample | string {
|
|
140
|
+
const o = obj(raw);
|
|
141
|
+
const share = o?.holdOutShare;
|
|
142
|
+
if (
|
|
143
|
+
o === undefined ||
|
|
144
|
+
(o.part !== 'search' && o.part !== 'hold-out') ||
|
|
145
|
+
typeof o.seed !== 'string' ||
|
|
146
|
+
o.seed === '' ||
|
|
147
|
+
o.seed.length > 200 ||
|
|
148
|
+
typeof share !== 'number' ||
|
|
149
|
+
share < 0.1 ||
|
|
150
|
+
share > 0.9 ||
|
|
151
|
+
Object.keys(o).some((key) => !['part', 'seed', 'holdOutShare'].includes(key))
|
|
152
|
+
) {
|
|
153
|
+
return "`sample` must be { part: 'search' | 'hold-out', seed, holdOutShare } with holdOutShare from 0.1 to 0.9";
|
|
154
|
+
}
|
|
155
|
+
return { part: o.part, seed: o.seed, holdOutShare: share };
|
|
156
|
+
}
|
|
157
|
+
|
|
87
158
|
/**
|
|
88
159
|
* A comparison eval run's settings from the start body: `baseline`,
|
|
89
160
|
* `reads`, `repetitions`, `k`, `classWeights` and a flow candidate's
|
|
@@ -99,13 +170,19 @@ export function parseComparison(
|
|
|
99
170
|
const { baseline, reads, repetitions, k, classWeights } = b;
|
|
100
171
|
const versions = b.versions === undefined ? undefined : parseVersions(b.versions);
|
|
101
172
|
if (typeof versions === 'string') return { kind: 'err', message: versions };
|
|
173
|
+
const overrides = b.overrides === undefined ? undefined : parseOverrides(b.overrides);
|
|
174
|
+
if (typeof overrides === 'string') return { kind: 'err', message: overrides };
|
|
175
|
+
const sample = b.sample === undefined ? undefined : parseSample(b.sample);
|
|
176
|
+
if (typeof sample === 'string') return { kind: 'err', message: sample };
|
|
102
177
|
if (
|
|
103
178
|
baseline === undefined &&
|
|
104
179
|
reads === undefined &&
|
|
105
180
|
repetitions === undefined &&
|
|
106
181
|
k === undefined &&
|
|
107
182
|
versions === undefined &&
|
|
108
|
-
classWeights === undefined
|
|
183
|
+
classWeights === undefined &&
|
|
184
|
+
overrides === undefined &&
|
|
185
|
+
sample === undefined
|
|
109
186
|
) {
|
|
110
187
|
return { kind: 'ok' };
|
|
111
188
|
}
|
|
@@ -144,6 +221,8 @@ export function parseComparison(
|
|
|
144
221
|
k: topK,
|
|
145
222
|
...(versions !== undefined && { versions }),
|
|
146
223
|
...(classWeights !== undefined && { classWeights }),
|
|
224
|
+
...(overrides !== undefined && { overrides }),
|
|
225
|
+
...(sample !== undefined && { sample }),
|
|
147
226
|
},
|
|
148
227
|
};
|
|
149
228
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* An agent candidate's `overrides`, checked when the comparison starts:
|
|
6
|
+
* each settings block must be one the version pins, its values satisfying
|
|
7
|
+
* the schema of the version it pins (model settings, for the
|
|
8
|
+
* model-settings block); a prompt template must be for the prompt block
|
|
9
|
+
* the version pins, and pass `checkDraftedTemplate` (it reads and names
|
|
10
|
+
* only what the agent has). Checked once, here, before any run exists:
|
|
11
|
+
* the replays use them as given, on resume too.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
type AgentId,
|
|
16
|
+
MODEL_SETTINGS_SCHEMA,
|
|
17
|
+
checkDraftedTemplate,
|
|
18
|
+
settingsSchemaIssues,
|
|
19
|
+
} from '@kindgi/agents';
|
|
20
|
+
import type { Semver, TenantId } from '@kindgi/types';
|
|
21
|
+
|
|
22
|
+
import type { AgentRegistryBinding } from '../agent-binding.js';
|
|
23
|
+
import type { BlockRegistryBinding } from '../block-binding.js';
|
|
24
|
+
import type { EvalOverrides } from '../eval-run-binding.js';
|
|
25
|
+
|
|
26
|
+
/** Where the check reads the agent version and its blocks. */
|
|
27
|
+
export interface SettingsOverridesCheck {
|
|
28
|
+
readonly agents: AgentRegistryBinding;
|
|
29
|
+
readonly blocks: BlockRegistryBinding;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface OverridesIssue {
|
|
33
|
+
readonly path: string;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** A JSON Pointer token: `~` and `/` escaped. */
|
|
38
|
+
const token = (id: string): string => id.replaceAll('~', '~0').replaceAll('/', '~1');
|
|
39
|
+
|
|
40
|
+
export async function checkSettingsOverrides(
|
|
41
|
+
check: SettingsOverridesCheck,
|
|
42
|
+
tenantId: TenantId,
|
|
43
|
+
candidate: { readonly agentId: string; readonly version: string },
|
|
44
|
+
overrides: EvalOverrides,
|
|
45
|
+
): Promise<OverridesIssue[]> {
|
|
46
|
+
const settings = overrides.settings ?? {};
|
|
47
|
+
const label = `${candidate.agentId} ${candidate.version}`;
|
|
48
|
+
const found = await check.agents.getVersion({
|
|
49
|
+
tenantId,
|
|
50
|
+
agentId: candidate.agentId as AgentId,
|
|
51
|
+
version: candidate.version as Semver,
|
|
52
|
+
});
|
|
53
|
+
if (found === null) {
|
|
54
|
+
return [{ path: '/agentRef/version', message: `agent ${label} isn't registered` }];
|
|
55
|
+
}
|
|
56
|
+
if (found.pins === undefined) {
|
|
57
|
+
return [
|
|
58
|
+
{
|
|
59
|
+
path: '/overrides/settings',
|
|
60
|
+
message: `${label} was published before pins: it has no pinned settings to replace`,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
const issues: OverridesIssue[] = [];
|
|
65
|
+
for (const [id, values] of Object.entries(settings)) {
|
|
66
|
+
const path = `/overrides/settings/${token(id)}`;
|
|
67
|
+
const version = found.pins.settings[id];
|
|
68
|
+
if (version === undefined) {
|
|
69
|
+
issues.push({ path, message: `${label} doesn't pin settings block "${id}"` });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const block = await check.blocks.getVersion({ tenantId, blockId: id, version });
|
|
73
|
+
if (block === null || block.kind !== 'settings') {
|
|
74
|
+
issues.push({ path, message: `settings block "${id}" version ${version} isn't published` });
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const schema = found.modelSettings?.id === id ? MODEL_SETTINGS_SCHEMA : block.content.schema;
|
|
78
|
+
if (schema === undefined) continue;
|
|
79
|
+
for (const issue of settingsSchemaIssues(values, schema)) {
|
|
80
|
+
issues.push({ path: `${path}${issue.path}`, message: issue.message });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const [id, { template }] of Object.entries(overrides.prompts ?? {})) {
|
|
84
|
+
const path = `/overrides/prompts/${token(id)}`;
|
|
85
|
+
const version = found.pins.prompts[id];
|
|
86
|
+
if (version === undefined) {
|
|
87
|
+
issues.push({ path, message: `${label} doesn't pin prompt block "${id}"` });
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const block = await check.blocks.getVersion({ tenantId, blockId: id, version });
|
|
91
|
+
if (block === null || block.kind !== 'prompt') {
|
|
92
|
+
issues.push({ path, message: `prompt block "${id}" version ${version} isn't published` });
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const drafted = checkDraftedTemplate(template, {
|
|
96
|
+
current: block.content,
|
|
97
|
+
settingsBlocks: Object.keys(found.pins.settings),
|
|
98
|
+
knownIds: [
|
|
99
|
+
candidate.agentId,
|
|
100
|
+
...Object.keys(found.pins.tools),
|
|
101
|
+
...Object.keys(found.pins.prompts),
|
|
102
|
+
...Object.keys(found.pins.settings),
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
for (const issue of drafted) issues.push({ path, message: issue.message });
|
|
106
|
+
}
|
|
107
|
+
return issues;
|
|
108
|
+
}
|
package/src/routes/eval-runs.ts
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
+
import type { Context } from 'hono';
|
|
5
6
|
|
|
6
7
|
import type { AgentId } from '@kindgi/agents';
|
|
8
|
+
import { type Action, ref } from '@kindgi/authz';
|
|
7
9
|
import type { Cursor, FlowId, ProjectId, RunId, Semver, TenantId, Timestamp } from '@kindgi/types';
|
|
8
10
|
|
|
9
11
|
import { statusFor, toWireError } from '../errors.js';
|
|
@@ -18,8 +20,11 @@ import {
|
|
|
18
20
|
type FlowRef,
|
|
19
21
|
} from '../eval-run-binding.js';
|
|
20
22
|
import { VERSIONS_NEED_A_FLOW } from '../judged-dispatcher.js';
|
|
23
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
21
24
|
import type { AppEnv } from '../types.js';
|
|
25
|
+
import { deniedBy } from './denied.js';
|
|
22
26
|
import { parseComparison } from './eval-comparison.js';
|
|
27
|
+
import { type SettingsOverridesCheck, checkSettingsOverrides } from './eval-overrides.js';
|
|
23
28
|
import { type FlowVersionsCheck, checkFlowVersions } from './eval-versions.js';
|
|
24
29
|
import { clampLimit } from './pagination.js';
|
|
25
30
|
import { parseScopeParams } from './scope-params.js';
|
|
@@ -43,6 +48,13 @@ import { formatSseFrame } from './sse.js';
|
|
|
43
48
|
* The binding chooses its underlying substrate (the in-process
|
|
44
49
|
* reference keeps runs in memory; a durable binding can back them with
|
|
45
50
|
* runs and their journal); this route only sees the surface.
|
|
51
|
+
*
|
|
52
|
+
* With an authorizer (T243 A): starting a run needs `write` on the
|
|
53
|
+
* project it lands in and `execute` on what it evaluates (the agent or
|
|
54
|
+
* flow), on top of the eval-suites router's own check on the suite. An
|
|
55
|
+
* eval run is read through its suite: `read` on the suite to list, get or
|
|
56
|
+
* follow it, `write` to cancel it. A run that isn't there is still the
|
|
57
|
+
* handler's 404.
|
|
46
58
|
*/
|
|
47
59
|
export interface EvalRunsRouters {
|
|
48
60
|
readonly start: Hono<AppEnv>;
|
|
@@ -57,10 +69,12 @@ export interface EvalRunsRouters {
|
|
|
57
69
|
export function evalRunsRouters(
|
|
58
70
|
binding: EvalRunBinding,
|
|
59
71
|
versionsCheck?: FlowVersionsCheck,
|
|
72
|
+
overridesCheck?: SettingsOverridesCheck,
|
|
73
|
+
authorizer?: Authorizer,
|
|
60
74
|
): EvalRunsRouters {
|
|
61
75
|
return {
|
|
62
|
-
start: startRouter(binding, versionsCheck),
|
|
63
|
-
readback: readbackRouter(binding),
|
|
76
|
+
start: startRouter(binding, versionsCheck, overridesCheck, authorizer),
|
|
77
|
+
readback: readbackRouter(binding, authorizer),
|
|
64
78
|
};
|
|
65
79
|
}
|
|
66
80
|
|
|
@@ -91,7 +105,42 @@ async function versionsRefusal(
|
|
|
91
105
|
};
|
|
92
106
|
}
|
|
93
107
|
|
|
94
|
-
|
|
108
|
+
/** The `validation-failed` error for an agent candidate's settings `overrides` that don't fit it; `undefined` when they do. */
|
|
109
|
+
async function overridesRefusal(
|
|
110
|
+
check: SettingsOverridesCheck | undefined,
|
|
111
|
+
tenantId: TenantId,
|
|
112
|
+
start: ParsedStartBody,
|
|
113
|
+
) {
|
|
114
|
+
const overrides = start.comparison?.overrides;
|
|
115
|
+
const agentRef = start.agentRef;
|
|
116
|
+
if (overrides === undefined || agentRef?.version === undefined) return undefined;
|
|
117
|
+
if (check === undefined) {
|
|
118
|
+
return {
|
|
119
|
+
code: 'validation-failed' as const,
|
|
120
|
+
message: "This runtime can't check overrides (it serves no agent or block registry).",
|
|
121
|
+
issues: [],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const issues = await checkSettingsOverrides(
|
|
125
|
+
check,
|
|
126
|
+
tenantId,
|
|
127
|
+
{ agentId: agentRef.agentId as unknown as string, version: agentRef.version },
|
|
128
|
+
overrides,
|
|
129
|
+
);
|
|
130
|
+
if (issues.length === 0) return undefined;
|
|
131
|
+
return {
|
|
132
|
+
code: 'validation-failed' as const,
|
|
133
|
+
message: `The overrides don't fit ${agentRef.agentId as unknown as string} ${agentRef.version} (${issues.length} issue${issues.length === 1 ? '' : 's'})`,
|
|
134
|
+
issues: issues as unknown as Record<string, unknown>[],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function startRouter(
|
|
139
|
+
binding: EvalRunBinding,
|
|
140
|
+
versionsCheck?: FlowVersionsCheck,
|
|
141
|
+
overridesCheck?: SettingsOverridesCheck,
|
|
142
|
+
authorizer?: Authorizer,
|
|
143
|
+
): Hono<AppEnv> {
|
|
95
144
|
const r = new Hono<AppEnv>();
|
|
96
145
|
|
|
97
146
|
r.post('/:suiteId/runs', async (c) => {
|
|
@@ -119,7 +168,18 @@ function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck)
|
|
|
119
168
|
c.status(statusFor(parsed.error.code) as never);
|
|
120
169
|
return c.json(toWireError(parsed.error, requestId));
|
|
121
170
|
}
|
|
122
|
-
const
|
|
171
|
+
const { projectId, agentRef, flowRef } = parsed.value;
|
|
172
|
+
const target =
|
|
173
|
+
agentRef !== undefined
|
|
174
|
+
? ref('agent', agentRef.agentId as unknown as string)
|
|
175
|
+
: ref('flow', flowRef?.flowId as unknown as string);
|
|
176
|
+
const refused =
|
|
177
|
+
(await deniedBy(authorizer, c, 'write', ref('project', projectId as unknown as string))) ??
|
|
178
|
+
(await deniedBy(authorizer, c, 'execute', target));
|
|
179
|
+
if (refused !== undefined) return refused;
|
|
180
|
+
const refusal =
|
|
181
|
+
(await versionsRefusal(versionsCheck, tenantId, parsed.value)) ??
|
|
182
|
+
(await overridesRefusal(overridesCheck, tenantId, parsed.value));
|
|
123
183
|
if (refusal !== undefined) {
|
|
124
184
|
c.status(statusFor(refusal.code) as never);
|
|
125
185
|
return c.json(toWireError(refusal, requestId));
|
|
@@ -206,8 +266,16 @@ function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck)
|
|
|
206
266
|
|
|
207
267
|
// ---------- /v1/eval-runs/* (readback + cancel + SSE) ----------
|
|
208
268
|
|
|
209
|
-
function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
269
|
+
function readbackRouter(binding: EvalRunBinding, authorizer?: Authorizer): Hono<AppEnv> {
|
|
210
270
|
const r = new Hono<AppEnv>();
|
|
271
|
+
/** The refusal, if any, of `action` on the suite of the run named in the path. */
|
|
272
|
+
const onRunSuite = async (c: Context<AppEnv>, action: Action): Promise<Response | undefined> => {
|
|
273
|
+
if (authorizer === undefined) return undefined;
|
|
274
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
275
|
+
const run = await binding.get({ tenantId, runId: c.req.param('runId') as RunId });
|
|
276
|
+
if (run === null) return undefined;
|
|
277
|
+
return deniedBy(authorizer, c, action, ref('eval_suite', run.suiteId));
|
|
278
|
+
};
|
|
211
279
|
|
|
212
280
|
// ---------- GET / (list) ----------
|
|
213
281
|
r.get('/', async (c) => {
|
|
@@ -270,8 +338,14 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
270
338
|
...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
|
|
271
339
|
...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
|
|
272
340
|
});
|
|
341
|
+
const visible =
|
|
342
|
+
authorizer === undefined
|
|
343
|
+
? page.data
|
|
344
|
+
: await authorizer.filterByCan(c, 'read', page.data, (run) =>
|
|
345
|
+
ref('eval_suite', run.suiteId),
|
|
346
|
+
);
|
|
273
347
|
return c.json({
|
|
274
|
-
data:
|
|
348
|
+
data: visible.map(serializeEvalRun),
|
|
275
349
|
hasMore: page.nextCursor !== undefined,
|
|
276
350
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
277
351
|
});
|
|
@@ -279,6 +353,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
279
353
|
|
|
280
354
|
// ---------- GET /:runId ----------
|
|
281
355
|
r.get('/:runId', async (c) => {
|
|
356
|
+
const refused = await onRunSuite(c, 'read');
|
|
357
|
+
if (refused !== undefined) return refused;
|
|
282
358
|
const requestId = c.get('requestId');
|
|
283
359
|
const tenantId = c.get('tenantId') as TenantId;
|
|
284
360
|
const runId = c.req.param('runId') as RunId;
|
|
@@ -298,6 +374,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
298
374
|
|
|
299
375
|
// ---------- POST /:runId/cancel ----------
|
|
300
376
|
r.post('/:runId/cancel', async (c) => {
|
|
377
|
+
const refused = await onRunSuite(c, 'write');
|
|
378
|
+
if (refused !== undefined) return refused;
|
|
301
379
|
const requestId = c.get('requestId');
|
|
302
380
|
const tenantId = c.get('tenantId') as TenantId;
|
|
303
381
|
const runId = c.req.param('runId') as RunId;
|
|
@@ -340,6 +418,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
340
418
|
|
|
341
419
|
// ---------- GET /:runId/events (SSE) ----------
|
|
342
420
|
r.get('/:runId/events', async (c) => {
|
|
421
|
+
const refused = await onRunSuite(c, 'read');
|
|
422
|
+
if (refused !== undefined) return refused;
|
|
343
423
|
const requestId = c.get('requestId');
|
|
344
424
|
const tenantId = c.get('tenantId') as TenantId;
|
|
345
425
|
const runId = c.req.param('runId') as RunId;
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import type { Authorizer } from '../middleware/authorize.js';
|
|
17
17
|
import type { AppEnv } from '../types.js';
|
|
18
18
|
import { clampLimit } from './pagination.js';
|
|
19
|
+
import { projectMismatch } from './project-mismatch.js';
|
|
19
20
|
import { parseScopeParams } from './scope-params.js';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -77,6 +78,19 @@ export function evalSuitesRouter(
|
|
|
77
78
|
r.use('/:suiteId/*', async (c, next) => {
|
|
78
79
|
const action = c.req.method === 'GET' ? 'read' : 'admin';
|
|
79
80
|
const suiteId = c.req.param('suiteId') ?? '';
|
|
81
|
+
// A test set built from judgments under a suite id never registered
|
|
82
|
+
// (no head row) has no suite to check yet: the build checks `admin`
|
|
83
|
+
// on the project it names, the project the new suite belongs to. A
|
|
84
|
+
// tombstoned suite keeps its head row, so it's checked as an existing
|
|
85
|
+
// one. Anything else under a suite id, and a build under an existing
|
|
86
|
+
// suite, checks the suite.
|
|
87
|
+
if (
|
|
88
|
+
c.req.method === 'POST' &&
|
|
89
|
+
c.req.path.endsWith('/versions/from-judgments') &&
|
|
90
|
+
!(await binding.headExists({ tenantId: c.get('tenantId') as TenantId, suiteId }))
|
|
91
|
+
) {
|
|
92
|
+
return next();
|
|
93
|
+
}
|
|
80
94
|
const mw = authorizer.authorize(action, () => ref('eval_suite', suiteId));
|
|
81
95
|
return mw(c, next);
|
|
82
96
|
});
|
|
@@ -128,8 +142,15 @@ export function evalSuitesRouter(
|
|
|
128
142
|
...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
|
|
129
143
|
...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
|
|
130
144
|
});
|
|
145
|
+
// Only what the caller may read (T243 A), as `GET …/:id` asks.
|
|
146
|
+
const visible =
|
|
147
|
+
authorizer === undefined
|
|
148
|
+
? page.data
|
|
149
|
+
: await authorizer.filterByCan(c, 'read', page.data, (a) =>
|
|
150
|
+
ref('eval_suite', a.id as unknown as string),
|
|
151
|
+
);
|
|
131
152
|
return c.json({
|
|
132
|
-
data:
|
|
153
|
+
data: visible.map(serializeEvalSuite),
|
|
133
154
|
hasMore: page.nextCursor !== undefined,
|
|
134
155
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
135
156
|
});
|
|
@@ -318,6 +339,9 @@ export function evalSuitesRouter(
|
|
|
318
339
|
),
|
|
319
340
|
);
|
|
320
341
|
}
|
|
342
|
+
if (outcome.kind === 'project-mismatch') {
|
|
343
|
+
return projectMismatch(c, 'eval-suite', outcome.suiteId, outcome.projectId);
|
|
344
|
+
}
|
|
321
345
|
if (outcome.kind === 'project-not-found') {
|
|
322
346
|
// Caller supplied a `projectId` that does not resolve within
|
|
323
347
|
// this tenant. Distinct signal from `already-registered` so the
|