@kindgi/api 0.0.0-bootstrap.0 → 0.1.1
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/LICENSE +201 -0
- package/README.md +216 -1
- package/dist/adapter-binding.d.ts +177 -0
- package/dist/adapter-binding.d.ts.map +1 -0
- package/dist/adapter-binding.js +12 -0
- package/dist/adapter-binding.js.map +1 -0
- package/dist/agent-binding.d.ts +207 -0
- package/dist/agent-binding.d.ts.map +1 -0
- package/dist/agent-binding.js +4 -0
- package/dist/agent-binding.js.map +1 -0
- package/dist/app.d.ts +770 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +397 -0
- package/dist/app.js.map +1 -0
- package/dist/capability-binding.d.ts +76 -0
- package/dist/capability-binding.d.ts.map +1 -0
- package/dist/capability-binding.js +4 -0
- package/dist/capability-binding.js.map +1 -0
- package/dist/cost-binding.d.ts +175 -0
- package/dist/cost-binding.d.ts.map +1 -0
- package/dist/cost-binding.js +13 -0
- package/dist/cost-binding.js.map +1 -0
- package/dist/deployment-binding.d.ts +201 -0
- package/dist/deployment-binding.d.ts.map +1 -0
- package/dist/deployment-binding.js +4 -0
- package/dist/deployment-binding.js.map +1 -0
- package/dist/env-binding.d.ts +132 -0
- package/dist/env-binding.d.ts.map +1 -0
- package/dist/env-binding.js +4 -0
- package/dist/env-binding.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +268 -0
- package/dist/errors.js.map +1 -0
- package/dist/eval-run-binding.d.ts +196 -0
- package/dist/eval-run-binding.d.ts.map +1 -0
- package/dist/eval-run-binding.js +16 -0
- package/dist/eval-run-binding.js.map +1 -0
- package/dist/eval-run-dispatcher.d.ts +131 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -0
- package/dist/eval-run-dispatcher.js +368 -0
- package/dist/eval-run-dispatcher.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +227 -0
- package/dist/eval-suite-binding.d.ts.map +1 -0
- package/dist/eval-suite-binding.js +24 -0
- package/dist/eval-suite-binding.js.map +1 -0
- package/dist/event-bus-binding.d.ts +107 -0
- package/dist/event-bus-binding.d.ts.map +1 -0
- package/dist/event-bus-binding.js +5 -0
- package/dist/event-bus-binding.js.map +1 -0
- package/dist/flow-binding.d.ts +194 -0
- package/dist/flow-binding.d.ts.map +1 -0
- package/dist/flow-binding.js +4 -0
- package/dist/flow-binding.js.map +1 -0
- package/dist/guardrail-binding.d.ts +138 -0
- package/dist/guardrail-binding.d.ts.map +1 -0
- package/dist/guardrail-binding.js +4 -0
- package/dist/guardrail-binding.js.map +1 -0
- package/dist/handler-binding.d.ts +126 -0
- package/dist/handler-binding.d.ts.map +1 -0
- package/dist/handler-binding.js +4 -0
- package/dist/handler-binding.js.map +1 -0
- package/dist/hitl-binding.d.ts +115 -0
- package/dist/hitl-binding.d.ts.map +1 -0
- package/dist/hitl-binding.js +4 -0
- package/dist/hitl-binding.js.map +1 -0
- package/dist/identity-directory-binding.d.ts +116 -0
- package/dist/identity-directory-binding.d.ts.map +1 -0
- package/dist/identity-directory-binding.js +4 -0
- package/dist/identity-directory-binding.js.map +1 -0
- package/dist/identity-provider-binding.d.ts +184 -0
- package/dist/identity-provider-binding.d.ts.map +1 -0
- package/dist/identity-provider-binding.js +4 -0
- package/dist/identity-provider-binding.js.map +1 -0
- package/dist/image-registry-binding.d.ts +165 -0
- package/dist/image-registry-binding.d.ts.map +1 -0
- package/dist/image-registry-binding.js +4 -0
- package/dist/image-registry-binding.js.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/key-management-binding.d.ts +101 -0
- package/dist/key-management-binding.d.ts.map +1 -0
- package/dist/key-management-binding.js +4 -0
- package/dist/key-management-binding.js.map +1 -0
- package/dist/mcp-endpoint-binding.d.ts +312 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -0
- package/dist/mcp-endpoint-binding.js +12 -0
- package/dist/mcp-endpoint-binding.js.map +1 -0
- package/dist/memory-binding.d.ts +209 -0
- package/dist/memory-binding.d.ts.map +1 -0
- package/dist/memory-binding.js +4 -0
- package/dist/memory-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +168 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +247 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/authorize.d.ts +26 -0
- package/dist/middleware/authorize.d.ts.map +1 -0
- package/dist/middleware/authorize.js +65 -0
- package/dist/middleware/authorize.js.map +1 -0
- package/dist/middleware/error-mapper.d.ts +20 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -0
- package/dist/middleware/error-mapper.js +34 -0
- package/dist/middleware/error-mapper.js.map +1 -0
- package/dist/middleware/idempotency.d.ts +43 -0
- package/dist/middleware/idempotency.d.ts.map +1 -0
- package/dist/middleware/idempotency.js +118 -0
- package/dist/middleware/idempotency.js.map +1 -0
- package/dist/middleware/principal.d.ts +4 -0
- package/dist/middleware/principal.d.ts.map +1 -0
- package/dist/middleware/principal.js +42 -0
- package/dist/middleware/principal.js.map +1 -0
- package/dist/middleware/public-run-routes.d.ts +16 -0
- package/dist/middleware/public-run-routes.d.ts.map +1 -0
- package/dist/middleware/public-run-routes.js +43 -0
- package/dist/middleware/public-run-routes.js.map +1 -0
- package/dist/middleware/request-id.d.ts +14 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +24 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/middleware/sigv4-verify.d.ts +64 -0
- package/dist/middleware/sigv4-verify.d.ts.map +1 -0
- package/dist/middleware/sigv4-verify.js +286 -0
- package/dist/middleware/sigv4-verify.js.map +1 -0
- package/dist/middleware/sigv4.d.ts +25 -0
- package/dist/middleware/sigv4.d.ts.map +1 -0
- package/dist/middleware/sigv4.js +120 -0
- package/dist/middleware/sigv4.js.map +1 -0
- package/dist/openapi/generate.d.ts +15 -0
- package/dist/openapi/generate.d.ts.map +1 -0
- package/dist/openapi/generate.js +241 -0
- package/dist/openapi/generate.js.map +1 -0
- package/dist/openapi/operations.d.ts +70 -0
- package/dist/openapi/operations.d.ts.map +1 -0
- package/dist/openapi/operations.js +5050 -0
- package/dist/openapi/operations.js.map +1 -0
- package/dist/openapi/schemas.d.ts +590 -0
- package/dist/openapi/schemas.d.ts.map +1 -0
- package/dist/openapi/schemas.js +5820 -0
- package/dist/openapi/schemas.js.map +1 -0
- package/dist/provenance-binding.d.ts +116 -0
- package/dist/provenance-binding.d.ts.map +1 -0
- package/dist/provenance-binding.js +31 -0
- package/dist/provenance-binding.js.map +1 -0
- package/dist/provider-binding.d.ts +174 -0
- package/dist/provider-binding.d.ts.map +1 -0
- package/dist/provider-binding.js +4 -0
- package/dist/provider-binding.js.map +1 -0
- package/dist/public-run-token.d.ts +97 -0
- package/dist/public-run-token.d.ts.map +1 -0
- package/dist/public-run-token.js +167 -0
- package/dist/public-run-token.js.map +1 -0
- package/dist/retention-binding.d.ts +69 -0
- package/dist/retention-binding.d.ts.map +1 -0
- package/dist/retention-binding.js +4 -0
- package/dist/retention-binding.js.map +1 -0
- package/dist/reviewer-binding.d.ts +84 -0
- package/dist/reviewer-binding.d.ts.map +1 -0
- package/dist/reviewer-binding.js +4 -0
- package/dist/reviewer-binding.js.map +1 -0
- package/dist/rotation-status-store.d.ts +96 -0
- package/dist/rotation-status-store.d.ts.map +1 -0
- package/dist/rotation-status-store.js +106 -0
- package/dist/rotation-status-store.js.map +1 -0
- package/dist/routes/adapters.d.ts +29 -0
- package/dist/routes/adapters.d.ts.map +1 -0
- package/dist/routes/adapters.js +230 -0
- package/dist/routes/adapters.js.map +1 -0
- package/dist/routes/agents.d.ts +17 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +342 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/approvals.d.ts +37 -0
- package/dist/routes/approvals.d.ts.map +1 -0
- package/dist/routes/approvals.js +551 -0
- package/dist/routes/approvals.js.map +1 -0
- package/dist/routes/artifacts.d.ts +25 -0
- package/dist/routes/artifacts.d.ts.map +1 -0
- package/dist/routes/artifacts.js +265 -0
- package/dist/routes/artifacts.js.map +1 -0
- package/dist/routes/audit.d.ts +6 -0
- package/dist/routes/audit.d.ts.map +1 -0
- package/dist/routes/audit.js +162 -0
- package/dist/routes/audit.js.map +1 -0
- package/dist/routes/auth.d.ts +47 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +630 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/capabilities.d.ts +14 -0
- package/dist/routes/capabilities.d.ts.map +1 -0
- package/dist/routes/capabilities.js +62 -0
- package/dist/routes/capabilities.js.map +1 -0
- package/dist/routes/compliance.d.ts +37 -0
- package/dist/routes/compliance.d.ts.map +1 -0
- package/dist/routes/compliance.js +321 -0
- package/dist/routes/compliance.js.map +1 -0
- package/dist/routes/conversations.d.ts +13 -0
- package/dist/routes/conversations.d.ts.map +1 -0
- package/dist/routes/conversations.js +295 -0
- package/dist/routes/conversations.js.map +1 -0
- package/dist/routes/cost.d.ts +24 -0
- package/dist/routes/cost.d.ts.map +1 -0
- package/dist/routes/cost.js +243 -0
- package/dist/routes/cost.js.map +1 -0
- package/dist/routes/deployments.d.ts +122 -0
- package/dist/routes/deployments.d.ts.map +1 -0
- package/dist/routes/deployments.js +1036 -0
- package/dist/routes/deployments.js.map +1 -0
- package/dist/routes/env.d.ts +62 -0
- package/dist/routes/env.d.ts.map +1 -0
- package/dist/routes/env.js +311 -0
- package/dist/routes/env.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +28 -0
- package/dist/routes/eval-runs.d.ts.map +1 -0
- package/dist/routes/eval-runs.js +479 -0
- package/dist/routes/eval-runs.js.map +1 -0
- package/dist/routes/eval-suites.d.ts +24 -0
- package/dist/routes/eval-suites.d.ts.map +1 -0
- package/dist/routes/eval-suites.js +381 -0
- package/dist/routes/eval-suites.js.map +1 -0
- package/dist/routes/event-triggers.d.ts +12 -0
- package/dist/routes/event-triggers.d.ts.map +1 -0
- package/dist/routes/event-triggers.js +218 -0
- package/dist/routes/event-triggers.js.map +1 -0
- package/dist/routes/flows.d.ts +23 -0
- package/dist/routes/flows.d.ts.map +1 -0
- package/dist/routes/flows.js +344 -0
- package/dist/routes/flows.js.map +1 -0
- package/dist/routes/guardrails.d.ts +33 -0
- package/dist/routes/guardrails.d.ts.map +1 -0
- package/dist/routes/guardrails.js +236 -0
- package/dist/routes/guardrails.js.map +1 -0
- package/dist/routes/identity.d.ts +39 -0
- package/dist/routes/identity.d.ts.map +1 -0
- package/dist/routes/identity.js +138 -0
- package/dist/routes/identity.js.map +1 -0
- package/dist/routes/mcp.d.ts +23 -0
- package/dist/routes/mcp.d.ts.map +1 -0
- package/dist/routes/mcp.js +727 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/memory.d.ts +16 -0
- package/dist/routes/memory.d.ts.map +1 -0
- package/dist/routes/memory.js +353 -0
- package/dist/routes/memory.js.map +1 -0
- package/dist/routes/observations.d.ts +19 -0
- package/dist/routes/observations.d.ts.map +1 -0
- package/dist/routes/observations.js +135 -0
- package/dist/routes/observations.js.map +1 -0
- package/dist/routes/orgs.d.ts +24 -0
- package/dist/routes/orgs.d.ts.map +1 -0
- package/dist/routes/orgs.js +208 -0
- package/dist/routes/orgs.js.map +1 -0
- package/dist/routes/pagination.d.ts +18 -0
- package/dist/routes/pagination.d.ts.map +1 -0
- package/dist/routes/pagination.js +35 -0
- package/dist/routes/pagination.js.map +1 -0
- package/dist/routes/policies.d.ts +23 -0
- package/dist/routes/policies.d.ts.map +1 -0
- package/dist/routes/policies.js +314 -0
- package/dist/routes/policies.js.map +1 -0
- package/dist/routes/projects.d.ts +45 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +485 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/proposals.d.ts +24 -0
- package/dist/routes/proposals.d.ts.map +1 -0
- package/dist/routes/proposals.js +581 -0
- package/dist/routes/proposals.js.map +1 -0
- package/dist/routes/provenance.d.ts +34 -0
- package/dist/routes/provenance.d.ts.map +1 -0
- package/dist/routes/provenance.js +274 -0
- package/dist/routes/provenance.js.map +1 -0
- package/dist/routes/providers.d.ts +32 -0
- package/dist/routes/providers.d.ts.map +1 -0
- package/dist/routes/providers.js +490 -0
- package/dist/routes/providers.js.map +1 -0
- package/dist/routes/public-run-tokens.d.ts +17 -0
- package/dist/routes/public-run-tokens.d.ts.map +1 -0
- package/dist/routes/public-run-tokens.js +69 -0
- package/dist/routes/public-run-tokens.js.map +1 -0
- package/dist/routes/retention.d.ts +19 -0
- package/dist/routes/retention.d.ts.map +1 -0
- package/dist/routes/retention.js +152 -0
- package/dist/routes/retention.js.map +1 -0
- package/dist/routes/reviewers.d.ts +5 -0
- package/dist/routes/reviewers.d.ts.map +1 -0
- package/dist/routes/reviewers.js +161 -0
- package/dist/routes/reviewers.js.map +1 -0
- package/dist/routes/runs.d.ts +34 -0
- package/dist/routes/runs.d.ts.map +1 -0
- package/dist/routes/runs.js +705 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/s3.d.ts +31 -0
- package/dist/routes/s3.d.ts.map +1 -0
- package/dist/routes/s3.js +433 -0
- package/dist/routes/s3.js.map +1 -0
- package/dist/routes/schedules.d.ts +20 -0
- package/dist/routes/schedules.d.ts.map +1 -0
- package/dist/routes/schedules.js +234 -0
- package/dist/routes/schedules.js.map +1 -0
- package/dist/routes/scope-params.d.ts +57 -0
- package/dist/routes/scope-params.d.ts.map +1 -0
- package/dist/routes/scope-params.js +105 -0
- package/dist/routes/scope-params.js.map +1 -0
- package/dist/routes/secret-ref.d.ts +20 -0
- package/dist/routes/secret-ref.d.ts.map +1 -0
- package/dist/routes/secret-ref.js +42 -0
- package/dist/routes/secret-ref.js.map +1 -0
- package/dist/routes/secrets.d.ts +53 -0
- package/dist/routes/secrets.d.ts.map +1 -0
- package/dist/routes/secrets.js +715 -0
- package/dist/routes/secrets.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +23 -0
- package/dist/routes/signing-keys.d.ts.map +1 -0
- package/dist/routes/signing-keys.js +212 -0
- package/dist/routes/signing-keys.js.map +1 -0
- package/dist/routes/sse.d.ts +58 -0
- package/dist/routes/sse.d.ts.map +1 -0
- package/dist/routes/sse.js +92 -0
- package/dist/routes/sse.js.map +1 -0
- package/dist/routes/teams.d.ts +30 -0
- package/dist/routes/teams.d.ts.map +1 -0
- package/dist/routes/teams.js +443 -0
- package/dist/routes/teams.js.map +1 -0
- package/dist/routes/tenant.d.ts +57 -0
- package/dist/routes/tenant.d.ts.map +1 -0
- package/dist/routes/tenant.js +352 -0
- package/dist/routes/tenant.js.map +1 -0
- package/dist/routes/tokens.d.ts +14 -0
- package/dist/routes/tokens.d.ts.map +1 -0
- package/dist/routes/tokens.js +231 -0
- package/dist/routes/tokens.js.map +1 -0
- package/dist/routes/tools.d.ts +33 -0
- package/dist/routes/tools.d.ts.map +1 -0
- package/dist/routes/tools.js +380 -0
- package/dist/routes/tools.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +10 -0
- package/dist/routes/webhook-endpoints.d.ts.map +1 -0
- package/dist/routes/webhook-endpoints.js +407 -0
- package/dist/routes/webhook-endpoints.js.map +1 -0
- package/dist/routes/webhooks.d.ts +21 -0
- package/dist/routes/webhooks.d.ts.map +1 -0
- package/dist/routes/webhooks.js +228 -0
- package/dist/routes/webhooks.js.map +1 -0
- package/dist/s3-credential-binding.d.ts +54 -0
- package/dist/s3-credential-binding.d.ts.map +1 -0
- package/dist/s3-credential-binding.js +4 -0
- package/dist/s3-credential-binding.js.map +1 -0
- package/dist/secrets-binding.d.ts +281 -0
- package/dist/secrets-binding.d.ts.map +1 -0
- package/dist/secrets-binding.js +10 -0
- package/dist/secrets-binding.js.map +1 -0
- package/dist/secrets-provider-binding.d.ts +164 -0
- package/dist/secrets-provider-binding.d.ts.map +1 -0
- package/dist/secrets-provider-binding.js +4 -0
- package/dist/secrets-provider-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +148 -0
- package/dist/session-store-binding.d.ts.map +1 -0
- package/dist/session-store-binding.js +4 -0
- package/dist/session-store-binding.js.map +1 -0
- package/dist/signing-key-binding.d.ts +210 -0
- package/dist/signing-key-binding.d.ts.map +1 -0
- package/dist/signing-key-binding.js +4 -0
- package/dist/signing-key-binding.js.map +1 -0
- package/dist/state-store-binding.d.ts +53 -0
- package/dist/state-store-binding.d.ts.map +1 -0
- package/dist/state-store-binding.js +38 -0
- package/dist/state-store-binding.js.map +1 -0
- package/dist/supervisor-binding.d.ts +526 -0
- package/dist/supervisor-binding.d.ts.map +1 -0
- package/dist/supervisor-binding.js +4 -0
- package/dist/supervisor-binding.js.map +1 -0
- package/dist/tenant-host-access.d.ts +41 -0
- package/dist/tenant-host-access.d.ts.map +1 -0
- package/dist/tenant-host-access.js +42 -0
- package/dist/tenant-host-access.js.map +1 -0
- package/dist/token-admin.d.ts +99 -0
- package/dist/token-admin.d.ts.map +1 -0
- package/dist/token-admin.js +4 -0
- package/dist/token-admin.js.map +1 -0
- package/dist/tool-binding.d.ts +247 -0
- package/dist/tool-binding.d.ts.map +1 -0
- package/dist/tool-binding.js +4 -0
- package/dist/tool-binding.js.map +1 -0
- package/dist/trigger-binding.d.ts +13 -0
- package/dist/trigger-binding.d.ts.map +1 -0
- package/dist/trigger-binding.js +4 -0
- package/dist/trigger-binding.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/webhook-endpoint-binding.d.ts +230 -0
- package/dist/webhook-endpoint-binding.d.ts.map +1 -0
- package/dist/webhook-endpoint-binding.js +12 -0
- package/dist/webhook-endpoint-binding.js.map +1 -0
- package/dist/xml.d.ts +79 -0
- package/dist/xml.d.ts.map +1 -0
- package/dist/xml.js +115 -0
- package/dist/xml.js.map +1 -0
- package/openapi.json +29649 -0
- package/package.json +76 -4
- package/scripts/emit-openapi.mjs +44 -0
- package/src/adapter-binding.ts +204 -0
- package/src/agent-binding.ts +231 -0
- package/src/app.ts +1286 -0
- package/src/capability-binding.ts +83 -0
- package/src/cost-binding.ts +213 -0
- package/src/deployment-binding.ts +225 -0
- package/src/env-binding.ts +140 -0
- package/src/errors.ts +295 -0
- package/src/eval-run-binding.ts +209 -0
- package/src/eval-run-dispatcher.ts +497 -0
- package/src/eval-suite-binding.ts +257 -0
- package/src/event-bus-binding.ts +127 -0
- package/src/flow-binding.ts +213 -0
- package/src/guardrail-binding.ts +151 -0
- package/src/handler-binding.ts +132 -0
- package/src/hitl-binding.ts +172 -0
- package/src/identity-directory-binding.ts +128 -0
- package/src/identity-provider-binding.ts +203 -0
- package/src/image-registry-binding.ts +193 -0
- package/src/index.ts +606 -0
- package/src/key-management-binding.ts +91 -0
- package/src/mcp-endpoint-binding.ts +311 -0
- package/src/memory-binding.ts +239 -0
- package/src/middleware/auth.ts +437 -0
- package/src/middleware/authorize.ts +125 -0
- package/src/middleware/error-mapper.ts +40 -0
- package/src/middleware/idempotency.ts +160 -0
- package/src/middleware/principal.ts +64 -0
- package/src/middleware/public-run-routes.ts +50 -0
- package/src/middleware/request-id.ts +28 -0
- package/src/middleware/sigv4-verify.ts +374 -0
- package/src/middleware/sigv4.ts +165 -0
- package/src/openapi/generate.ts +307 -0
- package/src/openapi/operations.ts +5444 -0
- package/src/openapi/schemas.ts +6363 -0
- package/src/provenance-binding.ts +169 -0
- package/src/provider-binding.ts +196 -0
- package/src/public-run-token.ts +263 -0
- package/src/retention-binding.ts +78 -0
- package/src/reviewer-binding.ts +99 -0
- package/src/rotation-status-store.ts +209 -0
- package/src/routes/adapters.ts +319 -0
- package/src/routes/agents.ts +424 -0
- package/src/routes/approvals.ts +759 -0
- package/src/routes/artifacts.ts +317 -0
- package/src/routes/audit.ts +219 -0
- package/src/routes/auth.ts +806 -0
- package/src/routes/capabilities.ts +79 -0
- package/src/routes/compliance.ts +482 -0
- package/src/routes/conversations.ts +369 -0
- package/src/routes/cost.ts +327 -0
- package/src/routes/deployments.ts +1493 -0
- package/src/routes/env.ts +429 -0
- package/src/routes/eval-runs.ts +631 -0
- package/src/routes/eval-suites.ts +490 -0
- package/src/routes/event-triggers.ts +283 -0
- package/src/routes/flows.ts +423 -0
- package/src/routes/guardrails.ts +320 -0
- package/src/routes/identity.ts +203 -0
- package/src/routes/mcp.ts +940 -0
- package/src/routes/memory.ts +430 -0
- package/src/routes/observations.ts +175 -0
- package/src/routes/orgs.ts +273 -0
- package/src/routes/pagination.ts +51 -0
- package/src/routes/policies.ts +413 -0
- package/src/routes/projects.ts +634 -0
- package/src/routes/proposals.ts +719 -0
- package/src/routes/provenance.ts +406 -0
- package/src/routes/providers.ts +624 -0
- package/src/routes/public-run-tokens.ts +104 -0
- package/src/routes/retention.ts +193 -0
- package/src/routes/reviewers.ts +209 -0
- package/src/routes/runs.ts +892 -0
- package/src/routes/s3.ts +519 -0
- package/src/routes/schedules.ts +300 -0
- package/src/routes/scope-params.ts +133 -0
- package/src/routes/secret-ref.ts +52 -0
- package/src/routes/secrets.ts +975 -0
- package/src/routes/signing-keys.ts +259 -0
- package/src/routes/sse.ts +148 -0
- package/src/routes/teams.ts +584 -0
- package/src/routes/tenant.ts +530 -0
- package/src/routes/tokens.ts +285 -0
- package/src/routes/tools.ts +491 -0
- package/src/routes/webhook-endpoints.ts +534 -0
- package/src/routes/webhooks.ts +296 -0
- package/src/s3-credential-binding.ts +58 -0
- package/src/secrets-binding.ts +308 -0
- package/src/secrets-provider-binding.ts +167 -0
- package/src/session-store-binding.ts +163 -0
- package/src/signing-key-binding.ts +235 -0
- package/src/state-store-binding.ts +84 -0
- package/src/supervisor-binding.ts +554 -0
- package/src/tenant-host-access.ts +62 -0
- package/src/token-admin.ts +104 -0
- package/src/tool-binding.ts +274 -0
- package/src/trigger-binding.ts +38 -0
- package/src/types.ts +74 -0
- package/src/webhook-endpoint-binding.ts +246 -0
- package/src/xml.ts +196 -0
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { ref } from '@kindgi/authz';
|
|
5
|
+
import { statusFor, toWireError } from '../errors.js';
|
|
6
|
+
import { clampLimit, decodeCursor } from './pagination.js';
|
|
7
|
+
import { parseScopeParams } from './scope-params.js';
|
|
8
|
+
import { formatSseFrame, isTerminalWireKind, parseLastEventId, projectJournalEntry, toRunProgressEvent, } from './sse.js';
|
|
9
|
+
const KERNEL_RUN_CHANNEL_PREFIX = 'kernel:run:';
|
|
10
|
+
/** How far up the parent chain a public token's grant reaches. */
|
|
11
|
+
const MAX_RUN_ANCESTRY = 16;
|
|
12
|
+
/**
|
|
13
|
+
* Runs resource routes (per `docs/API-ROUTE-CONVENTIONS.md` §7).
|
|
14
|
+
*
|
|
15
|
+
* Routes: `POST /` (start), `GET /:runId`, `GET /` (list),
|
|
16
|
+
* `POST /:runId/cancel`, `POST /:runId/resume`, `GET /:runId/stream`
|
|
17
|
+
* (SSE), `GET /:runId/journal`.
|
|
18
|
+
*/
|
|
19
|
+
export function runsRouter(binding, runBinding, options = {}, authorizer) {
|
|
20
|
+
const r = new Hono();
|
|
21
|
+
const eventBus = options.eventBus;
|
|
22
|
+
// Authorization — a run inherits its permissions from its project.
|
|
23
|
+
// Each check resolves the run's project (by run id) and asks the
|
|
24
|
+
// authorizer about that project:
|
|
25
|
+
//
|
|
26
|
+
// POST / — no route-level check; `execute` on the agent
|
|
27
|
+
// or flow is up to the run handler binding.
|
|
28
|
+
// GET /:runId — read on the run's project
|
|
29
|
+
// POST /:runId/cancel — write on the run's project
|
|
30
|
+
// POST /:runId/resume — execute on the run's project
|
|
31
|
+
// GET /:runId/journal — read on the run's project
|
|
32
|
+
// GET /:runId/stream — read on the run's project
|
|
33
|
+
// GET / — list; tenant-scoped, the scope filter narrows
|
|
34
|
+
// further (rows are not filtered per permission)
|
|
35
|
+
if (authorizer !== undefined) {
|
|
36
|
+
const projectFromRun = async (c) => {
|
|
37
|
+
const tenantId = c.get('tenantId');
|
|
38
|
+
const runId = c.req.param('runId') ?? '';
|
|
39
|
+
if (runId.length === 0)
|
|
40
|
+
return ref('tenant', tenantId);
|
|
41
|
+
const row = await runBinding.getRun(tenantId, runId);
|
|
42
|
+
if (row === null) {
|
|
43
|
+
// Fall back to tenant so the underlying handler surfaces
|
|
44
|
+
// 404 rather than the middleware masking it as 403.
|
|
45
|
+
return ref('tenant', tenantId);
|
|
46
|
+
}
|
|
47
|
+
return ref('project', row.projectId);
|
|
48
|
+
};
|
|
49
|
+
r.use('/:runId', async (c, next) => {
|
|
50
|
+
if (c.req.method !== 'GET')
|
|
51
|
+
return next();
|
|
52
|
+
const mw = authorizer.authorize('read', projectFromRun);
|
|
53
|
+
return mw(c, next);
|
|
54
|
+
});
|
|
55
|
+
r.use('/:runId/journal', async (c, next) => {
|
|
56
|
+
const mw = authorizer.authorize('read', projectFromRun);
|
|
57
|
+
return mw(c, next);
|
|
58
|
+
});
|
|
59
|
+
r.use('/:runId/stream', async (c, next) => {
|
|
60
|
+
const mw = authorizer.authorize('read', projectFromRun);
|
|
61
|
+
return mw(c, next);
|
|
62
|
+
});
|
|
63
|
+
// Progress: `read` for API tokens. A public run token has no
|
|
64
|
+
// principal; the handlers check that its grant covers the run.
|
|
65
|
+
const progressAuth = async (c, next) => {
|
|
66
|
+
if (c.get('tokenKind') === 'public-run')
|
|
67
|
+
return next();
|
|
68
|
+
const mw = authorizer.authorize('read', projectFromRun);
|
|
69
|
+
return mw(c, next);
|
|
70
|
+
};
|
|
71
|
+
r.use('/:runId/progress', progressAuth);
|
|
72
|
+
r.use('/:runId/progress/stream', progressAuth);
|
|
73
|
+
r.use('/:runId/cancel', async (c, next) => {
|
|
74
|
+
const mw = authorizer.authorize('write', projectFromRun);
|
|
75
|
+
return mw(c, next);
|
|
76
|
+
});
|
|
77
|
+
r.use('/:runId/resume', async (c, next) => {
|
|
78
|
+
const mw = authorizer.authorize('execute', projectFromRun);
|
|
79
|
+
return mw(c, next);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// ---------- POST / (start a run — agent | flow) ----------
|
|
83
|
+
r.post('/', async (c) => {
|
|
84
|
+
const requestId = c.get('requestId');
|
|
85
|
+
const tenantId = c.get('tenantId');
|
|
86
|
+
let body;
|
|
87
|
+
try {
|
|
88
|
+
body = await c.req.json();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
c.status(statusFor('bad-input'));
|
|
92
|
+
return c.json(toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId));
|
|
93
|
+
}
|
|
94
|
+
const parsed = parseStartRunBody(body);
|
|
95
|
+
if (parsed.kind === 'err') {
|
|
96
|
+
c.status(statusFor(parsed.error.code));
|
|
97
|
+
return c.json(toWireError(parsed.error, requestId));
|
|
98
|
+
}
|
|
99
|
+
const invocation = await invokeFromBody(binding, tenantId, parsed.value);
|
|
100
|
+
if (invocation.kind === 'err') {
|
|
101
|
+
c.status(statusFor(invocation.error.code));
|
|
102
|
+
return c.json(runFailureToWire(invocation.error, requestId));
|
|
103
|
+
}
|
|
104
|
+
const runId = invocation.runId;
|
|
105
|
+
const loaded = await runBinding.getRun(tenantId, runId);
|
|
106
|
+
if (loaded === null) {
|
|
107
|
+
c.status(statusFor('journal-error'));
|
|
108
|
+
return c.json(toWireError({ code: 'journal-error', message: `Run ${runId} started but row not readable` }, requestId));
|
|
109
|
+
}
|
|
110
|
+
// `wait: false` → the binding handed the run id back before the
|
|
111
|
+
// run finished: 202, and the caller polls `GET /v1/runs/:runId`.
|
|
112
|
+
c.status(parsed.value.wait === false ? 202 : 201);
|
|
113
|
+
const minted = options.publicRunTokens?.mint(tenantId, [runId]);
|
|
114
|
+
return c.json({
|
|
115
|
+
...serializeRun(loaded, { output: true }),
|
|
116
|
+
...(minted?.kind === 'ok' && {
|
|
117
|
+
publicAccessToken: minted.token,
|
|
118
|
+
publicAccessTokenExpiresAt: minted.expiresAt.toISOString(),
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
// ---------- GET /:runId ----------
|
|
123
|
+
r.get('/:runId', async (c) => {
|
|
124
|
+
const requestId = c.get('requestId');
|
|
125
|
+
const runId = c.req.param('runId');
|
|
126
|
+
const loaded = await runBinding.getRun(c.get('tenantId'), runId);
|
|
127
|
+
if (loaded === null) {
|
|
128
|
+
c.status(statusFor('run-not-found'));
|
|
129
|
+
return c.json(toWireError({ code: 'run-not-found', message: `No run with id ${runId}` }, requestId));
|
|
130
|
+
}
|
|
131
|
+
return c.json(serializeRun(loaded, { output: true }));
|
|
132
|
+
});
|
|
133
|
+
// ---------- GET /:runId/progress ----------
|
|
134
|
+
r.get('/:runId/progress', async (c) => {
|
|
135
|
+
const requestId = c.get('requestId');
|
|
136
|
+
const runId = c.req.param('runId');
|
|
137
|
+
const loaded = await readableRun(runBinding, c, runId);
|
|
138
|
+
if (loaded === null) {
|
|
139
|
+
c.status(statusFor('run-not-found'));
|
|
140
|
+
return c.json(toWireError({ code: 'run-not-found', message: `No run with id ${runId}` }, requestId));
|
|
141
|
+
}
|
|
142
|
+
return c.json(serializeRunProgress(loaded));
|
|
143
|
+
});
|
|
144
|
+
// ---------- GET / (list, cursor-paginated) ----------
|
|
145
|
+
//
|
|
146
|
+
// Content-scoped list; scope filter threaded via `parseScopeParams`.
|
|
147
|
+
// Every run belongs to exactly one project; `scope.kind === 'project'`
|
|
148
|
+
// narrows to that project, `scope.kind === 'org'` to the org's
|
|
149
|
+
// projects, and tenant / undefined behave as documented in
|
|
150
|
+
// scope-params.ts.
|
|
151
|
+
r.get('/', async (c) => {
|
|
152
|
+
const requestId = c.get('requestId');
|
|
153
|
+
const tenantId = c.get('tenantId');
|
|
154
|
+
const limit = clampLimit(c.req.query('limit'));
|
|
155
|
+
let cursorFilter = null;
|
|
156
|
+
const rawCursor = c.req.query('cursor');
|
|
157
|
+
if (rawCursor !== undefined && rawCursor.length > 0) {
|
|
158
|
+
const decoded = decodeCursor(rawCursor);
|
|
159
|
+
if (decoded === null) {
|
|
160
|
+
c.status(statusFor('bad-input'));
|
|
161
|
+
return c.json(toWireError({ code: 'bad-input', message: '`cursor` is malformed' }, requestId));
|
|
162
|
+
}
|
|
163
|
+
cursorFilter = decoded;
|
|
164
|
+
}
|
|
165
|
+
const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
|
|
166
|
+
if (scopeParsed.kind === 'err') {
|
|
167
|
+
c.status(statusFor('scope-invalid'));
|
|
168
|
+
return c.json(toWireError({ code: 'scope-invalid', message: scopeParsed.message }, requestId));
|
|
169
|
+
}
|
|
170
|
+
const listFilter = parseRunListFilter(c.req.query());
|
|
171
|
+
if (listFilter.kind === 'err') {
|
|
172
|
+
c.status(statusFor('bad-input'));
|
|
173
|
+
return c.json(toWireError({ code: 'bad-input', message: listFilter.message }, requestId));
|
|
174
|
+
}
|
|
175
|
+
const includeOutput = listFilter.value.includeOutput;
|
|
176
|
+
const page = await runBinding.listRuns(listRunsInput({
|
|
177
|
+
tenantId,
|
|
178
|
+
scope: scopeParsed.scope,
|
|
179
|
+
limit,
|
|
180
|
+
cursor: cursorFilter,
|
|
181
|
+
filter: listFilter.value,
|
|
182
|
+
}));
|
|
183
|
+
return c.json({
|
|
184
|
+
data: page.data.map((row) => serializeRun(row, { output: includeOutput })),
|
|
185
|
+
hasMore: page.nextCursor !== undefined,
|
|
186
|
+
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor }),
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
// ---------- POST /:runId/cancel ----------
|
|
190
|
+
r.post('/:runId/cancel', async (c) => {
|
|
191
|
+
const requestId = c.get('requestId');
|
|
192
|
+
const tenantId = c.get('tenantId');
|
|
193
|
+
const runId = c.req.param('runId');
|
|
194
|
+
const cancelled = await runBinding.cancelRun(tenantId, runId, eventBus);
|
|
195
|
+
if (cancelled.kind === 'err') {
|
|
196
|
+
const err = cancelled.error;
|
|
197
|
+
c.status(statusFor(err.code));
|
|
198
|
+
return c.json(toWireError(err, requestId));
|
|
199
|
+
}
|
|
200
|
+
// Re-read to return the updated row.
|
|
201
|
+
const reloaded = await runBinding.getRun(tenantId, runId);
|
|
202
|
+
if (reloaded === null) {
|
|
203
|
+
c.status(statusFor('journal-error'));
|
|
204
|
+
return c.json(toWireError({
|
|
205
|
+
code: 'journal-error',
|
|
206
|
+
message: 'Cancelled OK but failed to reload run row',
|
|
207
|
+
}, requestId));
|
|
208
|
+
}
|
|
209
|
+
return c.json(serializeRun(reloaded, { output: true }));
|
|
210
|
+
});
|
|
211
|
+
// ---------- POST /:runId/resume ----------
|
|
212
|
+
// Not available in this release. Every waitpoint a run can wait at
|
|
213
|
+
// belongs to an approval or to the runtime itself (a flow's agent step
|
|
214
|
+
// waiting on its child turn). Completing one here would skip what owns
|
|
215
|
+
// it: an approval's reviewer check and recorded decision, or the
|
|
216
|
+
// runtime's own wake-up. A run waiting for an approval continues
|
|
217
|
+
// through `POST /v1/approvals/:id/complete`. So nothing is read or
|
|
218
|
+
// completed; the route stays mounted for a clear answer.
|
|
219
|
+
r.post('/:runId/resume', (c) => {
|
|
220
|
+
c.status(statusFor('run-resume-not-supported'));
|
|
221
|
+
return c.json(toWireError({
|
|
222
|
+
code: 'run-resume-not-supported',
|
|
223
|
+
message: 'Resuming a run at a waitpoint is not available in this release: every waitpoint belongs to an approval or to the runtime. A run waiting for an approval continues when a reviewer decides it (POST /v1/approvals/{approvalId}/complete, or `kindgi approvals complete`).',
|
|
224
|
+
}, c.get('requestId')));
|
|
225
|
+
});
|
|
226
|
+
// ---------- GET /:runId/stream and /:runId/progress/stream (SSE) ----------
|
|
227
|
+
// One stream, two views: every event in full, or progress only (no
|
|
228
|
+
// payloads), which a public run token may follow.
|
|
229
|
+
const streamRun = async (c, view) => {
|
|
230
|
+
const requestId = c.get('requestId');
|
|
231
|
+
const tenantId = c.get('tenantId');
|
|
232
|
+
const runId = c.req.param('runId');
|
|
233
|
+
const since = parseLastEventId(c.req.header('last-event-id'));
|
|
234
|
+
// Verify the run belongs to this tenant before opening the stream —
|
|
235
|
+
// otherwise a cross-tenant probe learns run existence via the stream
|
|
236
|
+
// hanging vs 404-ing.
|
|
237
|
+
const run = await readableRun(runBinding, c, runId);
|
|
238
|
+
if (run === null) {
|
|
239
|
+
c.status(statusFor('run-not-found'));
|
|
240
|
+
return c.json(toWireError({ code: 'run-not-found', message: `No run with id ${runId}` }, requestId));
|
|
241
|
+
}
|
|
242
|
+
const encoder = new TextEncoder();
|
|
243
|
+
let lastEmittedSeq = since ?? -1;
|
|
244
|
+
const POLL_MS = 200;
|
|
245
|
+
const MAX_WAIT_MS = 5 * 60_000;
|
|
246
|
+
const body = new ReadableStream({
|
|
247
|
+
async start(controller) {
|
|
248
|
+
const startedAt = Date.now();
|
|
249
|
+
let closed = false;
|
|
250
|
+
const close = () => {
|
|
251
|
+
if (closed)
|
|
252
|
+
return;
|
|
253
|
+
closed = true;
|
|
254
|
+
try {
|
|
255
|
+
controller.close();
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
/* already closed */
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
// Shared projection helper: emit one journal-entry-shaped
|
|
262
|
+
// record to the stream. Returns true iff the entry was a
|
|
263
|
+
// terminal wire kind so the caller can close.
|
|
264
|
+
const emitEntry = (entry) => {
|
|
265
|
+
if (entry.sequence <= lastEmittedSeq)
|
|
266
|
+
return false;
|
|
267
|
+
const projected = projectJournalEntry({
|
|
268
|
+
sequence: entry.sequence,
|
|
269
|
+
kind: entry.kind,
|
|
270
|
+
...(entry.nodeId !== undefined && { nodeId: entry.nodeId }),
|
|
271
|
+
...(entry.payload !== undefined && { payload: entry.payload }),
|
|
272
|
+
timestamp: entry.timestamp,
|
|
273
|
+
}, runId, tenantId);
|
|
274
|
+
lastEmittedSeq = entry.sequence;
|
|
275
|
+
if (projected === null)
|
|
276
|
+
return false;
|
|
277
|
+
controller.enqueue(encoder.encode(formatSseFrame({
|
|
278
|
+
id: projected.event.eventId,
|
|
279
|
+
event: projected.wireKind,
|
|
280
|
+
data: view === 'progress' ? toRunProgressEvent(projected.event) : projected.event,
|
|
281
|
+
})));
|
|
282
|
+
return isTerminalWireKind(projected.wireKind);
|
|
283
|
+
};
|
|
284
|
+
// Push-mode: prefer the event bus when wired. The bus delivers
|
|
285
|
+
// journal entries as `doc` payloads; we backfill via journal
|
|
286
|
+
// reads from `since` first so `Last-Event-Id` resumes work
|
|
287
|
+
// whether we're on the push or poll path.
|
|
288
|
+
if (eventBus !== undefined) {
|
|
289
|
+
const abortCtrl = new AbortController();
|
|
290
|
+
let subscription = null;
|
|
291
|
+
let fallBackToPoll = false;
|
|
292
|
+
try {
|
|
293
|
+
// Backfill: read persisted journal up to now first, so a
|
|
294
|
+
// reconnect with `Last-Event-Id` doesn't miss events that
|
|
295
|
+
// landed while the client was disconnected. Then subscribe
|
|
296
|
+
// for the tail push-side.
|
|
297
|
+
const backfill = await runBinding.readJournal(tenantId, runId);
|
|
298
|
+
if (backfill.kind === 'err') {
|
|
299
|
+
controller.enqueue(encoder.encode(formatSseFrame({
|
|
300
|
+
id: `${runId}:error`,
|
|
301
|
+
event: 'error',
|
|
302
|
+
data: {
|
|
303
|
+
code: 'journal-error',
|
|
304
|
+
message: backfill.error.message,
|
|
305
|
+
requestId,
|
|
306
|
+
},
|
|
307
|
+
})));
|
|
308
|
+
close();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
let sawTerminal = false;
|
|
312
|
+
for (const entry of backfill.value) {
|
|
313
|
+
if (emitEntry({
|
|
314
|
+
sequence: entry.sequence,
|
|
315
|
+
kind: entry.kind,
|
|
316
|
+
...(entry.nodeId !== undefined && { nodeId: entry.nodeId }),
|
|
317
|
+
...(entry.payload !== undefined && { payload: entry.payload }),
|
|
318
|
+
timestamp: entry.timestamp,
|
|
319
|
+
})) {
|
|
320
|
+
sawTerminal = true;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (sawTerminal) {
|
|
324
|
+
close();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const subOutcome = await eventBus.subscribe(tenantId, `${KERNEL_RUN_CHANNEL_PREFIX}${runId}`, (payload) => {
|
|
328
|
+
const doc = payload.doc;
|
|
329
|
+
if (doc === null || doc === undefined)
|
|
330
|
+
return;
|
|
331
|
+
if (typeof doc.sequence !== 'number' || typeof doc.kind !== 'string')
|
|
332
|
+
return;
|
|
333
|
+
if (typeof doc.timestamp !== 'string')
|
|
334
|
+
return;
|
|
335
|
+
const wasTerminal = emitEntry({
|
|
336
|
+
sequence: doc.sequence,
|
|
337
|
+
kind: doc.kind,
|
|
338
|
+
...(typeof doc.nodeId === 'string' && { nodeId: doc.nodeId }),
|
|
339
|
+
...('payload' in doc && doc.payload !== undefined && { payload: doc.payload }),
|
|
340
|
+
timestamp: doc.timestamp,
|
|
341
|
+
});
|
|
342
|
+
if (wasTerminal) {
|
|
343
|
+
abortCtrl.abort();
|
|
344
|
+
close();
|
|
345
|
+
}
|
|
346
|
+
}, abortCtrl.signal, { sinceSeq: lastEmittedSeq < 0 ? 0 : lastEmittedSeq });
|
|
347
|
+
if (subOutcome.kind === 'err') {
|
|
348
|
+
// Subscription setup failed. Not fatal: leave the stream
|
|
349
|
+
// open and continue with the poll path below.
|
|
350
|
+
fallBackToPoll = true;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
subscription = subOutcome.value;
|
|
354
|
+
// Wait until close or max-wait window elapses. We rely
|
|
355
|
+
// on the subscription callback to write frames.
|
|
356
|
+
await new Promise((resolve) => {
|
|
357
|
+
const timer = setTimeout(() => resolve(), MAX_WAIT_MS);
|
|
358
|
+
const onDone = () => {
|
|
359
|
+
clearTimeout(timer);
|
|
360
|
+
resolve();
|
|
361
|
+
};
|
|
362
|
+
abortCtrl.signal.addEventListener('abort', onDone, { once: true });
|
|
363
|
+
});
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
finally {
|
|
368
|
+
abortCtrl.abort();
|
|
369
|
+
if (subscription !== null) {
|
|
370
|
+
try {
|
|
371
|
+
await subscription.unsubscribe();
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
/* cleanup best-effort */
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (!fallBackToPoll)
|
|
378
|
+
close();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
// Poll mode: no event bus wired, or subscribing failed. Poll the
|
|
382
|
+
// journal every 200 ms until a terminal entry or the max-wait
|
|
383
|
+
// window elapses.
|
|
384
|
+
const pollEmit = async () => {
|
|
385
|
+
const journal = await runBinding.readJournal(tenantId, runId);
|
|
386
|
+
if (journal.kind === 'err') {
|
|
387
|
+
const frame = formatSseFrame({
|
|
388
|
+
id: `${runId}:error`,
|
|
389
|
+
event: 'error',
|
|
390
|
+
data: {
|
|
391
|
+
code: 'journal-error',
|
|
392
|
+
message: journal.error.message,
|
|
393
|
+
requestId,
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
controller.enqueue(encoder.encode(frame));
|
|
397
|
+
return { terminal: true };
|
|
398
|
+
}
|
|
399
|
+
let sawTerminal = false;
|
|
400
|
+
for (const entry of journal.value) {
|
|
401
|
+
if (emitEntry({
|
|
402
|
+
sequence: entry.sequence,
|
|
403
|
+
kind: entry.kind,
|
|
404
|
+
...(entry.nodeId !== undefined && { nodeId: entry.nodeId }),
|
|
405
|
+
...(entry.payload !== undefined && { payload: entry.payload }),
|
|
406
|
+
timestamp: entry.timestamp,
|
|
407
|
+
})) {
|
|
408
|
+
sawTerminal = true;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return { terminal: sawTerminal };
|
|
412
|
+
};
|
|
413
|
+
try {
|
|
414
|
+
const first = await pollEmit();
|
|
415
|
+
if (first.terminal) {
|
|
416
|
+
close();
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
while (Date.now() - startedAt < MAX_WAIT_MS) {
|
|
420
|
+
await new Promise((r) => setTimeout(r, POLL_MS));
|
|
421
|
+
const step = await pollEmit();
|
|
422
|
+
if (step.terminal)
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
finally {
|
|
427
|
+
close();
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
return new Response(body, {
|
|
432
|
+
status: 200,
|
|
433
|
+
headers: {
|
|
434
|
+
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
435
|
+
'Cache-Control': 'no-cache',
|
|
436
|
+
Connection: 'keep-alive',
|
|
437
|
+
'X-Request-Id': requestId,
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
};
|
|
441
|
+
r.get('/:runId/stream', (c) => streamRun(c, 'full'));
|
|
442
|
+
r.get('/:runId/progress/stream', (c) => streamRun(c, 'progress'));
|
|
443
|
+
// ---------- GET /:runId/journal ----------
|
|
444
|
+
r.get('/:runId/journal', async (c) => {
|
|
445
|
+
const requestId = c.get('requestId');
|
|
446
|
+
const tenantId = c.get('tenantId');
|
|
447
|
+
const runId = c.req.param('runId');
|
|
448
|
+
const sinceRaw = c.req.query('since');
|
|
449
|
+
const since = sinceRaw !== undefined ? Number.parseInt(sinceRaw, 10) : undefined;
|
|
450
|
+
const journal = await runBinding.readJournal(tenantId, runId);
|
|
451
|
+
if (journal.kind === 'err') {
|
|
452
|
+
const err = journal.error;
|
|
453
|
+
c.status(statusFor(err.code));
|
|
454
|
+
return c.json(toWireError(err, requestId));
|
|
455
|
+
}
|
|
456
|
+
const filtered = since !== undefined && Number.isFinite(since)
|
|
457
|
+
? journal.value.filter((e) => e.sequence > since)
|
|
458
|
+
: journal.value;
|
|
459
|
+
return c.json({
|
|
460
|
+
data: filtered,
|
|
461
|
+
hasMore: false,
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
return r;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Wire body for a binding failure. `RunHandlerFailure.details` become
|
|
468
|
+
* the wire error's `details` (not nested under `details.details`);
|
|
469
|
+
* any other field a binding attaches rides along, and `code` /
|
|
470
|
+
* `message` always come from the failure itself.
|
|
471
|
+
*/
|
|
472
|
+
function runFailureToWire(failure, requestId) {
|
|
473
|
+
const { details, ...rest } = failure;
|
|
474
|
+
return toWireError({ ...details, ...rest }, requestId);
|
|
475
|
+
}
|
|
476
|
+
/** Hand a parsed start body to the binding: an agent turn or a flow run. */
|
|
477
|
+
function invokeFromBody(binding, tenantId, body) {
|
|
478
|
+
const common = {
|
|
479
|
+
tenantId,
|
|
480
|
+
...(body.projectId !== undefined && { projectId: body.projectId }),
|
|
481
|
+
input: body.input,
|
|
482
|
+
...(body.dryRun !== undefined && { dryRun: body.dryRun }),
|
|
483
|
+
...(body.wait !== undefined && { wait: body.wait }),
|
|
484
|
+
};
|
|
485
|
+
return body.kind === 'agent'
|
|
486
|
+
? binding.invokeAgent({
|
|
487
|
+
...common,
|
|
488
|
+
agentId: body.agentId,
|
|
489
|
+
...(body.agentVersion !== undefined && { agentVersion: body.agentVersion }),
|
|
490
|
+
})
|
|
491
|
+
: binding.invokeFlow({
|
|
492
|
+
...common,
|
|
493
|
+
flowId: body.flowId,
|
|
494
|
+
...(body.flowVersion !== undefined && { flowVersion: body.flowVersion }),
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Wire row for a run. `output` is the run's output once it completed;
|
|
499
|
+
* single-run responses carry it, lists only with `?include=output`
|
|
500
|
+
* (outputs can be large). Child runs carry their parent's run + node.
|
|
501
|
+
*/
|
|
502
|
+
function serializeRun(row, opts) {
|
|
503
|
+
return {
|
|
504
|
+
id: row.runId,
|
|
505
|
+
tenantId: row.tenantId,
|
|
506
|
+
projectId: row.projectId,
|
|
507
|
+
flowId: row.flowId,
|
|
508
|
+
flowVersion: row.flowVersion,
|
|
509
|
+
status: row.status,
|
|
510
|
+
dryRun: row.dryRun,
|
|
511
|
+
createdAt: row.createdAt,
|
|
512
|
+
updatedAt: row.updatedAt,
|
|
513
|
+
completedAt: row.completedAt ?? undefined,
|
|
514
|
+
failureMessage: row.failureMessage ?? undefined,
|
|
515
|
+
...(opts.output && row.output !== undefined && { output: row.output }),
|
|
516
|
+
...(row.parentRunId != null && { parentRunId: row.parentRunId }),
|
|
517
|
+
...(row.parentNodeId != null && { parentNodeId: row.parentNodeId }),
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
/** A run's progress: status and timing, no data. */
|
|
521
|
+
function serializeRunProgress(row) {
|
|
522
|
+
return {
|
|
523
|
+
id: row.runId,
|
|
524
|
+
flowId: row.flowId,
|
|
525
|
+
flowVersion: row.flowVersion,
|
|
526
|
+
status: row.status,
|
|
527
|
+
createdAt: row.createdAt,
|
|
528
|
+
updatedAt: row.updatedAt,
|
|
529
|
+
...(row.completedAt != null && { completedAt: row.completedAt }),
|
|
530
|
+
...(row.parentRunId != null && { parentRunId: row.parentRunId }),
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* The run when the caller may read it: any run of the tenant for an API
|
|
535
|
+
* token; for a public run token, a run the token names or a descendant
|
|
536
|
+
* of one. `null` otherwise, which the routes answer as 404 so a token
|
|
537
|
+
* learns nothing about other runs.
|
|
538
|
+
*/
|
|
539
|
+
async function readableRun(runBinding, c, runId) {
|
|
540
|
+
const tenantId = c.get('tenantId');
|
|
541
|
+
const row = await runBinding.getRun(tenantId, runId);
|
|
542
|
+
if (row === null || c.get('tokenKind') !== 'public-run')
|
|
543
|
+
return row;
|
|
544
|
+
const granted = c.get('publicRunIds') ?? [];
|
|
545
|
+
let current = row;
|
|
546
|
+
for (let depth = 0; current !== null && depth < MAX_RUN_ANCESTRY; depth += 1) {
|
|
547
|
+
if (granted.includes(current.runId))
|
|
548
|
+
return row;
|
|
549
|
+
if (current.parentRunId == null)
|
|
550
|
+
return null;
|
|
551
|
+
current = await runBinding.getRun(tenantId, current.parentRunId);
|
|
552
|
+
}
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
/** The binding query for `GET /v1/runs`: scope, page, and the parent filters. */
|
|
556
|
+
function listRunsInput(input) {
|
|
557
|
+
const { tenantId, scope, limit, cursor, filter } = input;
|
|
558
|
+
return {
|
|
559
|
+
tenantId,
|
|
560
|
+
...(scope?.kind === 'project' && {
|
|
561
|
+
scope: { kind: 'project', projectId: scope.projectId },
|
|
562
|
+
}),
|
|
563
|
+
...(scope?.kind === 'org' && {
|
|
564
|
+
scope: { kind: 'org', orgId: scope.orgId },
|
|
565
|
+
}),
|
|
566
|
+
limit,
|
|
567
|
+
...(cursor !== null && {
|
|
568
|
+
cursor: { createdAt: cursor.createdAt, id: cursor.id },
|
|
569
|
+
}),
|
|
570
|
+
...(filter.parentRunId !== undefined && { parent: { runId: filter.parentRunId } }),
|
|
571
|
+
...(filter.topLevelOnly && { topLevelOnly: true }),
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
/** `?parentRunId=` (children of a run), `?topLevel=true`, `?include=output`. */
|
|
575
|
+
function parseRunListFilter(query) {
|
|
576
|
+
const { parentRunId, topLevel, include } = query;
|
|
577
|
+
if (topLevel !== undefined && topLevel !== 'true' && topLevel !== 'false') {
|
|
578
|
+
return { kind: 'err', message: '`topLevel` must be `true` or `false`' };
|
|
579
|
+
}
|
|
580
|
+
const topLevelOnly = topLevel === 'true';
|
|
581
|
+
if (parentRunId !== undefined && parentRunId.length === 0) {
|
|
582
|
+
return { kind: 'err', message: '`parentRunId` must be a run id' };
|
|
583
|
+
}
|
|
584
|
+
if (parentRunId !== undefined && topLevelOnly) {
|
|
585
|
+
return { kind: 'err', message: '`parentRunId` and `topLevel=true` cannot be combined' };
|
|
586
|
+
}
|
|
587
|
+
const includes = include === undefined ? [] : include.split(',').map((i) => i.trim());
|
|
588
|
+
const unknown = includes.filter((i) => i !== 'output');
|
|
589
|
+
if (unknown.length > 0) {
|
|
590
|
+
return { kind: 'err', message: `Unknown \`include\` value(s): ${unknown.join(', ')}` };
|
|
591
|
+
}
|
|
592
|
+
return {
|
|
593
|
+
kind: 'ok',
|
|
594
|
+
value: {
|
|
595
|
+
...(parentRunId !== undefined && { parentRunId: parentRunId }),
|
|
596
|
+
topLevelOnly,
|
|
597
|
+
includeOutput: includes.includes('output'),
|
|
598
|
+
},
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
/** `options` of a start body: `dryRun?`, `wait?` (booleans). */
|
|
602
|
+
function parseStartOptions(raw) {
|
|
603
|
+
const options = (raw ?? {});
|
|
604
|
+
if (typeof options !== 'object' || options === null) {
|
|
605
|
+
return {
|
|
606
|
+
kind: 'err',
|
|
607
|
+
error: { code: 'bad-input', message: '`options` must be an object when supplied' },
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
for (const key of ['dryRun', 'wait']) {
|
|
611
|
+
if (options[key] !== undefined && typeof options[key] !== 'boolean') {
|
|
612
|
+
return {
|
|
613
|
+
kind: 'err',
|
|
614
|
+
error: { code: 'bad-input', message: `\`options.${key}\` must be a boolean` },
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
const { dryRun, wait } = options;
|
|
619
|
+
return {
|
|
620
|
+
kind: 'ok',
|
|
621
|
+
value: { ...(dryRun !== undefined && { dryRun }), ...(wait !== undefined && { wait }) },
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
function parseStartRunBody(body) {
|
|
625
|
+
if (body === null || typeof body !== 'object') {
|
|
626
|
+
return { kind: 'err', error: { code: 'bad-input', message: 'Request body must be an object' } };
|
|
627
|
+
}
|
|
628
|
+
const b = body;
|
|
629
|
+
const hasAgent = typeof b.agent === 'string' && b.agent.length > 0;
|
|
630
|
+
const hasGraph = typeof b.flow === 'string' && b.flow.length > 0;
|
|
631
|
+
if (hasAgent && hasGraph) {
|
|
632
|
+
return {
|
|
633
|
+
kind: 'err',
|
|
634
|
+
error: { code: 'bad-input', message: 'Provide exactly one of `agent` or `flow`, not both' },
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
if (!hasAgent && !hasGraph) {
|
|
638
|
+
return {
|
|
639
|
+
kind: 'err',
|
|
640
|
+
error: { code: 'bad-input', message: 'Request body must include `agent` or `flow`' },
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
if (!('input' in b)) {
|
|
644
|
+
return { kind: 'err', error: { code: 'bad-input', message: '`input` is required' } };
|
|
645
|
+
}
|
|
646
|
+
const options = parseStartOptions(b.options);
|
|
647
|
+
if (options.kind === 'err')
|
|
648
|
+
return options;
|
|
649
|
+
const { dryRun, wait } = options.value;
|
|
650
|
+
if (hasAgent) {
|
|
651
|
+
const agentVersion = b.agentVersion;
|
|
652
|
+
if (agentVersion !== undefined && typeof agentVersion !== 'string') {
|
|
653
|
+
return {
|
|
654
|
+
kind: 'err',
|
|
655
|
+
error: { code: 'bad-input', message: '`agentVersion` must be a string when supplied' },
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
const agentProjectIdRaw = b.projectId;
|
|
659
|
+
if (agentProjectIdRaw !== undefined && typeof agentProjectIdRaw !== 'string') {
|
|
660
|
+
return {
|
|
661
|
+
kind: 'err',
|
|
662
|
+
error: { code: 'bad-input', message: '`projectId` must be a string when supplied' },
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
kind: 'ok',
|
|
667
|
+
value: {
|
|
668
|
+
kind: 'agent',
|
|
669
|
+
agentId: b.agent,
|
|
670
|
+
...(agentVersion !== undefined && { agentVersion: agentVersion }),
|
|
671
|
+
...(agentProjectIdRaw !== undefined && { projectId: agentProjectIdRaw }),
|
|
672
|
+
input: b.input,
|
|
673
|
+
...(dryRun !== undefined && { dryRun }),
|
|
674
|
+
...(wait !== undefined && { wait }),
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
const flowVersion = b.flowVersion;
|
|
679
|
+
if (flowVersion !== undefined && typeof flowVersion !== 'string') {
|
|
680
|
+
return {
|
|
681
|
+
kind: 'err',
|
|
682
|
+
error: { code: 'bad-input', message: '`flowVersion` must be a string when supplied' },
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
const projectId = b.projectId;
|
|
686
|
+
if (projectId !== undefined && typeof projectId !== 'string') {
|
|
687
|
+
return {
|
|
688
|
+
kind: 'err',
|
|
689
|
+
error: { code: 'bad-input', message: '`projectId` must be a string when supplied' },
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
return {
|
|
693
|
+
kind: 'ok',
|
|
694
|
+
value: {
|
|
695
|
+
kind: 'flow',
|
|
696
|
+
flowId: b.flow,
|
|
697
|
+
...(flowVersion !== undefined && { flowVersion: flowVersion }),
|
|
698
|
+
...(projectId !== undefined && { projectId: projectId }),
|
|
699
|
+
input: b.input,
|
|
700
|
+
...(dryRun !== undefined && { dryRun }),
|
|
701
|
+
...(wait !== undefined && { wait }),
|
|
702
|
+
},
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
//# sourceMappingURL=runs.js.map
|