@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,77 @@
|
|
|
1
|
+
import type { ReviewerRole } from '@kindgi/authz';
|
|
2
|
+
import type { ProjectRole, TeamRole } from '@kindgi/platform';
|
|
3
|
+
import type { Result, TenantId } from '@kindgi/types';
|
|
4
|
+
/**
|
|
5
|
+
* A person's grants: what a person of the tenant may do, read in one
|
|
6
|
+
* call, and tenant admin given or taken (`/v1/identity/users/:id/grants`,
|
|
7
|
+
* `/grant`, `/ungrant`).
|
|
8
|
+
*
|
|
9
|
+
* The read lists what was granted *directly*: tenant admin, a role on a
|
|
10
|
+
* project (its memberships), a role in a team, and the reviewer roster.
|
|
11
|
+
* What a team's or an org's grants imply is not expanded. Project and
|
|
12
|
+
* team roles keep their own membership routes; only tenant admin is
|
|
13
|
+
* granted here, written before the call answers so the person's next
|
|
14
|
+
* request already holds it.
|
|
15
|
+
*/
|
|
16
|
+
export interface PersonGrants {
|
|
17
|
+
readonly userId: string;
|
|
18
|
+
/** Absent when the runtime has no authorization store: nothing grants it then. */
|
|
19
|
+
readonly tenantAdmin?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* A tenant member: reads the tenant's settings, not its projects. A
|
|
22
|
+
* person is one from being added. Absent when the runtime has no
|
|
23
|
+
* authorization store, or doesn't report it.
|
|
24
|
+
*/
|
|
25
|
+
readonly tenantMember?: boolean;
|
|
26
|
+
/** Direct project memberships. */
|
|
27
|
+
readonly projects: readonly {
|
|
28
|
+
readonly projectId: string;
|
|
29
|
+
readonly role: ProjectRole;
|
|
30
|
+
}[];
|
|
31
|
+
/** Team memberships. */
|
|
32
|
+
readonly teams: readonly {
|
|
33
|
+
readonly teamId: string;
|
|
34
|
+
readonly role: TeamRole;
|
|
35
|
+
}[];
|
|
36
|
+
/** The person's active entry on the reviewer roster. */
|
|
37
|
+
readonly reviewer?: {
|
|
38
|
+
readonly role: ReviewerRole;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** What `grant` and `ungrant` take: tenant admin (project and team roles have membership routes). */
|
|
42
|
+
export type PersonGrant = {
|
|
43
|
+
readonly kind: 'tenant-admin';
|
|
44
|
+
};
|
|
45
|
+
export interface PersonRef {
|
|
46
|
+
readonly tenantId: TenantId;
|
|
47
|
+
readonly userId: string;
|
|
48
|
+
}
|
|
49
|
+
/** A change to a person's grants, and who made it: `user:<id>` or `service_account:<id>`. */
|
|
50
|
+
export interface PersonGrantChange extends PersonRef {
|
|
51
|
+
readonly grant: PersonGrant;
|
|
52
|
+
readonly by?: string;
|
|
53
|
+
}
|
|
54
|
+
export type PersonGrantErrorCode =
|
|
55
|
+
/** No such person in the tenant's directory. */
|
|
56
|
+
'identity-user-not-found'
|
|
57
|
+
/** Granting to a person who was removed from the tenant. */
|
|
58
|
+
| 'identity-user-unregistered'
|
|
59
|
+
/** Removing tenant admin from the only person who holds it. */
|
|
60
|
+
| 'last-tenant-admin'
|
|
61
|
+
/** Removing tenant admin from the seed user, whom the runtime grants it at every boot. */
|
|
62
|
+
| 'seed-user-admin'
|
|
63
|
+
/** The runtime has no authorization store to write grants to. */
|
|
64
|
+
| 'person-grants-unsupported';
|
|
65
|
+
export interface PersonGrantError {
|
|
66
|
+
readonly code: PersonGrantErrorCode;
|
|
67
|
+
readonly message: string;
|
|
68
|
+
}
|
|
69
|
+
export interface PersonGrantsBinding {
|
|
70
|
+
/** The person's grants, or `null` when there's no such person. */
|
|
71
|
+
read(input: PersonRef): Promise<PersonGrants | null>;
|
|
72
|
+
/** Grant (a no-op when held); answers with the grants after. */
|
|
73
|
+
grant(input: PersonGrantChange): Promise<Result<PersonGrants, PersonGrantError>>;
|
|
74
|
+
/** Remove (a no-op when not held); answers with the grants after. */
|
|
75
|
+
ungrant(input: PersonGrantChange): Promise<Result<PersonGrants, PersonGrantError>>;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=person-grants-binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"person-grants-binding.d.ts","sourceRoot":"","sources":["../src/person-grants-binding.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC;IACzF,wBAAwB;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,EAAE,CAAC;IAChF,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;KAAE,CAAC;CACrD;AAED,qGAAqG;AACrG,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAE5D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,6FAA6F;AAC7F,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,oBAAoB;AAC9B,gDAAgD;AAC9C,yBAAyB;AAC3B,4DAA4D;GAC1D,4BAA4B;AAC9B,+DAA+D;GAC7D,mBAAmB;AACrB,0FAA0F;GACxF,iBAAiB;AACnB,iEAAiE;GAC/D,2BAA2B,CAAC;AAEhC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACrD,gEAAgE;IAChE,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACjF,qEAAqE;IACrE,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;CACpF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"person-grants-binding.js","sourceRoot":"","sources":["../src/person-grants-binding.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { ProjectBinding } from '@kindgi/platform';
|
|
2
|
+
import type { LiveScope, TenantId } from '@kindgi/types';
|
|
3
|
+
import type { AgentRegistryBinding } from './agent-binding.js';
|
|
4
|
+
import type { BlockRegistryBinding } from './block-binding.js';
|
|
5
|
+
import type { EvalComparison, EvalRunBinding } from './eval-run-binding.js';
|
|
6
|
+
import type { GateApproval } from './gate.js';
|
|
7
|
+
import type { AgentReleaseBindings, Promotion, PromotionActor } from './live-version-binding.js';
|
|
8
|
+
import { type FixProposalStatus, type ProposalEvaluationOutcome } from './proposal-status.js';
|
|
9
|
+
import { type PromotionRequestOutcome } from './routes/agent-releases.js';
|
|
10
|
+
import type { ProposalDrafter, ProposalEvidence, ProposalObjective, ProposalTier, ProposedChange, StoredProposal, SupervisorBinding } from './supervisor-binding.js';
|
|
11
|
+
/**
|
|
12
|
+
* The improvement-proposal lifecycle, from the bindings it runs on: what
|
|
13
|
+
* `/v1/proposals` serves, and what a runtime's improvement pass drafts
|
|
14
|
+
* and evaluates its proposal with. No authorization here: the route
|
|
15
|
+
* checks the caller; a pass acts as the runtime. Each call answers an
|
|
16
|
+
* outcome; an error carries the wire code the route answers with.
|
|
17
|
+
*/
|
|
18
|
+
export interface ProposalServiceDeps {
|
|
19
|
+
readonly store: Pick<SupervisorBinding, 'listProposals' | 'getProposal' | 'createProposal' | 'recordProposal'>;
|
|
20
|
+
readonly agents: AgentRegistryBinding;
|
|
21
|
+
readonly blocks: BlockRegistryBinding;
|
|
22
|
+
readonly evalRuns: EvalRunBinding;
|
|
23
|
+
readonly releases: AgentReleaseBindings;
|
|
24
|
+
readonly projects?: ProjectBinding;
|
|
25
|
+
}
|
|
26
|
+
/** An error with the code the API answers it with (`statusFor`), and its details. */
|
|
27
|
+
export type ProposalServiceError = {
|
|
28
|
+
readonly code: string;
|
|
29
|
+
readonly message: string;
|
|
30
|
+
} & Readonly<Record<string, unknown>>;
|
|
31
|
+
export type ProposalOutcome<T> = {
|
|
32
|
+
readonly kind: 'ok';
|
|
33
|
+
readonly value: T;
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: 'err';
|
|
36
|
+
readonly error: ProposalServiceError;
|
|
37
|
+
};
|
|
38
|
+
/** What a proposal's ids resolve to now, and the status that follows. */
|
|
39
|
+
export interface ProposalFacts {
|
|
40
|
+
readonly status: FixProposalStatus;
|
|
41
|
+
readonly evaluation?: ProposalEvaluationOutcome | null;
|
|
42
|
+
readonly promotion?: Promotion | null;
|
|
43
|
+
/** For a promoted proposal: whether its version still serves the scope. */
|
|
44
|
+
readonly liveNow?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface DraftProposalInput {
|
|
47
|
+
readonly tenantId: TenantId;
|
|
48
|
+
readonly agentId: string;
|
|
49
|
+
readonly fromVersion: string;
|
|
50
|
+
readonly scope: LiveScope;
|
|
51
|
+
readonly tier: ProposalTier;
|
|
52
|
+
readonly blockId: string;
|
|
53
|
+
readonly content: ProposedChange['change']['content'];
|
|
54
|
+
readonly hypothesis: string;
|
|
55
|
+
readonly evidence?: ProposalEvidence;
|
|
56
|
+
readonly drafter: ProposalDrafter;
|
|
57
|
+
}
|
|
58
|
+
export interface EvaluateProposalInput {
|
|
59
|
+
readonly tenantId: TenantId;
|
|
60
|
+
readonly proposal: StoredProposal;
|
|
61
|
+
readonly suiteId: string;
|
|
62
|
+
readonly objective: ProposalObjective;
|
|
63
|
+
readonly comparison?: EvalComparison;
|
|
64
|
+
/** Who it's done for: what the derived version records as `by`. */
|
|
65
|
+
readonly actor: PromotionActor;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* What a promotion that a drafter (not a person) asks for needs even when
|
|
69
|
+
* the scope's policy asks for none: a reviewer (K2). Any reviewer may
|
|
70
|
+
* approve: the drafter, not a person, requested it.
|
|
71
|
+
*/
|
|
72
|
+
export declare const DRAFTED_PROPOSAL_APPROVAL: GateApproval;
|
|
73
|
+
export declare function createProposalService(deps: ProposalServiceDeps): {
|
|
74
|
+
facts: (tenantId: TenantId) => (p: StoredProposal) => Promise<ProposalFacts>;
|
|
75
|
+
/**
|
|
76
|
+
* Store a proposal: new content for a block `fromVersion` pins, checked
|
|
77
|
+
* as publishing that block version would be. `deduped` when the same
|
|
78
|
+
* change from the same version for the same scope is open already.
|
|
79
|
+
*/
|
|
80
|
+
draft(input: DraftProposalInput): Promise<ProposalOutcome<{
|
|
81
|
+
proposal: StoredProposal;
|
|
82
|
+
deduped: boolean;
|
|
83
|
+
}>>;
|
|
84
|
+
/**
|
|
85
|
+
* Publish the proposal's block version and derive its agent version
|
|
86
|
+
* (once: an evaluation again reuses them), then start the comparison.
|
|
87
|
+
* Needs a writable agent registry and a tenant-wide live version.
|
|
88
|
+
*/
|
|
89
|
+
evaluate(input: EvaluateProposalInput): Promise<ProposalOutcome<StoredProposal>>;
|
|
90
|
+
/**
|
|
91
|
+
* A gated promotion of the candidate for the proposal's scope, with its
|
|
92
|
+
* evaluation's comparison. A drafter's proposal always waits for a
|
|
93
|
+
* reviewer (K2). `promotion` is the request's outcome, as promotions
|
|
94
|
+
* answer it; the proposal records its promotion once one is recorded.
|
|
95
|
+
*/
|
|
96
|
+
request(input: {
|
|
97
|
+
readonly tenantId: TenantId;
|
|
98
|
+
readonly proposal: StoredProposal;
|
|
99
|
+
readonly actor: PromotionActor;
|
|
100
|
+
readonly reason?: string;
|
|
101
|
+
}): Promise<ProposalOutcome<{
|
|
102
|
+
proposal: StoredProposal;
|
|
103
|
+
promotion: PromotionRequestOutcome;
|
|
104
|
+
}>>;
|
|
105
|
+
/** The scope back on its own pin before the proposal's promotion (or unpinned). */
|
|
106
|
+
rollback(input: {
|
|
107
|
+
readonly tenantId: TenantId;
|
|
108
|
+
readonly proposal: StoredProposal;
|
|
109
|
+
readonly actor: PromotionActor;
|
|
110
|
+
readonly reason?: string;
|
|
111
|
+
}): Promise<ProposalOutcome<StoredProposal>>;
|
|
112
|
+
withdraw(input: {
|
|
113
|
+
readonly tenantId: TenantId;
|
|
114
|
+
readonly proposal: StoredProposal;
|
|
115
|
+
readonly actor: PromotionActor;
|
|
116
|
+
readonly reason: string;
|
|
117
|
+
}): Promise<ProposalOutcome<StoredProposal>>;
|
|
118
|
+
};
|
|
119
|
+
export type ProposalService = ReturnType<typeof createProposalService>;
|
|
120
|
+
export declare function proposalNotFound(proposalId: string): ProposalServiceError;
|
|
121
|
+
//# sourceMappingURL=proposal-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal-service.d.ts","sourceRoot":"","sources":["../src/proposal-service.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAiB,QAAQ,EAAqB,MAAM,eAAe,CAAC;AAE3F,OAAO,KAAK,EAAE,oBAAoB,EAAsB,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAuB,MAAM,uBAAuB,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,oBAAoB,EAEpB,SAAS,EACT,cAAc,EACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,iBAAiB,EAGtB,KAAK,yBAAyB,EAI/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,uBAAuB,EAAoB,MAAM,4BAA4B,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EAEjB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAClB,iBAAiB,EACjB,eAAe,GAAG,aAAa,GAAG,gBAAgB,GAAG,gBAAgB,CACtE,CAAC;IACF,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;CACpC;AAED,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAC/F,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACxB,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC1C;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAEnE,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;IACrC,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,YAIvC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB;sBAIpC,QAAQ,KAAG,CAAC,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,aAAa,CAAC;IA0I/E;;;;OAIG;iBAEM,kBAAkB,GACxB,OAAO,CAAC,eAAe,CAAC;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IA8D3E;;;;OAIG;oBACmB,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;IA8DtF;;;;;OAKG;mBACkB;QACnB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,eAAe,CAAC;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,SAAS,EAAE,uBAAuB,CAAA;KAAE,CAAC,CAAC;IAmC9F,mFAAmF;oBAC7D;QACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;oBA2CtB;QACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;QAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;EAa/C;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIvE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAEzE"}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { tuplesForCreate } from '@kindgi/authz';
|
|
5
|
+
import { canonicalize } from '@kindgi/schema';
|
|
6
|
+
import { blockEditDefinition, publishBlockEdit } from './block-publish.js';
|
|
7
|
+
import { deriveAgentVersion } from './derive-agent-version.js';
|
|
8
|
+
import { PROPOSAL_ACTIONS, evaluationOutcome, proposalActionAllowed, proposalStatus, } from './proposal-status.js';
|
|
9
|
+
import { requestPromotion } from './routes/agent-releases.js';
|
|
10
|
+
import { liveScopeToWire } from './routes/live-scope-wire.js';
|
|
11
|
+
/**
|
|
12
|
+
* What a promotion that a drafter (not a person) asks for needs even when
|
|
13
|
+
* the scope's policy asks for none: a reviewer (K2). Any reviewer may
|
|
14
|
+
* approve: the drafter, not a person, requested it.
|
|
15
|
+
*/
|
|
16
|
+
export const DRAFTED_PROPOSAL_APPROVAL = {
|
|
17
|
+
role: 'standard',
|
|
18
|
+
count: 1,
|
|
19
|
+
separateApprover: false,
|
|
20
|
+
};
|
|
21
|
+
export function createProposalService(deps) {
|
|
22
|
+
const err = (error) => ({ kind: 'err', error });
|
|
23
|
+
/** A reader of proposal facts for one call: each agent's pins are read once. */
|
|
24
|
+
function facts(tenantId) {
|
|
25
|
+
const pins = new Map();
|
|
26
|
+
const pinsOf = (agentId) => {
|
|
27
|
+
const known = pins.get(agentId);
|
|
28
|
+
if (known !== undefined)
|
|
29
|
+
return known;
|
|
30
|
+
const found = deps.releases.live.list({ tenantId, agentId });
|
|
31
|
+
pins.set(agentId, found);
|
|
32
|
+
return found;
|
|
33
|
+
};
|
|
34
|
+
return async (p) => {
|
|
35
|
+
const promotion = p.promotionId === undefined
|
|
36
|
+
? undefined
|
|
37
|
+
: await deps.releases.promotions.get(tenantId, p.promotionId);
|
|
38
|
+
let evaluation;
|
|
39
|
+
if (p.evaluation !== undefined) {
|
|
40
|
+
const run = await deps.evalRuns.get({ tenantId, runId: p.evaluation.evalRunId });
|
|
41
|
+
evaluation = run === null ? null : evaluationOutcome(p.evaluation.objective, run);
|
|
42
|
+
}
|
|
43
|
+
const status = proposalStatus(p, promotion, evaluation);
|
|
44
|
+
let liveNow;
|
|
45
|
+
if (status === 'promoted' && promotion !== undefined && promotion !== null) {
|
|
46
|
+
const all = await pinsOf(p.agentId);
|
|
47
|
+
liveNow = all.some((pin) => pin.promotionId === promotion.id);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
status,
|
|
51
|
+
...(evaluation !== undefined && { evaluation }),
|
|
52
|
+
...(promotion !== undefined && { promotion }),
|
|
53
|
+
...(liveNow !== undefined && { liveNow }),
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** The 409 when the proposal's status doesn't allow `action`. */
|
|
58
|
+
async function refuseStatus(action, proposal, seen) {
|
|
59
|
+
const f = seen ?? (await facts(proposal.tenantId)(proposal));
|
|
60
|
+
if (proposalActionAllowed(action, f.status))
|
|
61
|
+
return undefined;
|
|
62
|
+
return invalidTransition(proposal, f.status, `it's ${f.status}, and ${action} needs one of: ${PROPOSAL_ACTIONS[action].join(', ')}.`);
|
|
63
|
+
}
|
|
64
|
+
/** Record a step; the 409 when another call recorded one first. */
|
|
65
|
+
async function record(proposal, step) {
|
|
66
|
+
const outcome = await deps.store.recordProposal({
|
|
67
|
+
tenantId: proposal.tenantId,
|
|
68
|
+
proposalId: proposal.id,
|
|
69
|
+
expectRevision: proposal.revision,
|
|
70
|
+
step,
|
|
71
|
+
});
|
|
72
|
+
if (outcome.kind === 'ok')
|
|
73
|
+
return { kind: 'ok', value: outcome.proposal };
|
|
74
|
+
if (outcome.kind === 'not-found')
|
|
75
|
+
return err(proposalNotFound(proposal.id));
|
|
76
|
+
return err({
|
|
77
|
+
code: 'proposal-invalid-state-transition',
|
|
78
|
+
message: `Proposal ${proposal.id} changed while this ran: read it again`,
|
|
79
|
+
proposalId: proposal.id,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Publish the block version and derive the agent version a proposal is evaluated as. */
|
|
83
|
+
async function makeCandidate(proposal, actor) {
|
|
84
|
+
const { tenantId } = proposal;
|
|
85
|
+
const { blockId, fromVersion } = proposal.change;
|
|
86
|
+
const from = await deps.blocks.getVersion({ tenantId, blockId, version: fromVersion });
|
|
87
|
+
if (from === null) {
|
|
88
|
+
return err(validationFailed(`Block "${blockId}" version ${fromVersion} is gone`, []));
|
|
89
|
+
}
|
|
90
|
+
const published = await publishBlockEdit({
|
|
91
|
+
blocks: deps.blocks,
|
|
92
|
+
tenantId,
|
|
93
|
+
from,
|
|
94
|
+
edit: editOf(proposal.tier, proposal.change.content),
|
|
95
|
+
});
|
|
96
|
+
if (published.kind === 'invalid') {
|
|
97
|
+
return err(validationFailed(`The proposal's content can't be published as block "${blockId}"`, published.issues));
|
|
98
|
+
}
|
|
99
|
+
const pinKind = proposal.tier === 'settings-block' ? 'settings' : 'prompts';
|
|
100
|
+
const userId = actor.kind === 'user' ? actor.id : undefined;
|
|
101
|
+
const derived = await deriveAgentVersion({
|
|
102
|
+
agents: deps.agents,
|
|
103
|
+
blocks: deps.blocks,
|
|
104
|
+
tenantId,
|
|
105
|
+
agentId: proposal.agentId,
|
|
106
|
+
from: proposal.fromVersion,
|
|
107
|
+
swaps: { [pinKind]: { [blockId]: published.version } },
|
|
108
|
+
label: `proposal ${proposal.id}`,
|
|
109
|
+
by: `${actor.kind}:${actor.id}`,
|
|
110
|
+
proposalId: proposal.id,
|
|
111
|
+
tuplesFor: (projectId) => (id) => tuplesForCreate({ kind: 'agent', id: id, tenantId, projectId }, userId ?? '00000000-0000-0000-0000-000000000000'),
|
|
112
|
+
});
|
|
113
|
+
if (derived.kind !== 'ok' && derived.kind !== 'reused') {
|
|
114
|
+
return err(validationFailed(derived.kind === 'invalid'
|
|
115
|
+
? `Can't derive a version from ${proposal.fromVersion}`
|
|
116
|
+
: `Can't derive a version from ${proposal.fromVersion} (${derived.kind})`, derived.kind === 'invalid' ? derived.issues : []));
|
|
117
|
+
}
|
|
118
|
+
const { agent } = derived;
|
|
119
|
+
if (agent.pinsDigest === undefined)
|
|
120
|
+
throw new Error('a derived version is pinned');
|
|
121
|
+
return {
|
|
122
|
+
kind: 'ok',
|
|
123
|
+
value: {
|
|
124
|
+
agentVersion: agent.version,
|
|
125
|
+
blockVersion: published.version,
|
|
126
|
+
pinsDigest: agent.pinsDigest,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
facts,
|
|
132
|
+
/**
|
|
133
|
+
* Store a proposal: new content for a block `fromVersion` pins, checked
|
|
134
|
+
* as publishing that block version would be. `deduped` when the same
|
|
135
|
+
* change from the same version for the same scope is open already.
|
|
136
|
+
*/
|
|
137
|
+
async draft(input) {
|
|
138
|
+
const { tenantId } = input;
|
|
139
|
+
const from = await deps.agents.getVersion({
|
|
140
|
+
tenantId,
|
|
141
|
+
agentId: input.agentId,
|
|
142
|
+
version: input.fromVersion,
|
|
143
|
+
});
|
|
144
|
+
if (from === null || from.unregisteredAt !== undefined) {
|
|
145
|
+
return err({
|
|
146
|
+
code: 'agent-version-not-found',
|
|
147
|
+
message: `${input.agentId} has no active version ${input.fromVersion}`,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const pinned = await pinnedBlock(deps.blocks, tenantId, from, input.tier, input.blockId);
|
|
151
|
+
if (pinned.kind === 'invalid')
|
|
152
|
+
return err(validationFailed(pinned.message, pinned.issues));
|
|
153
|
+
const edit = editOf(input.tier, input.content);
|
|
154
|
+
const checked = await blockEditDefinition({ blocks: deps.blocks, tenantId, from: pinned.block, edit }, pinned.block.version);
|
|
155
|
+
if (checked.kind === 'invalid') {
|
|
156
|
+
return err(validationFailed(`The new content isn't a valid version of block "${input.blockId}"`, checked.issues));
|
|
157
|
+
}
|
|
158
|
+
if (sameContent(pinned.block, edit)) {
|
|
159
|
+
return err(validationFailed(`The proposal doesn't change block "${input.blockId}"`, [
|
|
160
|
+
{
|
|
161
|
+
path: '/change/content',
|
|
162
|
+
message: `equals version ${pinned.block.version}, which ${input.fromVersion} pins`,
|
|
163
|
+
},
|
|
164
|
+
]));
|
|
165
|
+
}
|
|
166
|
+
const change = {
|
|
167
|
+
blockId: input.blockId,
|
|
168
|
+
fromVersion: pinned.block.version,
|
|
169
|
+
content: input.content,
|
|
170
|
+
};
|
|
171
|
+
const outcome = await deps.store.createProposal({
|
|
172
|
+
tenantId,
|
|
173
|
+
...(from.projectId !== undefined && { projectId: from.projectId }),
|
|
174
|
+
agentId: input.agentId,
|
|
175
|
+
fromVersion: input.fromVersion,
|
|
176
|
+
scope: input.scope,
|
|
177
|
+
tier: input.tier,
|
|
178
|
+
change,
|
|
179
|
+
hypothesis: input.hypothesis,
|
|
180
|
+
...(input.evidence !== undefined && { evidence: input.evidence }),
|
|
181
|
+
drafter: input.drafter,
|
|
182
|
+
fingerprint: fingerprintOf(input, change),
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
kind: 'ok',
|
|
186
|
+
value: { proposal: outcome.proposal, deduped: outcome.kind === 'dedup' },
|
|
187
|
+
};
|
|
188
|
+
},
|
|
189
|
+
/**
|
|
190
|
+
* Publish the proposal's block version and derive its agent version
|
|
191
|
+
* (once: an evaluation again reuses them), then start the comparison.
|
|
192
|
+
* Needs a writable agent registry and a tenant-wide live version.
|
|
193
|
+
*/
|
|
194
|
+
async evaluate(input) {
|
|
195
|
+
const { tenantId } = input;
|
|
196
|
+
let proposal = input.proposal;
|
|
197
|
+
const agentId = proposal.agentId;
|
|
198
|
+
const refused = await refuseStatus('evaluate', proposal);
|
|
199
|
+
if (refused !== undefined)
|
|
200
|
+
return err(refused);
|
|
201
|
+
// Evaluating derives an agent version: not into a registry that takes no writes.
|
|
202
|
+
if (deps.agents.readOnly !== undefined) {
|
|
203
|
+
return err({ code: 'registry-read-only', message: deps.agents.readOnly.reason });
|
|
204
|
+
}
|
|
205
|
+
// A version promoted nowhere is still the agent's latest, and the
|
|
206
|
+
// latest serves every scope nothing is pinned for.
|
|
207
|
+
if ((await deps.releases.live.resolve({ tenantId, agentId })) === null) {
|
|
208
|
+
return err({
|
|
209
|
+
code: 'proposal-needs-pin',
|
|
210
|
+
message: `${agentId} has no live version for the whole tenant, so a new version of it would serve every scope nothing is pinned for. Promote its current version for the tenant first (scope { "kind": "tenant" }), then evaluate.`,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
if (proposal.candidate === undefined) {
|
|
214
|
+
const made = await makeCandidate(proposal, input.actor);
|
|
215
|
+
if (made.kind === 'err')
|
|
216
|
+
return made;
|
|
217
|
+
const recorded = await record(proposal, { kind: 'candidate', candidate: made.value });
|
|
218
|
+
if (recorded.kind === 'err')
|
|
219
|
+
return recorded;
|
|
220
|
+
proposal = recorded.value;
|
|
221
|
+
}
|
|
222
|
+
const candidate = proposal.candidate;
|
|
223
|
+
if (candidate === undefined)
|
|
224
|
+
throw new Error('a recorded candidate is on the proposal');
|
|
225
|
+
const version = await deps.agents.getVersion({
|
|
226
|
+
tenantId,
|
|
227
|
+
agentId: proposal.agentId,
|
|
228
|
+
version: candidate.agentVersion,
|
|
229
|
+
});
|
|
230
|
+
if (version === null ||
|
|
231
|
+
version.unregisteredAt !== undefined ||
|
|
232
|
+
version.projectId === undefined) {
|
|
233
|
+
return err({
|
|
234
|
+
code: 'agent-version-not-found',
|
|
235
|
+
message: `The candidate ${agentId} ${candidate.agentVersion} is unregistered: withdraw this proposal and draft it again`,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const started = await deps.evalRuns.start({
|
|
239
|
+
tenantId,
|
|
240
|
+
projectId: version.projectId,
|
|
241
|
+
suiteId: input.suiteId,
|
|
242
|
+
agentRef: { agentId: proposal.agentId, version: candidate.agentVersion },
|
|
243
|
+
correlationId: `proposal:${proposal.id}`,
|
|
244
|
+
...(input.comparison !== undefined && { comparison: input.comparison }),
|
|
245
|
+
});
|
|
246
|
+
if (started.kind !== 'ok')
|
|
247
|
+
return err(startError(started));
|
|
248
|
+
return record(proposal, {
|
|
249
|
+
kind: 'evaluation',
|
|
250
|
+
evaluation: {
|
|
251
|
+
evalRunId: started.runId,
|
|
252
|
+
suiteId: input.suiteId,
|
|
253
|
+
objective: input.objective,
|
|
254
|
+
startedAt: new Date().toISOString(),
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
/**
|
|
259
|
+
* A gated promotion of the candidate for the proposal's scope, with its
|
|
260
|
+
* evaluation's comparison. A drafter's proposal always waits for a
|
|
261
|
+
* reviewer (K2). `promotion` is the request's outcome, as promotions
|
|
262
|
+
* answer it; the proposal records its promotion once one is recorded.
|
|
263
|
+
*/
|
|
264
|
+
async request(input) {
|
|
265
|
+
const { tenantId, proposal } = input;
|
|
266
|
+
const refused = await refuseStatus('request', proposal);
|
|
267
|
+
if (refused !== undefined)
|
|
268
|
+
return err(refused);
|
|
269
|
+
const { candidate, evaluation } = proposal;
|
|
270
|
+
if (candidate === undefined || evaluation === undefined) {
|
|
271
|
+
throw new Error('an evaluated proposal has a candidate and an evaluation');
|
|
272
|
+
}
|
|
273
|
+
const promotion = await requestPromotion(deps.agents, deps.releases, {
|
|
274
|
+
evalRuns: deps.evalRuns,
|
|
275
|
+
...(deps.projects !== undefined && { projects: deps.projects }),
|
|
276
|
+
}, {
|
|
277
|
+
tenantId,
|
|
278
|
+
agentId: proposal.agentId,
|
|
279
|
+
version: candidate.agentVersion,
|
|
280
|
+
scope: proposal.scope,
|
|
281
|
+
requestedBy: input.actor,
|
|
282
|
+
reason: input.reason ?? `Improvement proposal ${proposal.id}`,
|
|
283
|
+
evalRunId: evaluation.evalRunId,
|
|
284
|
+
}, proposal.drafter.kind === 'person' ? {} : { requireApproval: DRAFTED_PROPOSAL_APPROVAL });
|
|
285
|
+
if (promotion.kind !== 'ok')
|
|
286
|
+
return { kind: 'ok', value: { proposal, promotion } };
|
|
287
|
+
const recorded = await record(proposal, {
|
|
288
|
+
kind: 'promotion',
|
|
289
|
+
promotionId: promotion.promotion.id,
|
|
290
|
+
});
|
|
291
|
+
if (recorded.kind === 'err')
|
|
292
|
+
return recorded;
|
|
293
|
+
return { kind: 'ok', value: { proposal: recorded.value, promotion } };
|
|
294
|
+
},
|
|
295
|
+
/** The scope back on its own pin before the proposal's promotion (or unpinned). */
|
|
296
|
+
async rollback(input) {
|
|
297
|
+
const { tenantId, proposal } = input;
|
|
298
|
+
const seen = await facts(tenantId)(proposal);
|
|
299
|
+
const refused = await refuseStatus('rollback', proposal, seen);
|
|
300
|
+
if (refused !== undefined)
|
|
301
|
+
return err(refused);
|
|
302
|
+
const promotion = seen.promotion;
|
|
303
|
+
if (promotion === null || promotion === undefined || seen.liveNow !== true) {
|
|
304
|
+
return err(invalidTransition(proposal, seen.status, "its version doesn't serve the scope anymore (the scope was promoted, rolled back or unpinned since), so there's nothing of it to roll back."));
|
|
305
|
+
}
|
|
306
|
+
const request = {
|
|
307
|
+
tenantId,
|
|
308
|
+
agentId: proposal.agentId,
|
|
309
|
+
scope: proposal.scope,
|
|
310
|
+
requestedBy: input.actor,
|
|
311
|
+
reason: input.reason ?? `Rolled back improvement proposal ${proposal.id}`,
|
|
312
|
+
};
|
|
313
|
+
// Back to the scope's own pin before; with none, it falls back to the scope above.
|
|
314
|
+
const outcome = promotion.fromVersion === null
|
|
315
|
+
? await deps.releases.promotions.unpin(request)
|
|
316
|
+
: await deps.releases.promotions.rollback({
|
|
317
|
+
...request,
|
|
318
|
+
toVersion: promotion.fromVersion,
|
|
319
|
+
});
|
|
320
|
+
if (outcome.kind === 'err')
|
|
321
|
+
return err({ ...outcome.error });
|
|
322
|
+
return record(proposal, {
|
|
323
|
+
kind: 'rolled-back',
|
|
324
|
+
rolledBack: {
|
|
325
|
+
at: new Date().toISOString(),
|
|
326
|
+
promotionId: outcome.value.id,
|
|
327
|
+
by: `${input.actor.kind}:${input.actor.id}`,
|
|
328
|
+
...(input.reason !== undefined && { reason: input.reason }),
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
},
|
|
332
|
+
async withdraw(input) {
|
|
333
|
+
const refused = await refuseStatus('withdraw', input.proposal);
|
|
334
|
+
if (refused !== undefined)
|
|
335
|
+
return err(refused);
|
|
336
|
+
return record(input.proposal, {
|
|
337
|
+
kind: 'withdrawn',
|
|
338
|
+
withdrawn: {
|
|
339
|
+
at: new Date().toISOString(),
|
|
340
|
+
by: `${input.actor.kind}:${input.actor.id}`,
|
|
341
|
+
reason: input.reason,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
// ---------- helpers ----------
|
|
348
|
+
export function proposalNotFound(proposalId) {
|
|
349
|
+
return { code: 'proposal-not-found', message: `No proposal ${proposalId}`, proposalId };
|
|
350
|
+
}
|
|
351
|
+
function invalidTransition(proposal, status, why) {
|
|
352
|
+
return {
|
|
353
|
+
code: 'proposal-invalid-state-transition',
|
|
354
|
+
message: `Proposal ${proposal.id}: ${why}`,
|
|
355
|
+
proposalId: proposal.id,
|
|
356
|
+
status,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
function validationFailed(message, issues) {
|
|
360
|
+
return {
|
|
361
|
+
code: 'validation-failed',
|
|
362
|
+
message,
|
|
363
|
+
issues: issues,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function startError(outcome) {
|
|
367
|
+
switch (outcome.kind) {
|
|
368
|
+
case 'suite-not-found':
|
|
369
|
+
return {
|
|
370
|
+
code: 'eval-suite-not-found',
|
|
371
|
+
message: `No eval suite registered with id "${outcome.suiteId}"`,
|
|
372
|
+
suiteId: outcome.suiteId,
|
|
373
|
+
};
|
|
374
|
+
case 'dispatcher-not-registered':
|
|
375
|
+
return {
|
|
376
|
+
code: 'dispatcher-not-registered',
|
|
377
|
+
message: `No eval-run dispatcher registered for kind "${outcome.evalKind}"`,
|
|
378
|
+
};
|
|
379
|
+
case 'dispatcher-input-invalid':
|
|
380
|
+
return { code: 'dispatcher-input-invalid', message: outcome.message };
|
|
381
|
+
case 'project-not-found':
|
|
382
|
+
return {
|
|
383
|
+
code: 'bad-input',
|
|
384
|
+
message: `The candidate's project "${outcome.projectId}" isn't in this tenant`,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function editOf(tier, content) {
|
|
389
|
+
return tier === 'settings-block'
|
|
390
|
+
? { kind: 'settings', values: content.values }
|
|
391
|
+
: { kind: 'prompt', template: content.template };
|
|
392
|
+
}
|
|
393
|
+
function sameContent(pinned, edit) {
|
|
394
|
+
if (pinned.kind === 'settings' && edit.kind === 'settings') {
|
|
395
|
+
return canonicalize(pinned.content.values) === canonicalize(edit.values);
|
|
396
|
+
}
|
|
397
|
+
return pinned.kind === 'prompt' && edit.kind === 'prompt'
|
|
398
|
+
? pinned.content.template === edit.template
|
|
399
|
+
: false;
|
|
400
|
+
}
|
|
401
|
+
/** The block version `from` pins for the tier, or why there's none to change. */
|
|
402
|
+
async function pinnedBlock(blocks, tenantId, from, tier, blockId) {
|
|
403
|
+
const kind = tier === 'settings-block' ? 'settings' : 'prompts';
|
|
404
|
+
const what = tier === 'settings-block' ? 'settings' : 'prompt';
|
|
405
|
+
const named = `${from.id} ${from.version}`;
|
|
406
|
+
if (from.pins === undefined) {
|
|
407
|
+
return {
|
|
408
|
+
kind: 'invalid',
|
|
409
|
+
message: `${named} has no pins (it was published before pins); publish it again to pin it`,
|
|
410
|
+
issues: [],
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const version = from.pins[kind][blockId];
|
|
414
|
+
if (version === undefined) {
|
|
415
|
+
return {
|
|
416
|
+
kind: 'invalid',
|
|
417
|
+
message: `${named} doesn't use ${what} block "${blockId}"`,
|
|
418
|
+
issues: [
|
|
419
|
+
{
|
|
420
|
+
path: '/change/blockId',
|
|
421
|
+
message: `not a ${what} block this version pins; adding a block is a code change`,
|
|
422
|
+
},
|
|
423
|
+
],
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
const block = await blocks.getVersion({ tenantId, blockId, version });
|
|
427
|
+
if (block === null) {
|
|
428
|
+
return {
|
|
429
|
+
kind: 'invalid',
|
|
430
|
+
message: `Block "${blockId}" version ${version}, which ${named} pins, isn't in the block store`,
|
|
431
|
+
issues: [],
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return { kind: 'ok', block };
|
|
435
|
+
}
|
|
436
|
+
/** The same change, from the same version, for the same scope, is one proposal. */
|
|
437
|
+
function fingerprintOf(input, change) {
|
|
438
|
+
const canonical = canonicalize({
|
|
439
|
+
agentId: input.agentId,
|
|
440
|
+
fromVersion: input.fromVersion,
|
|
441
|
+
scope: liveScopeToWire(input.scope),
|
|
442
|
+
tier: input.tier,
|
|
443
|
+
change,
|
|
444
|
+
});
|
|
445
|
+
return `sha256:${createHash('sha256').update(canonical, 'utf8').digest('hex')}`;
|
|
446
|
+
}
|
|
447
|
+
//# sourceMappingURL=proposal-service.js.map
|