@wardby/cli 0.2.1 → 0.4.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 +53 -4
- package/README.md +52 -13
- package/dist/claude-coding-worker/driver.d.ts +6 -1
- package/dist/claude-coding-worker/driver.js +27 -1
- package/dist/claude-coding-worker/main.js +2 -0
- package/dist/claude-coding-worker/tool-socket.d.ts +9 -0
- package/dist/claude-coding-worker/tool-socket.js +26 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +14 -4
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +284 -36
- package/dist/coding/base-commit.d.ts +6 -0
- package/dist/coding/base-commit.js +12 -0
- package/dist/coding/collect-exclude.d.ts +25 -0
- package/dist/coding/collect-exclude.js +76 -0
- package/dist/coding/profile.d.ts +67 -22
- package/dist/coding/profile.js +58 -25
- package/dist/coding/protected-path-wording.d.ts +24 -0
- package/dist/coding/protected-path-wording.js +55 -0
- package/dist/coding/protected-paths.d.ts +31 -0
- package/dist/coding/protected-paths.js +48 -0
- package/dist/coding/protocol.d.ts +91 -4
- package/dist/coding/protocol.js +123 -12
- package/dist/coding/provider.d.ts +6 -1
- package/dist/coding/provider.js +16 -9
- package/dist/coding/registry/adapters.d.ts +2 -0
- package/dist/coding/registry/adapters.js +9 -0
- package/dist/coding/registry/allowlist.d.ts +9 -0
- package/dist/coding/registry/allowlist.js +28 -0
- package/dist/coding/registry/json-scan.d.ts +55 -0
- package/dist/coding/registry/json-scan.js +191 -0
- package/dist/coding/registry/lockfiles.d.ts +6 -0
- package/dist/coding/registry/lockfiles.js +89 -0
- package/dist/coding/registry/npm-lockfile.d.ts +9 -0
- package/dist/coding/registry/npm-lockfile.js +73 -0
- package/dist/coding/registry/npm-plan.d.ts +29 -0
- package/dist/coding/registry/npm-plan.js +289 -0
- package/dist/coding/registry/npm.d.ts +7 -0
- package/dist/coding/registry/npm.js +252 -0
- package/dist/coding/registry/pypi.d.ts +4 -0
- package/dist/coding/registry/pypi.js +210 -0
- package/dist/coding/registry/report.d.ts +37 -0
- package/dist/coding/registry/report.js +31 -0
- package/dist/coding/registry/token.d.ts +4 -0
- package/dist/coding/registry/token.js +7 -0
- package/dist/coding/registry/types.d.ts +286 -0
- package/dist/coding/registry/types.js +19 -0
- package/dist/coding/registry/worker-config.d.ts +14 -0
- package/dist/coding/registry/worker-config.js +31 -0
- package/dist/coding/services/builtins.d.ts +22 -0
- package/dist/coding/services/builtins.js +85 -0
- package/dist/coding/services/catalog.d.ts +443 -0
- package/dist/coding/services/catalog.js +159 -0
- package/dist/coding/services/declaration.d.ts +11 -0
- package/dist/coding/services/declaration.js +114 -0
- package/dist/coding/services/note.d.ts +8 -0
- package/dist/coding/services/note.js +15 -0
- package/dist/coding/services/resolve.d.ts +25 -0
- package/dist/coding/services/resolve.js +50 -0
- package/dist/coding/services/wording.d.ts +25 -0
- package/dist/coding/services/wording.js +70 -0
- package/dist/coding-proxy/main.js +24 -4
- package/dist/coding-worker/artifact.d.ts +6 -0
- package/dist/coding-worker/debug-trace.d.ts +37 -0
- package/dist/coding-worker/debug-trace.js +117 -0
- package/dist/coding-worker/driver.d.ts +13 -1
- package/dist/coding-worker/driver.js +102 -13
- package/dist/coding-worker/errors.js +8 -0
- package/dist/coding-worker/main.js +10 -2
- package/dist/coding-worker/sdk.d.ts +2 -2
- package/dist/coding-worker/sdk.js +7 -2
- package/dist/coding-worker/types.d.ts +3 -0
- package/dist/config/providers.d.ts +66 -0
- package/dist/config/providers.js +137 -0
- package/dist/core/attribution.d.ts +101 -0
- package/dist/core/attribution.js +208 -0
- package/dist/core/budget-groups.d.ts +120 -10
- package/dist/core/budget-groups.js +133 -24
- package/dist/core/budget-wording.d.ts +22 -0
- package/dist/core/budget-wording.js +55 -0
- package/dist/core/coding-queue.d.ts +3 -0
- package/dist/core/coding-queue.js +6 -2
- package/dist/core/coding-service-status.d.ts +11 -0
- package/dist/core/coding-service-status.js +17 -0
- package/dist/core/cost-report.d.ts +88 -0
- package/dist/core/cost-report.js +248 -0
- package/dist/core/datastores.js +18 -2
- package/dist/core/db.d.ts +5 -1
- package/dist/core/db.js +8 -2
- package/dist/core/dispatch.d.ts +74 -7
- package/dist/core/dispatch.js +382 -47
- package/dist/core/engine-native.js +44 -14
- package/dist/core/glob.d.ts +10 -0
- package/dist/core/glob.js +33 -0
- package/dist/core/grants.d.ts +86 -0
- package/dist/core/grants.js +126 -0
- package/dist/core/host-events.d.ts +72 -0
- package/dist/core/host-events.js +597 -0
- package/dist/core/host-identity-links.d.ts +54 -0
- package/dist/core/host-identity-links.js +189 -0
- package/dist/core/host-status.d.ts +78 -0
- package/dist/core/host-status.js +228 -0
- package/dist/core/in-flight-runs.d.ts +8 -0
- package/dist/core/in-flight-runs.js +56 -0
- package/dist/core/issue-bridge.d.ts +60 -0
- package/dist/core/issue-bridge.js +189 -0
- package/dist/core/issue-dedupe.d.ts +70 -0
- package/dist/core/issue-dedupe.js +255 -0
- package/dist/core/issue-events.d.ts +42 -0
- package/dist/core/issue-events.js +155 -0
- package/dist/core/issue-status.d.ts +29 -0
- package/dist/core/issue-status.js +241 -0
- package/dist/core/issue-tracker-tools.d.ts +64 -0
- package/dist/core/issue-tracker-tools.js +850 -0
- package/dist/core/model-usage.d.ts +10 -0
- package/dist/core/model-usage.js +24 -0
- package/dist/core/provider-wording.d.ts +12 -0
- package/dist/core/provider-wording.js +44 -0
- package/dist/core/reconciler.d.ts +42 -2
- package/dist/core/reconciler.js +97 -2
- package/dist/core/repo-access.d.ts +99 -0
- package/dist/core/repo-access.js +136 -0
- package/dist/core/review-host-checks.d.ts +11 -0
- package/dist/core/review-host-checks.js +41 -0
- package/dist/core/review-host-tools.d.ts +47 -0
- package/dist/core/review-host-tools.js +354 -0
- package/dist/core/run-heartbeat.d.ts +27 -0
- package/dist/core/run-heartbeat.js +54 -0
- package/dist/core/run-pricing.d.ts +61 -0
- package/dist/core/run-pricing.js +56 -0
- package/dist/core/runner.d.ts +33 -8
- package/dist/core/runner.js +410 -62
- package/dist/core/scheduler.d.ts +4 -1
- package/dist/core/scheduler.js +3 -2
- package/dist/core/secrets.d.ts +11 -2
- package/dist/core/secrets.js +25 -6
- package/dist/core/self-defects.d.ts +80 -0
- package/dist/core/self-defects.js +180 -0
- package/dist/core/subagent-memory-tools.d.ts +1 -1
- package/dist/core/subagent-memory-tools.js +16 -3
- package/dist/core/tool-admin.d.ts +81 -0
- package/dist/core/tool-admin.js +129 -0
- package/dist/core/tool-names.d.ts +42 -0
- package/dist/core/tool-names.js +67 -0
- package/dist/core/untrusted-content.d.ts +32 -0
- package/dist/core/untrusted-content.js +72 -0
- package/dist/core/webhooks.d.ts +17 -2
- package/dist/core/webhooks.js +42 -3
- package/dist/generated/prisma/browser.d.ts +166 -0
- package/dist/generated/prisma/client.d.ts +166 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +152 -52
- package/dist/generated/prisma/enums.d.ts +13 -0
- package/dist/generated/prisma/enums.js +12 -1
- package/dist/generated/prisma/internal/class.d.ts +242 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +2571 -577
- package/dist/generated/prisma/internal/prismaNamespace.js +312 -6
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +328 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +312 -6
- package/dist/generated/prisma/models/Agent.d.ts +682 -1
- package/dist/generated/prisma/models/AgentIssueProject.d.ts +1838 -0
- package/dist/generated/prisma/models/AgentIssueProject.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +1425 -0
- package/dist/generated/prisma/models/AgentRepository.js +1 -0
- package/dist/generated/prisma/models/AgentTool.d.ts +95 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +56 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +258 -7
- package/dist/generated/prisma/models/CodingProxySession.d.ts +195 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1405 -95
- package/dist/generated/prisma/models/CodingRunServiceStatus.d.ts +1404 -0
- package/dist/generated/prisma/models/CodingRunServiceStatus.js +1 -0
- package/dist/generated/prisma/models/CodingService.d.ts +1348 -0
- package/dist/generated/prisma/models/CodingService.js +1 -0
- package/dist/generated/prisma/models/HostEventDelivery.d.ts +946 -0
- package/dist/generated/prisma/models/HostEventDelivery.js +1 -0
- package/dist/generated/prisma/models/HostIdentity.d.ts +1232 -0
- package/dist/generated/prisma/models/HostIdentity.js +1 -0
- package/dist/generated/prisma/models/HostIdentityLinkRequest.d.ts +1473 -0
- package/dist/generated/prisma/models/HostIdentityLinkRequest.js +1 -0
- package/dist/generated/prisma/models/IssueFingerprint.d.ts +1183 -0
- package/dist/generated/prisma/models/IssueFingerprint.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +1255 -0
- package/dist/generated/prisma/models/IssuePullRequest.js +1 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.d.ts +1322 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.js +1 -0
- package/dist/generated/prisma/models/Principal.d.ts +455 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +1148 -0
- package/dist/generated/prisma/models/RegistryAllowance.js +1 -0
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +1219 -0
- package/dist/generated/prisma/models/RegistryApprovedVersion.js +1 -0
- package/dist/generated/prisma/models/RegistryFetch.d.ts +1428 -0
- package/dist/generated/prisma/models/RegistryFetch.js +1 -0
- package/dist/generated/prisma/models/RegistryPlanRefusal.d.ts +1294 -0
- package/dist/generated/prisma/models/RegistryPlanRefusal.js +1 -0
- package/dist/generated/prisma/models/RegistryVersionFact.d.ts +1085 -0
- package/dist/generated/prisma/models/RegistryVersionFact.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1437 -0
- package/dist/generated/prisma/models/ResourceGrant.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +1402 -82
- package/dist/generated/prisma/models/RunAttribution.d.ts +1259 -0
- package/dist/generated/prisma/models/RunAttribution.js +1 -0
- package/dist/generated/prisma/models/RunHostCheck.d.ts +1239 -0
- package/dist/generated/prisma/models/RunHostCheck.js +1 -0
- package/dist/generated/prisma/models/RunHostStatus.d.ts +1315 -0
- package/dist/generated/prisma/models/RunHostStatus.js +1 -0
- package/dist/generated/prisma/models/RunIssueStatus.d.ts +1199 -0
- package/dist/generated/prisma/models/RunIssueStatus.js +1 -0
- package/dist/generated/prisma/models/RunModelUsage.d.ts +1316 -0
- package/dist/generated/prisma/models/RunModelUsage.js +1 -0
- package/dist/generated/prisma/models/Tool.d.ts +15 -3
- package/dist/generated/prisma/models/WorkItem.d.ts +1408 -0
- package/dist/generated/prisma/models/WorkItem.js +1 -0
- package/dist/generated/prisma/models.d.ts +22 -0
- package/dist/help/build.d.ts +1 -0
- package/dist/help/build.js +9 -0
- package/dist/help/catalog.d.ts +24 -0
- package/dist/help/catalog.js +160 -0
- package/dist/help/cli.d.ts +2 -0
- package/dist/help/cli.js +65 -0
- package/dist/help/runtime.d.ts +3 -0
- package/dist/help/runtime.js +44 -0
- package/dist/help/search.d.ts +9 -0
- package/dist/help/search.js +104 -0
- package/dist/help-index.json +999 -0
- package/dist/import/cli-args.js +3 -2
- package/dist/import/create.d.ts +5 -0
- package/dist/import/create.js +67 -13
- package/dist/import/index.js +19 -9
- package/dist/import/neutral-schema.d.ts +18 -18
- package/dist/knowledge/check.d.ts +13 -0
- package/dist/knowledge/check.js +69 -0
- package/dist/knowledge/cli.d.ts +14 -0
- package/dist/knowledge/cli.js +67 -0
- package/dist/knowledge/concept.d.ts +54 -0
- package/dist/knowledge/concept.js +78 -0
- package/dist/knowledge/note.d.ts +11 -0
- package/dist/knowledge/note.js +39 -0
- package/dist/knowledge/relevance.d.ts +11 -0
- package/dist/knowledge/relevance.js +14 -0
- package/dist/knowledge/span-hash.d.ts +3 -0
- package/dist/knowledge/span-hash.js +16 -0
- package/dist/mcp/auth/access.d.ts +72 -0
- package/dist/mcp/auth/access.js +58 -0
- package/dist/mcp/auth/grants-cli.d.ts +149 -0
- package/dist/mcp/auth/grants-cli.js +518 -0
- package/dist/mcp/auth/host-account-cli.d.ts +2 -0
- package/dist/mcp/auth/host-account-cli.js +47 -0
- package/dist/mcp/auth/ownership.d.ts +25 -51
- package/dist/mcp/auth/ownership.js +19 -14
- package/dist/mcp/auth/repo-authorization.d.ts +22 -0
- package/dist/mcp/auth/repo-authorization.js +51 -0
- package/dist/mcp/auth/resource-server.d.ts +33 -2
- package/dist/mcp/auth/resource-server.js +99 -3
- package/dist/mcp/auth/self-hosted/browser.js +2 -2
- package/dist/mcp/auth/self-hosted/cli.js +47 -13
- package/dist/mcp/auth/self-hosted/credentials.d.ts +23 -5
- package/dist/mcp/auth/self-hosted/credentials.js +62 -4
- package/dist/mcp/auth/self-hosted/session.d.ts +7 -6
- package/dist/mcp/context.d.ts +30 -1
- package/dist/mcp/errors.d.ts +25 -6
- package/dist/mcp/errors.js +98 -0
- package/dist/mcp/host-events/deliveries.d.ts +9 -0
- package/dist/mcp/host-events/deliveries.js +17 -0
- package/dist/mcp/host-events/github-ingress.d.ts +38 -0
- package/dist/mcp/host-events/github-ingress.js +83 -0
- package/dist/mcp/host-events/github-user-callback.d.ts +18 -0
- package/dist/mcp/host-events/github-user-callback.js +50 -0
- package/dist/mcp/host-events/jira-ingress.d.ts +29 -0
- package/dist/mcp/host-events/jira-ingress.js +92 -0
- package/dist/mcp/index.d.ts +10 -1
- package/dist/mcp/index.js +187 -19
- package/dist/mcp/server.js +32 -11
- package/dist/mcp/tools/agents.js +519 -50
- package/dist/mcp/tools/budget-groups.js +3 -3
- package/dist/mcp/tools/cost-report.d.ts +8 -0
- package/dist/mcp/tools/cost-report.js +60 -0
- package/dist/mcp/tools/datastore.js +22 -15
- package/dist/mcp/tools/grants.d.ts +2 -0
- package/dist/mcp/tools/grants.js +239 -0
- package/dist/mcp/tools/help.d.ts +5 -0
- package/dist/mcp/tools/help.js +67 -0
- package/dist/mcp/tools/host-accounts.d.ts +2 -0
- package/dist/mcp/tools/host-accounts.js +114 -0
- package/dist/mcp/tools/issue-projects.d.ts +2 -0
- package/dist/mcp/tools/issue-projects.js +238 -0
- package/dist/mcp/tools/memory.d.ts +7 -1
- package/dist/mcp/tools/memory.js +5 -5
- package/dist/mcp/tools/model-catalog.d.ts +22 -0
- package/dist/mcp/tools/model-catalog.js +423 -0
- package/dist/mcp/tools/repositories.d.ts +2 -0
- package/dist/mcp/tools/repositories.js +182 -0
- package/dist/mcp/tools/runs.d.ts +6 -0
- package/dist/mcp/tools/runs.js +60 -6
- package/dist/mcp/tools/scheduling.js +3 -6
- package/dist/mcp/tools/secrets.js +18 -6
- package/dist/mcp/tools/services.d.ts +2 -0
- package/dist/mcp/tools/services.js +222 -0
- package/dist/mcp/tools/subagents.js +52 -16
- package/dist/mcp/tools/tools.d.ts +41 -0
- package/dist/mcp/tools/tools.js +201 -40
- package/dist/mcp/tools/trigger.js +65 -7
- package/dist/mcp/tools/webhooks.js +15 -4
- package/dist/mcp/transport/streamable-http.d.ts +15 -0
- package/dist/mcp/transport/streamable-http.js +55 -3
- package/dist/mcp/webhooks/ingress.d.ts +2 -1
- package/dist/mcp/webhooks/ingress.js +9 -2
- package/dist/providers/auth/delegating.d.ts +19 -0
- package/dist/providers/auth/delegating.js +71 -0
- package/dist/providers/auth/index.d.ts +2 -0
- package/dist/providers/auth/index.js +11 -0
- package/dist/providers/auth/self-hosted.d.ts +10 -2
- package/dist/providers/auth/self-hosted.js +55 -6
- package/dist/providers/auth/types.d.ts +6 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +4 -1
- package/dist/providers/coding-proxy/memory-ledger.js +31 -3
- package/dist/providers/coding-proxy/metering.d.ts +6 -1
- package/dist/providers/coding-proxy/metering.js +41 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +17 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +106 -8
- package/dist/providers/coding-proxy/proxy.d.ts +25 -2
- package/dist/providers/coding-proxy/proxy.js +561 -38
- package/dist/providers/coding-proxy/registry/audit.d.ts +131 -0
- package/dist/providers/coding-proxy/registry/audit.js +380 -0
- package/dist/providers/coding-proxy/registry/bounded-fetch.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/bounded-fetch.js +77 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +58 -0
- package/dist/providers/coding-proxy/registry/plan.js +304 -0
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +34 -0
- package/dist/providers/coding-proxy/registry/prisma-store.js +151 -0
- package/dist/providers/coding-proxy/registry/service.d.ts +213 -0
- package/dist/providers/coding-proxy/registry/service.js +1137 -0
- package/dist/providers/coding-proxy/registry/store.d.ts +127 -0
- package/dist/providers/coding-proxy/registry/store.js +70 -0
- package/dist/providers/coding-proxy/runtime.d.ts +17 -0
- package/dist/providers/coding-proxy/runtime.js +63 -0
- package/dist/providers/coding-proxy/secure-fetch.js +0 -1
- package/dist/providers/coding-proxy/server.d.ts +11 -0
- package/dist/providers/coding-proxy/server.js +163 -0
- package/dist/providers/coding-proxy/types.d.ts +33 -1
- package/dist/providers/coding-proxy/types.js +12 -1
- package/dist/providers/engine/types.d.ts +29 -0
- package/dist/providers/executor/build.d.ts +2 -2
- package/dist/providers/executor/composition.d.ts +3 -0
- package/dist/providers/executor/composition.js +28 -1
- package/dist/providers/executor/container.d.ts +134 -4
- package/dist/providers/executor/container.js +394 -37
- package/dist/providers/executor/dbos.d.ts +4 -3
- package/dist/providers/executor/dbos.js +7 -5
- package/dist/providers/executor/in-process.d.ts +2 -3
- package/dist/providers/executor/routing.d.ts +13 -0
- package/dist/providers/executor/routing.js +18 -0
- package/dist/providers/executor/types.d.ts +34 -0
- package/dist/providers/issue-tracker/adf.d.ts +31 -0
- package/dist/providers/issue-tracker/adf.js +181 -0
- package/dist/providers/issue-tracker/index.d.ts +5 -0
- package/dist/providers/issue-tracker/index.js +12 -0
- package/dist/providers/issue-tracker/jira-client.d.ts +41 -0
- package/dist/providers/issue-tracker/jira-client.js +151 -0
- package/dist/providers/issue-tracker/jira-events.d.ts +3 -0
- package/dist/providers/issue-tracker/jira-events.js +98 -0
- package/dist/providers/issue-tracker/jira.d.ts +116 -0
- package/dist/providers/issue-tracker/jira.js +502 -0
- package/dist/providers/issue-tracker/types.d.ts +269 -0
- package/dist/providers/issue-tracker/types.js +16 -0
- package/dist/providers/jobs/claude-tool-setup.d.ts +23 -0
- package/dist/providers/jobs/claude-tool-setup.js +50 -0
- package/dist/providers/jobs/collect-prune.d.ts +7 -0
- package/dist/providers/jobs/collect-prune.js +27 -0
- package/dist/providers/jobs/docker-isolation.d.ts +48 -3
- package/dist/providers/jobs/docker-isolation.js +213 -22
- package/dist/providers/jobs/docker-services.d.ts +35 -0
- package/dist/providers/jobs/docker-services.js +191 -0
- package/dist/providers/jobs/docker.d.ts +53 -2
- package/dist/providers/jobs/docker.js +307 -32
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +1 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +12 -3
- package/dist/providers/jobs/kubernetes-isolation.d.ts +17 -2
- package/dist/providers/jobs/kubernetes-isolation.js +238 -57
- package/dist/providers/jobs/kubernetes-platform.d.ts +10 -4
- package/dist/providers/jobs/kubernetes-platform.js +11 -5
- package/dist/providers/jobs/kubernetes-preflight.js +3 -0
- package/dist/providers/jobs/kubernetes.d.ts +24 -2
- package/dist/providers/jobs/kubernetes.js +153 -22
- package/dist/providers/jobs/service-state.d.ts +22 -0
- package/dist/providers/jobs/service-state.js +17 -0
- package/dist/providers/jobs/types.d.ts +18 -0
- package/dist/providers/llm/anthropic.d.ts +3 -3
- package/dist/providers/llm/anthropic.js +3 -5
- package/dist/providers/llm/bedrock.d.ts +3 -3
- package/dist/providers/llm/bedrock.js +3 -8
- package/dist/providers/llm/catalog-lookup.d.ts +10 -0
- package/dist/providers/llm/catalog-lookup.js +15 -0
- package/dist/providers/llm/catalog-shipped.d.ts +18 -0
- package/dist/providers/llm/catalog-shipped.js +197 -0
- package/dist/providers/llm/catalog-store.d.ts +58 -0
- package/dist/providers/llm/catalog-store.js +138 -0
- package/dist/providers/llm/catalog-types.d.ts +66 -0
- package/dist/providers/llm/catalog-types.js +64 -0
- package/dist/providers/llm/catalog.d.ts +61 -0
- package/dist/providers/llm/catalog.js +147 -0
- package/dist/providers/llm/claude-messages.d.ts +5 -1
- package/dist/providers/llm/claude-messages.js +1 -0
- package/dist/providers/llm/claude-provider.d.ts +10 -12
- package/dist/providers/llm/claude-provider.js +15 -6
- package/dist/providers/llm/index.d.ts +9 -6
- package/dist/providers/llm/index.js +8 -5
- package/dist/providers/llm/openai.d.ts +14 -5
- package/dist/providers/llm/openai.js +24 -14
- package/dist/providers/llm/pricing-core.d.ts +5 -3
- package/dist/providers/llm/registration.js +8 -12
- package/dist/providers/llm/routing.d.ts +21 -11
- package/dist/providers/llm/routing.js +47 -13
- package/dist/providers/llm/types.d.ts +12 -0
- package/dist/providers/llm/types.js +8 -1
- package/dist/providers/review-host/diff-lines.d.ts +16 -0
- package/dist/providers/review-host/diff-lines.js +59 -0
- package/dist/providers/review-host/github-events.d.ts +6 -0
- package/dist/providers/review-host/github-events.js +226 -0
- package/dist/providers/review-host/github-user-auth.d.ts +38 -0
- package/dist/providers/review-host/github-user-auth.js +128 -0
- package/dist/providers/review-host/github.d.ts +57 -0
- package/dist/providers/review-host/github.js +568 -0
- package/dist/providers/review-host/index.d.ts +12 -0
- package/dist/providers/review-host/index.js +30 -0
- package/dist/providers/review-host/review-format.d.ts +19 -0
- package/dist/providers/review-host/review-format.js +59 -0
- package/dist/providers/review-host/types.d.ts +309 -0
- package/dist/providers/review-host/types.js +24 -0
- package/dist/providers/vcs/git.d.ts +16 -6
- package/dist/providers/vcs/git.js +78 -34
- package/dist/providers/vcs/github.d.ts +94 -3
- package/dist/providers/vcs/github.js +223 -17
- package/dist/providers/vcs/types.d.ts +48 -4
- package/dist/quickstart/index.d.ts +2 -0
- package/dist/quickstart/index.js +36 -8
- package/dist/sandbox/fetch-policy.d.ts +20 -2
- package/dist/sandbox/fetch-policy.js +64 -3
- package/dist/sandbox/host-functions.d.ts +9 -1
- package/dist/sandbox/host-functions.js +12 -5
- package/dist/serve.js +8 -2
- package/dist/viewer/api-schema.d.ts +2757 -0
- package/dist/viewer/api-schema.js +165 -0
- package/dist/viewer/build-schemas.d.ts +2 -0
- package/dist/viewer/build-schemas.js +18 -0
- package/dist/viewer/event-bus.d.ts +38 -0
- package/dist/viewer/event-bus.js +232 -0
- package/dist/viewer/graph.d.ts +40 -0
- package/dist/viewer/graph.js +243 -0
- package/dist/viewer/http.d.ts +30 -0
- package/dist/viewer/http.js +133 -0
- package/dist/viewer/run-detail.d.ts +4 -0
- package/dist/viewer/run-detail.js +61 -0
- package/dist/wardby-bin.js +11 -0
- package/docs/README.md +40 -0
- package/docs/agent-recipes.md +383 -0
- package/docs/architecture-runtime.md +90 -0
- package/docs/assets/brand/wardby-icon-512.png +0 -0
- package/docs/assets/brand/wardby-icon.svg +16 -0
- package/docs/assets/brand/wardby-mascot-profile-512.png +0 -0
- package/docs/assets/brand/wardby-mascot.png +0 -0
- package/docs/assets/brand/wardby-mascot.svg +5 -0
- package/docs/assets/wardby-workflow.svg +106 -0
- package/docs/code-review-agents.md +508 -0
- package/docs/coding-agent-setup.md +175 -0
- package/docs/coding-packages.md +455 -0
- package/docs/coding-services.md +300 -0
- package/docs/coding-worker-byo-images.md +98 -0
- package/docs/coding-worker-isolation.md +1068 -0
- package/docs/getting-started-gke.md +632 -0
- package/docs/getting-started-identity-provider.md +319 -0
- package/docs/getting-started.md +147 -0
- package/docs/jira-agents.md +649 -0
- package/docs/knowledge.md +387 -0
- package/docs/models.md +221 -0
- package/docs/observability.md +53 -0
- package/docs/release-verification.md +66 -0
- package/docs/security-deployment.md +667 -0
- package/docs/viewer-api.md +142 -0
- package/help/admin-viewer.md +39 -0
- package/help/agent-recipes.md +173 -0
- package/help/architecture-agent.md +189 -0
- package/help/builder-agent.md +80 -0
- package/help/code-review-agents.md +37 -0
- package/help/coding-packages.md +31 -0
- package/help/coding-services.md +71 -0
- package/help/cost-attribution.md +67 -0
- package/help/creating-agents.md +90 -0
- package/help/deploy-gke.md +45 -0
- package/help/deployment-targets.md +39 -0
- package/help/errors/budget-group-exhausted.md +25 -0
- package/help/errors/docker-isolation-unsupported.md +26 -0
- package/help/errors/model-unavailable.md +63 -0
- package/help/errors/protected-path.md +45 -0
- package/help/errors/repo-access.md +27 -0
- package/help/errors/service-declaration-invalid.md +27 -0
- package/help/errors/service-declaration-unavailable.md +25 -0
- package/help/errors/service-launcher-unsupported.md +30 -0
- package/help/errors/service-not-allowed.md +27 -0
- package/help/errors/service-unknown.md +23 -0
- package/help/errors/service-unready.md +49 -0
- package/help/getting-started.md +32 -0
- package/help/github.md +48 -0
- package/help/identity-and-access.md +44 -0
- package/help/jira.md +135 -0
- package/help/knowledge.md +47 -0
- package/help/mcp.md +30 -0
- package/help/models.md +90 -0
- package/help/native-capabilities.md +30 -0
- package/help/observability.md +41 -0
- package/help/operating-agents.md +36 -0
- package/help/security.md +27 -0
- package/help/troubleshooting/budgets.md +32 -0
- package/help/troubleshooting/coding-workers.md +47 -0
- package/help/troubleshooting/repository-access.md +27 -0
- package/package.json +14 -3
- package/prisma/migrations/20260925010000_coding_collect_exclude/migration.sql +8 -0
- package/prisma/migrations/20260925015000_allowed_egress_default/migration.sql +8 -0
- package/prisma/migrations/20260925020000_coding_package_registry/migration.sql +55 -0
- package/prisma/migrations/20260925030000_tool_name_per_owner/migration.sql +11 -0
- package/prisma/migrations/20260926010000_run_trigger_host_event/migration.sql +7 -0
- package/prisma/migrations/20260926020000_code_review_hosts/migration.sql +53 -0
- package/prisma/migrations/20260926030000_auth_user_roles/migration.sql +9 -0
- package/prisma/migrations/20260926040000_agent_effort/migration.sql +6 -0
- package/prisma/migrations/20260926050000_registry_lockfile_plan/migration.sql +32 -0
- package/prisma/migrations/20260926050000_repo_access_authorization/migration.sql +82 -0
- package/prisma/migrations/20260926060000_registry_plan_refusal/migration.sql +19 -0
- package/prisma/migrations/20260926100000_registry_plan_refusal_published_at/migration.sql +5 -0
- package/prisma/migrations/20260926190000_run_host_status/migration.sql +18 -0
- package/prisma/migrations/20260926210000_run_host_status_at_dispatch/migration.sql +5 -0
- package/prisma/migrations/20260927010000_resource_grants/migration.sql +72 -0
- package/prisma/migrations/20260927020000_proxy_session_budget_exhausted/migration.sql +3 -0
- package/prisma/migrations/20260927030000_coding_debug_trace/migration.sql +4 -0
- package/prisma/migrations/20260927040000_proxy_session_upstream_failure/migration.sql +3 -0
- package/prisma/migrations/20260927050000_coding_run_services/migration.sql +74 -0
- package/prisma/migrations/20260928000000_coding_run_tool_image/migration.sql +5 -0
- package/prisma/migrations/20260930000000_jira_issue_projects/migration.sql +34 -0
- package/prisma/migrations/20261001000000_jira_phase2_allowlists/migration.sql +3 -0
- package/prisma/migrations/20261001010000_jira_link_types_allowlist/migration.sql +2 -0
- package/prisma/migrations/20261002000000_jira_coding_bridge/migration.sql +28 -0
- package/prisma/migrations/20261002010000_jira_issue_creation/migration.sql +25 -0
- package/prisma/migrations/20261003000000_issue_cost_attribution/migration.sql +56 -0
- package/prisma/migrations/20261003010000_coding_run_service_status/migration.sql +23 -0
- package/prisma/migrations/20261003020000_viewer_notify/migration.sql +54 -0
- package/prisma/migrations/20261003030000_viewer_notify_fixes/migration.sql +47 -0
- package/prisma/migrations/20261003040000_viewer_indexes/migration.sql +12 -0
- package/prisma/migrations/20261004000000_model_catalog/migration.sql +26 -0
- package/prisma/schema.prisma +663 -21
- package/dist/mcp/tools/models.d.ts +0 -8
- package/dist/mcp/tools/models.js +0 -15
- package/dist/providers/llm/pricing-anthropic.d.ts +0 -4
- package/dist/providers/llm/pricing-anthropic.js +0 -30
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +0 -12
- package/dist/providers/llm/pricing-bedrock-claude.js +0 -37
- package/dist/providers/llm/pricing.d.ts +0 -30
- package/dist/providers/llm/pricing.js +0 -74
|
@@ -29,20 +29,27 @@ import { finished } from "node:stream/promises";
|
|
|
29
29
|
import { createHash } from "node:crypto";
|
|
30
30
|
import { isIP } from "node:net";
|
|
31
31
|
import { logger } from "../../core/logger.js";
|
|
32
|
-
import { MAX_CODING_ARTIFACT_BYTES, parseCodingAgentOutputJson } from "../../coding/protocol.js";
|
|
32
|
+
import { MAX_CODING_ARTIFACT_BYTES, MAX_DEBUG_TRACE_LINE_BYTES, parseCodingAgentOutputJson, } from "../../coding/protocol.js";
|
|
33
33
|
import { CODING_PROXY_DENY_PORT, CODING_PROXY_PORT } from "./docker-isolation.js";
|
|
34
34
|
import { parseWorkerDiagnosticLine } from "./docker.js";
|
|
35
35
|
import { KubernetesAlreadyExistsError, KubernetesConflictError } from "./kubernetes-api.js";
|
|
36
|
-
import { ENFORCEMENT_PROBE_DENY_REACHABLE, ENFORCEMENT_PROBE_PROVEN, ENFORCEMENT_PROBE_DENY_REFUSED, ENFORCEMENT_PROBE_PROXY_UNREACHABLE, KEEPER_CONTAINER, KEEPER_SEEDED_MARKER, KUBERNETES_ISOLATION_ERROR, STORAGE_ROOT, WORKER_CONTAINER, assertRunNetworkPolicyMatches, assertRunPodMatches, buildCapabilitySecret, buildRunNetworkPolicy, buildRunPod, enforcementProbeScript, kubernetesRunNames, kubernetesRunNamesForToken, runLabels, validateKubernetesSpec, } from "./kubernetes-isolation.js";
|
|
36
|
+
import { ENFORCEMENT_PROBE_DENY_REACHABLE, ENFORCEMENT_PROBE_PROVEN, ENFORCEMENT_PROBE_DENY_REFUSED, ENFORCEMENT_PROBE_PROXY_UNREACHABLE, KEEPER_CONTAINER, KEEPER_SEEDED_MARKER, KUBERNETES_ISOLATION_ERROR, STORAGE_ROOT, TOOL_RUNNER_CONTAINER, WORKER_CONTAINER, assertRunNetworkPolicyMatches, assertRunPodMatches, buildCapabilitySecret, buildRunNetworkPolicy, buildRunPod, enforcementProbeScript, kubernetesRunNames, kubernetesRunNamesForToken, runLabels, serviceContainerName, validateKubernetesSpec, } from "./kubernetes-isolation.js";
|
|
37
|
+
import { claudeToolSetup } from "./claude-tool-setup.js";
|
|
37
38
|
import { readProxyWitness } from "./kubernetes-witness.js";
|
|
38
39
|
import { safeExtract } from "./safe-extract.js";
|
|
40
|
+
import { reportServiceState, } from "./service-state.js";
|
|
41
|
+
import { serviceUnreadyError } from "../../coding/services/wording.js";
|
|
39
42
|
import { replaceDirectoryFromStaging } from "./workspace-swap.js";
|
|
43
|
+
import { collectExclusions, normalizeCollectExclusions, tarExcludeArgs, } from "../../coding/collect-exclude.js";
|
|
40
44
|
const BACKEND = "kubernetes";
|
|
41
45
|
const RECORD_SCHEMA_VERSION = 1;
|
|
42
46
|
const RECORD_KEY = "record.json";
|
|
43
47
|
const STOP_GRACE_SECONDS = 10;
|
|
44
48
|
const DIAGNOSTIC_TAIL_LINES = 8;
|
|
45
|
-
|
|
49
|
+
// The API cuts the tail from its FRONT at limitBytes, so this must hold every
|
|
50
|
+
// tail line at full size: a debug-traced run writes lines of up to
|
|
51
|
+
// MAX_DEBUG_TRACE_LINE_BYTES just before its diagnostic line.
|
|
52
|
+
const DIAGNOSTIC_LIMIT_BYTES = DIAGNOSTIC_TAIL_LINES * MAX_DEBUG_TRACE_LINE_BYTES;
|
|
46
53
|
const MAX_WORKSPACE_ENTRIES = 100_000;
|
|
47
54
|
const MAX_RECORD_ATTEMPTS = 5;
|
|
48
55
|
const READY_POLL_MS = 250;
|
|
@@ -51,8 +58,17 @@ const DEFAULT_ENFORCEMENT_TIMEOUT_MS = 30_000;
|
|
|
51
58
|
const ENFORCEMENT_POLL_MS = 500;
|
|
52
59
|
/** Consecutive proven probes required (8787 reachable, 8788 blocked): one dropped SYN must not open the gate. */
|
|
53
60
|
const ENFORCEMENT_BLOCKED_STREAK = 3;
|
|
54
|
-
/**
|
|
55
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Default bound for one enforcement probe exec (the probe makes two sequential connects, so it
|
|
63
|
+
* gives up after at most 6 s of its own connect timeouts). Overridable per KubernetesJobConfig's
|
|
64
|
+
* `enforcementExecTimeoutMs` (KUBERNETES_ENFORCEMENT_EXEC_TIMEOUT_MS) — a resource-constrained
|
|
65
|
+
* keeper (e.g. a laptop `kind` cluster's default 250m CPU / 128Mi limit) can take noticeably
|
|
66
|
+
* longer than this to run even a healthy probe to completion. DEFAULT_ENFORCEMENT_TIMEOUT_MS
|
|
67
|
+
* above is exactly this default times ENFORCEMENT_BLOCKED_STREAK, which is not a coincidence: see
|
|
68
|
+
* the constructor, which derives the effective overall bound the same way from whichever exec
|
|
69
|
+
* timeout is actually configured, so the two never drift apart.
|
|
70
|
+
*/
|
|
71
|
+
const DEFAULT_ENFORCEMENT_EXEC_TIMEOUT_MS = 10_000;
|
|
56
72
|
/**
|
|
57
73
|
* What the gate reports at its bound, by the last probe's exit code. Each names a different place
|
|
58
74
|
* to look, and each carries the reason in its own message rather than in the documentation: an
|
|
@@ -141,6 +157,29 @@ const FATAL_WAITING_REASONS = new Set([
|
|
|
141
157
|
"CreateContainerError",
|
|
142
158
|
"CrashLoopBackOff",
|
|
143
159
|
]);
|
|
160
|
+
const IMAGE_WAITING_REASONS = new Set(["ErrImagePull", "ImagePullBackOff", "InvalidImageName"]);
|
|
161
|
+
/**
|
|
162
|
+
* A service sidecar's start-up state as the pod status shows it. The kubelet runs the startup
|
|
163
|
+
* probe, so attempt counts are unknown here; checks mirror waitForKeeper's own failure rules.
|
|
164
|
+
*/
|
|
165
|
+
function observedServiceState(status) {
|
|
166
|
+
if (status === undefined)
|
|
167
|
+
return { state: "pending" };
|
|
168
|
+
if ((status.restartCount ?? 0) > 0)
|
|
169
|
+
return { state: "failed", reason: "probe_failed" };
|
|
170
|
+
const waiting = status.state?.waiting?.reason ?? "";
|
|
171
|
+
if (IMAGE_WAITING_REASONS.has(waiting))
|
|
172
|
+
return { state: "failed", reason: "image_unavailable" };
|
|
173
|
+
if (FATAL_WAITING_REASONS.has(waiting))
|
|
174
|
+
return { state: "failed", reason: "start_failed" };
|
|
175
|
+
if (status.state?.terminated !== undefined)
|
|
176
|
+
return { state: "failed", reason: "exited" };
|
|
177
|
+
if (status.started === true)
|
|
178
|
+
return { state: "ready" };
|
|
179
|
+
if (status.state?.running !== undefined)
|
|
180
|
+
return { state: "probing" };
|
|
181
|
+
return { state: "pending" };
|
|
182
|
+
}
|
|
144
183
|
const CAPABILITY = /^rrp_[A-Za-z0-9_-]{16,512}$/;
|
|
145
184
|
const TOKEN = /^[a-f0-9]{20}$/;
|
|
146
185
|
const WORKSPACE_STORAGE = `${STORAGE_ROOT}/workspace`;
|
|
@@ -224,6 +263,11 @@ function exitedCleanlyInTime(pod, finishedAt, deadlineAt) {
|
|
|
224
263
|
const finished = new Date(finishedAt).getTime();
|
|
225
264
|
return Number.isFinite(finished) && finished <= deadlineAt + FINISHED_AT_SKEW_MS;
|
|
226
265
|
}
|
|
266
|
+
/** A Claude run's tool runner that restarted or exited: its socket (and any in-flight command) is gone. */
|
|
267
|
+
function toolRunnerFailed(statuses) {
|
|
268
|
+
const tool = statuses?.find((status) => status.name === TOOL_RUNNER_CONTAINER);
|
|
269
|
+
return tool !== undefined && ((tool.restartCount ?? 0) > 0 || tool.state?.terminated !== undefined);
|
|
270
|
+
}
|
|
227
271
|
/** Maps a pod read-back onto the next record state; `undefined` means "no change". Never called for terminal records. */
|
|
228
272
|
function observePod(pod, record, now, readyTimeoutMs) {
|
|
229
273
|
if (!pod) {
|
|
@@ -242,6 +286,16 @@ function observePod(pod, record, now, readyTimeoutMs) {
|
|
|
242
286
|
if (now >= record.deadlineAt || pod.status?.reason === "DeadlineExceeded") {
|
|
243
287
|
return { phase: "failed", result: { exitCode: 124, reason: "timed_out" }, deleteGraceSeconds: STOP_GRACE_SECONDS };
|
|
244
288
|
}
|
|
289
|
+
// Docker's worker_tool_runner_failed, for the same reason: without its tool runner a Claude worker
|
|
290
|
+
// can only stall until the deadline. Checked only while the worker still runs, so a clean finish
|
|
291
|
+
// (checked above) or the pod's own teardown never reads as a tool-runner failure.
|
|
292
|
+
if (!terminated && toolRunnerFailed(pod.status?.initContainerStatuses)) {
|
|
293
|
+
return {
|
|
294
|
+
phase: "failed",
|
|
295
|
+
result: { exitCode: 1, reason: "failed", diagnostic: "worker_tool_runner_failed" },
|
|
296
|
+
deleteGraceSeconds: STOP_GRACE_SECONDS,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
245
299
|
if (terminated) {
|
|
246
300
|
// An exit 0 that failed the guard above (pod being deleted, no usable finish time) is not a success.
|
|
247
301
|
if (terminated.exitCode === 0)
|
|
@@ -328,6 +382,7 @@ export class KubernetesJobLauncher {
|
|
|
328
382
|
createArchive;
|
|
329
383
|
warn;
|
|
330
384
|
enforcementTimeoutMs;
|
|
385
|
+
enforcementExecTimeoutMs;
|
|
331
386
|
preflightResult;
|
|
332
387
|
constructor(options) {
|
|
333
388
|
this.options = options;
|
|
@@ -339,10 +394,24 @@ export class KubernetesJobLauncher {
|
|
|
339
394
|
this.now = options.now ?? Date.now;
|
|
340
395
|
this.sleep = options.sleep ?? ((ms) => new Promise((resolvePromise) => setTimeout(resolvePromise, ms)));
|
|
341
396
|
this.readyTimeoutMs = options.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS;
|
|
342
|
-
this.
|
|
397
|
+
this.enforcementExecTimeoutMs = options.enforcementExecTimeoutMs ?? DEFAULT_ENFORCEMENT_EXEC_TIMEOUT_MS;
|
|
398
|
+
// Never less than a full blocked-streak's worth of worst-case probes: a longer configured exec
|
|
399
|
+
// timeout that left this unchanged could make the wall-clock bound expire before the loop ever
|
|
400
|
+
// has a chance to observe ENFORCEMENT_BLOCKED_STREAK consecutive probes, which would turn "the
|
|
401
|
+
// keeper is just slow" into an indistinguishable "the policy is not enforced" false negative.
|
|
402
|
+
// DEFAULT_ENFORCEMENT_TIMEOUT_MS (30_000) already equals the default exec timeout times the
|
|
403
|
+
// streak (10_000 * 3), so this is a no-op unless a longer exec timeout is actually configured.
|
|
404
|
+
this.enforcementTimeoutMs = Math.max(options.enforcementTimeoutMs ?? DEFAULT_ENFORCEMENT_TIMEOUT_MS, this.enforcementExecTimeoutMs * ENFORCEMENT_BLOCKED_STREAK);
|
|
343
405
|
this.createArchive = options.createArchive ?? hostTarArchive;
|
|
344
406
|
this.warn = options.onWarning ?? ((message) => kubernetesLog.warn(message));
|
|
345
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Services run as native sidecars in the run pod (kubernetes-isolation.ts), for either provider:
|
|
410
|
+
* Claude Code's tool runner is a sidecar in the same pod, so it reaches them on 127.0.0.1 too.
|
|
411
|
+
*/
|
|
412
|
+
supportsServicesFor(provider) {
|
|
413
|
+
return provider === "codex" || provider === "claude-code";
|
|
414
|
+
}
|
|
346
415
|
/**
|
|
347
416
|
* Every per-run object name derives from the run id, so the handle is known before any cluster call.
|
|
348
417
|
* The executor persists it first; a crash mid-launch then still has a handle to clean up with (the
|
|
@@ -359,7 +428,19 @@ export class KubernetesJobLauncher {
|
|
|
359
428
|
}
|
|
360
429
|
}
|
|
361
430
|
async launch(spec) {
|
|
362
|
-
|
|
431
|
+
try {
|
|
432
|
+
validateKubernetesSpec(spec);
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
// The thrown error already carries the real reason (e.g.
|
|
436
|
+
// "kubernetes_isolation_unsupported:image-not-registry-digest") and is rethrown unchanged;
|
|
437
|
+
// this only makes that reason visible to an operator watching logs before the caller (which
|
|
438
|
+
// may only surface the top-level error code) does anything with it. Nothing here is derived
|
|
439
|
+
// from spec content beyond that fixed reason tag — no image reference, no limit value.
|
|
440
|
+
if (error instanceof Error)
|
|
441
|
+
this.warn(`kubernetes_spec_rejected: ${error.message}`);
|
|
442
|
+
throw error;
|
|
443
|
+
}
|
|
363
444
|
await this.runPreflight();
|
|
364
445
|
const names = kubernetesRunNames(spec.runId);
|
|
365
446
|
const handle = { backend: BACKEND, id: `${this.namespace}/${names.token}` };
|
|
@@ -376,6 +457,7 @@ export class KubernetesJobLauncher {
|
|
|
376
457
|
createdAt,
|
|
377
458
|
deadlineAt: createdAt + spec.timeoutSec * 1000,
|
|
378
459
|
phase: "provisioning",
|
|
460
|
+
collectExclude: spec.collectExclude ?? collectExclusions([]),
|
|
379
461
|
};
|
|
380
462
|
try {
|
|
381
463
|
// The record is the idempotency fence before any other cluster side effect.
|
|
@@ -454,7 +536,9 @@ export class KubernetesJobLauncher {
|
|
|
454
536
|
throw new Error("kubernetes_workspace_destination_invalid");
|
|
455
537
|
}
|
|
456
538
|
const maxBytes = record.diskMb * 1024 * 1024;
|
|
457
|
-
await replaceDirectoryFromStaging(expected, maxBytes, "kubernetes_workspace_destination_invalid", (staging) => this.extractWorkspace(names, staging, maxBytes, this.transferBudgetMs(record)
|
|
539
|
+
await replaceDirectoryFromStaging(expected, maxBytes, "kubernetes_workspace_destination_invalid", (staging) => this.extractWorkspace(names, staging, maxBytes, this.transferBudgetMs(record),
|
|
540
|
+
// Names are always the current built-in list; only the paths come from the record.
|
|
541
|
+
normalizeCollectExclusions(record.collectExclude?.paths)));
|
|
458
542
|
}
|
|
459
543
|
async stop(handle, _reason) {
|
|
460
544
|
const names = this.namesFor(handle);
|
|
@@ -532,7 +616,7 @@ export class KubernetesJobLauncher {
|
|
|
532
616
|
// `exitCode` is this iteration's probe, and the bound below is only ever reached from here —
|
|
533
617
|
// so the verdict is always the *last* probe's, never a remembered earlier one.
|
|
534
618
|
const exitCode = await this.api.exec(this.namespace, names.pod, KEEPER_CONTAINER, command, {
|
|
535
|
-
timeoutMs:
|
|
619
|
+
timeoutMs: this.enforcementExecTimeoutMs,
|
|
536
620
|
});
|
|
537
621
|
blocked = exitCode === 0 ? blocked + 1 : 0;
|
|
538
622
|
if (blocked >= ENFORCEMENT_BLOCKED_STREAK)
|
|
@@ -552,7 +636,7 @@ export class KubernetesJobLauncher {
|
|
|
552
636
|
return structuredClone(handle);
|
|
553
637
|
}
|
|
554
638
|
async provision(spec, names, record) {
|
|
555
|
-
const { runtimeClassName, proxyService, platform } = this.options.config;
|
|
639
|
+
const { runtimeClassName, priorityClassName, proxyService, platform } = this.options.config;
|
|
556
640
|
if (!runtimeClassName) {
|
|
557
641
|
this.warn("kubernetes_runtime_class_unset: no runtime class configured; coding pods run without gVisor (development clusters only)");
|
|
558
642
|
}
|
|
@@ -563,12 +647,19 @@ export class KubernetesJobLauncher {
|
|
|
563
647
|
// which is only meaningful against a Service that actually exposes it with a ready backend.
|
|
564
648
|
const witness = await readProxyWitness(this.api, this.namespace, proxyService);
|
|
565
649
|
const proxyIp = witness.clusterIp;
|
|
566
|
-
const pod = buildRunPod(spec, {
|
|
650
|
+
const pod = buildRunPod(spec, {
|
|
651
|
+
namespace: this.namespace,
|
|
652
|
+
proxyIp,
|
|
653
|
+
runtimeClassName,
|
|
654
|
+
priorityClassName,
|
|
655
|
+
platform,
|
|
656
|
+
});
|
|
567
657
|
const policy = buildRunNetworkPolicy(spec, this.namespace);
|
|
568
|
-
|
|
658
|
+
const toolSetup = spec.provider === "claude-code" ? claudeToolSetup(spec, capability) : undefined;
|
|
659
|
+
await this.createIfMissing(() => this.api.createSecret(this.namespace, buildCapabilitySecret(spec, this.namespace, capability, toolSetup)));
|
|
569
660
|
await this.createIfMissing(() => this.api.createNetworkPolicy(this.namespace, policy));
|
|
570
661
|
await this.createIfMissing(() => this.api.createPod(this.namespace, pod));
|
|
571
|
-
await this.waitForKeeper(names);
|
|
662
|
+
await this.waitForKeeper(names, spec.runId, (spec.services ?? []).map((service) => service.name), spec.provider === "claude-code");
|
|
572
663
|
const [actualPod, actualPolicy] = await Promise.all([
|
|
573
664
|
this.api.readPod(this.namespace, names.pod),
|
|
574
665
|
this.api.readNetworkPolicy(this.namespace, names.policy),
|
|
@@ -612,14 +703,41 @@ export class KubernetesJobLauncher {
|
|
|
612
703
|
throw error;
|
|
613
704
|
}
|
|
614
705
|
}
|
|
615
|
-
async waitForKeeper(names) {
|
|
706
|
+
async waitForKeeper(names, runId, serviceNames, toolRunner = false) {
|
|
616
707
|
const started = this.now();
|
|
708
|
+
const reported = new Map();
|
|
709
|
+
const report = async (name, observed) => {
|
|
710
|
+
const key = `${observed.state}:${observed.reason ?? ""}`;
|
|
711
|
+
if (reported.get(name) === key)
|
|
712
|
+
return;
|
|
713
|
+
reported.set(name, key);
|
|
714
|
+
await reportServiceState(this.options.onServiceState, { runId, name, ...observed });
|
|
715
|
+
};
|
|
617
716
|
for (;;) {
|
|
618
717
|
const pod = await this.api.readPod(this.namespace, names.pod);
|
|
619
718
|
if (!pod || pod.status?.phase === "Failed")
|
|
620
719
|
throw new Error("kubernetes_pod_start_failed");
|
|
621
720
|
const statuses = pod.status?.containerStatuses ?? [];
|
|
622
721
|
const initStatuses = pod.status?.initContainerStatuses ?? [];
|
|
722
|
+
const sidecar = (name) => initStatuses.find((status) => status.name === serviceContainerName(name));
|
|
723
|
+
for (const name of serviceNames)
|
|
724
|
+
await report(name, observedServiceState(sidecar(name)));
|
|
725
|
+
// A service sidecar that restarted (its startup probe gave up), can't be pulled or created, or
|
|
726
|
+
// exited will never let the keeper start. Name the service rather than a generic start failure.
|
|
727
|
+
const failedService = serviceNames.find((name) => {
|
|
728
|
+
const status = sidecar(name);
|
|
729
|
+
return (status !== undefined &&
|
|
730
|
+
((status.restartCount ?? 0) > 0 ||
|
|
731
|
+
FATAL_WAITING_REASONS.has(status.state?.waiting?.reason ?? "") ||
|
|
732
|
+
status.state?.terminated !== undefined));
|
|
733
|
+
});
|
|
734
|
+
if (failedService !== undefined)
|
|
735
|
+
throw serviceUnreadyError(failedService);
|
|
736
|
+
const toolStatus = initStatuses.find((status) => status.name === TOOL_RUNNER_CONTAINER);
|
|
737
|
+
if (toolRunner &&
|
|
738
|
+
(toolRunnerFailed(initStatuses) || FATAL_WAITING_REASONS.has(toolStatus?.state?.waiting?.reason ?? ""))) {
|
|
739
|
+
throw new Error("kubernetes_tool_runner_failed");
|
|
740
|
+
}
|
|
623
741
|
const keeper = statuses.find((status) => status.name === KEEPER_CONTAINER);
|
|
624
742
|
if ([...initStatuses, ...statuses].some((status) => FATAL_WAITING_REASONS.has(status.state?.waiting?.reason ?? "")) ||
|
|
625
743
|
// A failed init container (kubectl's Init:Error) or a keeper that already exited can never become ready.
|
|
@@ -627,10 +745,25 @@ export class KubernetesJobLauncher {
|
|
|
627
745
|
keeper?.state?.terminated !== undefined) {
|
|
628
746
|
throw new Error("kubernetes_pod_start_failed");
|
|
629
747
|
}
|
|
630
|
-
if (keeper?.ready === true)
|
|
748
|
+
if (keeper?.ready === true) {
|
|
749
|
+
// Native sidecars start in order before the keeper, so a ready keeper means every service started.
|
|
750
|
+
for (const name of serviceNames)
|
|
751
|
+
await report(name, { state: "ready" });
|
|
631
752
|
return;
|
|
632
|
-
|
|
753
|
+
}
|
|
754
|
+
if (this.now() - started >= this.readyTimeoutMs) {
|
|
755
|
+
if (toolRunner && toolStatus?.started !== true) {
|
|
756
|
+
throw new Error("kubernetes_tool_runner_unready");
|
|
757
|
+
}
|
|
758
|
+
// At the bound, a service that never passed its startup probe (still pulling, still starting)
|
|
759
|
+
// is why the keeper never started.
|
|
760
|
+
const waiting = serviceNames.find((name) => sidecar(name)?.started !== true);
|
|
761
|
+
if (waiting !== undefined) {
|
|
762
|
+
await report(waiting, { state: "failed", reason: "timed_out" });
|
|
763
|
+
throw serviceUnreadyError(waiting);
|
|
764
|
+
}
|
|
633
765
|
throw new Error("kubernetes_pod_start_timeout");
|
|
766
|
+
}
|
|
634
767
|
await this.sleep(READY_POLL_MS);
|
|
635
768
|
}
|
|
636
769
|
}
|
|
@@ -754,9 +887,10 @@ export class KubernetesJobLauncher {
|
|
|
754
887
|
* Streams the keeper's workspace through the strict extractor into `staging`.
|
|
755
888
|
* The transfer is bounded by `timeoutMs` (see transferBudgetMs): on expiry the
|
|
756
889
|
* extraction is aborted. On any failure the output stream this method created
|
|
757
|
-
* is destroyed, since the exec's own timeout does not end it.
|
|
890
|
+
* is destroyed, since the exec's own timeout does not end it. Excluded dependency
|
|
891
|
+
* and cache paths never leave the pod (see src/coding/collect-exclude.ts).
|
|
758
892
|
*/
|
|
759
|
-
async extractWorkspace(names, staging, maxBytes, timeoutMs) {
|
|
893
|
+
async extractWorkspace(names, staging, maxBytes, timeoutMs, exclusions) {
|
|
760
894
|
const output = new PassThrough();
|
|
761
895
|
// Errors are surfaced through the exec/extraction promises; never let a late destroy() crash the process.
|
|
762
896
|
output.on("error", () => undefined);
|
|
@@ -767,10 +901,7 @@ export class KubernetesJobLauncher {
|
|
|
767
901
|
signal: controller.signal,
|
|
768
902
|
});
|
|
769
903
|
const execution = this.api
|
|
770
|
-
.exec(this.namespace, names.pod, KEEPER_CONTAINER, ["tar", "-C", WORKSPACE_STORAGE, "-cf", "-", "."], {
|
|
771
|
-
stdout: output,
|
|
772
|
-
timeoutMs,
|
|
773
|
-
})
|
|
904
|
+
.exec(this.namespace, names.pod, KEEPER_CONTAINER, ["tar", "-C", WORKSPACE_STORAGE, ...tarExcludeArgs(exclusions), "-cf", "-", "."], { stdout: output, timeoutMs })
|
|
774
905
|
.then((exitCode) => {
|
|
775
906
|
if (exitCode !== 0)
|
|
776
907
|
throw new Error("kubernetes_workspace_archive_failed");
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Display-only observation of coding-run service start-up (docs/coding-services.md): launchers
|
|
3
|
+
* report each service's state as they see it, for the viewer. Never part of the launch's own
|
|
4
|
+
* control flow: a reporter error is swallowed. The launcher does await each report inline,
|
|
5
|
+
* though, so a reporter must be fast.
|
|
6
|
+
*/
|
|
7
|
+
export type ServiceState = "pending" | "probing" | "ready" | "failed";
|
|
8
|
+
/** Fixed identifiers only: never probe output, container logs, or anything from the repository. */
|
|
9
|
+
export type ServiceFailureReason = "image_unavailable" | "start_failed" | "exited" | "probe_failed" | "timed_out";
|
|
10
|
+
export interface ServiceStateUpdate {
|
|
11
|
+
runId: string;
|
|
12
|
+
/** The catalog service name (CodingService.name). */
|
|
13
|
+
name: string;
|
|
14
|
+
state: ServiceState;
|
|
15
|
+
/** Readiness probes completed so far; only launchers that run the probe themselves (Docker) know it. */
|
|
16
|
+
attempts?: number;
|
|
17
|
+
/** Set only with state "failed". */
|
|
18
|
+
reason?: ServiceFailureReason;
|
|
19
|
+
}
|
|
20
|
+
export type ServiceStateReporter = (update: ServiceStateUpdate) => Promise<void>;
|
|
21
|
+
/** Calls `reporter` if there is one; any error it throws is dropped (status is display-only). */
|
|
22
|
+
export declare function reportServiceState(reporter: ServiceStateReporter | undefined, update: ServiceStateUpdate): Promise<void>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Display-only observation of coding-run service start-up (docs/coding-services.md): launchers
|
|
3
|
+
* report each service's state as they see it, for the viewer. Never part of the launch's own
|
|
4
|
+
* control flow: a reporter error is swallowed. The launcher does await each report inline,
|
|
5
|
+
* though, so a reporter must be fast.
|
|
6
|
+
*/
|
|
7
|
+
/** Calls `reporter` if there is one; any error it throws is dropped (status is display-only). */
|
|
8
|
+
export async function reportServiceState(reporter, update) {
|
|
9
|
+
if (!reporter)
|
|
10
|
+
return;
|
|
11
|
+
try {
|
|
12
|
+
await reporter(update);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Display-only: a lost update must never fail or slow a launch.
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
* values are carried in a versioned input artifact, never expanded into an
|
|
4
4
|
* arbitrary environment map or shell command.
|
|
5
5
|
*/
|
|
6
|
+
import type { CodingProvider } from "../../coding/provider.js";
|
|
6
7
|
export interface JobResourceLimits {
|
|
7
8
|
cpus: number;
|
|
8
9
|
memoryMb: number;
|
|
9
10
|
pids: number;
|
|
10
11
|
diskMb: number;
|
|
11
12
|
}
|
|
13
|
+
import type { CollectExclusions } from "../../coding/collect-exclude.js";
|
|
14
|
+
import type { ResolvedCodingService } from "../../coding/services/catalog.js";
|
|
12
15
|
export interface JobSpec {
|
|
13
16
|
kind: "coding-agent";
|
|
14
17
|
runId: string;
|
|
@@ -21,6 +24,16 @@ export interface JobSpec {
|
|
|
21
24
|
timeoutSec: number;
|
|
22
25
|
limits: JobResourceLimits;
|
|
23
26
|
labels: Record<string, string>;
|
|
27
|
+
/** Workspace paths never collected; absent on legacy specs, which get the built-in names. */
|
|
28
|
+
collectExclude?: CollectExclusions;
|
|
29
|
+
/**
|
|
30
|
+
* Coding-run services (docs/coding-services.md): catalog snapshots resolved
|
|
31
|
+
* at dispatch, started next to the worker. Their images and environments come
|
|
32
|
+
* from the admin-managed catalog, never from repository content. Absent for
|
|
33
|
+
* a run without services (never an empty list), so such a spec, and its hash,
|
|
34
|
+
* is unchanged.
|
|
35
|
+
*/
|
|
36
|
+
services?: ResolvedCodingService[];
|
|
24
37
|
}
|
|
25
38
|
/** Opaque provider reference. Callers persist both fields exactly as given. */
|
|
26
39
|
export interface JobHandle {
|
|
@@ -77,4 +90,9 @@ export interface JobLauncher {
|
|
|
77
90
|
/** A launcher that can safely copy a terminal worker workspace back to trusted storage. */
|
|
78
91
|
export interface WorkspaceJobLauncher extends JobLauncher {
|
|
79
92
|
materializeWorkspace: (handle: JobHandle, destination: string) => Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Whether this launcher starts JobSpec.services for a run of `provider`: Kubernetes and Docker, for
|
|
95
|
+
* Codex and Claude Code. Absent means no services at all.
|
|
96
|
+
*/
|
|
97
|
+
supportsServicesFor?(provider: CodingProvider): boolean;
|
|
80
98
|
}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Direct Anthropic (Claude) adapter for the LlmProvider seam. `@anthropic-ai/sdk`
|
|
3
3
|
* is imported only here; all protocol/pricing-dispatch logic lives in the
|
|
4
4
|
* shared ClaudeLlmProvider base class (claude-provider.ts) — this file's only
|
|
5
|
-
* job is constructing the right client
|
|
5
|
+
* job is constructing the right client.
|
|
6
6
|
*/
|
|
7
7
|
import Anthropic from "@anthropic-ai/sdk";
|
|
8
8
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
9
|
-
|
|
9
|
+
import type { CatalogLookup } from "./catalog-lookup.js";
|
|
10
10
|
export declare function anthropicCredentialsPresent(env?: NodeJS.ProcessEnv): boolean;
|
|
11
11
|
export declare class AnthropicLlmProvider extends ClaudeLlmProvider {
|
|
12
|
-
constructor(apiKey?: string, client?: Anthropic);
|
|
12
|
+
constructor(apiKey?: string, client?: Anthropic, lookup?: CatalogLookup);
|
|
13
13
|
}
|
|
@@ -2,20 +2,18 @@
|
|
|
2
2
|
* Direct Anthropic (Claude) adapter for the LlmProvider seam. `@anthropic-ai/sdk`
|
|
3
3
|
* is imported only here; all protocol/pricing-dispatch logic lives in the
|
|
4
4
|
* shared ClaudeLlmProvider base class (claude-provider.ts) — this file's only
|
|
5
|
-
* job is constructing the right client
|
|
5
|
+
* job is constructing the right client.
|
|
6
6
|
*/
|
|
7
7
|
import Anthropic from "@anthropic-ai/sdk";
|
|
8
8
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
9
|
-
import { anthropicPriceUsd, getAnthropicPricing } from "./pricing-anthropic.js";
|
|
10
|
-
export { anthropicSupportedModels } from "./pricing-anthropic.js";
|
|
11
9
|
export function anthropicCredentialsPresent(env = process.env) {
|
|
12
10
|
return Boolean(env.ANTHROPIC_API_KEY);
|
|
13
11
|
}
|
|
14
12
|
export class AnthropicLlmProvider extends ClaudeLlmProvider {
|
|
15
|
-
constructor(apiKey = process.env.ANTHROPIC_API_KEY ?? "", client) {
|
|
13
|
+
constructor(apiKey = process.env.ANTHROPIC_API_KEY ?? "", client, lookup) {
|
|
16
14
|
if (!client && !apiKey) {
|
|
17
15
|
throw new Error("ANTHROPIC_API_KEY is not set — required by the Anthropic LlmProvider adapter.");
|
|
18
16
|
}
|
|
19
|
-
super(client ?? new Anthropic({ apiKey }),
|
|
17
|
+
super(client ?? new Anthropic({ apiKey }), lookup);
|
|
20
18
|
}
|
|
21
19
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* is imported only here; all protocol/pricing-dispatch logic lives in the
|
|
4
4
|
* shared ClaudeLlmProvider base class (claude-provider.ts) — AnthropicBedrock
|
|
5
5
|
* exposes the identical .messages.stream() surface as @anthropic-ai/sdk, so
|
|
6
|
-
* this file's only job is constructing the right client
|
|
6
|
+
* this file's only job is constructing the right client.
|
|
7
7
|
*
|
|
8
8
|
* Named BedrockClaudeLlmProvider, not BedrockLlmProvider: Bedrock hosts
|
|
9
9
|
* multiple model vendors, and this adapter only ever speaks the
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { AnthropicBedrock } from "@anthropic-ai/bedrock-sdk";
|
|
14
14
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
15
|
-
|
|
15
|
+
import type { CatalogLookup } from "./catalog-lookup.js";
|
|
16
16
|
export declare function bedrockCredentialsPresent(env?: NodeJS.ProcessEnv): boolean;
|
|
17
17
|
export declare class BedrockClaudeLlmProvider extends ClaudeLlmProvider {
|
|
18
|
-
constructor(region?: string, client?: AnthropicBedrock);
|
|
18
|
+
constructor(region?: string, client?: AnthropicBedrock, lookup?: CatalogLookup);
|
|
19
19
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* is imported only here; all protocol/pricing-dispatch logic lives in the
|
|
4
4
|
* shared ClaudeLlmProvider base class (claude-provider.ts) — AnthropicBedrock
|
|
5
5
|
* exposes the identical .messages.stream() surface as @anthropic-ai/sdk, so
|
|
6
|
-
* this file's only job is constructing the right client
|
|
6
|
+
* this file's only job is constructing the right client.
|
|
7
7
|
*
|
|
8
8
|
* Named BedrockClaudeLlmProvider, not BedrockLlmProvider: Bedrock hosts
|
|
9
9
|
* multiple model vendors, and this adapter only ever speaks the
|
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { AnthropicBedrock } from "@anthropic-ai/bedrock-sdk";
|
|
14
14
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
15
|
-
import { bedrockClaudePriceUsd, getBedrockClaudePricing } from "./pricing-bedrock-claude.js";
|
|
16
|
-
export { bedrockClaudeSupportedModels } from "./pricing-bedrock-claude.js";
|
|
17
15
|
export function bedrockCredentialsPresent(env = process.env) {
|
|
18
16
|
// A region is the one thing Bedrock always needs; AWS resolves actual
|
|
19
17
|
// credentials from the standard default chain (env keys, shared config,
|
|
@@ -21,13 +19,10 @@ export function bedrockCredentialsPresent(env = process.env) {
|
|
|
21
19
|
return Boolean(env.BEDROCK_REGION ?? env.AWS_REGION);
|
|
22
20
|
}
|
|
23
21
|
export class BedrockClaudeLlmProvider extends ClaudeLlmProvider {
|
|
24
|
-
constructor(region = process.env.BEDROCK_REGION ?? process.env.AWS_REGION ?? "", client) {
|
|
22
|
+
constructor(region = process.env.BEDROCK_REGION ?? process.env.AWS_REGION ?? "", client, lookup) {
|
|
25
23
|
if (!client && !region) {
|
|
26
24
|
throw new Error("BEDROCK_REGION (or AWS_REGION) is required by the Bedrock Claude LlmProvider adapter.");
|
|
27
25
|
}
|
|
28
|
-
super(client ?? new AnthropicBedrock({ awsRegion: region }),
|
|
29
|
-
getPricing: getBedrockClaudePricing,
|
|
30
|
-
priceUsd: bedrockClaudePriceUsd,
|
|
31
|
-
});
|
|
26
|
+
super(client ?? new AnthropicBedrock({ awsRegion: region }), lookup);
|
|
32
27
|
}
|
|
33
28
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How an adapter finds the catalog entry for a model. The default reads the
|
|
3
|
+
* process's current catalog; pinnedLookup binds an adapter to one run's
|
|
4
|
+
* stored entry. Kept apart from the store so adapters depend only on this.
|
|
5
|
+
*/
|
|
6
|
+
import { type CatalogEntry } from "./catalog-types.js";
|
|
7
|
+
/** Throws ModelUnavailableError for a model it does not serve. */
|
|
8
|
+
export type CatalogLookup = (model: string) => CatalogEntry;
|
|
9
|
+
export declare const currentLookup: CatalogLookup;
|
|
10
|
+
export declare function pinnedLookup(entry: CatalogEntry): CatalogLookup;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How an adapter finds the catalog entry for a model. The default reads the
|
|
3
|
+
* process's current catalog; pinnedLookup binds an adapter to one run's
|
|
4
|
+
* stored entry. Kept apart from the store so adapters depend only on this.
|
|
5
|
+
*/
|
|
6
|
+
import { ModelUnavailableError } from "./catalog-types.js";
|
|
7
|
+
import { currentModelCatalog } from "./catalog-store.js";
|
|
8
|
+
export const currentLookup = (model) => currentModelCatalog().require(model);
|
|
9
|
+
export function pinnedLookup(entry) {
|
|
10
|
+
return (model) => {
|
|
11
|
+
if (model !== entry.modelId)
|
|
12
|
+
throw new ModelUnavailableError(model, "not_in_catalog");
|
|
13
|
+
return entry;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model catalog wardby ships. Every entry is fully literal: rates are the
|
|
3
|
+
* provider's own published numbers for that exact model, never derived from
|
|
4
|
+
* another field (CLAUDE.md "LLM pricing tables — STRICT"). A deployment's
|
|
5
|
+
* admins override or extend this with ModelCatalogEntry rows (set_model);
|
|
6
|
+
* this file changes only with a wardby release, and SHIPPED_CATALOG_VERSION
|
|
7
|
+
* must be bumped whenever any value here changes.
|
|
8
|
+
*
|
|
9
|
+
* Anthropic and Bedrock rates are the 5-minute cache-TTL numbers
|
|
10
|
+
* (platform.claude.com/docs/en/about-claude/pricing): wardby only emits the
|
|
11
|
+
* default 5-minute cache_control breakpoint. OpenAI's pre-GPT-5.6 models have
|
|
12
|
+
* no distinct cache-write tier (a first-time prefix bills at the standard
|
|
13
|
+
* input rate), so their cacheWritePerMTok is their own input rate, stated
|
|
14
|
+
* literally.
|
|
15
|
+
*/
|
|
16
|
+
import type { CatalogEntry } from "./catalog-types.js";
|
|
17
|
+
export declare const SHIPPED_CATALOG_VERSION = "2026-10-03";
|
|
18
|
+
export declare const SHIPPED_CATALOG: readonly CatalogEntry[];
|