@kindgi/api 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-binding.d.ts +13 -0
- package/dist/agent-binding.d.ts.map +1 -1
- package/dist/agent-pins.d.ts.map +1 -1
- package/dist/agent-pins.js +18 -2
- package/dist/agent-pins.js.map +1 -1
- package/dist/app.d.ts +110 -17
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +163 -35
- package/dist/app.js.map +1 -1
- package/dist/block-publish.d.ts +56 -0
- package/dist/block-publish.d.ts.map +1 -0
- package/dist/block-publish.js +132 -0
- package/dist/block-publish.js.map +1 -0
- package/dist/caller.d.ts +24 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +47 -0
- package/dist/caller.js.map +1 -0
- package/dist/capability-binding.d.ts +11 -0
- package/dist/capability-binding.d.ts.map +1 -1
- package/dist/cost-binding.d.ts +19 -0
- package/dist/cost-binding.d.ts.map +1 -1
- package/dist/cost-binding.js.map +1 -1
- package/dist/derive-agent-version.d.ts +7 -0
- package/dist/derive-agent-version.d.ts.map +1 -1
- package/dist/derive-agent-version.js +4 -0
- package/dist/derive-agent-version.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +75 -7
- package/dist/errors.js.map +1 -1
- package/dist/eval-case-binding.d.ts +16 -4
- package/dist/eval-case-binding.d.ts.map +1 -1
- package/dist/eval-run-binding.d.ts +31 -0
- package/dist/eval-run-binding.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.d.ts +7 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.js.map +1 -1
- package/dist/eval-sample.d.ts +11 -0
- package/dist/eval-sample.d.ts.map +1 -0
- package/dist/eval-sample.js +34 -0
- package/dist/eval-sample.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +13 -0
- package/dist/eval-suite-binding.d.ts.map +1 -1
- package/dist/eval-suite-binding.js.map +1 -1
- package/dist/flow-binding.d.ts +18 -0
- package/dist/flow-binding.d.ts.map +1 -1
- package/dist/flow-pins.d.ts.map +1 -1
- package/dist/flow-pins.js +18 -2
- package/dist/flow-pins.js.map +1 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +25 -0
- package/dist/gate.js.map +1 -1
- package/dist/handler-binding.d.ts +32 -0
- package/dist/handler-binding.d.ts.map +1 -1
- package/dist/hitl-binding.d.ts +23 -0
- package/dist/hitl-binding.d.ts.map +1 -1
- package/dist/identity-directory-binding.d.ts +82 -4
- package/dist/identity-directory-binding.d.ts.map +1 -1
- package/dist/identity-provider-binding.d.ts +197 -17
- package/dist/identity-provider-binding.d.ts.map +1 -1
- package/dist/improvement-pass-binding.d.ts +196 -0
- package/dist/improvement-pass-binding.d.ts.map +1 -0
- package/dist/improvement-pass-binding.js +9 -0
- package/dist/improvement-pass-binding.js.map +1 -0
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/judged-dispatcher.d.ts +25 -4
- package/dist/judged-dispatcher.d.ts.map +1 -1
- package/dist/judged-dispatcher.js +43 -6
- package/dist/judged-dispatcher.js.map +1 -1
- package/dist/judgment-binding.d.ts +25 -1
- package/dist/judgment-binding.d.ts.map +1 -1
- package/dist/mcp-endpoint-binding.d.ts +7 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -1
- package/dist/memory-binding.d.ts +124 -17
- package/dist/memory-binding.d.ts.map +1 -1
- package/dist/memory-erasure-binding.d.ts +145 -0
- package/dist/memory-erasure-binding.d.ts.map +1 -0
- package/dist/memory-erasure-binding.js +4 -0
- package/dist/memory-erasure-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +66 -13
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +150 -50
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/authorize.d.ts +9 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +122 -4
- package/dist/middleware/authorize.js.map +1 -1
- package/dist/middleware/error-mapper.d.ts +5 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -1
- package/dist/middleware/error-mapper.js +14 -1
- package/dist/middleware/error-mapper.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +70 -5
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +174 -41
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/key-project.d.ts +17 -0
- package/dist/middleware/key-project.d.ts.map +1 -0
- package/dist/middleware/key-project.js +75 -0
- package/dist/middleware/key-project.js.map +1 -0
- package/dist/middleware/principal.d.ts.map +1 -1
- package/dist/middleware/principal.js +9 -5
- package/dist/middleware/principal.js.map +1 -1
- package/dist/middleware/project-ref.d.ts.map +1 -1
- package/dist/middleware/project-ref.js +3 -0
- package/dist/middleware/project-ref.js.map +1 -1
- package/dist/openapi/generate.d.ts.map +1 -1
- package/dist/openapi/generate.js +5 -2
- package/dist/openapi/generate.js.map +1 -1
- package/dist/openapi/operations.d.ts.map +1 -1
- package/dist/openapi/operations.js +919 -140
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +90 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2081 -359
- package/dist/openapi/schemas.js.map +1 -1
- package/dist/person-grants-binding.d.ts +77 -0
- package/dist/person-grants-binding.d.ts.map +1 -0
- package/dist/person-grants-binding.js +4 -0
- package/dist/person-grants-binding.js.map +1 -0
- package/dist/proposal-service.d.ts +121 -0
- package/dist/proposal-service.d.ts.map +1 -0
- package/dist/proposal-service.js +447 -0
- package/dist/proposal-service.js.map +1 -0
- package/dist/proposal-status.d.ts +60 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +109 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/provider-binding.d.ts +10 -0
- package/dist/provider-binding.d.ts.map +1 -1
- package/dist/publish-refused.d.ts +28 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +24 -3
- package/dist/publish-refused.js.map +1 -1
- package/dist/routes/adapters.d.ts +2 -1
- package/dist/routes/adapters.d.ts.map +1 -1
- package/dist/routes/adapters.js +3 -1
- package/dist/routes/adapters.js.map +1 -1
- package/dist/routes/agent-releases.d.ts +55 -3
- package/dist/routes/agent-releases.d.ts.map +1 -1
- package/dist/routes/agent-releases.js +85 -55
- package/dist/routes/agent-releases.js.map +1 -1
- package/dist/routes/agents.d.ts +12 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +100 -2
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts +15 -3
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +133 -122
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/artifacts.d.ts +25 -3
- package/dist/routes/artifacts.d.ts.map +1 -1
- package/dist/routes/artifacts.js +116 -7
- package/dist/routes/artifacts.js.map +1 -1
- package/dist/routes/auth.d.ts +25 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +655 -281
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/blocks.d.ts.map +1 -1
- package/dist/routes/blocks.js +2 -42
- package/dist/routes/blocks.js.map +1 -1
- package/dist/routes/capabilities.d.ts +2 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +6 -1
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +9 -10
- package/dist/routes/compliance.d.ts.map +1 -1
- package/dist/routes/compliance.js +42 -61
- package/dist/routes/compliance.js.map +1 -1
- package/dist/routes/conversations.d.ts +8 -1
- package/dist/routes/conversations.d.ts.map +1 -1
- package/dist/routes/conversations.js +87 -8
- package/dist/routes/conversations.js.map +1 -1
- package/dist/routes/cost.d.ts +12 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +74 -3
- package/dist/routes/cost.js.map +1 -1
- package/dist/routes/denied.d.ts +11 -0
- package/dist/routes/denied.d.ts.map +1 -0
- package/dist/routes/denied.js +17 -0
- package/dist/routes/denied.js.map +1 -0
- package/dist/routes/deployments.d.ts +10 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +171 -13
- package/dist/routes/deployments.js.map +1 -1
- package/dist/routes/eval-comparison.d.ts.map +1 -1
- package/dist/routes/eval-comparison.js +69 -1
- package/dist/routes/eval-comparison.js.map +1 -1
- package/dist/routes/eval-overrides.d.ts +18 -0
- package/dist/routes/eval-overrides.d.ts.map +1 -0
- package/dist/routes/eval-overrides.js +81 -0
- package/dist/routes/eval-overrides.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +10 -1
- package/dist/routes/eval-runs.d.ts.map +1 -1
- package/dist/routes/eval-runs.js +66 -7
- package/dist/routes/eval-runs.js.map +1 -1
- package/dist/routes/eval-suites.d.ts.map +1 -1
- package/dist/routes/eval-suites.js +28 -2
- package/dist/routes/eval-suites.js.map +1 -1
- package/dist/routes/event-triggers.d.ts +5 -1
- package/dist/routes/event-triggers.d.ts.map +1 -1
- package/dist/routes/event-triggers.js +26 -3
- package/dist/routes/event-triggers.js.map +1 -1
- package/dist/routes/export-signing-keys.d.ts +12 -0
- package/dist/routes/export-signing-keys.d.ts.map +1 -0
- package/dist/routes/export-signing-keys.js +24 -0
- package/dist/routes/export-signing-keys.js.map +1 -0
- package/dist/routes/flows.d.ts.map +1 -1
- package/dist/routes/flows.js +9 -1
- package/dist/routes/flows.js.map +1 -1
- package/dist/routes/gate-policies.d.ts +4 -1
- package/dist/routes/gate-policies.d.ts.map +1 -1
- package/dist/routes/gate-policies.js +29 -5
- package/dist/routes/gate-policies.js.map +1 -1
- package/dist/routes/guardrails.d.ts +16 -14
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +39 -3
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/identity.d.ts +20 -4
- package/dist/routes/identity.d.ts.map +1 -1
- package/dist/routes/identity.js +246 -6
- package/dist/routes/identity.js.map +1 -1
- package/dist/routes/improvement-passes.d.ts +52 -0
- package/dist/routes/improvement-passes.d.ts.map +1 -0
- package/dist/routes/improvement-passes.js +449 -0
- package/dist/routes/improvement-passes.js.map +1 -0
- package/dist/routes/judged-suites.d.ts +50 -0
- package/dist/routes/judged-suites.d.ts.map +1 -1
- package/dist/routes/judged-suites.js +66 -27
- package/dist/routes/judged-suites.js.map +1 -1
- package/dist/routes/judgment-context.d.ts +18 -2
- package/dist/routes/judgment-context.d.ts.map +1 -1
- package/dist/routes/judgment-context.js +63 -5
- package/dist/routes/judgment-context.js.map +1 -1
- package/dist/routes/judgment-flow-context.d.ts.map +1 -1
- package/dist/routes/judgment-flow-context.js +14 -2
- package/dist/routes/judgment-flow-context.js.map +1 -1
- package/dist/routes/judgments.d.ts.map +1 -1
- package/dist/routes/judgments.js +8 -1
- package/dist/routes/judgments.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +26 -1
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/memory-access.d.ts +43 -0
- package/dist/routes/memory-access.d.ts.map +1 -0
- package/dist/routes/memory-access.js +114 -0
- package/dist/routes/memory-access.js.map +1 -0
- package/dist/routes/memory-erasures.d.ts +25 -0
- package/dist/routes/memory-erasures.d.ts.map +1 -0
- package/dist/routes/memory-erasures.js +214 -0
- package/dist/routes/memory-erasures.js.map +1 -0
- package/dist/routes/memory-parse.d.ts +38 -0
- package/dist/routes/memory-parse.d.ts.map +1 -0
- package/dist/routes/memory-parse.js +199 -0
- package/dist/routes/memory-parse.js.map +1 -0
- package/dist/routes/memory.d.ts +9 -4
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/memory.js +226 -234
- package/dist/routes/memory.js.map +1 -1
- package/dist/routes/observations.d.ts +4 -1
- package/dist/routes/observations.d.ts.map +1 -1
- package/dist/routes/observations.js +8 -2
- package/dist/routes/observations.js.map +1 -1
- package/dist/routes/pagination.d.ts +7 -0
- package/dist/routes/pagination.d.ts.map +1 -1
- package/dist/routes/pagination.js +10 -0
- package/dist/routes/pagination.js.map +1 -1
- package/dist/routes/policies.d.ts +2 -1
- package/dist/routes/policies.d.ts.map +1 -1
- package/dist/routes/policies.js +3 -1
- package/dist/routes/policies.js.map +1 -1
- package/dist/routes/project-mismatch.d.ts +22 -0
- package/dist/routes/project-mismatch.d.ts.map +1 -0
- package/dist/routes/project-mismatch.js +34 -0
- package/dist/routes/project-mismatch.js.map +1 -0
- package/dist/routes/projects.d.ts +15 -4
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +100 -9
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/proposals.d.ts +25 -17
- package/dist/routes/proposals.d.ts.map +1 -1
- package/dist/routes/proposals.js +340 -507
- package/dist/routes/proposals.js.map +1 -1
- package/dist/routes/provenance.d.ts +17 -3
- package/dist/routes/provenance.d.ts.map +1 -1
- package/dist/routes/provenance.js +79 -103
- package/dist/routes/provenance.js.map +1 -1
- package/dist/routes/providers.d.ts +17 -1
- package/dist/routes/providers.d.ts.map +1 -1
- package/dist/routes/providers.js +110 -3
- package/dist/routes/providers.js.map +1 -1
- package/dist/routes/public-run-tokens.d.ts.map +1 -1
- package/dist/routes/public-run-tokens.js +3 -0
- package/dist/routes/public-run-tokens.js.map +1 -1
- package/dist/routes/readable-projects.d.ts +26 -0
- package/dist/routes/readable-projects.d.ts.map +1 -0
- package/dist/routes/readable-projects.js +39 -0
- package/dist/routes/readable-projects.js.map +1 -0
- package/dist/routes/runs.d.ts +10 -0
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +92 -42
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/schedules.d.ts +21 -13
- package/dist/routes/schedules.d.ts.map +1 -1
- package/dist/routes/schedules.js +416 -55
- package/dist/routes/schedules.js.map +1 -1
- package/dist/routes/segments.d.ts +2 -0
- package/dist/routes/segments.d.ts.map +1 -1
- package/dist/routes/segments.js +5 -0
- package/dist/routes/segments.js.map +1 -1
- package/dist/routes/service-accounts.d.ts +17 -0
- package/dist/routes/service-accounts.d.ts.map +1 -0
- package/dist/routes/service-accounts.js +212 -0
- package/dist/routes/service-accounts.js.map +1 -0
- package/dist/routes/sign-in-options.d.ts +50 -0
- package/dist/routes/sign-in-options.d.ts.map +1 -0
- package/dist/routes/sign-in-options.js +98 -0
- package/dist/routes/sign-in-options.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +2 -1
- package/dist/routes/signing-keys.d.ts.map +1 -1
- package/dist/routes/signing-keys.js +3 -1
- package/dist/routes/signing-keys.js.map +1 -1
- package/dist/routes/tenant-access.d.ts +13 -0
- package/dist/routes/tenant-access.d.ts.map +1 -0
- package/dist/routes/tenant-access.js +26 -0
- package/dist/routes/tenant-access.js.map +1 -0
- package/dist/routes/tenant.d.ts.map +1 -1
- package/dist/routes/tenant.js +4 -0
- package/dist/routes/tenant.js.map +1 -1
- package/dist/routes/token-sign-in.d.ts +36 -0
- package/dist/routes/token-sign-in.d.ts.map +1 -0
- package/dist/routes/token-sign-in.js +101 -0
- package/dist/routes/token-sign-in.js.map +1 -0
- package/dist/routes/tokens.d.ts +15 -5
- package/dist/routes/tokens.d.ts.map +1 -1
- package/dist/routes/tokens.js +162 -43
- package/dist/routes/tokens.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +9 -1
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/trigger-access.d.ts +29 -0
- package/dist/routes/trigger-access.d.ts.map +1 -0
- package/dist/routes/trigger-access.js +33 -0
- package/dist/routes/trigger-access.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +2 -1
- package/dist/routes/webhook-endpoints.d.ts.map +1 -1
- package/dist/routes/webhook-endpoints.js +11 -3
- package/dist/routes/webhook-endpoints.js.map +1 -1
- package/dist/routes/webhooks.d.ts +5 -1
- package/dist/routes/webhooks.d.ts.map +1 -1
- package/dist/routes/webhooks.js +25 -2
- package/dist/routes/webhooks.js.map +1 -1
- package/dist/run-failure.d.ts +21 -0
- package/dist/run-failure.d.ts.map +1 -0
- package/dist/run-failure.js +29 -0
- package/dist/run-failure.js.map +1 -0
- package/dist/service-account-binding.d.ts +108 -0
- package/dist/service-account-binding.d.ts.map +1 -0
- package/dist/service-account-binding.js +4 -0
- package/dist/service-account-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +61 -13
- package/dist/session-store-binding.d.ts.map +1 -1
- package/dist/signed-export.d.ts +89 -0
- package/dist/signed-export.d.ts.map +1 -0
- package/dist/signed-export.js +149 -0
- package/dist/signed-export.js.map +1 -0
- package/dist/supervisor-binding.d.ts +186 -413
- package/dist/supervisor-binding.d.ts.map +1 -1
- package/dist/testing/app-bindings.d.ts +33 -0
- package/dist/testing/app-bindings.d.ts.map +1 -0
- package/dist/testing/app-bindings.js +112 -0
- package/dist/testing/app-bindings.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +13 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/stub-binding.d.ts +34 -0
- package/dist/testing/stub-binding.d.ts.map +1 -0
- package/dist/testing/stub-binding.js +42 -0
- package/dist/testing/stub-binding.js.map +1 -0
- package/dist/testing/trigger-registry.d.ts +21 -0
- package/dist/testing/trigger-registry.d.ts.map +1 -0
- package/dist/testing/trigger-registry.js +206 -0
- package/dist/testing/trigger-registry.js.map +1 -0
- package/dist/token-admin.d.ts +46 -8
- package/dist/token-admin.d.ts.map +1 -1
- package/dist/token-admin.js.map +1 -1
- package/dist/tool-binding.d.ts +13 -0
- package/dist/tool-binding.d.ts.map +1 -1
- package/dist/trigger-binding.d.ts +2 -2
- package/dist/trigger-binding.d.ts.map +1 -1
- package/dist/trigger-binding.js +1 -1
- package/dist/trigger-binding.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.d.ts +19 -3
- package/dist/webhook-endpoint-binding.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.js +1 -1
- package/dist/webhook-endpoint-binding.js.map +1 -1
- package/openapi.json +15387 -8789
- package/package.json +26 -22
- package/src/agent-binding.ts +14 -0
- package/src/agent-pins.ts +18 -2
- package/src/app.ts +366 -80
- package/src/block-publish.ts +181 -0
- package/src/caller.ts +62 -0
- package/src/capability-binding.ts +12 -0
- package/src/cost-binding.ts +19 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +75 -7
- package/src/eval-case-binding.ts +17 -1
- package/src/eval-run-binding.ts +31 -0
- package/src/eval-run-dispatcher.ts +7 -0
- package/src/eval-sample.ts +42 -0
- package/src/eval-suite-binding.ts +14 -0
- package/src/flow-binding.ts +19 -0
- package/src/flow-pins.ts +18 -2
- package/src/gate.ts +26 -0
- package/src/handler-binding.ts +36 -1
- package/src/hitl-binding.ts +24 -0
- package/src/identity-directory-binding.ts +85 -4
- package/src/identity-provider-binding.ts +216 -21
- package/src/improvement-pass-binding.ts +193 -0
- package/src/index.ts +153 -31
- package/src/judged-dispatcher.ts +78 -11
- package/src/judgment-binding.ts +25 -1
- package/src/mcp-endpoint-binding.ts +7 -0
- package/src/memory-binding.ts +121 -17
- package/src/memory-erasure-binding.ts +156 -0
- package/src/middleware/auth.ts +228 -62
- package/src/middleware/authorize.ts +155 -3
- package/src/middleware/error-mapper.ts +15 -1
- package/src/middleware/idempotency.ts +230 -43
- package/src/middleware/key-project.ts +86 -0
- package/src/middleware/principal.ts +9 -5
- package/src/middleware/project-ref.ts +3 -0
- package/src/openapi/generate.ts +11 -2
- package/src/openapi/operations.ts +1060 -143
- package/src/openapi/schemas.ts +2387 -469
- package/src/person-grants-binding.ts +76 -0
- package/src/proposal-service.ts +640 -0
- package/src/proposal-status.ts +176 -0
- package/src/provider-binding.ts +10 -0
- package/src/publish-refused.ts +56 -9
- package/src/routes/adapters.ts +4 -0
- package/src/routes/agent-releases.ts +121 -69
- package/src/routes/agents.ts +128 -1
- package/src/routes/approvals.ts +164 -154
- package/src/routes/artifacts.ts +181 -11
- package/src/routes/auth.ts +804 -336
- package/src/routes/blocks.ts +2 -53
- package/src/routes/capabilities.ts +10 -1
- package/src/routes/compliance.ts +60 -99
- package/src/routes/conversations.ts +101 -7
- package/src/routes/cost.ts +110 -4
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +210 -17
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +89 -6
- package/src/routes/eval-suites.ts +32 -2
- package/src/routes/event-triggers.ts +27 -3
- package/src/routes/export-signing-keys.ts +31 -0
- package/src/routes/flows.ts +12 -1
- package/src/routes/gate-policies.ts +37 -6
- package/src/routes/guardrails.ts +61 -2
- package/src/routes/identity.ts +328 -10
- package/src/routes/improvement-passes.ts +541 -0
- package/src/routes/judged-suites.ts +113 -43
- package/src/routes/judgment-context.ts +76 -5
- package/src/routes/judgment-flow-context.ts +16 -2
- package/src/routes/judgments.ts +17 -3
- package/src/routes/mcp.ts +29 -1
- package/src/routes/memory-access.ts +160 -0
- package/src/routes/memory-erasures.ts +240 -0
- package/src/routes/memory-parse.ts +250 -0
- package/src/routes/memory.ts +244 -286
- package/src/routes/observations.ts +15 -2
- package/src/routes/pagination.ts +12 -0
- package/src/routes/policies.ts +7 -1
- package/src/routes/project-mismatch.ts +56 -0
- package/src/routes/projects.ts +107 -13
- package/src/routes/proposals.ts +370 -611
- package/src/routes/provenance.ts +99 -133
- package/src/routes/providers.ts +142 -3
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/readable-projects.ts +66 -0
- package/src/routes/runs.ts +119 -39
- package/src/routes/schedules.ts +472 -60
- package/src/routes/segments.ts +11 -0
- package/src/routes/service-accounts.ts +262 -0
- package/src/routes/sign-in-options.ts +168 -0
- package/src/routes/signing-keys.ts +7 -1
- package/src/routes/tenant-access.ts +37 -0
- package/src/routes/tenant.ts +6 -0
- package/src/routes/token-sign-in.ts +161 -0
- package/src/routes/tokens.ts +172 -46
- package/src/routes/tools.ts +12 -1
- package/src/routes/trigger-access.ts +72 -0
- package/src/routes/webhook-endpoints.ts +15 -3
- package/src/routes/webhooks.ts +26 -2
- package/src/run-failure.ts +42 -0
- package/src/service-account-binding.ts +113 -0
- package/src/session-store-binding.ts +65 -13
- package/src/signed-export.ts +250 -0
- package/src/supervisor-binding.ts +169 -409
- package/src/testing/app-bindings.ts +142 -0
- package/src/testing/index.ts +21 -0
- package/src/testing/stub-binding.ts +53 -0
- package/src/testing/trigger-registry.ts +259 -0
- package/src/token-admin.ts +40 -8
- package/src/tool-binding.ts +14 -0
- package/src/trigger-binding.ts +8 -1
- package/src/types.ts +16 -0
- package/src/webhook-endpoint-binding.ts +18 -3
package/src/routes/memory.ts
CHANGED
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
|
-
import { Hono } from 'hono';
|
|
4
|
+
import { type Context, Hono } from 'hono';
|
|
5
5
|
|
|
6
|
-
import type { Fact,
|
|
6
|
+
import type { Fact, MemoryReaders, MemoryScope } from '@kindgi/memory';
|
|
7
7
|
import type { FactId, TenantId } from '@kindgi/types';
|
|
8
8
|
|
|
9
9
|
import { statusFor, toWireError } from '../errors.js';
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
MemoryBinding,
|
|
12
|
+
MemoryFactChangeOutcome,
|
|
13
|
+
MemoryRetrievalHit,
|
|
14
|
+
} from '../memory-binding.js';
|
|
11
15
|
import type { AppEnv } from '../types.js';
|
|
16
|
+
import {
|
|
17
|
+
type MemoryAccessDeps,
|
|
18
|
+
callerAttribution,
|
|
19
|
+
callerRef,
|
|
20
|
+
memoryReadersFor,
|
|
21
|
+
memoryWriteProblem,
|
|
22
|
+
} from './memory-access.js';
|
|
23
|
+
import {
|
|
24
|
+
parseScopeParam,
|
|
25
|
+
parseTime,
|
|
26
|
+
parseVersion,
|
|
27
|
+
validateRetrieveIntent,
|
|
28
|
+
validateSupersedeBody,
|
|
29
|
+
validateWriteFactBody,
|
|
30
|
+
} from './memory-parse.js';
|
|
12
31
|
import { clampLimit } from './pagination.js';
|
|
13
32
|
import { parseScopeParams } from './scope-params.js';
|
|
14
33
|
|
|
@@ -16,14 +35,18 @@ import { parseScopeParams } from './scope-params.js';
|
|
|
16
35
|
* Memory resource routes.
|
|
17
36
|
*
|
|
18
37
|
* Storage is caller-plugged via `MemoryBinding`. The API package does
|
|
19
|
-
* not own memory persistence, retrieval, or embeddings
|
|
38
|
+
* not own memory persistence, retrieval, or embeddings: deployments
|
|
20
39
|
* wire a binding that wraps the memory subsystem alongside their own
|
|
21
40
|
* `EmbeddingProviderRegistry` and per-type retrieval policies.
|
|
22
41
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
42
|
+
* A fact keeps its id across revisions: supersede writes the next one,
|
|
43
|
+
* delete tombstones it (the retention sweep removes it later), verify
|
|
44
|
+
* marks it verified. Every read sees only what the caller may
|
|
45
|
+
* (`memory-access.ts`): the binding applies it inside its query, and a
|
|
46
|
+
* fact the caller can't see is not found. Every write is checked against
|
|
47
|
+
* the scope it names.
|
|
25
48
|
*/
|
|
26
|
-
export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
|
|
49
|
+
export function memoryRouter(binding: MemoryBinding, access: MemoryAccessDeps = {}): Hono<AppEnv> {
|
|
27
50
|
const r = new Hono<AppEnv>();
|
|
28
51
|
|
|
29
52
|
// ---------- GET /facts (list, cursor-paginated) ----------
|
|
@@ -31,7 +54,6 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
|
|
|
31
54
|
const requestId = c.get('requestId');
|
|
32
55
|
const tenantId = c.get('tenantId') as TenantId;
|
|
33
56
|
const limit = clampLimit(c.req.query('limit'));
|
|
34
|
-
|
|
35
57
|
const cursorRaw = c.req.query('cursor');
|
|
36
58
|
const typeRaw = c.req.query('type');
|
|
37
59
|
const scopeRaw = c.req.query('scope');
|
|
@@ -40,25 +62,16 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
|
|
|
40
62
|
if (scopeRaw !== undefined && scopeRaw.length > 0) {
|
|
41
63
|
const parsed = parseScopeParam(scopeRaw);
|
|
42
64
|
if (parsed === null) {
|
|
43
|
-
c
|
|
44
|
-
return c.json(
|
|
45
|
-
toWireError(
|
|
46
|
-
{ code: 'bad-input', message: 'Query parameter `scope` must be a JSON object' },
|
|
47
|
-
requestId,
|
|
48
|
-
),
|
|
49
|
-
);
|
|
65
|
+
return fail(c, 'bad-input', 'Query parameter `scope` must be a JSON object');
|
|
50
66
|
}
|
|
51
67
|
scope = parsed;
|
|
52
68
|
}
|
|
53
|
-
if (scopeNamesOtherTenant(scope, tenantId))
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
69
|
+
if (scopeNamesOtherTenant(scope, tenantId)) return failScopeMismatch(c);
|
|
70
|
+
const asOf = parseTime(c.req.query('asOf'), 'asOf');
|
|
71
|
+
if (asOf.kind === 'err') return fail(c, 'bad-input', asOf.message);
|
|
57
72
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
// `?scope=` query param + `scope: Partial<MemoryScope>` field above
|
|
61
|
-
// are a separate filter — both coexist by design.
|
|
73
|
+
// `?scopeKind` + `?scopeId` + `?inherit` narrow by the platform scope
|
|
74
|
+
// (`platformScope`); `?scope=` is the memory scope. Both coexist.
|
|
62
75
|
const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
|
|
63
76
|
if (scopeParsed.kind === 'err') {
|
|
64
77
|
c.status(statusFor('scope-invalid') as never);
|
|
@@ -69,7 +82,9 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
|
|
|
69
82
|
|
|
70
83
|
const page = await binding.listFacts({
|
|
71
84
|
tenantId,
|
|
85
|
+
readers: await memoryReadersFor(c, access),
|
|
72
86
|
limit,
|
|
87
|
+
...(asOf.value !== undefined && { asOf: asOf.value }),
|
|
73
88
|
...(cursorRaw !== undefined &&
|
|
74
89
|
cursorRaw.length > 0 && {
|
|
75
90
|
cursor: cursorRaw as import('@kindgi/types').Cursor,
|
|
@@ -86,154 +101,232 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
|
|
|
86
101
|
});
|
|
87
102
|
});
|
|
88
103
|
|
|
89
|
-
// ---------- GET /facts/:factId ----------
|
|
104
|
+
// ---------- GET /facts/:factId (?version | ?asOf) ----------
|
|
90
105
|
r.get('/facts/:factId', async (c) => {
|
|
91
|
-
const requestId = c.get('requestId');
|
|
92
106
|
const tenantId = c.get('tenantId') as TenantId;
|
|
93
107
|
const factId = c.req.param('factId') as FactId;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
),
|
|
107
|
-
);
|
|
108
|
-
}
|
|
108
|
+
const version = parseVersion(c.req.query('version'), 'version');
|
|
109
|
+
if (version.kind === 'err') return fail(c, 'bad-input', version.message);
|
|
110
|
+
const asOf = parseTime(c.req.query('asOf'), 'asOf');
|
|
111
|
+
if (asOf.kind === 'err') return fail(c, 'bad-input', asOf.message);
|
|
112
|
+
const fact = await binding.getFact({
|
|
113
|
+
tenantId,
|
|
114
|
+
factId,
|
|
115
|
+
readers: await memoryReadersFor(c, access),
|
|
116
|
+
...(version.value !== undefined && { version: version.value }),
|
|
117
|
+
...(asOf.value !== undefined && { asOf: asOf.value }),
|
|
118
|
+
});
|
|
119
|
+
if (fact === null) return failNotFound(c, factId);
|
|
109
120
|
return c.json(serializeFact(fact));
|
|
110
121
|
});
|
|
111
122
|
|
|
123
|
+
// ---------- GET /facts/:factId/revisions ----------
|
|
124
|
+
r.get('/facts/:factId/revisions', async (c) => {
|
|
125
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
126
|
+
const factId = c.req.param('factId') as FactId;
|
|
127
|
+
if (binding.listRevisions === undefined) return unsupported(c, 'fact history');
|
|
128
|
+
const revisions = await binding.listRevisions({
|
|
129
|
+
tenantId,
|
|
130
|
+
factId,
|
|
131
|
+
readers: await memoryReadersFor(c, access),
|
|
132
|
+
});
|
|
133
|
+
if (revisions === null) return failNotFound(c, factId);
|
|
134
|
+
return c.json({ data: revisions.map(serializeFact) });
|
|
135
|
+
});
|
|
136
|
+
|
|
112
137
|
// ---------- POST /facts (write) ----------
|
|
113
138
|
r.post('/facts', async (c) => {
|
|
114
|
-
const requestId = c.get('requestId');
|
|
115
139
|
const tenantId = c.get('tenantId') as TenantId;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
if (body === null || typeof body !== 'object') {
|
|
127
|
-
c.status(statusFor('bad-input') as never);
|
|
128
|
-
return c.json(
|
|
129
|
-
toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const validation = validateWriteFactBody(body as Record<string, unknown>);
|
|
134
|
-
if (validation.kind === 'err') {
|
|
135
|
-
c.status(statusFor('bad-input') as never);
|
|
136
|
-
return c.json(toWireError({ code: 'bad-input', message: validation.message }, requestId));
|
|
137
|
-
}
|
|
138
|
-
const { type, scope, content, retention, contentHash } = validation.value;
|
|
139
|
-
if (scopeNamesOtherTenant(scope, tenantId)) {
|
|
140
|
-
c.status(statusFor('scope-mismatch') as never);
|
|
141
|
-
return c.json(toWireError(SCOPE_MISMATCH, requestId));
|
|
142
|
-
}
|
|
140
|
+
const body = await readObject(c);
|
|
141
|
+
if (typeof body === 'string') return fail(c, 'bad-input', body);
|
|
142
|
+
const validation = validateWriteFactBody(body);
|
|
143
|
+
if (validation.kind === 'err') return fail(c, 'bad-input', validation.message);
|
|
144
|
+
const { scope, ...rest } = validation.value;
|
|
145
|
+
if (scopeNamesOtherTenant(scope, tenantId)) return failScopeMismatch(c);
|
|
146
|
+
const refused = await memoryWriteProblem(c, access, scope);
|
|
147
|
+
if (refused !== undefined) return fail(c, 'permission-denied', refused);
|
|
143
148
|
|
|
144
149
|
const outcome = await binding.writeFact({
|
|
145
150
|
tenantId,
|
|
146
|
-
type,
|
|
147
151
|
scope,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
...(contentHash !== undefined && { contentHash }),
|
|
152
|
+
...rest,
|
|
153
|
+
attributedTo: callerAttribution(c),
|
|
151
154
|
});
|
|
152
|
-
if (outcome.kind === 'embedding-unavailable')
|
|
153
|
-
|
|
154
|
-
return c.json(toWireError({ code: 'bad-input', message: outcome.message }, requestId));
|
|
155
|
-
}
|
|
156
|
-
if (outcome.kind === 'error') {
|
|
157
|
-
c.status(statusFor(outcome.code) as never);
|
|
158
|
-
return c.json(toWireError({ code: outcome.code, message: outcome.message }, requestId));
|
|
159
|
-
}
|
|
155
|
+
if (outcome.kind === 'embedding-unavailable') return fail(c, 'bad-input', outcome.message);
|
|
156
|
+
if (outcome.kind === 'error') return fail(c, outcome.code, outcome.message);
|
|
160
157
|
c.status(201);
|
|
161
158
|
return c.json(serializeFact(outcome.fact));
|
|
162
159
|
});
|
|
163
160
|
|
|
164
161
|
// ---------- POST /facts/:factId/supersede ----------
|
|
165
162
|
r.post('/facts/:factId/supersede', async (c) => {
|
|
166
|
-
const requestId = c.get('requestId');
|
|
167
163
|
const tenantId = c.get('tenantId') as TenantId;
|
|
168
164
|
const factId = c.req.param('factId') as FactId;
|
|
165
|
+
const body = await readObject(c);
|
|
166
|
+
if (typeof body === 'string') return fail(c, 'bad-input', body);
|
|
167
|
+
const validation = validateSupersedeBody(body);
|
|
168
|
+
if (validation.kind === 'err') return fail(c, 'bad-input', validation.message);
|
|
169
|
+
const target = await writableFact(c, factId);
|
|
170
|
+
if (target.kind === 'response') return target.response;
|
|
171
|
+
const outcome = await binding.supersedeFact({
|
|
172
|
+
tenantId,
|
|
173
|
+
factId,
|
|
174
|
+
readers: target.readers,
|
|
175
|
+
...validation.value,
|
|
176
|
+
attributedTo: callerAttribution(c),
|
|
177
|
+
});
|
|
178
|
+
return changeResponse(c, factId, outcome);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// ---------- DELETE /facts/:factId (tombstone) ----------
|
|
182
|
+
r.delete('/facts/:factId', async (c) => {
|
|
183
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
184
|
+
const factId = c.req.param('factId') as FactId;
|
|
185
|
+
if (binding.deleteFact === undefined) return unsupported(c, 'deleting facts');
|
|
186
|
+
const expectVersion = parseVersion(c.req.query('expectVersion'), 'expectVersion');
|
|
187
|
+
if (expectVersion.kind === 'err') return fail(c, 'bad-input', expectVersion.message);
|
|
188
|
+
const target = await writableFact(c, factId);
|
|
189
|
+
if (target.kind === 'response') return target.response;
|
|
190
|
+
const outcome = await binding.deleteFact({
|
|
191
|
+
tenantId,
|
|
192
|
+
factId,
|
|
193
|
+
readers: target.readers,
|
|
194
|
+
by: callerRef(c),
|
|
195
|
+
...(expectVersion.value !== undefined && { expectVersion: expectVersion.value }),
|
|
196
|
+
});
|
|
197
|
+
return changeResponse(c, factId, outcome);
|
|
198
|
+
});
|
|
169
199
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
200
|
+
// ---------- POST /facts/:factId/verify ----------
|
|
201
|
+
r.post('/facts/:factId/verify', async (c) => {
|
|
202
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
203
|
+
const factId = c.req.param('factId') as FactId;
|
|
204
|
+
if (binding.verifyFact === undefined) return unsupported(c, 'verifying facts');
|
|
205
|
+
const body = await readObject(c, { emptyIsObject: true });
|
|
206
|
+
if (typeof body === 'string') return fail(c, 'bad-input', body);
|
|
207
|
+
const expectVersion = parseVersion(body.expectVersion, 'expectVersion');
|
|
208
|
+
if (expectVersion.kind === 'err') return fail(c, 'bad-input', expectVersion.message);
|
|
209
|
+
const target = await writableFact(c, factId);
|
|
210
|
+
if (target.kind === 'response') return target.response;
|
|
211
|
+
const outcome = await binding.verifyFact({
|
|
212
|
+
tenantId,
|
|
213
|
+
factId,
|
|
214
|
+
readers: target.readers,
|
|
215
|
+
by: callerRef(c),
|
|
216
|
+
...(expectVersion.value !== undefined && { expectVersion: expectVersion.value }),
|
|
187
217
|
});
|
|
218
|
+
return changeResponse(c, factId, outcome);
|
|
188
219
|
});
|
|
189
220
|
|
|
190
221
|
// ---------- POST /retrieve ----------
|
|
191
222
|
r.post('/retrieve', async (c) => {
|
|
192
|
-
const requestId = c.get('requestId');
|
|
193
223
|
const tenantId = c.get('tenantId') as TenantId;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
);
|
|
224
|
+
const body = await readObject(c);
|
|
225
|
+
if (typeof body === 'string') return fail(c, 'bad-input', body);
|
|
226
|
+
const validation = validateRetrieveIntent(body);
|
|
227
|
+
if (validation.kind === 'err') return fail(c, 'bad-input', validation.message);
|
|
228
|
+
if (scopeNamesOtherTenant(validation.value.scope, tenantId)) return failScopeMismatch(c);
|
|
229
|
+
const outcome = await binding.retrieve({
|
|
230
|
+
tenantId,
|
|
231
|
+
intent: validation.value,
|
|
232
|
+
readers: await memoryReadersFor(c, access),
|
|
233
|
+
});
|
|
234
|
+
// Search by meaning on a deployment without embeddings: not the
|
|
235
|
+
// request's fault, and never an empty success.
|
|
236
|
+
if (outcome.kind === 'embedding-unavailable') {
|
|
237
|
+
return fail(c, 'semantic-unavailable', outcome.message);
|
|
209
238
|
}
|
|
239
|
+
if (outcome.kind === 'error') return fail(c, outcome.code, outcome.message);
|
|
240
|
+
return c.json({ results: outcome.results.map(serializeRetrievalHit) });
|
|
241
|
+
});
|
|
210
242
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
243
|
+
/**
|
|
244
|
+
* The fact the caller may see and change: its current revision is read
|
|
245
|
+
* (as the caller sees it), and the caller must be allowed to write in
|
|
246
|
+
* its scope.
|
|
247
|
+
*/
|
|
248
|
+
async function writableFact(
|
|
249
|
+
c: Context<AppEnv>,
|
|
250
|
+
factId: FactId,
|
|
251
|
+
): Promise<
|
|
252
|
+
| { readonly kind: 'ok'; readonly readers: MemoryReaders }
|
|
253
|
+
| { readonly kind: 'response'; readonly response: Response }
|
|
254
|
+
> {
|
|
255
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
256
|
+
const readers = await memoryReadersFor(c, access);
|
|
257
|
+
const current = await binding.getFact({ tenantId, factId, readers });
|
|
258
|
+
if (current === null) return { kind: 'response', response: failNotFound(c, factId) };
|
|
259
|
+
const refused = await memoryWriteProblem(c, access, current.scope);
|
|
260
|
+
if (refused !== undefined) {
|
|
261
|
+
return { kind: 'response', response: fail(c, 'permission-denied', refused) };
|
|
215
262
|
}
|
|
263
|
+
return { kind: 'ok', readers };
|
|
264
|
+
}
|
|
216
265
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return c.json(toWireError(SCOPE_MISMATCH, requestId));
|
|
220
|
-
}
|
|
266
|
+
return r;
|
|
267
|
+
}
|
|
221
268
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
results: outcome.results.map(serializeRetrievalHit),
|
|
233
|
-
});
|
|
269
|
+
// -------------------- responses --------------------
|
|
270
|
+
|
|
271
|
+
function fail(c: Context<AppEnv>, code: string, message: string, extra = {}): Response {
|
|
272
|
+
c.status(statusFor(code) as never);
|
|
273
|
+
return c.json(toWireError({ code, message, ...extra }, c.get('requestId')));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function failNotFound(c: Context<AppEnv>, factId: FactId): Response {
|
|
277
|
+
return fail(c, 'fact-not-found', `No fact with id "${factId as unknown as string}"`, {
|
|
278
|
+
factId: factId as unknown as string,
|
|
234
279
|
});
|
|
280
|
+
}
|
|
235
281
|
|
|
236
|
-
|
|
282
|
+
function failScopeMismatch(c: Context<AppEnv>): Response {
|
|
283
|
+
return fail(c, 'scope-mismatch', '`scope.tenantId` does not match the caller tenant.');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function unsupported(c: Context<AppEnv>, what: string): Response {
|
|
287
|
+
return fail(c, 'memory-operation-unsupported', `This runtime's memory doesn't support ${what}.`);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function changeResponse(
|
|
291
|
+
c: Context<AppEnv>,
|
|
292
|
+
factId: FactId,
|
|
293
|
+
outcome: MemoryFactChangeOutcome,
|
|
294
|
+
): Response {
|
|
295
|
+
switch (outcome.kind) {
|
|
296
|
+
case 'ok':
|
|
297
|
+
return c.json(serializeFact(outcome.fact));
|
|
298
|
+
case 'not-found':
|
|
299
|
+
return failNotFound(c, factId);
|
|
300
|
+
case 'fact-changed':
|
|
301
|
+
return fail(
|
|
302
|
+
c,
|
|
303
|
+
'fact-changed',
|
|
304
|
+
`Fact "${factId as unknown as string}" is at revision ${outcome.current.version} now: read it again, then retry.`,
|
|
305
|
+
{ factId: factId as unknown as string, currentVersion: outcome.current.version },
|
|
306
|
+
);
|
|
307
|
+
case 'legal-hold':
|
|
308
|
+
return fail(c, 'legal-hold', outcome.message, { factId: factId as unknown as string });
|
|
309
|
+
case 'error':
|
|
310
|
+
return fail(c, outcome.code, outcome.message);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async function readObject(
|
|
315
|
+
c: Context<AppEnv>,
|
|
316
|
+
options: { readonly emptyIsObject?: boolean } = {},
|
|
317
|
+
): Promise<Record<string, unknown> | string> {
|
|
318
|
+
const text = await c.req.text();
|
|
319
|
+
if (text.trim() === '' && options.emptyIsObject === true) return {};
|
|
320
|
+
let body: unknown;
|
|
321
|
+
try {
|
|
322
|
+
body = JSON.parse(text);
|
|
323
|
+
} catch {
|
|
324
|
+
return 'Request body must be valid JSON';
|
|
325
|
+
}
|
|
326
|
+
if (body === null || typeof body !== 'object' || Array.isArray(body)) {
|
|
327
|
+
return 'Request body must be an object';
|
|
328
|
+
}
|
|
329
|
+
return body as Record<string, unknown>;
|
|
237
330
|
}
|
|
238
331
|
|
|
239
332
|
// -------------------- serialization --------------------
|
|
@@ -241,6 +334,7 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
|
|
|
241
334
|
function serializeFact(f: Fact): Record<string, unknown> {
|
|
242
335
|
return {
|
|
243
336
|
id: f.id as unknown as string,
|
|
337
|
+
...(f.revisionId !== undefined && { revisionId: f.revisionId }),
|
|
244
338
|
type: f.type,
|
|
245
339
|
scope: f.scope,
|
|
246
340
|
version: f.version,
|
|
@@ -255,6 +349,20 @@ function serializeFact(f: Fact): Record<string, unknown> {
|
|
|
255
349
|
...(f.source !== undefined && { source: f.source }),
|
|
256
350
|
...(f.causedByLogId !== undefined && { causedByLogId: f.causedByLogId }),
|
|
257
351
|
...(f.supersedes !== undefined && { supersedes: f.supersedes as unknown as string }),
|
|
352
|
+
...(f.trust !== undefined && { trust: f.trust }),
|
|
353
|
+
...(f.verifiedBy !== undefined && { verifiedBy: f.verifiedBy }),
|
|
354
|
+
...(f.verifiedAt !== undefined && { verifiedAt: f.verifiedAt }),
|
|
355
|
+
...(f.attributedTo !== undefined && { attributedTo: f.attributedTo }),
|
|
356
|
+
...(f.generatedBy !== undefined && { generatedBy: f.generatedBy }),
|
|
357
|
+
...(f.subjects !== undefined && { subjects: f.subjects }),
|
|
358
|
+
...(f.validFrom !== undefined && { validFrom: f.validFrom }),
|
|
359
|
+
...(f.validUntil !== undefined && { validUntil: f.validUntil }),
|
|
360
|
+
...(f.observedAt !== undefined && { observedAt: f.observedAt }),
|
|
361
|
+
...(f.invalidatedAt !== undefined && { invalidatedAt: f.invalidatedAt }),
|
|
362
|
+
...(f.invalidatedBy !== undefined && { invalidatedBy: f.invalidatedBy }),
|
|
363
|
+
...(f.invalidationReason !== undefined && { invalidationReason: f.invalidationReason }),
|
|
364
|
+
...(f.review !== undefined && { review: f.review }),
|
|
365
|
+
...(f.expiresAt !== undefined && { expiresAt: f.expiresAt }),
|
|
258
366
|
};
|
|
259
367
|
}
|
|
260
368
|
|
|
@@ -267,15 +375,10 @@ function serializeRetrievalHit(h: MemoryRetrievalHit): Record<string, unknown> {
|
|
|
267
375
|
|
|
268
376
|
// -------------------- request parsing --------------------
|
|
269
377
|
|
|
270
|
-
const SCOPE_MISMATCH = {
|
|
271
|
-
code: 'scope-mismatch',
|
|
272
|
-
message: '`scope.tenantId` does not match the caller tenant.',
|
|
273
|
-
} as const;
|
|
274
|
-
|
|
275
378
|
/**
|
|
276
379
|
* A memory scope in a request may name a tenant; it must be the caller's
|
|
277
380
|
* (derived from the token). Same rule as the secrets, env and policy
|
|
278
|
-
* routes
|
|
381
|
+
* routes: a request can never read or write another tenant's memory.
|
|
279
382
|
*/
|
|
280
383
|
function scopeNamesOtherTenant(
|
|
281
384
|
scope: Partial<MemoryScope> | undefined,
|
|
@@ -283,148 +386,3 @@ function scopeNamesOtherTenant(
|
|
|
283
386
|
): boolean {
|
|
284
387
|
return scope?.tenantId !== undefined && scope.tenantId !== tenantId;
|
|
285
388
|
}
|
|
286
|
-
|
|
287
|
-
function parseScopeParam(raw: string): Partial<MemoryScope> | null {
|
|
288
|
-
try {
|
|
289
|
-
const decoded = JSON.parse(raw) as unknown;
|
|
290
|
-
if (decoded === null || typeof decoded !== 'object' || Array.isArray(decoded)) return null;
|
|
291
|
-
return decoded as Partial<MemoryScope>;
|
|
292
|
-
} catch {
|
|
293
|
-
return null;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// -------------------- validators --------------------
|
|
298
|
-
|
|
299
|
-
type ValidationResult<T> =
|
|
300
|
-
| { readonly kind: 'ok'; readonly value: T }
|
|
301
|
-
| { readonly kind: 'err'; readonly message: string };
|
|
302
|
-
|
|
303
|
-
interface ValidatedWriteFactBody {
|
|
304
|
-
readonly type: string;
|
|
305
|
-
readonly scope: MemoryScope;
|
|
306
|
-
readonly content: unknown;
|
|
307
|
-
readonly retention?: Retention;
|
|
308
|
-
readonly contentHash?: string;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function validateWriteFactBody(
|
|
312
|
-
body: Record<string, unknown>,
|
|
313
|
-
): ValidationResult<ValidatedWriteFactBody> {
|
|
314
|
-
const type = body.type;
|
|
315
|
-
if (typeof type !== 'string' || type.length === 0) {
|
|
316
|
-
return { kind: 'err', message: 'Field `type` must be a non-empty string' };
|
|
317
|
-
}
|
|
318
|
-
const rawScope = body.scope;
|
|
319
|
-
if (rawScope === null || typeof rawScope !== 'object' || Array.isArray(rawScope)) {
|
|
320
|
-
return { kind: 'err', message: 'Field `scope` must be an object' };
|
|
321
|
-
}
|
|
322
|
-
const scope = rawScope as MemoryScope;
|
|
323
|
-
if (typeof (scope as { tenantId?: unknown }).tenantId !== 'string') {
|
|
324
|
-
return { kind: 'err', message: 'Field `scope.tenantId` must be a string' };
|
|
325
|
-
}
|
|
326
|
-
if (!('content' in body)) {
|
|
327
|
-
return { kind: 'err', message: 'Field `content` is required' };
|
|
328
|
-
}
|
|
329
|
-
const rawRetention = body.retention;
|
|
330
|
-
let retention: Retention | undefined;
|
|
331
|
-
if (rawRetention !== undefined) {
|
|
332
|
-
if (rawRetention === null || typeof rawRetention !== 'object' || Array.isArray(rawRetention)) {
|
|
333
|
-
return { kind: 'err', message: 'Field `retention` must be an object when present' };
|
|
334
|
-
}
|
|
335
|
-
retention = rawRetention as Retention;
|
|
336
|
-
}
|
|
337
|
-
const rawContentHash = body.contentHash;
|
|
338
|
-
let contentHash: string | undefined;
|
|
339
|
-
if (rawContentHash !== undefined) {
|
|
340
|
-
if (typeof rawContentHash !== 'string' || rawContentHash.length === 0) {
|
|
341
|
-
return {
|
|
342
|
-
kind: 'err',
|
|
343
|
-
message: 'Field `contentHash` must be a non-empty string when present',
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
contentHash = rawContentHash;
|
|
347
|
-
}
|
|
348
|
-
return {
|
|
349
|
-
kind: 'ok',
|
|
350
|
-
value: {
|
|
351
|
-
type,
|
|
352
|
-
scope,
|
|
353
|
-
content: body.content,
|
|
354
|
-
...(retention !== undefined && { retention }),
|
|
355
|
-
...(contentHash !== undefined && { contentHash }),
|
|
356
|
-
},
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function validateRetrieveIntent(
|
|
361
|
-
body: Record<string, unknown>,
|
|
362
|
-
): ValidationResult<MemoryRetrieveIntent> {
|
|
363
|
-
const mode = body.mode;
|
|
364
|
-
if (mode !== 'list' && mode !== 'keyword' && mode !== 'semantic' && mode !== 'both') {
|
|
365
|
-
return {
|
|
366
|
-
kind: 'err',
|
|
367
|
-
message: 'Field `mode` must be one of "list", "keyword", "semantic", "both"',
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
let query: string | undefined;
|
|
371
|
-
const rawQuery = body.query;
|
|
372
|
-
if (rawQuery !== undefined) {
|
|
373
|
-
if (typeof rawQuery !== 'string') {
|
|
374
|
-
return { kind: 'err', message: 'Field `query` must be a string when present' };
|
|
375
|
-
}
|
|
376
|
-
query = rawQuery;
|
|
377
|
-
}
|
|
378
|
-
if ((mode === 'keyword' || mode === 'semantic' || mode === 'both') && query === undefined) {
|
|
379
|
-
return {
|
|
380
|
-
kind: 'err',
|
|
381
|
-
message: `Field \`query\` is required when \`mode\` is "${mode}"`,
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
let type: string | undefined;
|
|
385
|
-
const rawType = body.type;
|
|
386
|
-
if (rawType !== undefined) {
|
|
387
|
-
if (typeof rawType !== 'string' || rawType.length === 0) {
|
|
388
|
-
return { kind: 'err', message: 'Field `type` must be a non-empty string when present' };
|
|
389
|
-
}
|
|
390
|
-
type = rawType;
|
|
391
|
-
}
|
|
392
|
-
let scope: Partial<MemoryScope> | undefined;
|
|
393
|
-
const rawScope = body.scope;
|
|
394
|
-
if (rawScope !== undefined) {
|
|
395
|
-
if (rawScope === null || typeof rawScope !== 'object' || Array.isArray(rawScope)) {
|
|
396
|
-
return { kind: 'err', message: 'Field `scope` must be an object when present' };
|
|
397
|
-
}
|
|
398
|
-
scope = rawScope as Partial<MemoryScope>;
|
|
399
|
-
}
|
|
400
|
-
let limit: number | undefined;
|
|
401
|
-
const rawLimit = body.limit;
|
|
402
|
-
if (rawLimit !== undefined) {
|
|
403
|
-
if (typeof rawLimit !== 'number' || !Number.isFinite(rawLimit) || rawLimit < 1) {
|
|
404
|
-
return { kind: 'err', message: 'Field `limit` must be a positive number when present' };
|
|
405
|
-
}
|
|
406
|
-
limit = Math.floor(rawLimit);
|
|
407
|
-
}
|
|
408
|
-
let embeddingModel: string | undefined;
|
|
409
|
-
const rawEmbeddingModel = body.embeddingModel;
|
|
410
|
-
if (rawEmbeddingModel !== undefined) {
|
|
411
|
-
if (typeof rawEmbeddingModel !== 'string' || rawEmbeddingModel.length === 0) {
|
|
412
|
-
return {
|
|
413
|
-
kind: 'err',
|
|
414
|
-
message: 'Field `embeddingModel` must be a non-empty string when present',
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
embeddingModel = rawEmbeddingModel;
|
|
418
|
-
}
|
|
419
|
-
return {
|
|
420
|
-
kind: 'ok',
|
|
421
|
-
value: {
|
|
422
|
-
mode,
|
|
423
|
-
...(query !== undefined && { query }),
|
|
424
|
-
...(type !== undefined && { type }),
|
|
425
|
-
...(scope !== undefined && { scope }),
|
|
426
|
-
...(limit !== undefined && { limit }),
|
|
427
|
-
...(embeddingModel !== undefined && { embeddingModel }),
|
|
428
|
-
},
|
|
429
|
-
};
|
|
430
|
-
}
|