@wardby/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +131 -0
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +282 -0
- package/bin/wardby.js +3 -0
- package/deploy/local/docker-compose.yml +19 -0
- package/dist/claude-coding-worker/driver.d.ts +70 -0
- package/dist/claude-coding-worker/driver.js +128 -0
- package/dist/claude-coding-worker/main.d.ts +2 -0
- package/dist/claude-coding-worker/main.js +41 -0
- package/dist/claude-coding-worker/sdk.d.ts +4 -0
- package/dist/claude-coding-worker/sdk.js +43 -0
- package/dist/claude-coding-worker/tool-relay.d.ts +1 -0
- package/dist/claude-coding-worker/tool-relay.js +9 -0
- package/dist/cli-help.d.ts +1 -0
- package/dist/cli-help.js +20 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.js +629 -0
- package/dist/coding/observability.d.ts +59 -0
- package/dist/coding/observability.js +77 -0
- package/dist/coding/profile.d.ts +88 -0
- package/dist/coding/profile.js +137 -0
- package/dist/coding/protocol.d.ts +345 -0
- package/dist/coding/protocol.js +445 -0
- package/dist/coding/provider.d.ts +4 -0
- package/dist/coding/provider.js +18 -0
- package/dist/coding-proxy/main.d.ts +1 -0
- package/dist/coding-proxy/main.js +51 -0
- package/dist/coding-worker/artifact.d.ts +16 -0
- package/dist/coding-worker/artifact.js +37 -0
- package/dist/coding-worker/driver.d.ts +46 -0
- package/dist/coding-worker/driver.js +158 -0
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +23 -0
- package/dist/coding-worker/isolation-probe.d.ts +1 -0
- package/dist/coding-worker/isolation-probe.js +146 -0
- package/dist/coding-worker/keeper.d.ts +4 -0
- package/dist/coding-worker/keeper.js +29 -0
- package/dist/coding-worker/main.d.ts +2 -0
- package/dist/coding-worker/main.js +43 -0
- package/dist/coding-worker/sdk.d.ts +26 -0
- package/dist/coding-worker/sdk.js +28 -0
- package/dist/coding-worker/types.d.ts +64 -0
- package/dist/coding-worker/types.js +1 -0
- package/dist/config/providers.d.ts +158 -0
- package/dist/config/providers.js +162 -0
- package/dist/core/budget-groups.d.ts +72 -0
- package/dist/core/budget-groups.js +149 -0
- package/dist/core/budget.d.ts +63 -0
- package/dist/core/budget.js +69 -0
- package/dist/core/coding-queue.d.ts +32 -0
- package/dist/core/coding-queue.js +54 -0
- package/dist/core/cron.d.ts +31 -0
- package/dist/core/cron.js +43 -0
- package/dist/core/datastores.d.ts +41 -0
- package/dist/core/datastores.js +105 -0
- package/dist/core/db.d.ts +2 -0
- package/dist/core/db.js +2 -0
- package/dist/core/dispatch.d.ts +81 -0
- package/dist/core/dispatch.js +184 -0
- package/dist/core/engine-native.d.ts +29 -0
- package/dist/core/engine-native.js +259 -0
- package/dist/core/http-runtime.d.ts +7 -0
- package/dist/core/http-runtime.js +101 -0
- package/dist/core/lease.d.ts +13 -0
- package/dist/core/lease.js +22 -0
- package/dist/core/logger.d.ts +13 -0
- package/dist/core/logger.js +45 -0
- package/dist/core/memory-tools.d.ts +11 -0
- package/dist/core/memory-tools.js +122 -0
- package/dist/core/reconciler.d.ts +45 -0
- package/dist/core/reconciler.js +152 -0
- package/dist/core/runner.d.ts +87 -0
- package/dist/core/runner.js +529 -0
- package/dist/core/scheduler.d.ts +47 -0
- package/dist/core/scheduler.js +121 -0
- package/dist/core/secrets.d.ts +46 -0
- package/dist/core/secrets.js +100 -0
- package/dist/core/subagent-memory-tools.d.ts +18 -0
- package/dist/core/subagent-memory-tools.js +121 -0
- package/dist/core/timing.d.ts +7 -0
- package/dist/core/timing.js +7 -0
- package/dist/core/webhooks.d.ts +23 -0
- package/dist/core/webhooks.js +113 -0
- package/dist/env.d.ts +11 -0
- package/dist/env.js +13 -0
- package/dist/import/budgets.d.ts +16 -0
- package/dist/import/budgets.js +21 -0
- package/dist/import/bundle.d.ts +16 -0
- package/dist/import/bundle.js +61 -0
- package/dist/import/cli-args.d.ts +2 -0
- package/dist/import/cli-args.js +44 -0
- package/dist/import/create.d.ts +34 -0
- package/dist/import/create.js +363 -0
- package/dist/import/index.d.ts +25 -0
- package/dist/import/index.js +130 -0
- package/dist/import/model-gate.d.ts +1 -0
- package/dist/import/model-gate.js +3 -0
- package/dist/import/neutral-schema.d.ts +369 -0
- package/dist/import/neutral-schema.js +109 -0
- package/dist/import/preflight.d.ts +41 -0
- package/dist/import/preflight.js +71 -0
- package/dist/import/report.d.ts +5 -0
- package/dist/import/report.js +98 -0
- package/dist/import/tool-scan.d.ts +8 -0
- package/dist/import/tool-scan.js +20 -0
- package/dist/mcp/auth/ownership.d.ts +113 -0
- package/dist/mcp/auth/ownership.js +87 -0
- package/dist/mcp/auth/principal.d.ts +9 -0
- package/dist/mcp/auth/principal.js +9 -0
- package/dist/mcp/auth/resource-server.d.ts +47 -0
- package/dist/mcp/auth/resource-server.js +82 -0
- package/dist/mcp/auth/self-hosted/browser.d.ts +3 -0
- package/dist/mcp/auth/self-hosted/browser.js +273 -0
- package/dist/mcp/auth/self-hosted/cli.d.ts +2 -0
- package/dist/mcp/auth/self-hosted/cli.js +39 -0
- package/dist/mcp/auth/self-hosted/credentials.d.ts +58 -0
- package/dist/mcp/auth/self-hosted/credentials.js +106 -0
- package/dist/mcp/auth/self-hosted/rate-limit.d.ts +13 -0
- package/dist/mcp/auth/self-hosted/rate-limit.js +20 -0
- package/dist/mcp/auth/self-hosted/session.d.ts +36 -0
- package/dist/mcp/auth/self-hosted/session.js +110 -0
- package/dist/mcp/capabilities.d.ts +11 -0
- package/dist/mcp/capabilities.js +10 -0
- package/dist/mcp/context.d.ts +46 -0
- package/dist/mcp/context.js +1 -0
- package/dist/mcp/errors.d.ts +13 -0
- package/dist/mcp/errors.js +22 -0
- package/dist/mcp/index.d.ts +32 -0
- package/dist/mcp/index.js +187 -0
- package/dist/mcp/jsonrpc.d.ts +8 -0
- package/dist/mcp/jsonrpc.js +1 -0
- package/dist/mcp/server.d.ts +107 -0
- package/dist/mcp/server.js +203 -0
- package/dist/mcp/tasks/manager.d.ts +63 -0
- package/dist/mcp/tasks/manager.js +103 -0
- package/dist/mcp/tools/agents.d.ts +2 -0
- package/dist/mcp/tools/agents.js +375 -0
- package/dist/mcp/tools/budget-groups.d.ts +2 -0
- package/dist/mcp/tools/budget-groups.js +136 -0
- package/dist/mcp/tools/datastore.d.ts +2 -0
- package/dist/mcp/tools/datastore.js +217 -0
- package/dist/mcp/tools/memory.d.ts +3 -0
- package/dist/mcp/tools/memory.js +60 -0
- package/dist/mcp/tools/models.d.ts +8 -0
- package/dist/mcp/tools/models.js +15 -0
- package/dist/mcp/tools/runs.d.ts +2 -0
- package/dist/mcp/tools/runs.js +61 -0
- package/dist/mcp/tools/scheduling.d.ts +2 -0
- package/dist/mcp/tools/scheduling.js +48 -0
- package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -0
- package/dist/mcp/tools/secret-elicitation-form.js +93 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +5 -0
- package/dist/mcp/tools/secret-elicitation-server.js +57 -0
- package/dist/mcp/tools/secret-elicitation.d.ts +38 -0
- package/dist/mcp/tools/secret-elicitation.js +52 -0
- package/dist/mcp/tools/secrets.d.ts +13 -0
- package/dist/mcp/tools/secrets.js +124 -0
- package/dist/mcp/tools/subagents.d.ts +2 -0
- package/dist/mcp/tools/subagents.js +133 -0
- package/dist/mcp/tools/text-result.d.ts +6 -0
- package/dist/mcp/tools/text-result.js +3 -0
- package/dist/mcp/tools/tools.d.ts +2 -0
- package/dist/mcp/tools/tools.js +211 -0
- package/dist/mcp/tools/trigger.d.ts +2 -0
- package/dist/mcp/tools/trigger.js +120 -0
- package/dist/mcp/tools/webhooks.d.ts +2 -0
- package/dist/mcp/tools/webhooks.js +34 -0
- package/dist/mcp/transport/http-limits.d.ts +17 -0
- package/dist/mcp/transport/http-limits.js +92 -0
- package/dist/mcp/transport/stdio.d.ts +23 -0
- package/dist/mcp/transport/stdio.js +6 -0
- package/dist/mcp/transport/streamable-http.d.ts +34 -0
- package/dist/mcp/transport/streamable-http.js +158 -0
- package/dist/mcp/unattended-schedules.d.ts +15 -0
- package/dist/mcp/unattended-schedules.js +21 -0
- package/dist/mcp/webhooks/ingress.d.ts +17 -0
- package/dist/mcp/webhooks/ingress.js +33 -0
- package/dist/observability/config.d.ts +6 -0
- package/dist/observability/config.js +20 -0
- package/dist/observability/metrics-server.d.ts +11 -0
- package/dist/observability/metrics-server.js +47 -0
- package/dist/observability/metrics.d.ts +36 -0
- package/dist/observability/metrics.js +158 -0
- package/dist/providers/auth/authorization-server.d.ts +41 -0
- package/dist/providers/auth/authorization-server.js +1 -0
- package/dist/providers/auth/delegating.d.ts +44 -0
- package/dist/providers/auth/delegating.js +105 -0
- package/dist/providers/auth/index.d.ts +11 -0
- package/dist/providers/auth/index.js +20 -0
- package/dist/providers/auth/release-gate.d.ts +1 -0
- package/dist/providers/auth/release-gate.js +4 -0
- package/dist/providers/auth/self-hosted.d.ts +78 -0
- package/dist/providers/auth/self-hosted.js +377 -0
- package/dist/providers/auth/subject.d.ts +1 -0
- package/dist/providers/auth/subject.js +6 -0
- package/dist/providers/auth/types.d.ts +63 -0
- package/dist/providers/auth/types.js +22 -0
- package/dist/providers/coding-proxy/deny-port.d.ts +5 -0
- package/dist/providers/coding-proxy/deny-port.js +45 -0
- package/dist/providers/coding-proxy/environment-credentials.d.ts +7 -0
- package/dist/providers/coding-proxy/environment-credentials.js +16 -0
- package/dist/providers/coding-proxy/index.d.ts +7 -0
- package/dist/providers/coding-proxy/index.js +7 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -0
- package/dist/providers/coding-proxy/memory-ledger.js +103 -0
- package/dist/providers/coding-proxy/metering.d.ts +20 -0
- package/dist/providers/coding-proxy/metering.js +161 -0
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +213 -0
- package/dist/providers/coding-proxy/proxy.d.ts +75 -0
- package/dist/providers/coding-proxy/proxy.js +721 -0
- package/dist/providers/coding-proxy/runtime.d.ts +18 -0
- package/dist/providers/coding-proxy/runtime.js +39 -0
- package/dist/providers/coding-proxy/secure-fetch.d.ts +9 -0
- package/dist/providers/coding-proxy/secure-fetch.js +72 -0
- package/dist/providers/coding-proxy/server.d.ts +17 -0
- package/dist/providers/coding-proxy/server.js +139 -0
- package/dist/providers/coding-proxy/types.d.ts +99 -0
- package/dist/providers/coding-proxy/types.js +1 -0
- package/dist/providers/datastore/index.d.ts +2 -0
- package/dist/providers/datastore/index.js +2 -0
- package/dist/providers/datastore/postgres.d.ts +20 -0
- package/dist/providers/datastore/postgres.js +130 -0
- package/dist/providers/datastore/scoped.d.ts +10 -0
- package/dist/providers/datastore/scoped.js +46 -0
- package/dist/providers/datastore/types.d.ts +31 -0
- package/dist/providers/datastore/types.js +7 -0
- package/dist/providers/email/types.d.ts +46 -0
- package/dist/providers/email/types.js +8 -0
- package/dist/providers/engine/index.d.ts +1 -0
- package/dist/providers/engine/index.js +1 -0
- package/dist/providers/engine/types.d.ts +67 -0
- package/dist/providers/engine/types.js +16 -0
- package/dist/providers/executor/build.d.ts +6 -0
- package/dist/providers/executor/build.js +15 -0
- package/dist/providers/executor/composition.d.ts +14 -0
- package/dist/providers/executor/composition.js +123 -0
- package/dist/providers/executor/container.d.ts +184 -0
- package/dist/providers/executor/container.js +936 -0
- package/dist/providers/executor/dbos-status.d.ts +50 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +53 -0
- package/dist/providers/executor/dbos.js +269 -0
- package/dist/providers/executor/in-process.d.ts +18 -0
- package/dist/providers/executor/in-process.js +38 -0
- package/dist/providers/executor/index.d.ts +8 -0
- package/dist/providers/executor/index.js +8 -0
- package/dist/providers/executor/routing.d.ts +48 -0
- package/dist/providers/executor/routing.js +70 -0
- package/dist/providers/executor/types.d.ts +55 -0
- package/dist/providers/executor/types.js +1 -0
- package/dist/providers/index.d.ts +43 -0
- package/dist/providers/index.js +18 -0
- package/dist/providers/jobs/docker-isolation.d.ts +166 -0
- package/dist/providers/jobs/docker-isolation.js +724 -0
- package/dist/providers/jobs/docker.d.ts +127 -0
- package/dist/providers/jobs/docker.js +1027 -0
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +98 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +142 -0
- package/dist/providers/jobs/fake.d.ts +23 -0
- package/dist/providers/jobs/fake.js +132 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +60 -0
- package/dist/providers/jobs/kubernetes-api.js +20 -0
- package/dist/providers/jobs/kubernetes-client.d.ts +36 -0
- package/dist/providers/jobs/kubernetes-client.js +171 -0
- package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +49 -0
- package/dist/providers/jobs/kubernetes-dry-run-fixture.js +141 -0
- package/dist/providers/jobs/kubernetes-isolation.d.ts +147 -0
- package/dist/providers/jobs/kubernetes-isolation.js +607 -0
- package/dist/providers/jobs/kubernetes-platform.d.ts +177 -0
- package/dist/providers/jobs/kubernetes-platform.js +280 -0
- package/dist/providers/jobs/kubernetes-preflight.d.ts +59 -0
- package/dist/providers/jobs/kubernetes-preflight.js +339 -0
- package/dist/providers/jobs/kubernetes-witness.d.ts +10 -0
- package/dist/providers/jobs/kubernetes-witness.js +193 -0
- package/dist/providers/jobs/kubernetes.d.ts +127 -0
- package/dist/providers/jobs/kubernetes.js +874 -0
- package/dist/providers/jobs/safe-extract.d.ts +9 -0
- package/dist/providers/jobs/safe-extract.js +325 -0
- package/dist/providers/jobs/types.d.ts +78 -0
- package/dist/providers/jobs/types.js +6 -0
- package/dist/providers/jobs/workspace-swap.d.ts +2 -0
- package/dist/providers/jobs/workspace-swap.js +47 -0
- package/dist/providers/llm/anthropic.d.ts +13 -0
- package/dist/providers/llm/anthropic.js +21 -0
- package/dist/providers/llm/bedrock.d.ts +19 -0
- package/dist/providers/llm/bedrock.js +33 -0
- package/dist/providers/llm/claude-messages.d.ts +106 -0
- package/dist/providers/llm/claude-messages.js +157 -0
- package/dist/providers/llm/claude-provider.d.ts +40 -0
- package/dist/providers/llm/claude-provider.js +31 -0
- package/dist/providers/llm/index.d.ts +10 -0
- package/dist/providers/llm/index.js +10 -0
- package/dist/providers/llm/openai.d.ts +23 -0
- package/dist/providers/llm/openai.js +156 -0
- package/dist/providers/llm/pricing-anthropic.d.ts +4 -0
- package/dist/providers/llm/pricing-anthropic.js +30 -0
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +12 -0
- package/dist/providers/llm/pricing-bedrock-claude.js +37 -0
- package/dist/providers/llm/pricing-core.d.ts +26 -0
- package/dist/providers/llm/pricing-core.js +17 -0
- package/dist/providers/llm/pricing.d.ts +30 -0
- package/dist/providers/llm/pricing.js +74 -0
- package/dist/providers/llm/registration.d.ts +8 -0
- package/dist/providers/llm/registration.js +39 -0
- package/dist/providers/llm/routing.d.ts +25 -0
- package/dist/providers/llm/routing.js +32 -0
- package/dist/providers/llm/types.d.ts +85 -0
- package/dist/providers/llm/types.js +12 -0
- package/dist/providers/memory/index.d.ts +2 -0
- package/dist/providers/memory/index.js +2 -0
- package/dist/providers/memory/postgres.d.ts +20 -0
- package/dist/providers/memory/postgres.js +72 -0
- package/dist/providers/memory/types.d.ts +32 -0
- package/dist/providers/memory/types.js +17 -0
- package/dist/providers/secrets/app-key.d.ts +8 -0
- package/dist/providers/secrets/app-key.js +50 -0
- package/dist/providers/secrets/index.d.ts +10 -0
- package/dist/providers/secrets/index.js +13 -0
- package/dist/providers/secrets/transfer-envelope.d.ts +12 -0
- package/dist/providers/secrets/transfer-envelope.js +35 -0
- package/dist/providers/secrets/types.d.ts +18 -0
- package/dist/providers/secrets/types.js +12 -0
- package/dist/providers/storage/types.d.ts +18 -0
- package/dist/providers/storage/types.js +7 -0
- package/dist/providers/vcs/git.d.ts +105 -0
- package/dist/providers/vcs/git.js +710 -0
- package/dist/providers/vcs/github.d.ts +105 -0
- package/dist/providers/vcs/github.js +394 -0
- package/dist/providers/vcs/index.d.ts +6 -0
- package/dist/providers/vcs/index.js +26 -0
- package/dist/providers/vcs/types.d.ts +118 -0
- package/dist/providers/vcs/types.js +1 -0
- package/dist/sandbox/bounded-json.d.ts +2 -0
- package/dist/sandbox/bounded-json.js +36 -0
- package/dist/sandbox/bridge.d.ts +15 -0
- package/dist/sandbox/bridge.js +78 -0
- package/dist/sandbox/eval-core.d.ts +37 -0
- package/dist/sandbox/eval-core.js +159 -0
- package/dist/sandbox/fetch-policy.d.ts +24 -0
- package/dist/sandbox/fetch-policy.js +96 -0
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +5 -0
- package/dist/sandbox/generated/zod.bundle.js +1 -0
- package/dist/sandbox/host-functions.d.ts +29 -0
- package/dist/sandbox/host-functions.js +168 -0
- package/dist/sandbox/limits.d.ts +39 -0
- package/dist/sandbox/limits.js +39 -0
- package/dist/sandbox/parser-worker/__fixtures__/crash.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/crash.js +6 -0
- package/dist/sandbox/parser-worker/__fixtures__/echo.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/echo.js +5 -0
- package/dist/sandbox/parser-worker/__fixtures__/reject.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/reject.js +5 -0
- package/dist/sandbox/parser-worker/__fixtures__/spin-forever.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/spin-forever.js +11 -0
- package/dist/sandbox/parser-worker/pool.d.ts +13 -0
- package/dist/sandbox/parser-worker/pool.js +111 -0
- package/dist/sandbox/parser-worker/worker.d.ts +14 -0
- package/dist/sandbox/parser-worker/worker.js +63 -0
- package/dist/sandbox/pii-redaction.d.ts +1 -0
- package/dist/sandbox/pii-redaction.js +29 -0
- package/dist/sandbox/prelude.d.ts +26 -0
- package/dist/sandbox/prelude.js +408 -0
- package/dist/sandbox/quickjs-module.d.ts +13 -0
- package/dist/sandbox/quickjs-module.js +19 -0
- package/dist/sandbox/run-in-sandbox.d.ts +34 -0
- package/dist/sandbox/run-in-sandbox.js +53 -0
- package/dist/sandbox/safe-fetch.d.ts +26 -0
- package/dist/sandbox/safe-fetch.js +140 -0
- package/dist/sandbox/tool-capabilities.d.ts +66 -0
- package/dist/sandbox/tool-capabilities.js +103 -0
- package/dist/sandbox/zod-params.d.ts +22 -0
- package/dist/sandbox/zod-params.js +60 -0
- package/dist/serve.d.ts +14 -0
- package/dist/serve.js +54 -0
- package/dist/wardby-bin.d.ts +2 -0
- package/dist/wardby-bin.js +20 -0
- package/package.json +123 -0
- package/prisma/migrations/20260905000000_init/migration.sql +34 -0
- package/prisma/migrations/20260905010000_scheduler_durability/migration.sql +31 -0
- package/prisma/migrations/20260905020000_tools_multiturn/migration.sql +47 -0
- package/prisma/migrations/20260905030000_cache_tool_json_schema/migration.sql +13 -0
- package/prisma/migrations/20260906000000_mcp_phase4/migration.sql +115 -0
- package/prisma/migrations/20260906010000_run_final_text/migration.sql +7 -0
- package/prisma/migrations/20260906020000_run_turns/migration.sql +6 -0
- package/prisma/migrations/20260906030000_task_principal_id/migration.sql +5 -0
- package/prisma/migrations/20260906040000_secure_self_hosted_oauth/migration.sql +67 -0
- package/prisma/migrations/20260906050000_phase5_coding_agents/migration.sql +52 -0
- package/prisma/migrations/20260906060000_tool_capability_scoping/migration.sql +22 -0
- package/prisma/migrations/20260906070000_datastore_pii_flag/migration.sql +6 -0
- package/prisma/migrations/20260906080000_secret_elicitation_outcomes/migration.sql +13 -0
- package/prisma/migrations/20260907010000_coding_proxy_ledger/migration.sql +57 -0
- package/prisma/migrations/20260907020000_budget_groups/migration.sql +24 -0
- package/prisma/migrations/20260907030000_coding_webhook_task_override/migration.sql +4 -0
- package/prisma/migrations/20260908010000_run_execution_backend/migration.sql +2 -0
- package/prisma/migrations/20260908020000_coding_run_audit_metadata/migration.sql +7 -0
- package/prisma/migrations/20260910010000_agent_secret_bound_name/migration.sql +16 -0
- package/prisma/migrations/20260911010000_coding_worker_toolchains/migration.sql +5 -0
- package/prisma/migrations/20260912010000_coding_provider_contract/migration.sql +24 -0
- package/prisma/migrations/20260912020000_coding_proxy_protocol/migration.sql +10 -0
- package/prisma/migrations/20260912030000_agent_memory/migration.sql +18 -0
- package/prisma/migrations/20260912040000_named_shared_datastores/migration.sql +68 -0
- package/prisma/migrations/20260913000000_run_trigger_webhook/migration.sql +2 -0
- package/prisma/migrations/20260913010000_agent_sub_agent/migration.sql +32 -0
- package/prisma/migrations/20260913020000_run_task_override/migration.sql +5 -0
- package/prisma/migrations/20260913030000_coding_run_root/migration.sql +11 -0
- package/prisma/migrations/20260922010000_coding_run_queued_at/migration.sql +8 -0
- package/prisma/migrations/20260922020000_coding_workspace_disk/migration.sql +8 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +723 -0
- package/scripts/git-askpass.sh +11 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email seam — outbound and inbound mail.
|
|
3
|
+
*
|
|
4
|
+
* Backs the sandbox `sendEmail` / `getInboundEmail` APIs.
|
|
5
|
+
* Default adapter: SmtpEmailProvider.
|
|
6
|
+
* Native adapter: SesSnsS3EmailProvider (SES out; SNS/S3 inbound).
|
|
7
|
+
*/
|
|
8
|
+
export interface EmailAttachment {
|
|
9
|
+
filename: string;
|
|
10
|
+
contentType: string;
|
|
11
|
+
content: Buffer;
|
|
12
|
+
}
|
|
13
|
+
export interface OutboundEmail {
|
|
14
|
+
to: string[];
|
|
15
|
+
cc?: string[];
|
|
16
|
+
bcc?: string[];
|
|
17
|
+
subject: string;
|
|
18
|
+
text?: string;
|
|
19
|
+
html?: string;
|
|
20
|
+
/** Sender address; the provider's configured default is used if omitted. */
|
|
21
|
+
from?: string;
|
|
22
|
+
replyTo?: string;
|
|
23
|
+
attachments?: EmailAttachment[];
|
|
24
|
+
}
|
|
25
|
+
export interface InboundEmail {
|
|
26
|
+
messageId: string;
|
|
27
|
+
from: string;
|
|
28
|
+
to: string[];
|
|
29
|
+
subject: string;
|
|
30
|
+
text?: string;
|
|
31
|
+
html?: string;
|
|
32
|
+
attachments: EmailAttachment[];
|
|
33
|
+
receivedAt: Date;
|
|
34
|
+
/** True only if the provider verified DMARC (with SPF/DKIM alignment). */
|
|
35
|
+
dmarcPass: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface EmailProvider {
|
|
38
|
+
send(msg: OutboundEmail): Promise<{
|
|
39
|
+
messageId: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Fetch messages routed to a mailbox/address key. */
|
|
42
|
+
fetchInbound(mailbox: string, opts?: {
|
|
43
|
+
since?: Date;
|
|
44
|
+
limit?: number;
|
|
45
|
+
}): Promise<InboundEmail[]>;
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Engine seam — the control flow *inside* a run: turns, tool calls,
|
|
3
|
+
* branching. A future LangGraph adapter is a swap at this seam, not a
|
|
4
|
+
* rewrite of the runner. Distinct from the `Executor` seam (Phase 2),
|
|
5
|
+
* which is *around* a run (how it survives a crash and resumes) — see the
|
|
6
|
+
* Phase 3 design doc's layer-boundaries section.
|
|
7
|
+
*
|
|
8
|
+
* The engine owns the entire turn loop AND the budget lifecycle
|
|
9
|
+
* (pre-flight refuse, cumulative pre-turn gate, mid-stream cutoff,
|
|
10
|
+
* graceful wind-down) — never split with the caller. Every model call
|
|
11
|
+
* must go through `ctx.providers.llm` so the guardrail holds regardless of
|
|
12
|
+
* which engine is driving: an engine that calls a provider SDK directly
|
|
13
|
+
* blinds the pre-flight refuse and mid-stream cutoff, and is not allowed.
|
|
14
|
+
*/
|
|
15
|
+
import type { ProviderRegistry } from "../index.js";
|
|
16
|
+
/** The subset of Agent fields the engine needs — not the Prisma type, to keep this seam Prisma-agnostic. */
|
|
17
|
+
export interface EngineAgent {
|
|
18
|
+
systemPrompt: string;
|
|
19
|
+
model: string;
|
|
20
|
+
budgetUsd: number;
|
|
21
|
+
maxTurns: number;
|
|
22
|
+
}
|
|
23
|
+
export interface LoadedTool {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
/** Derived from the tool's Zod schema via zod-to-json-schema at load time. */
|
|
27
|
+
jsonSchema: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Durable step boundary. A checkpointing executor (DbosExecutor) supplies
|
|
31
|
+
* one that records each step's result, so a run resumed after a crash
|
|
32
|
+
* replays completed steps from the record instead of re-executing them
|
|
33
|
+
* (and re-spending). When absent, `fn` runs directly.
|
|
34
|
+
*
|
|
35
|
+
* Contract for engines: `fn`'s return value must be plain JSON data, and
|
|
36
|
+
* `name` must be deterministic for a given position in the run — the
|
|
37
|
+
* replay matches steps by order, so control flow between steps must depend
|
|
38
|
+
* only on earlier step results and on `agent` fields fixed at run start.
|
|
39
|
+
*/
|
|
40
|
+
export type StepRunner = <T>(name: string, fn: () => Promise<T>) => Promise<T>;
|
|
41
|
+
/** The no-checkpoint default: run the step body directly. */
|
|
42
|
+
export declare const runStepInline: StepRunner;
|
|
43
|
+
export interface EngineRunContext {
|
|
44
|
+
agent: EngineAgent;
|
|
45
|
+
tools: LoadedTool[];
|
|
46
|
+
providers: Pick<ProviderRegistry, "llm">;
|
|
47
|
+
/** Host bridge: validates params (Zod-in-sandbox) then runs the tool body in the WASM sandbox. Never throws — a tool/validation failure is a JSON error result string, fed back to the model as the tool's result. */
|
|
48
|
+
runSandboxTool(name: string, argsJson: string): Promise<string>;
|
|
49
|
+
onText?: (delta: string) => void;
|
|
50
|
+
/** See StepRunner. Optional; the in-process executor leaves it unset. */
|
|
51
|
+
step?: StepRunner;
|
|
52
|
+
}
|
|
53
|
+
export type EngineStatus = "succeeded" | "budget_exhausted" | "refused" | "failed";
|
|
54
|
+
export interface EngineResult {
|
|
55
|
+
status: EngineStatus;
|
|
56
|
+
finalText: string;
|
|
57
|
+
turns: number;
|
|
58
|
+
usage: {
|
|
59
|
+
tokensIn: number;
|
|
60
|
+
tokensOut: number;
|
|
61
|
+
costUsd: number;
|
|
62
|
+
};
|
|
63
|
+
error?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface Engine {
|
|
66
|
+
run(ctx: EngineRunContext): Promise<EngineResult>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Engine seam — the control flow *inside* a run: turns, tool calls,
|
|
3
|
+
* branching. A future LangGraph adapter is a swap at this seam, not a
|
|
4
|
+
* rewrite of the runner. Distinct from the `Executor` seam (Phase 2),
|
|
5
|
+
* which is *around* a run (how it survives a crash and resumes) — see the
|
|
6
|
+
* Phase 3 design doc's layer-boundaries section.
|
|
7
|
+
*
|
|
8
|
+
* The engine owns the entire turn loop AND the budget lifecycle
|
|
9
|
+
* (pre-flight refuse, cumulative pre-turn gate, mid-stream cutoff,
|
|
10
|
+
* graceful wind-down) — never split with the caller. Every model call
|
|
11
|
+
* must go through `ctx.providers.llm` so the guardrail holds regardless of
|
|
12
|
+
* which engine is driving: an engine that calls a provider SDK directly
|
|
13
|
+
* blinds the pre-flight refuse and mid-stream cutoff, and is not allowed.
|
|
14
|
+
*/
|
|
15
|
+
/** The no-checkpoint default: run the step body directly. */
|
|
16
|
+
export const runStepInline = (_name, fn) => fn();
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PrismaClient } from "@prisma/client";
|
|
2
|
+
import type { ProviderRegistry } from "../index.js";
|
|
3
|
+
import { type ProviderConfig } from "../../config/providers.js";
|
|
4
|
+
import type { Executor } from "./types.js";
|
|
5
|
+
/** Select the Executor adapter from EXECUTOR. Constructing never connects; call `launch?.()` for that. */
|
|
6
|
+
export declare function buildExecutor(config: Pick<ProviderConfig, "executor">, providers: Pick<ProviderRegistry, "llm" | "engine" | "datastore" | "secrets" | "memory">, db?: PrismaClient, env?: NodeJS.ProcessEnv): Executor;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { loadDbosConfig } from "../../config/providers.js";
|
|
2
|
+
import { prisma as defaultDb } from "../../core/db.js";
|
|
3
|
+
import { InProcessExecutor } from "./in-process.js";
|
|
4
|
+
import { DbosExecutor } from "./dbos.js";
|
|
5
|
+
/** Select the Executor adapter from EXECUTOR. Constructing never connects; call `launch?.()` for that. */
|
|
6
|
+
export function buildExecutor(config, providers, db = defaultDb, env = process.env) {
|
|
7
|
+
switch (config.executor) {
|
|
8
|
+
case "in-process":
|
|
9
|
+
return new InProcessExecutor(providers, db);
|
|
10
|
+
case "dbos":
|
|
11
|
+
return new DbosExecutor(providers, loadDbosConfig(env), db);
|
|
12
|
+
default:
|
|
13
|
+
throw new Error(`EXECUTOR "${String(config.executor)}" has no adapter (use "in-process" or "dbos").`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PrismaClient } from "@prisma/client";
|
|
2
|
+
import { type ProviderConfig } from "../../config/providers.js";
|
|
3
|
+
import type { KubernetesApi } from "../jobs/kubernetes-api.js";
|
|
4
|
+
import type { Executor } from "./types.js";
|
|
5
|
+
export interface ConfiguredExecutorOptions {
|
|
6
|
+
native: Executor;
|
|
7
|
+
db: PrismaClient;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
providerConfig?: ProviderConfig;
|
|
10
|
+
/** Tests only: replaces the kubeconfig-backed client when JOB_LAUNCHER=kubernetes. */
|
|
11
|
+
kubernetesApi?: KubernetesApi;
|
|
12
|
+
}
|
|
13
|
+
/** Builds container execution only when Docker or Kubernetes is explicitly selected. */
|
|
14
|
+
export declare function buildConfiguredExecutor(options: ConfiguredExecutorOptions): Executor;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { tmpdir } from "node:os";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { loadCodingConcurrencyConfig, loadContainerExecutorConfig, loadGitHubVcsConfig, loadKubernetesJobConfig, loadProviderConfig, } from "../../config/providers.js";
|
|
4
|
+
import { drainCodingQueue } from "../../core/coding-queue.js";
|
|
5
|
+
import { logger } from "../../core/logger.js";
|
|
6
|
+
import { EnvironmentCredentialResolver } from "../coding-proxy/environment-credentials.js";
|
|
7
|
+
import { CodingProxy } from "../coding-proxy/proxy.js";
|
|
8
|
+
import { PrismaProxyLedger } from "../coding-proxy/prisma-ledger.js";
|
|
9
|
+
import { DockerJobLauncher } from "../jobs/docker.js";
|
|
10
|
+
import { ClientNodeKubernetesApi } from "../jobs/kubernetes-client.js";
|
|
11
|
+
import { isRegistryDigest } from "../jobs/kubernetes-isolation.js";
|
|
12
|
+
import { assertPlatformConfig, platformProfile } from "../jobs/kubernetes-platform.js";
|
|
13
|
+
import { runKubernetesPreflight } from "../jobs/kubernetes-preflight.js";
|
|
14
|
+
import { KubernetesJobLauncher } from "../jobs/kubernetes.js";
|
|
15
|
+
import { buildVcsProvider } from "../vcs/index.js";
|
|
16
|
+
import { ContainerExecutor, PrismaContainerExecutionStore, RunCapabilityVault } from "./container.js";
|
|
17
|
+
import { PrismaExecutionKindResolver, RoutingExecutor } from "./routing.js";
|
|
18
|
+
const compositionLog = logger.child({ module: "executor-composition" });
|
|
19
|
+
/** Builds container execution only when Docker or Kubernetes is explicitly selected. */
|
|
20
|
+
export function buildConfiguredExecutor(options) {
|
|
21
|
+
const env = options.env ?? process.env;
|
|
22
|
+
const providerConfig = options.providerConfig ?? loadProviderConfig(env);
|
|
23
|
+
if (providerConfig.jobs !== "docker" && providerConfig.jobs !== "kubernetes")
|
|
24
|
+
return options.native;
|
|
25
|
+
const github = loadGitHubVcsConfig(env);
|
|
26
|
+
const config = loadContainerExecutorConfig(env);
|
|
27
|
+
if (!config.workerImage)
|
|
28
|
+
throw new Error(`CODING_WORKER_IMAGE is required when JOB_LAUNCHER=${providerConfig.jobs}.`);
|
|
29
|
+
const proxyContainer = config.proxyContainer;
|
|
30
|
+
if (providerConfig.jobs === "docker" && !proxyContainer) {
|
|
31
|
+
throw new Error("CODING_PROXY_CONTAINER is required when JOB_LAUNCHER=docker.");
|
|
32
|
+
}
|
|
33
|
+
const workspaceRoot = resolve(github.workRoot ?? resolve(tmpdir(), "wardby-vcs"));
|
|
34
|
+
const artifactRoot = resolve(config.artifactRoot ?? resolve(tmpdir(), "wardby-coding-artifacts"));
|
|
35
|
+
const vcs = buildVcsProvider(providerConfig, { ...github, workRoot: workspaceRoot });
|
|
36
|
+
const capabilities = new RunCapabilityVault();
|
|
37
|
+
const sessions = new CodingProxy({
|
|
38
|
+
ledger: new PrismaProxyLedger(options.db),
|
|
39
|
+
credentials: new EnvironmentCredentialResolver(env),
|
|
40
|
+
});
|
|
41
|
+
let jobs;
|
|
42
|
+
if (providerConfig.jobs === "kubernetes") {
|
|
43
|
+
if (!isRegistryDigest(config.workerImage)) {
|
|
44
|
+
throw new Error("CODING_WORKER_IMAGE must be a registry digest (repo@sha256:...) when JOB_LAUNCHER=kubernetes.");
|
|
45
|
+
}
|
|
46
|
+
const kubernetes = loadKubernetesJobConfig(env);
|
|
47
|
+
// The preflight only runs on the first launch; a configuration that cannot work should
|
|
48
|
+
// fail the process at start-up, not the first coding run an hour later.
|
|
49
|
+
assertPlatformConfig(platformProfile(kubernetes.platform), {
|
|
50
|
+
runtimeClassName: kubernetes.runtimeClassName,
|
|
51
|
+
maxDiskMb: config.maxDiskMb,
|
|
52
|
+
});
|
|
53
|
+
const api = options.kubernetesApi ?? new ClientNodeKubernetesApi({ context: kubernetes.context });
|
|
54
|
+
const workerImage = config.workerImage;
|
|
55
|
+
jobs = new KubernetesJobLauncher({
|
|
56
|
+
api,
|
|
57
|
+
config: kubernetes,
|
|
58
|
+
workspaceRoot,
|
|
59
|
+
resolveCapability: (runId) => capabilities.get(runId),
|
|
60
|
+
readyTimeoutMs: kubernetes.readyTimeoutMs,
|
|
61
|
+
preflight: async () => {
|
|
62
|
+
const { proxyIp } = await runKubernetesPreflight({
|
|
63
|
+
api,
|
|
64
|
+
config: kubernetes,
|
|
65
|
+
workerImage,
|
|
66
|
+
maxDiskMb: config.maxDiskMb,
|
|
67
|
+
timeoutMs: kubernetes.preflightTimeoutMs,
|
|
68
|
+
});
|
|
69
|
+
return { proxyIp };
|
|
70
|
+
},
|
|
71
|
+
onWarning: (message) => compositionLog.warn(message),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const stateRoot = resolve(config.stateRoot ?? resolve(tmpdir(), "wardby-docker-jobs"));
|
|
76
|
+
jobs = new DockerJobLauncher({
|
|
77
|
+
stateRoot,
|
|
78
|
+
workspaceRoot,
|
|
79
|
+
proxyContainer: proxyContainer,
|
|
80
|
+
resolveCapability: (runId) => capabilities.get(runId),
|
|
81
|
+
isRunActive: async (runId, handle) => {
|
|
82
|
+
const coding = await options.db.codingRun.findUnique({
|
|
83
|
+
where: { runId },
|
|
84
|
+
include: { run: { select: { status: true } } },
|
|
85
|
+
});
|
|
86
|
+
return (coding?.run.status === "running" && coding.jobBackend === handle.backend && coding.jobHandle === handle.id);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const concurrency = loadCodingConcurrencyConfig(env);
|
|
91
|
+
// The release hook needs the composed RoutingExecutor, which only exists
|
|
92
|
+
// after the ContainerExecutor it wraps is built. The closure reads
|
|
93
|
+
// `composed` only when a run finishes, which is after this function returns.
|
|
94
|
+
const coding = new ContainerExecutor({
|
|
95
|
+
store: new PrismaContainerExecutionStore(options.db, { maxConcurrent: concurrency.maxConcurrent }),
|
|
96
|
+
jobs,
|
|
97
|
+
vcs,
|
|
98
|
+
sessions,
|
|
99
|
+
capabilities,
|
|
100
|
+
artifactRoot,
|
|
101
|
+
workerImage: config.workerImage,
|
|
102
|
+
claudeWorkerImage: config.claudeWorkerImage,
|
|
103
|
+
claudeToolRunnerImage: config.claudeToolRunnerImage,
|
|
104
|
+
additionalWorkerImages: config.additionalWorkerImages,
|
|
105
|
+
credentialRef: config.credentialRef,
|
|
106
|
+
anthropicCredentialRef: config.anthropicCredentialRef,
|
|
107
|
+
limits: { cpus: config.cpus, memoryMb: config.memoryMb, pids: config.pids, diskMb: config.diskMb },
|
|
108
|
+
maxDiskMb: config.maxDiskMb,
|
|
109
|
+
onSlotReleased: () => {
|
|
110
|
+
void drainCodingQueue({
|
|
111
|
+
db: options.db,
|
|
112
|
+
executor: composed,
|
|
113
|
+
maxConcurrent: concurrency.maxConcurrent,
|
|
114
|
+
queueTimeoutSec: concurrency.queueTimeoutSec,
|
|
115
|
+
}).catch((err) => {
|
|
116
|
+
// Never throws: the next scheduler tick drains again.
|
|
117
|
+
compositionLog.warn({ err }, "coding queue drain after a released slot failed");
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
const composed = new RoutingExecutor(new PrismaExecutionKindResolver(options.db), options.native, coding);
|
|
122
|
+
return composed;
|
|
123
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { PrismaClient } from "@prisma/client";
|
|
2
|
+
import { type CodingRunObserver } from "../../coding/observability.js";
|
|
3
|
+
import { type CodingRunResult } from "../../coding/protocol.js";
|
|
4
|
+
import type { ProxyProtocol } from "../coding-proxy/types.js";
|
|
5
|
+
import type { JobHandle, JobResourceLimits, WorkspaceJobLauncher } from "../jobs/types.js";
|
|
6
|
+
import type { VcsProvider } from "../vcs/types.js";
|
|
7
|
+
import type { CodingImageSelector, ExecutionRecoveryResult, Executor, PersistedExecutionHandle } from "./types.js";
|
|
8
|
+
export interface ContainerRunSnapshot {
|
|
9
|
+
runId: string;
|
|
10
|
+
status: string;
|
|
11
|
+
agentKind: string;
|
|
12
|
+
/** Human-readable agent name (e.g. "knock-knock-implement") -- surfaced in continuation status notifications. */
|
|
13
|
+
agentName: string;
|
|
14
|
+
ownerId: string | null;
|
|
15
|
+
task: string;
|
|
16
|
+
repository: string;
|
|
17
|
+
baseRef: string;
|
|
18
|
+
headRef: string;
|
|
19
|
+
provider: string;
|
|
20
|
+
model: string;
|
|
21
|
+
timeoutSec: number;
|
|
22
|
+
allowedEgress: unknown;
|
|
23
|
+
protectedPaths: unknown;
|
|
24
|
+
/** Revision-in-place: set when this run continues another run's branch/PR. See preflight(). */
|
|
25
|
+
rootCodingRunId: string | null;
|
|
26
|
+
budgetUsd: number;
|
|
27
|
+
tokensIn: number;
|
|
28
|
+
tokensOut: number;
|
|
29
|
+
costUsd: number;
|
|
30
|
+
jobHandle: JobHandle | null;
|
|
31
|
+
provisioningClaim: string | null;
|
|
32
|
+
proxySessionId: string | null;
|
|
33
|
+
result: unknown;
|
|
34
|
+
workerImage: string | null;
|
|
35
|
+
workspaceDiskMb: number | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* claimed: this caller owns provisioning. unavailable: someone else does, or
|
|
39
|
+
* the run is no longer active. queued: every concurrency slot is taken, or
|
|
40
|
+
* the free ones belong to older queued runs; the run stays pending with
|
|
41
|
+
* CodingRun.queuedAt set until drainCodingQueue starts it.
|
|
42
|
+
*/
|
|
43
|
+
export type ProvisioningClaim = "claimed" | "unavailable" | "queued";
|
|
44
|
+
export interface ContainerExecutionStore {
|
|
45
|
+
load(runId: string): Promise<ContainerRunSnapshot | null>;
|
|
46
|
+
claimProvisioning(runId: string, claimId: string): Promise<ProvisioningClaim>;
|
|
47
|
+
persistHandle(runId: string, claimId: string, handle: JobHandle): Promise<void>;
|
|
48
|
+
heartbeat(runId: string): Promise<void>;
|
|
49
|
+
complete(runId: string, status: "succeeded" | "budget_exhausted", result: CodingRunResult): Promise<void>;
|
|
50
|
+
terminate(runId: string, status: "failed" | "refused" | "lost" | "cancelled", error: string, audit?: CodingFailureAudit): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export interface CodingFailureAudit {
|
|
53
|
+
failureCategory: string;
|
|
54
|
+
diagnosticId: string;
|
|
55
|
+
}
|
|
56
|
+
export declare class PrismaContainerExecutionStore implements ContainerExecutionStore {
|
|
57
|
+
private readonly db;
|
|
58
|
+
private readonly options;
|
|
59
|
+
constructor(db: PrismaClient, options?: {
|
|
60
|
+
maxConcurrent?: number;
|
|
61
|
+
});
|
|
62
|
+
load(runId: string): Promise<ContainerRunSnapshot | null>;
|
|
63
|
+
claimProvisioning(runId: string, claimId: string): Promise<ProvisioningClaim>;
|
|
64
|
+
persistHandle(runId: string, claimId: string, handle: JobHandle): Promise<void>;
|
|
65
|
+
heartbeat(runId: string): Promise<void>;
|
|
66
|
+
complete(runId: string, status: "succeeded" | "budget_exhausted", result: CodingRunResult): Promise<void>;
|
|
67
|
+
terminate(runId: string, status: "failed" | "refused" | "lost" | "cancelled", error: string, audit?: CodingFailureAudit): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
export interface CodingSessionController {
|
|
70
|
+
createSession(input: {
|
|
71
|
+
runId: string;
|
|
72
|
+
credentialRef: string;
|
|
73
|
+
protocol: ProxyProtocol;
|
|
74
|
+
allowedModels: string[];
|
|
75
|
+
deadlineAt: Date;
|
|
76
|
+
budgetUsd: number;
|
|
77
|
+
}): Promise<{
|
|
78
|
+
id: string;
|
|
79
|
+
capability: string;
|
|
80
|
+
}>;
|
|
81
|
+
cancelSession(sessionId: string): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
/** Plain capabilities live only for the short provisioning window. */
|
|
84
|
+
export declare class RunCapabilityVault {
|
|
85
|
+
private readonly values;
|
|
86
|
+
set(runId: string, capability: string): void;
|
|
87
|
+
get(runId: string): Promise<string>;
|
|
88
|
+
delete(runId: string): void;
|
|
89
|
+
}
|
|
90
|
+
export interface ContainerExecutorOptions {
|
|
91
|
+
store: ContainerExecutionStore;
|
|
92
|
+
jobs: WorkspaceJobLauncher;
|
|
93
|
+
vcs: VcsProvider;
|
|
94
|
+
sessions: CodingSessionController;
|
|
95
|
+
capabilities: RunCapabilityVault;
|
|
96
|
+
artifactRoot: string;
|
|
97
|
+
workerImage: string;
|
|
98
|
+
/** Additional toolchains beyond the "node" baseline (workerImage). Keyed by toolchain, then version. */
|
|
99
|
+
additionalWorkerImages?: Record<string, Record<string, string>>;
|
|
100
|
+
credentialRef: string;
|
|
101
|
+
claudeWorkerImage?: string;
|
|
102
|
+
claudeToolRunnerImage?: string;
|
|
103
|
+
anthropicCredentialRef?: string;
|
|
104
|
+
limits: JobResourceLimits;
|
|
105
|
+
/** Operator ceiling (MiB) on CodingRun.workspaceDiskMb; see coding_workspace_disk_exceeds_limit in jobSpec. */
|
|
106
|
+
maxDiskMb: number;
|
|
107
|
+
pollMinMs?: number;
|
|
108
|
+
pollMaxMs?: number;
|
|
109
|
+
/** How often to beat the heartbeat during a long launch; defaults to a third of the reconciler's timeout. */
|
|
110
|
+
heartbeatIntervalMs?: number;
|
|
111
|
+
sleep?: (milliseconds: number) => Promise<void>;
|
|
112
|
+
now?: () => Date;
|
|
113
|
+
observer?: CodingRunObserver;
|
|
114
|
+
/**
|
|
115
|
+
* Called after a run this process executed reaches a terminal status,
|
|
116
|
+
* so a waiting run can take the freed concurrency slot right away rather
|
|
117
|
+
* than on the next scheduler tick. Never called for a run that was queued.
|
|
118
|
+
*/
|
|
119
|
+
onSlotReleased?: () => void;
|
|
120
|
+
}
|
|
121
|
+
export declare class ContainerExecutor implements Executor {
|
|
122
|
+
private readonly options;
|
|
123
|
+
private readonly artifactRoot;
|
|
124
|
+
private readonly active;
|
|
125
|
+
private readonly sleep;
|
|
126
|
+
private readonly now;
|
|
127
|
+
private readonly observer;
|
|
128
|
+
private readonly startedAt;
|
|
129
|
+
constructor(options: ContainerExecutorOptions);
|
|
130
|
+
start(runId: string): Promise<void>;
|
|
131
|
+
stop(runId: string, reason?: string): Promise<void>;
|
|
132
|
+
recover(handle: PersistedExecutionHandle): Promise<ExecutionRecoveryResult>;
|
|
133
|
+
private execute;
|
|
134
|
+
/**
|
|
135
|
+
* Runs `work` while keeping the run's heartbeat fresh.
|
|
136
|
+
*
|
|
137
|
+
* `jobs.launch` is one long await that legitimately takes minutes on a real
|
|
138
|
+
* cluster — the pod cannot be scheduled until an autoscaler has created a node
|
|
139
|
+
* for it — and nothing inside it beats the heartbeat. Meanwhile the reconciler
|
|
140
|
+
* sweeps any run whose heartbeat is older than HEARTBEAT_TIMEOUT_MS and
|
|
141
|
+
* declares it lost, which deletes the job out from under the launch that is
|
|
142
|
+
* still running. The launch then fails on its own pod having vanished, so a
|
|
143
|
+
* single healthy run produces two failures and neither names the real cause.
|
|
144
|
+
*
|
|
145
|
+
* Measured on GKE Autopilot (2026-09-23): a scheduled run whose pod was
|
|
146
|
+
* waiting on a cold gVisor node pool was declared lost at exactly 60s, and the
|
|
147
|
+
* launch it had interrupted failed 32s later with
|
|
148
|
+
* `kubernetes_isolation_unsupported:timeout`. This never appeared on kind,
|
|
149
|
+
* where a pod is scheduled in seconds and the heartbeat gap stays well inside
|
|
150
|
+
* the timeout. The gap is what is wrong, not the timeout: a run that is
|
|
151
|
+
* provisioning IS alive, and the executor is the only thing that knows it.
|
|
152
|
+
*
|
|
153
|
+
* Failures to beat are swallowed on purpose. A missed beat costs at worst the
|
|
154
|
+
* recovery this exists to prevent, while throwing here would fail a launch
|
|
155
|
+
* that is otherwise healthy.
|
|
156
|
+
*/
|
|
157
|
+
private whileHeartbeating;
|
|
158
|
+
private preflight;
|
|
159
|
+
private finishTerminal;
|
|
160
|
+
private resultFor;
|
|
161
|
+
resolveCodingWorkerImage(selector: CodingImageSelector): string;
|
|
162
|
+
private requireCurrent;
|
|
163
|
+
private jobSpec;
|
|
164
|
+
private credentialRef;
|
|
165
|
+
private writeInput;
|
|
166
|
+
private artifactPath;
|
|
167
|
+
private preflightForCleanup;
|
|
168
|
+
private abandon;
|
|
169
|
+
private cleanupTerminal;
|
|
170
|
+
private emit;
|
|
171
|
+
private terminal;
|
|
172
|
+
/**
|
|
173
|
+
* `cancelled` is passed by the one caller that knows — stop(). It is never
|
|
174
|
+
* inferred from the message: `failureCategory` substring-matches, and
|
|
175
|
+
* "cancel"/"Canceled" is routine phrasing in gRPC, Kubernetes, Docker and
|
|
176
|
+
* aborted-HTTP errors ("rpc error: code = Canceled desc = context canceled"),
|
|
177
|
+
* so inferring it would silence exactly the genuine failures this log exists
|
|
178
|
+
* to surface.
|
|
179
|
+
*/
|
|
180
|
+
private failure;
|
|
181
|
+
private duration;
|
|
182
|
+
}
|
|
183
|
+
/** Operator-facing failure text: the message plus its cause chain, redacted. */
|
|
184
|
+
export declare function describeFailure(error: unknown, depth?: number): string;
|