@kindgi/api 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-binding.d.ts +13 -0
- package/dist/agent-binding.d.ts.map +1 -1
- package/dist/agent-pins.d.ts.map +1 -1
- package/dist/agent-pins.js +18 -2
- package/dist/agent-pins.js.map +1 -1
- package/dist/app.d.ts +110 -17
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +163 -35
- package/dist/app.js.map +1 -1
- package/dist/block-publish.d.ts +56 -0
- package/dist/block-publish.d.ts.map +1 -0
- package/dist/block-publish.js +132 -0
- package/dist/block-publish.js.map +1 -0
- package/dist/caller.d.ts +24 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +47 -0
- package/dist/caller.js.map +1 -0
- package/dist/capability-binding.d.ts +11 -0
- package/dist/capability-binding.d.ts.map +1 -1
- package/dist/cost-binding.d.ts +19 -0
- package/dist/cost-binding.d.ts.map +1 -1
- package/dist/cost-binding.js.map +1 -1
- package/dist/derive-agent-version.d.ts +7 -0
- package/dist/derive-agent-version.d.ts.map +1 -1
- package/dist/derive-agent-version.js +4 -0
- package/dist/derive-agent-version.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +75 -7
- package/dist/errors.js.map +1 -1
- package/dist/eval-case-binding.d.ts +16 -4
- package/dist/eval-case-binding.d.ts.map +1 -1
- package/dist/eval-run-binding.d.ts +31 -0
- package/dist/eval-run-binding.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.d.ts +7 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.js.map +1 -1
- package/dist/eval-sample.d.ts +11 -0
- package/dist/eval-sample.d.ts.map +1 -0
- package/dist/eval-sample.js +34 -0
- package/dist/eval-sample.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +13 -0
- package/dist/eval-suite-binding.d.ts.map +1 -1
- package/dist/eval-suite-binding.js.map +1 -1
- package/dist/flow-binding.d.ts +18 -0
- package/dist/flow-binding.d.ts.map +1 -1
- package/dist/flow-pins.d.ts.map +1 -1
- package/dist/flow-pins.js +18 -2
- package/dist/flow-pins.js.map +1 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +25 -0
- package/dist/gate.js.map +1 -1
- package/dist/handler-binding.d.ts +32 -0
- package/dist/handler-binding.d.ts.map +1 -1
- package/dist/hitl-binding.d.ts +23 -0
- package/dist/hitl-binding.d.ts.map +1 -1
- package/dist/identity-directory-binding.d.ts +82 -4
- package/dist/identity-directory-binding.d.ts.map +1 -1
- package/dist/identity-provider-binding.d.ts +197 -17
- package/dist/identity-provider-binding.d.ts.map +1 -1
- package/dist/improvement-pass-binding.d.ts +196 -0
- package/dist/improvement-pass-binding.d.ts.map +1 -0
- package/dist/improvement-pass-binding.js +9 -0
- package/dist/improvement-pass-binding.js.map +1 -0
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/judged-dispatcher.d.ts +25 -4
- package/dist/judged-dispatcher.d.ts.map +1 -1
- package/dist/judged-dispatcher.js +43 -6
- package/dist/judged-dispatcher.js.map +1 -1
- package/dist/judgment-binding.d.ts +25 -1
- package/dist/judgment-binding.d.ts.map +1 -1
- package/dist/mcp-endpoint-binding.d.ts +7 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -1
- package/dist/memory-binding.d.ts +124 -17
- package/dist/memory-binding.d.ts.map +1 -1
- package/dist/memory-erasure-binding.d.ts +145 -0
- package/dist/memory-erasure-binding.d.ts.map +1 -0
- package/dist/memory-erasure-binding.js +4 -0
- package/dist/memory-erasure-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +66 -13
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +150 -50
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/authorize.d.ts +9 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +122 -4
- package/dist/middleware/authorize.js.map +1 -1
- package/dist/middleware/error-mapper.d.ts +5 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -1
- package/dist/middleware/error-mapper.js +14 -1
- package/dist/middleware/error-mapper.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +70 -5
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +174 -41
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/key-project.d.ts +17 -0
- package/dist/middleware/key-project.d.ts.map +1 -0
- package/dist/middleware/key-project.js +75 -0
- package/dist/middleware/key-project.js.map +1 -0
- package/dist/middleware/principal.d.ts.map +1 -1
- package/dist/middleware/principal.js +9 -5
- package/dist/middleware/principal.js.map +1 -1
- package/dist/middleware/project-ref.d.ts.map +1 -1
- package/dist/middleware/project-ref.js +3 -0
- package/dist/middleware/project-ref.js.map +1 -1
- package/dist/openapi/generate.d.ts.map +1 -1
- package/dist/openapi/generate.js +5 -2
- package/dist/openapi/generate.js.map +1 -1
- package/dist/openapi/operations.d.ts.map +1 -1
- package/dist/openapi/operations.js +919 -140
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +90 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2081 -359
- package/dist/openapi/schemas.js.map +1 -1
- package/dist/person-grants-binding.d.ts +77 -0
- package/dist/person-grants-binding.d.ts.map +1 -0
- package/dist/person-grants-binding.js +4 -0
- package/dist/person-grants-binding.js.map +1 -0
- package/dist/proposal-service.d.ts +121 -0
- package/dist/proposal-service.d.ts.map +1 -0
- package/dist/proposal-service.js +447 -0
- package/dist/proposal-service.js.map +1 -0
- package/dist/proposal-status.d.ts +60 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +109 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/provider-binding.d.ts +10 -0
- package/dist/provider-binding.d.ts.map +1 -1
- package/dist/publish-refused.d.ts +28 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +24 -3
- package/dist/publish-refused.js.map +1 -1
- package/dist/routes/adapters.d.ts +2 -1
- package/dist/routes/adapters.d.ts.map +1 -1
- package/dist/routes/adapters.js +3 -1
- package/dist/routes/adapters.js.map +1 -1
- package/dist/routes/agent-releases.d.ts +55 -3
- package/dist/routes/agent-releases.d.ts.map +1 -1
- package/dist/routes/agent-releases.js +85 -55
- package/dist/routes/agent-releases.js.map +1 -1
- package/dist/routes/agents.d.ts +12 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +100 -2
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts +15 -3
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +133 -122
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/artifacts.d.ts +25 -3
- package/dist/routes/artifacts.d.ts.map +1 -1
- package/dist/routes/artifacts.js +116 -7
- package/dist/routes/artifacts.js.map +1 -1
- package/dist/routes/auth.d.ts +25 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +655 -281
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/blocks.d.ts.map +1 -1
- package/dist/routes/blocks.js +2 -42
- package/dist/routes/blocks.js.map +1 -1
- package/dist/routes/capabilities.d.ts +2 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +6 -1
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +9 -10
- package/dist/routes/compliance.d.ts.map +1 -1
- package/dist/routes/compliance.js +42 -61
- package/dist/routes/compliance.js.map +1 -1
- package/dist/routes/conversations.d.ts +8 -1
- package/dist/routes/conversations.d.ts.map +1 -1
- package/dist/routes/conversations.js +87 -8
- package/dist/routes/conversations.js.map +1 -1
- package/dist/routes/cost.d.ts +12 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +74 -3
- package/dist/routes/cost.js.map +1 -1
- package/dist/routes/denied.d.ts +11 -0
- package/dist/routes/denied.d.ts.map +1 -0
- package/dist/routes/denied.js +17 -0
- package/dist/routes/denied.js.map +1 -0
- package/dist/routes/deployments.d.ts +10 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +171 -13
- package/dist/routes/deployments.js.map +1 -1
- package/dist/routes/eval-comparison.d.ts.map +1 -1
- package/dist/routes/eval-comparison.js +69 -1
- package/dist/routes/eval-comparison.js.map +1 -1
- package/dist/routes/eval-overrides.d.ts +18 -0
- package/dist/routes/eval-overrides.d.ts.map +1 -0
- package/dist/routes/eval-overrides.js +81 -0
- package/dist/routes/eval-overrides.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +10 -1
- package/dist/routes/eval-runs.d.ts.map +1 -1
- package/dist/routes/eval-runs.js +66 -7
- package/dist/routes/eval-runs.js.map +1 -1
- package/dist/routes/eval-suites.d.ts.map +1 -1
- package/dist/routes/eval-suites.js +28 -2
- package/dist/routes/eval-suites.js.map +1 -1
- package/dist/routes/event-triggers.d.ts +5 -1
- package/dist/routes/event-triggers.d.ts.map +1 -1
- package/dist/routes/event-triggers.js +26 -3
- package/dist/routes/event-triggers.js.map +1 -1
- package/dist/routes/export-signing-keys.d.ts +12 -0
- package/dist/routes/export-signing-keys.d.ts.map +1 -0
- package/dist/routes/export-signing-keys.js +24 -0
- package/dist/routes/export-signing-keys.js.map +1 -0
- package/dist/routes/flows.d.ts.map +1 -1
- package/dist/routes/flows.js +9 -1
- package/dist/routes/flows.js.map +1 -1
- package/dist/routes/gate-policies.d.ts +4 -1
- package/dist/routes/gate-policies.d.ts.map +1 -1
- package/dist/routes/gate-policies.js +29 -5
- package/dist/routes/gate-policies.js.map +1 -1
- package/dist/routes/guardrails.d.ts +16 -14
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +39 -3
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/identity.d.ts +20 -4
- package/dist/routes/identity.d.ts.map +1 -1
- package/dist/routes/identity.js +246 -6
- package/dist/routes/identity.js.map +1 -1
- package/dist/routes/improvement-passes.d.ts +52 -0
- package/dist/routes/improvement-passes.d.ts.map +1 -0
- package/dist/routes/improvement-passes.js +449 -0
- package/dist/routes/improvement-passes.js.map +1 -0
- package/dist/routes/judged-suites.d.ts +50 -0
- package/dist/routes/judged-suites.d.ts.map +1 -1
- package/dist/routes/judged-suites.js +66 -27
- package/dist/routes/judged-suites.js.map +1 -1
- package/dist/routes/judgment-context.d.ts +18 -2
- package/dist/routes/judgment-context.d.ts.map +1 -1
- package/dist/routes/judgment-context.js +63 -5
- package/dist/routes/judgment-context.js.map +1 -1
- package/dist/routes/judgment-flow-context.d.ts.map +1 -1
- package/dist/routes/judgment-flow-context.js +14 -2
- package/dist/routes/judgment-flow-context.js.map +1 -1
- package/dist/routes/judgments.d.ts.map +1 -1
- package/dist/routes/judgments.js +8 -1
- package/dist/routes/judgments.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +26 -1
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/memory-access.d.ts +43 -0
- package/dist/routes/memory-access.d.ts.map +1 -0
- package/dist/routes/memory-access.js +114 -0
- package/dist/routes/memory-access.js.map +1 -0
- package/dist/routes/memory-erasures.d.ts +25 -0
- package/dist/routes/memory-erasures.d.ts.map +1 -0
- package/dist/routes/memory-erasures.js +214 -0
- package/dist/routes/memory-erasures.js.map +1 -0
- package/dist/routes/memory-parse.d.ts +38 -0
- package/dist/routes/memory-parse.d.ts.map +1 -0
- package/dist/routes/memory-parse.js +199 -0
- package/dist/routes/memory-parse.js.map +1 -0
- package/dist/routes/memory.d.ts +9 -4
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/memory.js +226 -234
- package/dist/routes/memory.js.map +1 -1
- package/dist/routes/observations.d.ts +4 -1
- package/dist/routes/observations.d.ts.map +1 -1
- package/dist/routes/observations.js +8 -2
- package/dist/routes/observations.js.map +1 -1
- package/dist/routes/pagination.d.ts +7 -0
- package/dist/routes/pagination.d.ts.map +1 -1
- package/dist/routes/pagination.js +10 -0
- package/dist/routes/pagination.js.map +1 -1
- package/dist/routes/policies.d.ts +2 -1
- package/dist/routes/policies.d.ts.map +1 -1
- package/dist/routes/policies.js +3 -1
- package/dist/routes/policies.js.map +1 -1
- package/dist/routes/project-mismatch.d.ts +22 -0
- package/dist/routes/project-mismatch.d.ts.map +1 -0
- package/dist/routes/project-mismatch.js +34 -0
- package/dist/routes/project-mismatch.js.map +1 -0
- package/dist/routes/projects.d.ts +15 -4
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +100 -9
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/proposals.d.ts +25 -17
- package/dist/routes/proposals.d.ts.map +1 -1
- package/dist/routes/proposals.js +340 -507
- package/dist/routes/proposals.js.map +1 -1
- package/dist/routes/provenance.d.ts +17 -3
- package/dist/routes/provenance.d.ts.map +1 -1
- package/dist/routes/provenance.js +79 -103
- package/dist/routes/provenance.js.map +1 -1
- package/dist/routes/providers.d.ts +17 -1
- package/dist/routes/providers.d.ts.map +1 -1
- package/dist/routes/providers.js +110 -3
- package/dist/routes/providers.js.map +1 -1
- package/dist/routes/public-run-tokens.d.ts.map +1 -1
- package/dist/routes/public-run-tokens.js +3 -0
- package/dist/routes/public-run-tokens.js.map +1 -1
- package/dist/routes/readable-projects.d.ts +26 -0
- package/dist/routes/readable-projects.d.ts.map +1 -0
- package/dist/routes/readable-projects.js +39 -0
- package/dist/routes/readable-projects.js.map +1 -0
- package/dist/routes/runs.d.ts +10 -0
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +92 -42
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/schedules.d.ts +21 -13
- package/dist/routes/schedules.d.ts.map +1 -1
- package/dist/routes/schedules.js +416 -55
- package/dist/routes/schedules.js.map +1 -1
- package/dist/routes/segments.d.ts +2 -0
- package/dist/routes/segments.d.ts.map +1 -1
- package/dist/routes/segments.js +5 -0
- package/dist/routes/segments.js.map +1 -1
- package/dist/routes/service-accounts.d.ts +17 -0
- package/dist/routes/service-accounts.d.ts.map +1 -0
- package/dist/routes/service-accounts.js +212 -0
- package/dist/routes/service-accounts.js.map +1 -0
- package/dist/routes/sign-in-options.d.ts +50 -0
- package/dist/routes/sign-in-options.d.ts.map +1 -0
- package/dist/routes/sign-in-options.js +98 -0
- package/dist/routes/sign-in-options.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +2 -1
- package/dist/routes/signing-keys.d.ts.map +1 -1
- package/dist/routes/signing-keys.js +3 -1
- package/dist/routes/signing-keys.js.map +1 -1
- package/dist/routes/tenant-access.d.ts +13 -0
- package/dist/routes/tenant-access.d.ts.map +1 -0
- package/dist/routes/tenant-access.js +26 -0
- package/dist/routes/tenant-access.js.map +1 -0
- package/dist/routes/tenant.d.ts.map +1 -1
- package/dist/routes/tenant.js +4 -0
- package/dist/routes/tenant.js.map +1 -1
- package/dist/routes/token-sign-in.d.ts +36 -0
- package/dist/routes/token-sign-in.d.ts.map +1 -0
- package/dist/routes/token-sign-in.js +101 -0
- package/dist/routes/token-sign-in.js.map +1 -0
- package/dist/routes/tokens.d.ts +15 -5
- package/dist/routes/tokens.d.ts.map +1 -1
- package/dist/routes/tokens.js +162 -43
- package/dist/routes/tokens.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +9 -1
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/trigger-access.d.ts +29 -0
- package/dist/routes/trigger-access.d.ts.map +1 -0
- package/dist/routes/trigger-access.js +33 -0
- package/dist/routes/trigger-access.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +2 -1
- package/dist/routes/webhook-endpoints.d.ts.map +1 -1
- package/dist/routes/webhook-endpoints.js +11 -3
- package/dist/routes/webhook-endpoints.js.map +1 -1
- package/dist/routes/webhooks.d.ts +5 -1
- package/dist/routes/webhooks.d.ts.map +1 -1
- package/dist/routes/webhooks.js +25 -2
- package/dist/routes/webhooks.js.map +1 -1
- package/dist/run-failure.d.ts +21 -0
- package/dist/run-failure.d.ts.map +1 -0
- package/dist/run-failure.js +29 -0
- package/dist/run-failure.js.map +1 -0
- package/dist/service-account-binding.d.ts +108 -0
- package/dist/service-account-binding.d.ts.map +1 -0
- package/dist/service-account-binding.js +4 -0
- package/dist/service-account-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +61 -13
- package/dist/session-store-binding.d.ts.map +1 -1
- package/dist/signed-export.d.ts +89 -0
- package/dist/signed-export.d.ts.map +1 -0
- package/dist/signed-export.js +149 -0
- package/dist/signed-export.js.map +1 -0
- package/dist/supervisor-binding.d.ts +186 -413
- package/dist/supervisor-binding.d.ts.map +1 -1
- package/dist/testing/app-bindings.d.ts +33 -0
- package/dist/testing/app-bindings.d.ts.map +1 -0
- package/dist/testing/app-bindings.js +112 -0
- package/dist/testing/app-bindings.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +13 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/stub-binding.d.ts +34 -0
- package/dist/testing/stub-binding.d.ts.map +1 -0
- package/dist/testing/stub-binding.js +42 -0
- package/dist/testing/stub-binding.js.map +1 -0
- package/dist/testing/trigger-registry.d.ts +21 -0
- package/dist/testing/trigger-registry.d.ts.map +1 -0
- package/dist/testing/trigger-registry.js +206 -0
- package/dist/testing/trigger-registry.js.map +1 -0
- package/dist/token-admin.d.ts +46 -8
- package/dist/token-admin.d.ts.map +1 -1
- package/dist/token-admin.js.map +1 -1
- package/dist/tool-binding.d.ts +13 -0
- package/dist/tool-binding.d.ts.map +1 -1
- package/dist/trigger-binding.d.ts +2 -2
- package/dist/trigger-binding.d.ts.map +1 -1
- package/dist/trigger-binding.js +1 -1
- package/dist/trigger-binding.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.d.ts +19 -3
- package/dist/webhook-endpoint-binding.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.js +1 -1
- package/dist/webhook-endpoint-binding.js.map +1 -1
- package/openapi.json +15387 -8789
- package/package.json +26 -22
- package/src/agent-binding.ts +14 -0
- package/src/agent-pins.ts +18 -2
- package/src/app.ts +366 -80
- package/src/block-publish.ts +181 -0
- package/src/caller.ts +62 -0
- package/src/capability-binding.ts +12 -0
- package/src/cost-binding.ts +19 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +75 -7
- package/src/eval-case-binding.ts +17 -1
- package/src/eval-run-binding.ts +31 -0
- package/src/eval-run-dispatcher.ts +7 -0
- package/src/eval-sample.ts +42 -0
- package/src/eval-suite-binding.ts +14 -0
- package/src/flow-binding.ts +19 -0
- package/src/flow-pins.ts +18 -2
- package/src/gate.ts +26 -0
- package/src/handler-binding.ts +36 -1
- package/src/hitl-binding.ts +24 -0
- package/src/identity-directory-binding.ts +85 -4
- package/src/identity-provider-binding.ts +216 -21
- package/src/improvement-pass-binding.ts +193 -0
- package/src/index.ts +153 -31
- package/src/judged-dispatcher.ts +78 -11
- package/src/judgment-binding.ts +25 -1
- package/src/mcp-endpoint-binding.ts +7 -0
- package/src/memory-binding.ts +121 -17
- package/src/memory-erasure-binding.ts +156 -0
- package/src/middleware/auth.ts +228 -62
- package/src/middleware/authorize.ts +155 -3
- package/src/middleware/error-mapper.ts +15 -1
- package/src/middleware/idempotency.ts +230 -43
- package/src/middleware/key-project.ts +86 -0
- package/src/middleware/principal.ts +9 -5
- package/src/middleware/project-ref.ts +3 -0
- package/src/openapi/generate.ts +11 -2
- package/src/openapi/operations.ts +1060 -143
- package/src/openapi/schemas.ts +2387 -469
- package/src/person-grants-binding.ts +76 -0
- package/src/proposal-service.ts +640 -0
- package/src/proposal-status.ts +176 -0
- package/src/provider-binding.ts +10 -0
- package/src/publish-refused.ts +56 -9
- package/src/routes/adapters.ts +4 -0
- package/src/routes/agent-releases.ts +121 -69
- package/src/routes/agents.ts +128 -1
- package/src/routes/approvals.ts +164 -154
- package/src/routes/artifacts.ts +181 -11
- package/src/routes/auth.ts +804 -336
- package/src/routes/blocks.ts +2 -53
- package/src/routes/capabilities.ts +10 -1
- package/src/routes/compliance.ts +60 -99
- package/src/routes/conversations.ts +101 -7
- package/src/routes/cost.ts +110 -4
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +210 -17
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +89 -6
- package/src/routes/eval-suites.ts +32 -2
- package/src/routes/event-triggers.ts +27 -3
- package/src/routes/export-signing-keys.ts +31 -0
- package/src/routes/flows.ts +12 -1
- package/src/routes/gate-policies.ts +37 -6
- package/src/routes/guardrails.ts +61 -2
- package/src/routes/identity.ts +328 -10
- package/src/routes/improvement-passes.ts +541 -0
- package/src/routes/judged-suites.ts +113 -43
- package/src/routes/judgment-context.ts +76 -5
- package/src/routes/judgment-flow-context.ts +16 -2
- package/src/routes/judgments.ts +17 -3
- package/src/routes/mcp.ts +29 -1
- package/src/routes/memory-access.ts +160 -0
- package/src/routes/memory-erasures.ts +240 -0
- package/src/routes/memory-parse.ts +250 -0
- package/src/routes/memory.ts +244 -286
- package/src/routes/observations.ts +15 -2
- package/src/routes/pagination.ts +12 -0
- package/src/routes/policies.ts +7 -1
- package/src/routes/project-mismatch.ts +56 -0
- package/src/routes/projects.ts +107 -13
- package/src/routes/proposals.ts +370 -611
- package/src/routes/provenance.ts +99 -133
- package/src/routes/providers.ts +142 -3
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/readable-projects.ts +66 -0
- package/src/routes/runs.ts +119 -39
- package/src/routes/schedules.ts +472 -60
- package/src/routes/segments.ts +11 -0
- package/src/routes/service-accounts.ts +262 -0
- package/src/routes/sign-in-options.ts +168 -0
- package/src/routes/signing-keys.ts +7 -1
- package/src/routes/tenant-access.ts +37 -0
- package/src/routes/tenant.ts +6 -0
- package/src/routes/token-sign-in.ts +161 -0
- package/src/routes/tokens.ts +172 -46
- package/src/routes/tools.ts +12 -1
- package/src/routes/trigger-access.ts +72 -0
- package/src/routes/webhook-endpoints.ts +15 -3
- package/src/routes/webhooks.ts +26 -2
- package/src/run-failure.ts +42 -0
- package/src/service-account-binding.ts +113 -0
- package/src/session-store-binding.ts +65 -13
- package/src/signed-export.ts +250 -0
- package/src/supervisor-binding.ts +169 -409
- package/src/testing/app-bindings.ts +142 -0
- package/src/testing/index.ts +21 -0
- package/src/testing/stub-binding.ts +53 -0
- package/src/testing/trigger-registry.ts +259 -0
- package/src/token-admin.ts +40 -8
- package/src/tool-binding.ts +14 -0
- package/src/trigger-binding.ts +8 -1
- package/src/types.ts +16 -0
- package/src/webhook-endpoint-binding.ts +18 -3
package/dist/routes/proposals.js
CHANGED
|
@@ -1,581 +1,414 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
|
+
import { ref } from '@kindgi/authz';
|
|
4
5
|
import { statusFor, toWireError } from '../errors.js';
|
|
6
|
+
import { createProposalService, proposalNotFound, } from '../proposal-service.js';
|
|
7
|
+
import { FIX_PROPOSAL_STATUSES, } from '../proposal-status.js';
|
|
8
|
+
import { actorOf, promotionResponse, scopeFromQuery } from './agent-releases.js';
|
|
9
|
+
import { parseComparison } from './eval-comparison.js';
|
|
10
|
+
import { liveScopeToWire, parseLiveScopeBody } from './live-scope-wire.js';
|
|
5
11
|
import { clampLimit } from './pagination.js';
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
'dry-running',
|
|
10
|
-
'dry-run-passed',
|
|
11
|
-
'dry-run-failed',
|
|
12
|
-
'proposed-for-review',
|
|
13
|
-
'approved',
|
|
14
|
-
'rejected',
|
|
15
|
-
'applied',
|
|
16
|
-
'rolled-back',
|
|
17
|
-
'withdrawn',
|
|
18
|
-
]);
|
|
19
|
-
const PROPOSAL_TIERS = new Set([
|
|
20
|
-
'prompt',
|
|
21
|
-
'retrieval',
|
|
22
|
-
'tool-config',
|
|
23
|
-
]);
|
|
24
|
-
const REVIEWER_ROLES = new Set([
|
|
25
|
-
'standard',
|
|
26
|
-
'senior',
|
|
27
|
-
'admin',
|
|
28
|
-
]);
|
|
12
|
+
const TIERS = ['settings-block', 'prompt-block'];
|
|
13
|
+
const OBJECTIVES = ['weightedYesShare', 'weightedPrecisionAtK'];
|
|
14
|
+
const MAX_TEXT = 2000;
|
|
29
15
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
16
|
+
* Improvement proposals (`/v1/proposals`): a change to one data block an
|
|
17
|
+
* agent version pins (new settings values, or a new prompt template),
|
|
18
|
+
* for one live scope, taken through the same comparison, gate and
|
|
19
|
+
* promotion as any other version (`createProposalService`).
|
|
33
20
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
21
|
+
* GET / list (statuses derived): by agent, tier, status and live scope
|
|
22
|
+
* GET /:id one
|
|
23
|
+
* POST / a hand-written proposal (a draft)
|
|
24
|
+
* POST /:id/evaluate publish the block version and derive the agent
|
|
25
|
+
* version (inert until promoted), then compare it
|
|
26
|
+
* on a test set (202)
|
|
27
|
+
* POST /:id/request a gated promotion of the candidate for the scope
|
|
28
|
+
* (201 promoted, 202 in review, 422 gate-failed)
|
|
29
|
+
* POST /:id/rollback the scope goes back to what served it before
|
|
30
|
+
* POST /:id/withdraw closed by a person
|
|
37
31
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* the runtime won't accept (e.g., apply on a proposal still in
|
|
43
|
-
* `dry-running`) surface as `409 proposal-invalid-state-transition`.
|
|
44
|
-
* This is a caller/state conflict per `docs/API-ROUTE-CONVENTIONS.md`
|
|
45
|
-
* §4.3 — the request was well-formed but the resource is not in
|
|
46
|
-
* the required state.
|
|
32
|
+
* Authorized on the proposal's agent: reading is `read`, drafting,
|
|
33
|
+
* evaluating and withdrawing are `publish` (they make versions), and
|
|
34
|
+
* requesting and rolling back are `promote`. A proposal the caller can't
|
|
35
|
+
* read answers 404, as one that doesn't exist.
|
|
47
36
|
*/
|
|
48
|
-
export function proposalsRouter(
|
|
37
|
+
export function proposalsRouter(store, deps, authorizer, mount) {
|
|
49
38
|
const r = new Hono();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
const service = createProposalService({ ...deps, store });
|
|
40
|
+
// Routes mounted before `/:proposalId` (an improvement pass's `improve`).
|
|
41
|
+
mount?.(r, service);
|
|
42
|
+
/** `undefined` when allowed; else the 403. */
|
|
43
|
+
async function deny(c, action, agentId) {
|
|
44
|
+
if (authorizer === undefined)
|
|
45
|
+
return undefined;
|
|
46
|
+
const decision = await authorizer.check(c, action, ref('agent', agentId));
|
|
47
|
+
if (decision.allowed)
|
|
48
|
+
return undefined;
|
|
49
|
+
return fail(c, 'permission-denied', {
|
|
50
|
+
code: 'permission-denied',
|
|
51
|
+
message: `Permission denied: this needs ${action} on agent "${agentId}" (${decision.reason})`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** The proposal, if it exists and the caller may read it (else the 404). */
|
|
55
|
+
async function load(c) {
|
|
56
|
+
const proposalId = c.req.param('proposalId') ?? '';
|
|
57
|
+
const stored = await store.getProposal({
|
|
58
|
+
tenantId: c.get('tenantId'),
|
|
59
|
+
proposalId: proposalId,
|
|
60
|
+
});
|
|
61
|
+
const hidden = stored !== null &&
|
|
62
|
+
authorizer !== undefined &&
|
|
63
|
+
!(await authorizer.can(c, 'read', ref('agent', stored.agentId)));
|
|
64
|
+
if (stored === null || hidden)
|
|
65
|
+
return failWith(c, proposalNotFound(proposalId));
|
|
66
|
+
return stored;
|
|
67
|
+
}
|
|
68
|
+
async function answer(c, stored, status = 200) {
|
|
69
|
+
const f = await service.facts(c.get('tenantId'))(stored);
|
|
70
|
+
c.status(status);
|
|
71
|
+
return c.json(serialize(stored, f));
|
|
72
|
+
}
|
|
73
|
+
/** Read the body and the proposal, and check the caller may `action` it. */
|
|
74
|
+
async function prepare(c, action) {
|
|
75
|
+
const body = await readBody(c);
|
|
76
|
+
if (body === undefined)
|
|
77
|
+
return badInput(c, 'Request body must be a JSON object');
|
|
78
|
+
const proposal = await load(c);
|
|
79
|
+
if (proposal instanceof Response)
|
|
80
|
+
return proposal;
|
|
81
|
+
const denied = await deny(c, action, proposal.agentId);
|
|
82
|
+
return denied ?? { body, proposal };
|
|
83
|
+
}
|
|
84
|
+
// ---------- GET / ----------
|
|
65
85
|
r.get('/', async (c) => {
|
|
66
|
-
const requestId = c.get('requestId');
|
|
67
86
|
const tenantId = c.get('tenantId');
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
let tier;
|
|
83
|
-
if (tierRaw !== undefined && tierRaw.length > 0) {
|
|
84
|
-
if (!PROPOSAL_TIERS.has(tierRaw)) {
|
|
85
|
-
c.status(statusFor('bad-input'));
|
|
86
|
-
return c.json(toWireError({ code: 'bad-input', message: `Unknown \`tier\` value: ${tierRaw}` }, requestId));
|
|
87
|
-
}
|
|
88
|
-
tier = tierRaw;
|
|
89
|
-
}
|
|
90
|
-
const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
|
|
91
|
-
if (scopeParsed.kind === 'err') {
|
|
92
|
-
c.status(statusFor('scope-invalid'));
|
|
93
|
-
return c.json(toWireError({ code: 'scope-invalid', message: scopeParsed.message }, requestId));
|
|
94
|
-
}
|
|
95
|
-
const page = await binding.listProposals({
|
|
87
|
+
const status = c.req.query('status');
|
|
88
|
+
if (status !== undefined && !FIX_PROPOSAL_STATUSES.includes(status)) {
|
|
89
|
+
return badInput(c, `Unknown \`status\`: ${status}`);
|
|
90
|
+
}
|
|
91
|
+
const tier = c.req.query('tier');
|
|
92
|
+
if (tier !== undefined && !TIERS.includes(tier)) {
|
|
93
|
+
return badInput(c, `Unknown \`tier\`: ${tier} (one of ${TIERS.join(', ')})`);
|
|
94
|
+
}
|
|
95
|
+
const scope = scopeFromQuery((n) => c.req.query(n), c.req.queries('segment') ?? []);
|
|
96
|
+
if (scope.kind === 'err')
|
|
97
|
+
return badInput(c, scope.message);
|
|
98
|
+
const agentId = c.req.query('agentId');
|
|
99
|
+
const cursor = c.req.query('cursor');
|
|
100
|
+
const page = await store.listProposals({
|
|
96
101
|
tenantId,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
...(
|
|
100
|
-
...(
|
|
101
|
-
...(
|
|
102
|
-
...(tier !== undefined && { tier }),
|
|
103
|
-
...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
|
|
104
|
-
...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
|
|
102
|
+
limit: clampLimit(c.req.query('limit')),
|
|
103
|
+
...(cursor !== undefined && cursor !== '' && { cursor: cursor }),
|
|
104
|
+
...(agentId !== undefined && agentId !== '' && { agentId: agentId }),
|
|
105
|
+
...(tier !== undefined && { tier: tier }),
|
|
106
|
+
...(scope.scope !== undefined && { liveScope: scope.scope }),
|
|
105
107
|
});
|
|
108
|
+
const readable = authorizer === undefined
|
|
109
|
+
? page.data
|
|
110
|
+
: await authorizer.filterByCan(c, 'read', page.data, (p) => ref('agent', p.agentId));
|
|
111
|
+
const read = service.facts(tenantId);
|
|
112
|
+
const rows = await Promise.all(readable.map(async (p) => serialize(p, await read(p))));
|
|
106
113
|
return c.json({
|
|
107
|
-
|
|
114
|
+
// A status filter applies after deriving, so a page can hold fewer rows than `limit`.
|
|
115
|
+
data: status === undefined ? rows : rows.filter((row) => row.status === status),
|
|
108
116
|
hasMore: page.nextCursor !== undefined,
|
|
109
117
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor }),
|
|
110
118
|
});
|
|
111
119
|
});
|
|
112
120
|
// ---------- GET /:proposalId ----------
|
|
113
121
|
r.get('/:proposalId', async (c) => {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const proposal = await binding.getProposal({ tenantId, supervisorId, proposalId });
|
|
119
|
-
if (proposal === null) {
|
|
120
|
-
return proposalNotFound(c, requestId, proposalId);
|
|
121
|
-
}
|
|
122
|
-
return c.json(serializeProposal(proposal));
|
|
122
|
+
const stored = await load(c);
|
|
123
|
+
if (stored instanceof Response)
|
|
124
|
+
return stored;
|
|
125
|
+
return answer(c, stored);
|
|
123
126
|
});
|
|
124
|
-
// ---------- POST / (
|
|
127
|
+
// ---------- POST / (a hand-written proposal) ----------
|
|
125
128
|
r.post('/', async (c) => {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
patternRefs: parsed.value.patternRefs,
|
|
148
|
-
hypothesis: parsed.value.hypothesis,
|
|
149
|
-
proposerRuleId: parsed.value.proposerRuleId,
|
|
129
|
+
const body = await readBody(c);
|
|
130
|
+
if (body === undefined)
|
|
131
|
+
return badInput(c, 'Request body must be a JSON object');
|
|
132
|
+
const parsed = parseCreateBody(body);
|
|
133
|
+
if (typeof parsed === 'string')
|
|
134
|
+
return badInput(c, parsed);
|
|
135
|
+
const denied = await deny(c, 'publish', parsed.agentId);
|
|
136
|
+
if (denied !== undefined)
|
|
137
|
+
return denied;
|
|
138
|
+
const actor = actorOf(c);
|
|
139
|
+
const outcome = await service.draft({
|
|
140
|
+
tenantId: c.get('tenantId'),
|
|
141
|
+
agentId: parsed.agentId,
|
|
142
|
+
fromVersion: parsed.fromVersion,
|
|
143
|
+
scope: parsed.scope,
|
|
144
|
+
tier: parsed.tier,
|
|
145
|
+
blockId: parsed.blockId,
|
|
146
|
+
content: parsed.content,
|
|
147
|
+
hypothesis: parsed.hypothesis,
|
|
148
|
+
...(parsed.judgmentIds !== undefined && { evidence: { judgmentIds: parsed.judgmentIds } }),
|
|
149
|
+
drafter: { kind: 'person', by: `${actor.kind}:${actor.id}` },
|
|
150
150
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// X-Idempotent-Replay pattern from the idempotency middleware).
|
|
155
|
-
if (outcome.kind === 'dedup') {
|
|
151
|
+
if (outcome.kind === 'err')
|
|
152
|
+
return failWith(c, outcome.error);
|
|
153
|
+
if (outcome.value.deduped) {
|
|
156
154
|
c.header('X-Proposal-Deduped', 'true');
|
|
155
|
+
return answer(c, outcome.value.proposal);
|
|
157
156
|
}
|
|
158
|
-
c.
|
|
159
|
-
return c.json(serializeProposal(outcome.proposal));
|
|
157
|
+
return answer(c, outcome.value.proposal, 201);
|
|
160
158
|
});
|
|
161
|
-
// ---------- POST /:proposalId/
|
|
162
|
-
r.post('/:proposalId/
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
tenantId,
|
|
180
|
-
supervisorId,
|
|
181
|
-
proposalId,
|
|
182
|
-
datasetId: parsed.value.datasetId,
|
|
183
|
-
datasetVersion: parsed.value.datasetVersion,
|
|
184
|
-
criterion: parsed.value.criterion,
|
|
185
|
-
});
|
|
186
|
-
if (outcome.kind === 'not-found') {
|
|
187
|
-
return proposalNotFound(c, requestId, proposalId);
|
|
188
|
-
}
|
|
189
|
-
if (outcome.kind === 'invalid-transition') {
|
|
190
|
-
return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
|
|
191
|
-
}
|
|
192
|
-
if (outcome.kind === 'runtime-error') {
|
|
193
|
-
return runtimeError(c, requestId, outcome.code, outcome.message);
|
|
194
|
-
}
|
|
195
|
-
return c.json({
|
|
196
|
-
proposal: serializeProposal(outcome.proposal),
|
|
197
|
-
passed: outcome.passed,
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
// ---------- POST /:proposalId/submit-review ----------
|
|
201
|
-
r.post('/:proposalId/submit-review', async (c) => {
|
|
202
|
-
const requestId = c.get('requestId');
|
|
203
|
-
const tenantId = c.get('tenantId');
|
|
204
|
-
const supervisorId = c.req.header('x-supervisor-id');
|
|
205
|
-
const proposalId = c.req.param('proposalId');
|
|
206
|
-
// Body is optional — every field on submit-review is an override.
|
|
207
|
-
let body = {};
|
|
208
|
-
try {
|
|
209
|
-
const raw = await c.req.text();
|
|
210
|
-
if (raw.length > 0)
|
|
211
|
-
body = JSON.parse(raw);
|
|
212
|
-
}
|
|
213
|
-
catch {
|
|
214
|
-
return badInput(c, requestId, 'Request body must be valid JSON');
|
|
215
|
-
}
|
|
216
|
-
const parsed = parseSubmitReviewBody(body);
|
|
217
|
-
if (parsed.kind === 'err') {
|
|
218
|
-
return badInput(c, requestId, parsed.message);
|
|
219
|
-
}
|
|
220
|
-
const outcome = await binding.submitReview({
|
|
221
|
-
tenantId,
|
|
222
|
-
supervisorId,
|
|
223
|
-
proposalId,
|
|
224
|
-
...(parsed.value.requiredRole !== undefined && { requiredRole: parsed.value.requiredRole }),
|
|
225
|
-
...(parsed.value.expiresAt !== undefined && { expiresAt: parsed.value.expiresAt }),
|
|
226
|
-
});
|
|
227
|
-
if (outcome.kind === 'not-found') {
|
|
228
|
-
return proposalNotFound(c, requestId, proposalId);
|
|
229
|
-
}
|
|
230
|
-
if (outcome.kind === 'invalid-transition') {
|
|
231
|
-
return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
|
|
232
|
-
}
|
|
233
|
-
if (outcome.kind === 'ground-layer-violation') {
|
|
234
|
-
c.status(statusFor('ground-layer-violation'));
|
|
235
|
-
return c.json(toWireError({
|
|
236
|
-
code: 'ground-layer-violation',
|
|
237
|
-
message: `Proposal ${outcome.proposalId} violated ground guardrail ${outcome.guardrailId}: ${outcome.reason}`,
|
|
238
|
-
proposalId: outcome.proposalId,
|
|
239
|
-
guardrailId: outcome.guardrailId,
|
|
240
|
-
reason: outcome.reason,
|
|
241
|
-
}, requestId));
|
|
242
|
-
}
|
|
243
|
-
if (outcome.kind === 'runtime-error') {
|
|
244
|
-
return runtimeError(c, requestId, outcome.code, outcome.message);
|
|
245
|
-
}
|
|
246
|
-
return c.json({
|
|
247
|
-
proposal: serializeProposal(outcome.proposal),
|
|
248
|
-
approvalId: outcome.approvalId,
|
|
249
|
-
metaFix: outcome.metaFix,
|
|
159
|
+
// ---------- POST /:proposalId/evaluate ----------
|
|
160
|
+
r.post('/:proposalId/evaluate', async (c) => {
|
|
161
|
+
const body = await readBody(c);
|
|
162
|
+
if (body === undefined)
|
|
163
|
+
return badInput(c, 'Request body must be a JSON object');
|
|
164
|
+
const parsed = parseEvaluateBody(body);
|
|
165
|
+
if (typeof parsed === 'string')
|
|
166
|
+
return badInput(c, parsed);
|
|
167
|
+
const ready = await prepare(c, 'publish');
|
|
168
|
+
if (ready instanceof Response)
|
|
169
|
+
return ready;
|
|
170
|
+
const outcome = await service.evaluate({
|
|
171
|
+
tenantId: c.get('tenantId'),
|
|
172
|
+
proposal: ready.proposal,
|
|
173
|
+
suiteId: parsed.suiteId,
|
|
174
|
+
objective: parsed.objective,
|
|
175
|
+
...(parsed.comparison !== undefined && { comparison: parsed.comparison }),
|
|
176
|
+
actor: actorOf(c),
|
|
250
177
|
});
|
|
178
|
+
if (outcome.kind === 'err')
|
|
179
|
+
return failWith(c, outcome.error);
|
|
180
|
+
return answer(c, outcome.value, 202);
|
|
251
181
|
});
|
|
252
|
-
// ---------- POST /:proposalId/
|
|
253
|
-
r.post('/:proposalId/
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return badInput(c, requestId, 'Request body must be valid JSON');
|
|
266
|
-
}
|
|
267
|
-
const parsed = parseApplyBody(body);
|
|
268
|
-
if (parsed.kind === 'err') {
|
|
269
|
-
return badInput(c, requestId, parsed.message);
|
|
270
|
-
}
|
|
271
|
-
const outcome = await binding.applyProposal({
|
|
272
|
-
tenantId,
|
|
273
|
-
supervisorId,
|
|
274
|
-
proposalId,
|
|
275
|
-
...(parsed.value.newVersion !== undefined && { newVersion: parsed.value.newVersion }),
|
|
276
|
-
});
|
|
277
|
-
if (outcome.kind === 'not-found') {
|
|
278
|
-
return proposalNotFound(c, requestId, proposalId);
|
|
279
|
-
}
|
|
280
|
-
if (outcome.kind === 'invalid-transition') {
|
|
281
|
-
return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
|
|
282
|
-
}
|
|
283
|
-
if (outcome.kind === 'runtime-error') {
|
|
284
|
-
return runtimeError(c, requestId, outcome.code, outcome.message);
|
|
285
|
-
}
|
|
286
|
-
return c.json({
|
|
287
|
-
proposalId: outcome.proposalId,
|
|
288
|
-
appliedVersion: outcome.appliedVersion,
|
|
289
|
-
appliedAt: outcome.appliedAt,
|
|
182
|
+
// ---------- POST /:proposalId/request ----------
|
|
183
|
+
r.post('/:proposalId/request', async (c) => {
|
|
184
|
+
const ready = await prepare(c, 'promote');
|
|
185
|
+
if (ready instanceof Response)
|
|
186
|
+
return ready;
|
|
187
|
+
const reason = optionalText(ready.body, 'reason');
|
|
188
|
+
if (reason.kind === 'err')
|
|
189
|
+
return badInput(c, reason.message);
|
|
190
|
+
const outcome = await service.request({
|
|
191
|
+
tenantId: c.get('tenantId'),
|
|
192
|
+
proposal: ready.proposal,
|
|
193
|
+
actor: actorOf(c),
|
|
194
|
+
...(reason.value !== undefined && { reason: reason.value }),
|
|
290
195
|
});
|
|
196
|
+
if (outcome.kind === 'err')
|
|
197
|
+
return failWith(c, outcome.error);
|
|
198
|
+
const { proposal, promotion } = outcome.value;
|
|
199
|
+
if (promotion.kind !== 'ok')
|
|
200
|
+
return promotionResponse(c, promotion);
|
|
201
|
+
if (promotion.promotion.status === 'refused') {
|
|
202
|
+
return promotionResponse(c, promotion, { proposalId: proposal.id });
|
|
203
|
+
}
|
|
204
|
+
return answer(c, proposal, promotion.promotion.status === 'pending-approval' ? 202 : 201);
|
|
291
205
|
});
|
|
292
206
|
// ---------- POST /:proposalId/rollback ----------
|
|
293
207
|
r.post('/:proposalId/rollback', async (c) => {
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const parsed = parseReasonBody(body);
|
|
306
|
-
if (parsed.kind === 'err') {
|
|
307
|
-
return badInput(c, requestId, parsed.message);
|
|
308
|
-
}
|
|
309
|
-
const outcome = await binding.rollbackProposal({
|
|
310
|
-
tenantId,
|
|
311
|
-
supervisorId,
|
|
312
|
-
proposalId,
|
|
313
|
-
reason: parsed.value.reason,
|
|
314
|
-
});
|
|
315
|
-
if (outcome.kind === 'not-found') {
|
|
316
|
-
return proposalNotFound(c, requestId, proposalId);
|
|
317
|
-
}
|
|
318
|
-
if (outcome.kind === 'invalid-transition') {
|
|
319
|
-
return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
|
|
320
|
-
}
|
|
321
|
-
if (outcome.kind === 'runtime-error') {
|
|
322
|
-
return runtimeError(c, requestId, outcome.code, outcome.message);
|
|
323
|
-
}
|
|
324
|
-
return c.json({
|
|
325
|
-
proposalId: outcome.proposalId,
|
|
326
|
-
rolledBackAt: outcome.rolledBackAt,
|
|
208
|
+
const ready = await prepare(c, 'promote');
|
|
209
|
+
if (ready instanceof Response)
|
|
210
|
+
return ready;
|
|
211
|
+
const reason = optionalText(ready.body, 'reason');
|
|
212
|
+
if (reason.kind === 'err')
|
|
213
|
+
return badInput(c, reason.message);
|
|
214
|
+
const outcome = await service.rollback({
|
|
215
|
+
tenantId: c.get('tenantId'),
|
|
216
|
+
proposal: ready.proposal,
|
|
217
|
+
actor: actorOf(c),
|
|
218
|
+
...(reason.value !== undefined && { reason: reason.value }),
|
|
327
219
|
});
|
|
220
|
+
if (outcome.kind === 'err')
|
|
221
|
+
return failWith(c, outcome.error);
|
|
222
|
+
return answer(c, outcome.value);
|
|
328
223
|
});
|
|
329
224
|
// ---------- POST /:proposalId/withdraw ----------
|
|
330
225
|
r.post('/:proposalId/withdraw', async (c) => {
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
const outcome = await binding.withdrawProposal({
|
|
347
|
-
tenantId,
|
|
348
|
-
supervisorId,
|
|
349
|
-
proposalId,
|
|
350
|
-
reason: parsed.value.reason,
|
|
226
|
+
const ready = await prepare(c, 'publish');
|
|
227
|
+
if (ready instanceof Response)
|
|
228
|
+
return ready;
|
|
229
|
+
const reason = optionalText(ready.body, 'reason');
|
|
230
|
+
if (reason.kind === 'err')
|
|
231
|
+
return badInput(c, reason.message);
|
|
232
|
+
if (reason.value === undefined) {
|
|
233
|
+
return badInput(c, '`reason` is required: why it was withdrawn');
|
|
234
|
+
}
|
|
235
|
+
const outcome = await service.withdraw({
|
|
236
|
+
tenantId: c.get('tenantId'),
|
|
237
|
+
proposal: ready.proposal,
|
|
238
|
+
actor: actorOf(c),
|
|
239
|
+
reason: reason.value,
|
|
351
240
|
});
|
|
352
|
-
if (outcome.kind === '
|
|
353
|
-
return
|
|
354
|
-
|
|
355
|
-
if (outcome.kind === 'invalid-transition') {
|
|
356
|
-
return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
|
|
357
|
-
}
|
|
358
|
-
if (outcome.kind === 'runtime-error') {
|
|
359
|
-
return runtimeError(c, requestId, outcome.code, outcome.message);
|
|
360
|
-
}
|
|
361
|
-
return c.json(serializeProposal(outcome.proposal));
|
|
241
|
+
if (outcome.kind === 'err')
|
|
242
|
+
return failWith(c, outcome.error);
|
|
243
|
+
return answer(c, outcome.value);
|
|
362
244
|
});
|
|
363
245
|
return r;
|
|
364
246
|
}
|
|
365
|
-
//
|
|
366
|
-
function
|
|
247
|
+
// ---------- wire ----------
|
|
248
|
+
function evaluationWire(stored, seen) {
|
|
249
|
+
if (seen === undefined || seen === null)
|
|
250
|
+
return { ...stored };
|
|
251
|
+
return {
|
|
252
|
+
...stored,
|
|
253
|
+
runStatus: seen.runStatus,
|
|
254
|
+
...(seen.baseline !== undefined && { baseline: seen.baseline }),
|
|
255
|
+
...(seen.candidate !== undefined && { candidate: seen.candidate }),
|
|
256
|
+
...(seen.delta !== undefined && { delta: seen.delta }),
|
|
257
|
+
...(seen.spread !== undefined && { spread: seen.spread }),
|
|
258
|
+
...(seen.cases !== undefined && { cases: seen.cases }),
|
|
259
|
+
...(seen.better !== undefined && { better: seen.better }),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
export function serialize(p, f) {
|
|
263
|
+
const promotion = f.promotion ?? undefined;
|
|
367
264
|
return {
|
|
368
265
|
id: p.id,
|
|
369
|
-
tenantId: p.tenantId,
|
|
370
|
-
supervisorId: p.supervisorId,
|
|
371
266
|
agentId: p.agentId,
|
|
372
|
-
|
|
267
|
+
fromVersion: p.fromVersion,
|
|
268
|
+
scope: liveScopeToWire(p.scope),
|
|
373
269
|
tier: p.tier,
|
|
374
270
|
change: p.change,
|
|
375
|
-
patternRefs: p.patternRefs,
|
|
376
271
|
hypothesis: p.hypothesis,
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
...(p.
|
|
381
|
-
...(p.
|
|
382
|
-
|
|
272
|
+
...(p.evidence !== undefined && { evidence: p.evidence }),
|
|
273
|
+
drafter: p.drafter,
|
|
274
|
+
status: f.status,
|
|
275
|
+
...(p.candidate !== undefined && { candidate: p.candidate }),
|
|
276
|
+
...(p.evaluation !== undefined && { evaluation: evaluationWire(p.evaluation, f.evaluation) }),
|
|
277
|
+
...(promotion !== undefined && {
|
|
278
|
+
promotion: {
|
|
279
|
+
id: promotion.id,
|
|
280
|
+
status: promotion.status ?? 'promoted',
|
|
281
|
+
...(promotion.approvalId !== undefined && { approvalId: promotion.approvalId }),
|
|
282
|
+
...(f.liveNow !== undefined && { liveNow: f.liveNow }),
|
|
283
|
+
},
|
|
383
284
|
}),
|
|
384
|
-
...(p.
|
|
385
|
-
...(p.
|
|
386
|
-
...(p.rolledBackAt !== undefined && { rolledBackAt: p.rolledBackAt }),
|
|
285
|
+
...(p.rolledBack !== undefined && { rolledBack: p.rolledBack }),
|
|
286
|
+
...(p.withdrawn !== undefined && { withdrawn: p.withdrawn }),
|
|
387
287
|
createdAt: p.createdAt,
|
|
388
288
|
updatedAt: p.updatedAt,
|
|
389
|
-
...(p.resolvedAt !== undefined && { resolvedAt: p.resolvedAt }),
|
|
390
289
|
};
|
|
391
290
|
}
|
|
392
|
-
function
|
|
393
|
-
|
|
394
|
-
|
|
291
|
+
function obj(value) {
|
|
292
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
293
|
+
? value
|
|
294
|
+
: undefined;
|
|
395
295
|
}
|
|
396
|
-
function
|
|
397
|
-
|
|
398
|
-
return c.json(toWireError({
|
|
399
|
-
code: 'proposal-not-found',
|
|
400
|
-
message: `No proposal with id "${proposalId}"`,
|
|
401
|
-
proposalId: proposalId,
|
|
402
|
-
}, requestId));
|
|
296
|
+
function nonEmpty(value) {
|
|
297
|
+
return typeof value === 'string' && value.trim() !== '' && value.length <= MAX_TEXT;
|
|
403
298
|
}
|
|
404
|
-
function
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
299
|
+
function parseContent(tier, raw) {
|
|
300
|
+
const content = obj(raw);
|
|
301
|
+
const keys = content === undefined ? [] : Object.keys(content);
|
|
302
|
+
if (tier === 'settings-block') {
|
|
303
|
+
return content !== undefined && obj(content.values) !== undefined && keys.length === 1
|
|
304
|
+
? undefined
|
|
305
|
+
: '`change.content` for a settings block is { values: { … } } (the schema carries over)';
|
|
306
|
+
}
|
|
307
|
+
return content !== undefined && typeof content.template === 'string' && keys.length === 1
|
|
308
|
+
? undefined
|
|
309
|
+
: '`change.content` for a prompt block is { template } (the parameters carry over)';
|
|
413
310
|
}
|
|
414
|
-
function
|
|
415
|
-
|
|
416
|
-
|
|
311
|
+
function parseEvidence(raw) {
|
|
312
|
+
if (raw === undefined)
|
|
313
|
+
return {};
|
|
314
|
+
const evidence = obj(raw);
|
|
315
|
+
const ids = evidence?.judgmentIds;
|
|
316
|
+
const valid = evidence !== undefined &&
|
|
317
|
+
Object.keys(evidence).every((k) => k === 'judgmentIds') &&
|
|
318
|
+
(ids === undefined || (Array.isArray(ids) && ids.every((id) => nonEmpty(id))));
|
|
319
|
+
if (!valid)
|
|
320
|
+
return '`evidence` is { judgmentIds?: string[] }';
|
|
321
|
+
return ids === undefined ? {} : { judgmentIds: ids };
|
|
417
322
|
}
|
|
418
|
-
function
|
|
419
|
-
if (
|
|
420
|
-
return
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
const agentId = b.agentId;
|
|
424
|
-
if (typeof agentId !== 'string' || agentId.length === 0) {
|
|
425
|
-
return { kind: 'err', message: 'Field `agentId` must be a non-empty string' };
|
|
426
|
-
}
|
|
427
|
-
const agentVersion = b.agentVersion;
|
|
428
|
-
if (typeof agentVersion !== 'string' || agentVersion.length === 0) {
|
|
429
|
-
return { kind: 'err', message: 'Field `agentVersion` must be a non-empty string' };
|
|
323
|
+
function parseCreateBody(b) {
|
|
324
|
+
if (!nonEmpty(b.agentId))
|
|
325
|
+
return '`agentId` is required';
|
|
326
|
+
if (!nonEmpty(b.fromVersion)) {
|
|
327
|
+
return '`fromVersion` is required: the agent version the change applies to';
|
|
430
328
|
}
|
|
329
|
+
const scope = parseLiveScopeBody(b.scope);
|
|
330
|
+
if (scope.kind === 'err')
|
|
331
|
+
return scope.message;
|
|
332
|
+
if (!TIERS.includes(b.tier))
|
|
333
|
+
return `\`tier\` must be one of ${TIERS.join(', ')}`;
|
|
431
334
|
const tier = b.tier;
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const patternRefs = b.patternRefs;
|
|
443
|
-
if (!Array.isArray(patternRefs)) {
|
|
444
|
-
return { kind: 'err', message: 'Field `patternRefs` must be an array' };
|
|
445
|
-
}
|
|
446
|
-
const hypothesis = b.hypothesis;
|
|
447
|
-
if (typeof hypothesis !== 'string' || hypothesis.length === 0) {
|
|
448
|
-
return { kind: 'err', message: 'Field `hypothesis` must be a non-empty string' };
|
|
449
|
-
}
|
|
450
|
-
const proposerRuleId = b.proposerRuleId;
|
|
451
|
-
if (typeof proposerRuleId !== 'string' || proposerRuleId.length === 0) {
|
|
452
|
-
return { kind: 'err', message: 'Field `proposerRuleId` must be a non-empty string' };
|
|
335
|
+
const change = obj(b.change);
|
|
336
|
+
if (change === undefined)
|
|
337
|
+
return '`change` must be an object: { blockId, content }';
|
|
338
|
+
if (!nonEmpty(change.blockId))
|
|
339
|
+
return '`change.blockId` is required';
|
|
340
|
+
const contentProblem = parseContent(tier, change.content);
|
|
341
|
+
if (contentProblem !== undefined)
|
|
342
|
+
return contentProblem;
|
|
343
|
+
if (!nonEmpty(b.hypothesis)) {
|
|
344
|
+
return '`hypothesis` is required: what the change should improve, and why';
|
|
453
345
|
}
|
|
346
|
+
const evidence = parseEvidence(b.evidence);
|
|
347
|
+
if (typeof evidence === 'string')
|
|
348
|
+
return evidence;
|
|
454
349
|
return {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
proposerRuleId,
|
|
464
|
-
},
|
|
350
|
+
agentId: b.agentId,
|
|
351
|
+
fromVersion: b.fromVersion,
|
|
352
|
+
scope: scope.scope,
|
|
353
|
+
tier,
|
|
354
|
+
blockId: change.blockId,
|
|
355
|
+
content: change.content,
|
|
356
|
+
hypothesis: b.hypothesis,
|
|
357
|
+
...evidence,
|
|
465
358
|
};
|
|
466
359
|
}
|
|
467
|
-
function
|
|
468
|
-
if (
|
|
469
|
-
return
|
|
360
|
+
function parseEvaluateBody(b) {
|
|
361
|
+
if (!nonEmpty(b.suiteId)) {
|
|
362
|
+
return '`suiteId` is required: the test set (a judged eval suite) to compare on';
|
|
470
363
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (typeof datasetId !== 'string' || datasetId.length === 0) {
|
|
474
|
-
return { kind: 'err', message: 'Field `datasetId` must be a non-empty string' };
|
|
364
|
+
if (b.objective !== undefined && !OBJECTIVES.includes(b.objective)) {
|
|
365
|
+
return `\`objective\` must be one of ${OBJECTIVES.join(', ')}`;
|
|
475
366
|
}
|
|
476
|
-
const
|
|
477
|
-
if (
|
|
478
|
-
return {
|
|
479
|
-
}
|
|
480
|
-
const rawCriterion = b.criterion;
|
|
481
|
-
if (rawCriterion === null || typeof rawCriterion !== 'object') {
|
|
482
|
-
return { kind: 'err', message: 'Field `criterion` must be an object' };
|
|
483
|
-
}
|
|
484
|
-
const cr = rawCriterion;
|
|
485
|
-
if (cr.kind === 'min-pass-rate') {
|
|
486
|
-
const minPassRate = cr.minPassRate;
|
|
487
|
-
if (typeof minPassRate !== 'number' || !Number.isFinite(minPassRate)) {
|
|
488
|
-
return {
|
|
489
|
-
kind: 'err',
|
|
490
|
-
message: 'Field `criterion.minPassRate` must be a finite number for kind "min-pass-rate"',
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
return {
|
|
494
|
-
kind: 'ok',
|
|
495
|
-
value: { datasetId, datasetVersion, criterion: { kind: 'min-pass-rate', minPassRate } },
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
if (cr.kind === 'strict-improvement') {
|
|
499
|
-
const baseline = cr.baselinePassRate;
|
|
500
|
-
const minDelta = cr.minDelta;
|
|
501
|
-
if (typeof baseline !== 'number' || !Number.isFinite(baseline)) {
|
|
502
|
-
return {
|
|
503
|
-
kind: 'err',
|
|
504
|
-
message: 'Field `criterion.baselinePassRate` must be a finite number for kind "strict-improvement"',
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
if (typeof minDelta !== 'number' || !Number.isFinite(minDelta)) {
|
|
508
|
-
return {
|
|
509
|
-
kind: 'err',
|
|
510
|
-
message: 'Field `criterion.minDelta` must be a finite number for kind "strict-improvement"',
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
return {
|
|
514
|
-
kind: 'ok',
|
|
515
|
-
value: {
|
|
516
|
-
datasetId,
|
|
517
|
-
datasetVersion,
|
|
518
|
-
criterion: { kind: 'strict-improvement', baselinePassRate: baseline, minDelta },
|
|
519
|
-
},
|
|
520
|
-
};
|
|
367
|
+
const extra = Object.keys(b).filter((k) => !['suiteId', 'objective', 'reads', 'repetitions', 'k', 'classWeights', 'sample'].includes(k));
|
|
368
|
+
if (extra.length > 0) {
|
|
369
|
+
return `\`${extra[0]}\` isn't a field of an evaluation: { suiteId, objective?, reads?, repetitions?, k?, classWeights?, sample? }`;
|
|
521
370
|
}
|
|
371
|
+
const comparison = parseComparison(b);
|
|
372
|
+
if (comparison.kind === 'err')
|
|
373
|
+
return comparison.message;
|
|
522
374
|
return {
|
|
523
|
-
|
|
524
|
-
|
|
375
|
+
suiteId: b.suiteId,
|
|
376
|
+
objective: b.objective ?? 'weightedYesShare',
|
|
377
|
+
...(comparison.value !== undefined && { comparison: comparison.value }),
|
|
525
378
|
};
|
|
526
379
|
}
|
|
527
|
-
function
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
return {
|
|
538
|
-
kind: 'err',
|
|
539
|
-
message: 'Field `requiredRole` must be one of "standard", "senior", "admin"',
|
|
540
|
-
};
|
|
541
|
-
}
|
|
542
|
-
out.requiredRole = requiredRole;
|
|
543
|
-
}
|
|
544
|
-
const expiresAt = b.expiresAt;
|
|
545
|
-
if (expiresAt !== undefined) {
|
|
546
|
-
if (typeof expiresAt !== 'string' || Number.isNaN(new Date(expiresAt).getTime())) {
|
|
547
|
-
return { kind: 'err', message: 'Field `expiresAt` must be an ISO date string' };
|
|
548
|
-
}
|
|
549
|
-
out.expiresAt = expiresAt;
|
|
550
|
-
}
|
|
551
|
-
return { kind: 'ok', value: out };
|
|
380
|
+
function optionalText(body, field) {
|
|
381
|
+
const v = body[field];
|
|
382
|
+
if (v === undefined)
|
|
383
|
+
return { kind: 'ok' };
|
|
384
|
+
return nonEmpty(v)
|
|
385
|
+
? { kind: 'ok', value: v }
|
|
386
|
+
: {
|
|
387
|
+
kind: 'err',
|
|
388
|
+
message: `\`${field}\` must be a non-empty string (at most ${MAX_TEXT} characters)`,
|
|
389
|
+
};
|
|
552
390
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
391
|
+
/** The body as an object; `{}` when empty, `undefined` when it isn't a JSON object. */
|
|
392
|
+
async function readBody(c) {
|
|
393
|
+
const text = await c.req.text();
|
|
394
|
+
if (text.trim() === '')
|
|
395
|
+
return {};
|
|
396
|
+
try {
|
|
397
|
+
return obj(JSON.parse(text));
|
|
556
398
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
if (newVersion !== undefined) {
|
|
560
|
-
if (typeof newVersion !== 'string' || newVersion.length === 0) {
|
|
561
|
-
return {
|
|
562
|
-
kind: 'err',
|
|
563
|
-
message: 'Field `newVersion` must be a non-empty string when present',
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
return { kind: 'ok', value: { newVersion } };
|
|
399
|
+
catch {
|
|
400
|
+
return undefined;
|
|
567
401
|
}
|
|
568
|
-
return { kind: 'ok', value: {} };
|
|
569
402
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
return
|
|
403
|
+
// ---------- helpers ----------
|
|
404
|
+
function fail(c, code, error) {
|
|
405
|
+
c.status(statusFor(code));
|
|
406
|
+
return c.json(toWireError(error, c.get('requestId')));
|
|
407
|
+
}
|
|
408
|
+
function badInput(c, message) {
|
|
409
|
+
return fail(c, 'bad-input', { code: 'bad-input', message });
|
|
410
|
+
}
|
|
411
|
+
function failWith(c, error) {
|
|
412
|
+
return fail(c, error.code, error);
|
|
580
413
|
}
|
|
581
414
|
//# sourceMappingURL=proposals.js.map
|