@wardby/cli 0.6.0 → 0.7.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/deploy/local/docker-compose.quickstart-coding.yml +13 -0
- package/dist/claude-coding-worker/driver.d.ts +21 -3
- package/dist/claude-coding-worker/driver.js +125 -17
- package/dist/claude-coding-worker/main.js +34 -6
- package/dist/claude-coding-worker/sdk.js +12 -1
- package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
- package/dist/claude-coding-worker/tool-socket.js +111 -0
- package/dist/claude-coding-worker/transcript.d.ts +18 -0
- package/dist/claude-coding-worker/transcript.js +77 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +1 -0
- package/dist/cli.js +24 -10
- package/dist/coding/continuation-wording.d.ts +35 -0
- package/dist/coding/continuation-wording.js +73 -0
- package/dist/coding/linked-issue-note.d.ts +23 -0
- package/dist/coding/linked-issue-note.js +47 -0
- package/dist/coding/merge-wording.d.ts +28 -0
- package/dist/coding/merge-wording.js +78 -0
- package/dist/coding/pr-description-note.d.ts +9 -0
- package/dist/coding/pr-description-note.js +32 -0
- package/dist/coding/profile.d.ts +46 -126
- package/dist/coding/profile.js +45 -4
- package/dist/coding/protected-path-wording.d.ts +8 -0
- package/dist/coding/protected-path-wording.js +1 -1
- package/dist/coding/protocol.d.ts +264 -346
- package/dist/coding/protocol.js +235 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +12 -0
- package/dist/coding/registry/allowlist.d.ts +12 -0
- package/dist/coding/registry/allowlist.js +14 -1
- package/dist/coding/registry/audit-mode.d.ts +153 -0
- package/dist/coding/registry/audit-mode.js +304 -0
- package/dist/coding/registry/lockfile-shared.d.ts +36 -0
- package/dist/coding/registry/lockfile-shared.js +128 -0
- package/dist/coding/registry/lockfiles.js +1 -1
- package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
- package/dist/coding/registry/npm-lockfile-formats.js +41 -0
- package/dist/coding/registry/npm-lockfile.d.ts +8 -4
- package/dist/coding/registry/npm-lockfile.js +4 -6
- package/dist/coding/registry/npm.js +78 -8
- package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
- package/dist/coding/registry/pnpm-lockfile.js +189 -0
- package/dist/coding/registry/pypi-plan.d.ts +50 -0
- package/dist/coding/registry/pypi-plan.js +406 -0
- package/dist/coding/registry/pypi-requirements.d.ts +58 -0
- package/dist/coding/registry/pypi-requirements.js +155 -0
- package/dist/coding/registry/pypi.d.ts +3 -27
- package/dist/coding/registry/pypi.js +40 -154
- package/dist/coding/registry/refusal-hints.d.ts +20 -0
- package/dist/coding/registry/refusal-hints.js +61 -0
- package/dist/coding/registry/refusal-wording.d.ts +11 -0
- package/dist/coding/registry/refusal-wording.js +56 -0
- package/dist/coding/registry/report.d.ts +70 -8
- package/dist/coding/registry/report.js +112 -5
- package/dist/coding/registry/types.d.ts +58 -8
- package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
- package/dist/coding/registry/yarn-lockfile.js +367 -0
- package/dist/coding/services/catalog.d.ts +37 -351
- package/dist/coding/transcript/claude-code.d.ts +13 -0
- package/dist/coding/transcript/claude-code.js +273 -0
- package/dist/coding/transcript/download-protocol.d.ts +30 -0
- package/dist/coding/transcript/download-protocol.js +18 -0
- package/dist/coding/transcript/format.d.ts +20 -0
- package/dist/coding/transcript/format.js +32 -0
- package/dist/coding/transcript/recorder.d.ts +51 -0
- package/dist/coding/transcript/recorder.js +225 -0
- package/dist/coding/transcript/resume/checkout.d.ts +31 -0
- package/dist/coding/transcript/resume/checkout.js +203 -0
- package/dist/coding/transcript/resume/command.d.ts +17 -0
- package/dist/coding/transcript/resume/command.js +176 -0
- package/dist/coding/transcript/resume/download.d.ts +20 -0
- package/dist/coding/transcript/resume/download.js +153 -0
- package/dist/coding/transcript/resume/launch.d.ts +38 -0
- package/dist/coding/transcript/resume/launch.js +128 -0
- package/dist/coding/transcript/resume/session-file.d.ts +13 -0
- package/dist/coding/transcript/resume/session-file.js +79 -0
- package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
- package/dist/coding/transcript/resume/stand-in.js +49 -0
- package/dist/coding-worker/artifact.d.ts +8 -3
- package/dist/coding-worker/artifact.js +3 -1
- package/dist/coding-worker/debug-trace.d.ts +6 -5
- package/dist/coding-worker/debug-trace.js +13 -18
- package/dist/coding-worker/dependency-cache.d.mts +229 -0
- package/dist/coding-worker/dependency-cache.mjs +2123 -0
- package/dist/coding-worker/driver.d.ts +4 -3
- package/dist/coding-worker/driver.js +116 -38
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/task-note.d.ts +11 -0
- package/dist/coding-worker/task-note.js +13 -0
- package/dist/coding-worker/types.d.ts +11 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +82 -0
- package/dist/config/test-simulators.js +305 -0
- package/dist/core/async-context.d.ts +2 -0
- package/dist/core/async-context.js +12 -0
- package/dist/core/budget-events.d.ts +108 -0
- package/dist/core/budget-events.js +346 -0
- package/dist/core/budget-groups.d.ts +50 -1
- package/dist/core/budget-groups.js +236 -27
- package/dist/core/budget-stopped-head.d.ts +46 -0
- package/dist/core/budget-stopped-head.js +81 -0
- package/dist/core/budget-topup.d.ts +51 -0
- package/dist/core/budget-topup.js +156 -0
- package/dist/core/budget-wording.d.ts +16 -2
- package/dist/core/budget-wording.js +40 -2
- package/dist/core/coding-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -0
- package/dist/core/cron.d.ts +19 -1
- package/dist/core/cron.js +17 -0
- package/dist/core/datastores.js +1 -1
- package/dist/core/deferred-coding.d.ts +14 -0
- package/dist/core/deferred-coding.js +62 -0
- package/dist/core/delegation-child.d.ts +25 -0
- package/dist/core/delegation-child.js +37 -0
- package/dist/core/dispatch.d.ts +42 -0
- package/dist/core/dispatch.js +131 -56
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +168 -0
- package/dist/core/grants.d.ts +19 -6
- package/dist/core/grants.js +55 -6
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +284 -24
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +298 -20
- package/dist/core/issue-bridge.d.ts +50 -6
- package/dist/core/issue-bridge.js +124 -33
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +4 -10
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +54 -26
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +14 -1
- package/dist/core/lost-run-children.d.ts +6 -0
- package/dist/core/lost-run-children.js +32 -0
- package/dist/core/mark-ready.d.ts +34 -0
- package/dist/core/mark-ready.js +152 -0
- package/dist/core/markdown-code.d.ts +8 -0
- package/dist/core/markdown-code.js +107 -0
- package/dist/core/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +8 -1
- package/dist/core/notification-templates.d.ts +1 -7
- package/dist/core/notification-templates.js +36 -2
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +4 -3
- package/dist/core/reconciler.js +8 -1
- package/dist/core/related-pull-requests.d.ts +11 -3
- package/dist/core/related-pull-requests.js +27 -14
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/review-fix.d.ts +1 -1
- package/dist/core/review-fix.js +2 -1
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +3 -0
- package/dist/core/review-host-tools.js +99 -13
- package/dist/core/review-reads.d.ts +55 -0
- package/dist/core/review-reads.js +233 -0
- package/dist/core/run-status.d.ts +12 -0
- package/dist/core/run-status.js +12 -0
- package/dist/core/runner.d.ts +80 -34
- package/dist/core/runner.js +439 -144
- package/dist/core/schedule-start.d.ts +12 -0
- package/dist/core/schedule-start.js +14 -0
- package/dist/core/secret-broker-config.d.ts +10 -74
- package/dist/core/secret-guard.d.ts +46 -0
- package/dist/core/secret-guard.js +104 -0
- package/dist/core/secret-guarded-stores.d.ts +12 -0
- package/dist/core/secret-guarded-stores.js +41 -0
- package/dist/core/secret-spans.d.ts +50 -0
- package/dist/core/secret-spans.js +94 -0
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/workflow-events.d.ts +14 -2
- package/dist/core/workflow-events.js +4 -0
- package/dist/core/workflow-run-events.d.ts +5 -3
- package/dist/core/workflow-run-events.js +43 -8
- package/dist/core/zod-json-schema.d.ts +4 -0
- package/dist/core/zod-json-schema.js +39 -0
- package/dist/core/zod3-window.d.ts +35 -0
- package/dist/core/zod3-window.js +124 -0
- package/dist/generated/prisma/browser.d.ts +34 -3
- package/dist/generated/prisma/client.d.ts +34 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +220 -60
- package/dist/generated/prisma/enums.d.ts +10 -0
- package/dist/generated/prisma/enums.js +8 -0
- package/dist/generated/prisma/internal/class.d.ts +44 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +428 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +92 -1
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +95 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +92 -1
- package/dist/generated/prisma/models/Agent.d.ts +106 -8
- package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +229 -1
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
- package/dist/generated/prisma/models/CodingRun.d.ts +1637 -1
- package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
- package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
- package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
- package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +738 -2
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
- package/dist/generated/prisma/models/RunTranscript.js +1 -0
- package/dist/generated/prisma/models.d.ts +4 -0
- package/dist/help-index.json +1320 -69
- package/dist/import/create.js +32 -3
- package/dist/import/neutral-schema.d.ts +50 -281
- package/dist/import/neutral-schema.js +5 -4
- package/dist/knowledge/check.d.ts +1 -1
- package/dist/knowledge/cli.d.ts +11 -1
- package/dist/knowledge/cli.js +37 -4
- package/dist/knowledge/concept.d.ts +3 -19
- package/dist/knowledge/location.d.ts +31 -0
- package/dist/knowledge/location.js +78 -0
- package/dist/mcp/auth/access.d.ts +10 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
- package/dist/mcp/host-events/github-ingress.d.ts +2 -0
- package/dist/mcp/host-events/github-ingress.js +2 -1
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +58 -10
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +33 -14
- package/dist/mcp/tools/agents.d.ts +4 -0
- package/dist/mcp/tools/agents.js +198 -16
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +9 -3
- package/dist/mcp/tools/memory.js +11 -1
- package/dist/mcp/tools/notification-channels.js +2 -2
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/repositories.js +18 -5
- package/dist/mcp/tools/run-access.d.ts +16 -0
- package/dist/mcp/tools/run-access.js +25 -0
- package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
- package/dist/mcp/tools/run-transcript-download.js +129 -0
- package/dist/mcp/tools/run-transcript.d.ts +19 -0
- package/dist/mcp/tools/run-transcript.js +70 -0
- package/dist/mcp/tools/runs.js +34 -12
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-elicitation-form.js +5 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -61
- package/dist/mcp/tools/secrets.js +2 -2
- package/dist/mcp/tools/stop-run.d.ts +2 -0
- package/dist/mcp/tools/stop-run.js +82 -0
- package/dist/mcp/tools/subagents.js +2 -2
- package/dist/mcp/tools/tools.d.ts +1 -1
- package/dist/mcp/tools/tools.js +25 -9
- package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
- package/dist/mcp/transport/stdio-link-host.js +67 -0
- package/dist/mcp/transport/streamable-http.d.ts +13 -0
- package/dist/mcp/transport/streamable-http.js +41 -1
- package/dist/native-worker/docker-launcher.d.ts +38 -2
- package/dist/native-worker/docker-launcher.js +65 -5
- package/dist/native-worker/gateway-server.d.ts +41 -3
- package/dist/native-worker/gateway-server.js +124 -27
- package/dist/native-worker/gateway.d.ts +27 -1
- package/dist/native-worker/gateway.js +70 -4
- package/dist/native-worker/http-server.d.ts +3 -1
- package/dist/native-worker/http-server.js +11 -7
- package/dist/native-worker/http-transport.js +1 -1
- package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
- package/dist/native-worker/kubernetes-launcher.js +43 -3
- package/dist/native-worker/launch.d.ts +18 -1
- package/dist/native-worker/launch.js +6 -1
- package/dist/native-worker/ledger.d.ts +18 -2
- package/dist/native-worker/ledger.js +57 -4
- package/dist/native-worker/loopback.js +3 -8
- package/dist/native-worker/main.d.ts +2 -1
- package/dist/native-worker/main.js +14 -3
- package/dist/native-worker/protocol.d.ts +129 -577
- package/dist/native-worker/protocol.js +47 -1
- package/dist/native-worker/sandbox-executor.d.ts +17 -2
- package/dist/native-worker/sandbox-executor.js +78 -4
- package/dist/native-worker/stderr-redaction.d.ts +77 -0
- package/dist/native-worker/stderr-redaction.js +237 -0
- package/dist/native-worker/stdio.d.ts +1 -1
- package/dist/native-worker/stdio.js +6 -5
- package/dist/native-worker/warm-pool.d.ts +2 -2
- package/dist/native-worker/warm-pool.js +4 -4
- package/dist/native-worker/worker.js +28 -2
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/self-hosted.d.ts +1 -1
- package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
- package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
- package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
- package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
- package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
- package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
- package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
- package/dist/providers/coding-proxy/hold.d.ts +32 -0
- package/dist/providers/coding-proxy/hold.js +86 -0
- package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
- package/dist/providers/coding-proxy/interrupted.js +104 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
- package/dist/providers/coding-proxy/memory-ledger.js +84 -8
- package/dist/providers/coding-proxy/metering.d.ts +16 -0
- package/dist/providers/coding-proxy/metering.js +27 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
- package/dist/providers/coding-proxy/proxy.d.ts +14 -1
- package/dist/providers/coding-proxy/proxy.js +166 -14
- package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
- package/dist/providers/coding-proxy/registry/audit.js +94 -17
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
- package/dist/providers/coding-proxy/registry/plan.js +201 -48
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
- package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
- package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
- package/dist/providers/coding-proxy/registry/service.js +579 -112
- package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
- package/dist/providers/coding-proxy/registry/store.js +54 -1
- package/dist/providers/coding-proxy/runtime.d.ts +4 -0
- package/dist/providers/coding-proxy/runtime.js +78 -16
- package/dist/providers/coding-proxy/server.d.ts +6 -1
- package/dist/providers/coding-proxy/server.js +45 -1
- package/dist/providers/coding-proxy/types.d.ts +65 -1
- package/dist/providers/datastore/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +17 -2
- package/dist/providers/engine/types.js +17 -0
- package/dist/providers/executor/composition.d.ts +10 -3
- package/dist/providers/executor/composition.js +47 -7
- package/dist/providers/executor/container.d.ts +361 -8
- package/dist/providers/executor/container.js +1136 -91
- package/dist/providers/executor/dbos-status.d.ts +31 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +50 -1
- package/dist/providers/executor/dbos.js +207 -20
- package/dist/providers/executor/deferred.d.ts +12 -24
- package/dist/providers/executor/deferred.js +10 -29
- package/dist/providers/executor/in-process.d.ts +9 -1
- package/dist/providers/executor/in-process.js +14 -4
- package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
- package/dist/providers/executor/linked-issue-reader.js +30 -0
- package/dist/providers/executor/routing.d.ts +2 -0
- package/dist/providers/executor/routing.js +4 -0
- package/dist/providers/executor/types.d.ts +13 -0
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/issue-tracker/types.d.ts +17 -0
- package/dist/providers/issue-tracker/types.js +39 -1
- package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
- package/dist/providers/jobs/claude-tool-setup.js +5 -2
- package/dist/providers/jobs/docker-isolation.d.ts +8 -0
- package/dist/providers/jobs/docker-isolation.js +17 -0
- package/dist/providers/jobs/docker.d.ts +1 -0
- package/dist/providers/jobs/docker.js +27 -2
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
- package/dist/providers/jobs/kubernetes-api.js +10 -0
- package/dist/providers/jobs/kubernetes-client.js +10 -1
- package/dist/providers/jobs/kubernetes-isolation.d.ts +2 -0
- package/dist/providers/jobs/kubernetes-isolation.js +17 -1
- package/dist/providers/jobs/kubernetes.d.ts +6 -1
- package/dist/providers/jobs/kubernetes.js +105 -16
- package/dist/providers/jobs/types.d.ts +33 -0
- package/dist/providers/jobs/types.js +13 -1
- package/dist/providers/llm/anthropic.js +5 -1
- package/dist/providers/llm/bedrock.d.ts +0 -12
- package/dist/providers/llm/bedrock.js +4 -0
- package/dist/providers/llm/claude-messages.d.ts +3 -1
- package/dist/providers/llm/claude-messages.js +4 -1
- package/dist/providers/llm/claude-provider.d.ts +2 -2
- package/dist/providers/llm/claude-provider.js +2 -2
- package/dist/providers/llm/openai.d.ts +2 -2
- package/dist/providers/llm/openai.js +6 -2
- package/dist/providers/llm/routing.d.ts +2 -2
- package/dist/providers/llm/routing.js +2 -2
- package/dist/providers/llm/types.d.ts +12 -2
- package/dist/providers/review-host/github-events.d.ts +9 -1
- package/dist/providers/review-host/github-events.js +34 -12
- package/dist/providers/review-host/github.d.ts +29 -2
- package/dist/providers/review-host/github.js +224 -29
- package/dist/providers/review-host/local.d.ts +8 -4
- package/dist/providers/review-host/local.js +49 -31
- package/dist/providers/review-host/patch-pages.d.ts +41 -0
- package/dist/providers/review-host/patch-pages.js +176 -0
- package/dist/providers/review-host/review-format.d.ts +19 -1
- package/dist/providers/review-host/review-format.js +38 -7
- package/dist/providers/review-host/types.d.ts +134 -2
- package/dist/providers/review-host/types.js +8 -0
- package/dist/providers/storage/gcs.d.ts +63 -0
- package/dist/providers/storage/gcs.js +69 -0
- package/dist/providers/storage/index.d.ts +15 -0
- package/dist/providers/storage/index.js +14 -0
- package/dist/providers/storage/local.d.ts +24 -0
- package/dist/providers/storage/local.js +92 -0
- package/dist/providers/storage/meter.d.ts +14 -0
- package/dist/providers/storage/meter.js +34 -0
- package/dist/providers/storage/s3.d.ts +41 -0
- package/dist/providers/storage/s3.js +107 -0
- package/dist/providers/storage/types.d.ts +37 -3
- package/dist/providers/storage/types.js +21 -4
- package/dist/providers/vcs/git.d.ts +33 -2
- package/dist/providers/vcs/git.js +324 -22
- package/dist/providers/vcs/github-remote.d.ts +26 -3
- package/dist/providers/vcs/github-remote.js +124 -14
- package/dist/providers/vcs/github.d.ts +214 -6
- package/dist/providers/vcs/github.js +447 -45
- package/dist/providers/vcs/index.js +8 -1
- package/dist/providers/vcs/pr-description.d.ts +127 -0
- package/dist/providers/vcs/pr-description.js +270 -0
- package/dist/providers/vcs/remote.d.ts +33 -1
- package/dist/providers/vcs/routing.d.ts +4 -2
- package/dist/providers/vcs/routing.js +6 -0
- package/dist/providers/vcs/types.d.ts +80 -3
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +6 -6
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +1 -0
- package/dist/sandbox/host-functions.js +6 -11
- package/dist/sandbox/secret-broker.js +3 -4
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +8 -1
- package/dist/viewer/api-schema.d.ts +349 -2627
- package/dist/viewer/api-schema.js +7 -0
- package/dist/viewer/build-schemas.js +6 -2
- package/dist/viewer/openapi.js +2 -4
- package/dist/wardby-bin.js +10 -0
- package/docs/agent-recipes.md +58 -20
- package/docs/code-review-agents.md +551 -41
- package/docs/coding-agent-setup.md +489 -7
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +20 -0
- package/docs/coding-worker-isolation.md +105 -30
- package/docs/getting-started-gke.md +124 -137
- package/docs/getting-started-identity-provider.md +10 -1
- package/docs/getting-started.md +9 -0
- package/docs/jira-agents.md +17 -8
- package/docs/knowledge/blob-not-found-semantics.md +41 -0
- package/docs/knowledge/bounded-file-descriptor.md +52 -0
- package/docs/knowledge/delegation-admission-slots.md +52 -0
- package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
- package/docs/knowledge/import-rename-target.md +52 -0
- package/docs/knowledge/index.md +57 -0
- package/docs/knowledge/log.md +9 -0
- package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
- package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
- package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
- package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
- package/docs/knowledge/overview-cli.md +74 -0
- package/docs/knowledge/overview-coding-proxy.md +72 -0
- package/docs/knowledge/overview-coding.md +72 -0
- package/docs/knowledge/overview-config.md +60 -0
- package/docs/knowledge/overview-core.md +72 -0
- package/docs/knowledge/overview-deploy.md +83 -0
- package/docs/knowledge/overview-mcp.md +61 -0
- package/docs/knowledge/overview-prisma.md +72 -0
- package/docs/knowledge/overview-providers.md +89 -0
- package/docs/knowledge/overview-sandbox.md +83 -0
- package/docs/knowledge/overview-surfaces.md +83 -0
- package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
- package/docs/knowledge/proxy-settlement-projections.md +41 -0
- package/docs/knowledge/run-pricing-first-writer.md +43 -0
- package/docs/knowledge/schedule-claim-transaction.md +41 -0
- package/docs/knowledge/secret-entry-replica-contract.md +52 -0
- package/docs/knowledge/terminal-run-first-writer.md +41 -0
- package/docs/knowledge/transactional-agent-authorization.md +52 -0
- package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
- package/docs/knowledge/warm-input-publication.md +30 -0
- package/docs/knowledge/workspace-staging-failure.md +54 -0
- package/docs/knowledge.md +54 -14
- package/docs/native-sandbox.md +119 -23
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +33 -2
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +42 -10
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +24 -2
- package/help/architecture-agent.md +11 -6
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- package/help/code-review-agents.md +177 -6
- package/help/coding-packages.md +156 -6
- package/help/cost-attribution.md +9 -5
- package/help/creating-agents.md +14 -1
- package/help/dependency-cache.md +143 -0
- package/help/deploy-gke.md +15 -8
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-stream-quota-exceeded.md +33 -0
- package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
- package/help/errors/continuation-closed.md +9 -12
- package/help/errors/delegation-conflict.md +24 -0
- package/help/errors/file-list-truncated.md +45 -0
- package/help/errors/full-read-required.md +49 -0
- package/help/errors/github-account-not-allowed.md +4 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-worker-exited.md +3 -2
- package/help/errors/package-not-allowed-pending.md +52 -0
- package/help/errors/package-not-allowed.md +51 -0
- package/help/errors/package-refusals.md +43 -0
- package/help/errors/patch-cursor-malformed.md +31 -0
- package/help/errors/run-lost.md +39 -0
- package/help/errors/run-transcript-download.md +44 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/target-merge.md +40 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/identity-and-access.md +2 -0
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +1 -1
- package/help/low-power-mode.md +7 -1
- package/help/merge-order-check.md +5 -0
- package/help/native-capabilities.md +29 -1
- package/help/native-sandbox.md +15 -1
- package/help/operating-agents.md +5 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +10 -7
- package/help/resume-runs-locally.md +131 -0
- package/help/review-fix-rounds.md +33 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +19 -5
- package/help/status-comments.md +31 -0
- package/help/stop-run.md +58 -0
- package/help/troubleshooting/budgets.md +28 -0
- package/help/troubleshooting/coding-workers.md +78 -7
- package/package.json +17 -10
- package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
- package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
- package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
- package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
- package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
- package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
- package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
- package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
- package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
- package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
- package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
- package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
- package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
- package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
- package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
- package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
- package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
- package/prisma/schema.prisma +311 -97
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { codingTopUpRoom, MIN_RESERVATION_USD } from "./budget-groups.js";
|
|
2
|
+
import { GROUP_DISPATCH_LOCK_SQL, isSerializationConflict, isTransactionUnavailable } from "./dispatch.js";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
4
|
+
const topUpLog = logger.child({ module: "budget-topup" });
|
|
5
|
+
/** Share of the base one step adds, unless one maximum request hold is more. */
|
|
6
|
+
export const TOP_UP_STEP_SHARE = 0.1;
|
|
7
|
+
/** Headroom: the share of the base, or this many of the run's largest request holds if more. */
|
|
8
|
+
export const TOP_UP_HEADROOM_SHARE = 0.2;
|
|
9
|
+
export const TOP_UP_HEADROOM_HOLDS = 2;
|
|
10
|
+
const roundMicro = (usd) => Math.round(usd / MIN_RESERVATION_USD) * MIN_RESERVATION_USD;
|
|
11
|
+
const floorMicro = (usd) => Math.floor(usd / MIN_RESERVATION_USD + 1e-6) * MIN_RESERVATION_USD;
|
|
12
|
+
/** The run's grant, limit and proxy-session totals, or the outcome when there is nothing to ask for. */
|
|
13
|
+
async function readState(db, runId) {
|
|
14
|
+
const coding = await db.codingRun.findUnique({
|
|
15
|
+
where: { runId },
|
|
16
|
+
select: {
|
|
17
|
+
budgetReservedUsd: true,
|
|
18
|
+
budgetBaseUsd: true,
|
|
19
|
+
budgetLimitUsd: true,
|
|
20
|
+
run: { select: { status: true } },
|
|
21
|
+
proxySession: { select: { id: true, status: true, budgetExhaustedAt: true } },
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
if (!coding || coding.budgetLimitUsd == null)
|
|
25
|
+
return { outcome: "closed" };
|
|
26
|
+
const grantedUsd = Number(coding.budgetReservedUsd);
|
|
27
|
+
const limitUsd = Number(coding.budgetLimitUsd);
|
|
28
|
+
const result = { outcome: "closed", grantedUsd };
|
|
29
|
+
if (grantedUsd + MIN_RESERVATION_USD > limitUsd)
|
|
30
|
+
return result;
|
|
31
|
+
if (coding.run.status !== "running" && coding.run.status !== "pending")
|
|
32
|
+
return result;
|
|
33
|
+
// Already refused by the proxy: the worker is stopping, a grant now would only be held for nothing.
|
|
34
|
+
const session = coding.proxySession;
|
|
35
|
+
if (!session || session.status !== "active" || session.budgetExhaustedAt)
|
|
36
|
+
return result;
|
|
37
|
+
const refused = await db.runBudgetEvent.findFirst({
|
|
38
|
+
where: { runId, kind: "overrun_unavailable" },
|
|
39
|
+
select: { id: true },
|
|
40
|
+
});
|
|
41
|
+
if (refused)
|
|
42
|
+
return result;
|
|
43
|
+
// Totals as the proxy ledger counts them (prisma-ledger.ts reserve).
|
|
44
|
+
const totals = await db.$queryRaw `
|
|
45
|
+
SELECT
|
|
46
|
+
COALESCE(SUM(CASE
|
|
47
|
+
WHEN "status" = 'completed' THEN "actualCostUsd"
|
|
48
|
+
WHEN "status" = 'uncertain' AND "costEstimated" THEN "actualCostUsd"
|
|
49
|
+
ELSE 0
|
|
50
|
+
END), 0) AS "spent",
|
|
51
|
+
COALESCE(SUM(CASE
|
|
52
|
+
WHEN "status" = 'reserved' THEN "reservationUsd"
|
|
53
|
+
WHEN "status" = 'uncertain' AND NOT "costEstimated" THEN "reservationUsd"
|
|
54
|
+
ELSE 0
|
|
55
|
+
END), 0) AS "held",
|
|
56
|
+
COALESCE(MAX(COALESCE("ceilingUsd", "reservationUsd")), 0) AS "maxHold"
|
|
57
|
+
FROM "CodingProxyRequest" WHERE "sessionId" = ${session.id}
|
|
58
|
+
`;
|
|
59
|
+
return {
|
|
60
|
+
baseUsd: coding.budgetBaseUsd == null ? grantedUsd : Number(coding.budgetBaseUsd),
|
|
61
|
+
grantedUsd,
|
|
62
|
+
limitUsd,
|
|
63
|
+
sessionId: session.id,
|
|
64
|
+
spentUsd: Number(totals[0]?.spent ?? 0),
|
|
65
|
+
heldUsd: Number(totals[0]?.held ?? 0),
|
|
66
|
+
maxHoldUsd: Number(totals[0]?.maxHold ?? 0),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* How far below its grant a run asks for its next step. Agent loops grow their
|
|
71
|
+
* context, so the next request usually holds more than any before it, and the
|
|
72
|
+
* top-up has to land before it is sent.
|
|
73
|
+
*/
|
|
74
|
+
function headroomUsd(state) {
|
|
75
|
+
return Math.max(TOP_UP_HEADROOM_HOLDS * state.maxHoldUsd, TOP_UP_HEADROOM_SHARE * state.baseUsd);
|
|
76
|
+
}
|
|
77
|
+
/** Close to its grant: within its headroom. */
|
|
78
|
+
function isClose(state) {
|
|
79
|
+
return state.spentUsd + state.heldUsd >= state.grantedUsd - headroomUsd(state);
|
|
80
|
+
}
|
|
81
|
+
/** Near enough to its grant that the next poll should come soon. */
|
|
82
|
+
function isNear(state) {
|
|
83
|
+
return state.spentUsd + state.heldUsd >= state.grantedUsd - 2 * headroomUsd(state);
|
|
84
|
+
}
|
|
85
|
+
async function grantOnce(tx, runId, now) {
|
|
86
|
+
// First statement: serializes with dispatch and every other top-up (see GROUP_DISPATCH_LOCK_SQL).
|
|
87
|
+
await tx.$executeRawUnsafe(GROUP_DISPATCH_LOCK_SQL);
|
|
88
|
+
const state = await readState(tx, runId);
|
|
89
|
+
if ("outcome" in state)
|
|
90
|
+
return state;
|
|
91
|
+
if (!isClose(state))
|
|
92
|
+
return { outcome: "not_needed", grantedUsd: state.grantedUsd, near: isNear(state) };
|
|
93
|
+
const room = await codingTopUpRoom(tx, runId, now);
|
|
94
|
+
const step = Math.max(TOP_UP_STEP_SHARE * state.baseUsd, state.maxHoldUsd);
|
|
95
|
+
const grant = floorMicro(Math.min(step, state.limitUsd - state.grantedUsd, room.roomUsd));
|
|
96
|
+
if (grant < MIN_RESERVATION_USD) {
|
|
97
|
+
const details = {
|
|
98
|
+
source: "top-up",
|
|
99
|
+
capUsd: room.detail?.capUsd ?? 0,
|
|
100
|
+
spentUsd: room.detail?.spentUsd ?? 0,
|
|
101
|
+
heldUsd: room.detail?.heldUsd ?? 0,
|
|
102
|
+
leftUsd: room.roomUsd,
|
|
103
|
+
baseBudgetUsd: state.baseUsd,
|
|
104
|
+
grantedUsd: state.grantedUsd,
|
|
105
|
+
limitUsd: state.limitUsd,
|
|
106
|
+
...(room.groupName ? { groupName: room.groupName } : {}),
|
|
107
|
+
};
|
|
108
|
+
await tx.runBudgetEvent.create({
|
|
109
|
+
data: {
|
|
110
|
+
runId,
|
|
111
|
+
kind: "overrun_unavailable",
|
|
112
|
+
limit: room.limitedBy ?? "run",
|
|
113
|
+
details: details,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
return { outcome: "unavailable", grantedUsd: state.grantedUsd };
|
|
117
|
+
}
|
|
118
|
+
const grantedUsd = Math.min(state.limitUsd, roundMicro(state.grantedUsd + grant));
|
|
119
|
+
await tx.codingRun.update({ where: { runId }, data: { budgetReservedUsd: grantedUsd } });
|
|
120
|
+
await tx.codingProxySession.updateMany({
|
|
121
|
+
where: { id: state.sessionId, status: "active" },
|
|
122
|
+
data: { budgetUsd: grantedUsd },
|
|
123
|
+
});
|
|
124
|
+
return { outcome: "granted", grantedUsd, near: true };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Grants the run one overrun step when it is close to its grant and its
|
|
128
|
+
* budget group and run tree have room. Cheap when it is not close: that is
|
|
129
|
+
* read without the lock. One attempt per call, so a poll never blocks on
|
|
130
|
+
* retries: a serialization conflict (or a lock not had in time) answers
|
|
131
|
+
* not_needed and near, and the caller's next poll, soon, asks again.
|
|
132
|
+
*/
|
|
133
|
+
export async function topUpCodingBudget(db, runId, now = new Date()) {
|
|
134
|
+
const state = await readState(db, runId);
|
|
135
|
+
if ("outcome" in state)
|
|
136
|
+
return state;
|
|
137
|
+
if (!isClose(state))
|
|
138
|
+
return { outcome: "not_needed", grantedUsd: state.grantedUsd, near: isNear(state) };
|
|
139
|
+
try {
|
|
140
|
+
const result = await db.$transaction((tx) => grantOnce(tx, runId, now), {
|
|
141
|
+
isolationLevel: "Serializable",
|
|
142
|
+
maxWait: TOP_UP_TX_MAX_WAIT_MS,
|
|
143
|
+
});
|
|
144
|
+
if (result.outcome === "granted" || result.outcome === "unavailable") {
|
|
145
|
+
topUpLog.info({ runId, outcome: result.outcome, grantedUsd: result.grantedUsd }, "coding run overrun top-up");
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (!isSerializationConflict(err) && !isTransactionUnavailable(err))
|
|
151
|
+
throw err;
|
|
152
|
+
return { outcome: "not_needed", grantedUsd: state.grantedUsd, near: true };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** How long one top-up waits to start its transaction: short, so a poll (and its heartbeat) is never held long. */
|
|
156
|
+
export const TOP_UP_TX_MAX_WAIT_MS = 2_000;
|
|
@@ -6,17 +6,31 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { PrismaClient } from "#prisma";
|
|
8
8
|
export interface BudgetFacts {
|
|
9
|
-
/** The run's own budget (a coding run's reservation); falls back to the agent's. */
|
|
9
|
+
/** The run's own budget (a coding run's reservation: its grant); falls back to the agent's. */
|
|
10
10
|
runBudgetUsd?: number | null;
|
|
11
11
|
agentBudgetUsd: number;
|
|
12
|
+
/** The run's budget before the agent's allowed overrun; absent for runs from before the setting. */
|
|
13
|
+
baseBudgetUsd?: number | null;
|
|
14
|
+
/** The most the run could have been topped up to (CodingRun.budgetLimitUsd); absent = its reservation. */
|
|
15
|
+
limitUsd?: number | null;
|
|
12
16
|
budgetGroupName?: string | null;
|
|
13
17
|
/** The run was refused before it started. */
|
|
14
18
|
refused?: boolean;
|
|
15
19
|
}
|
|
20
|
+
/** A group name is operator-chosen text; keep it to one short, quote-free line. */
|
|
21
|
+
export declare function groupName(name: string | null | undefined): string | null;
|
|
22
|
+
/** The allowed overrun as a whole percent, or null when the run had none (no base, or it rounds to 0%). */
|
|
23
|
+
export declare function overrunPercent(baseUsd: number | null | undefined, limitUsd: number): number | null;
|
|
16
24
|
export declare function budgetSentence(facts: BudgetFacts): string;
|
|
25
|
+
/**
|
|
26
|
+
* For a run that finished over its base budget: what it spent and by how much
|
|
27
|
+
* it went over, and whether that stayed inside the allowed overrun. Undefined
|
|
28
|
+
* when the spend is within the base budget.
|
|
29
|
+
*/
|
|
30
|
+
export declare function overrunSentence(costUsd: number, baseUsd: number, limitUsd: number): string | undefined;
|
|
17
31
|
/**
|
|
18
32
|
* The sentence for a finished run, read from the database: a coding run's
|
|
19
33
|
* reserved budget, otherwise the agent's. Falls back to a sentence without
|
|
20
34
|
* amounts when they cannot be read. Never throws.
|
|
21
35
|
*/
|
|
22
|
-
export declare function loadBudgetSentence(db: Pick<PrismaClient, "run">, runId: string, status: string): Promise<string>;
|
|
36
|
+
export declare function loadBudgetSentence(db: Pick<PrismaClient, "run" | "runBudgetEvent">, runId: string, status: string): Promise<string>;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
import { hostBudgetSentence, loadBudgetEvent } from "./budget-events.js";
|
|
1
2
|
const MAX_GROUP_NAME_CHARS = 64;
|
|
2
3
|
const usd = (amount) => `$${amount.toFixed(2)}`;
|
|
3
4
|
/** A group name is operator-chosen text; keep it to one short, quote-free line. */
|
|
4
|
-
function groupName(name) {
|
|
5
|
+
export function groupName(name) {
|
|
5
6
|
const cleaned = (name ?? "").replace(/["`]/g, "").replace(/\s+/g, " ").trim().slice(0, MAX_GROUP_NAME_CHARS);
|
|
6
7
|
return cleaned || null;
|
|
7
8
|
}
|
|
9
|
+
/** The allowed overrun as a whole percent, or null when the run had none (no base, or it rounds to 0%). */
|
|
10
|
+
export function overrunPercent(baseUsd, limitUsd) {
|
|
11
|
+
if (baseUsd == null || !(baseUsd > 0) || !(baseUsd < limitUsd))
|
|
12
|
+
return null;
|
|
13
|
+
const percent = Math.round((limitUsd / baseUsd - 1) * 100);
|
|
14
|
+
return percent > 0 ? percent : null;
|
|
15
|
+
}
|
|
8
16
|
export function budgetSentence(facts) {
|
|
9
17
|
const group = groupName(facts.budgetGroupName);
|
|
10
18
|
if (facts.refused) {
|
|
@@ -14,6 +22,16 @@ export function budgetSentence(facts) {
|
|
|
14
22
|
: `Out of budget: ${within}.`;
|
|
15
23
|
}
|
|
16
24
|
const runBudget = facts.runBudgetUsd ?? facts.agentBudgetUsd;
|
|
25
|
+
const base = facts.baseBudgetUsd;
|
|
26
|
+
const limit = facts.limitUsd ?? runBudget;
|
|
27
|
+
const percent = overrunPercent(base, limit);
|
|
28
|
+
if (base != null && percent !== null && runBudget > base) {
|
|
29
|
+
// Topped up only partly: what of the overrun its group and run tree had room for.
|
|
30
|
+
const overrun = runBudget < limit
|
|
31
|
+
? `${usd(runBudget - base)} of its ${percent}% allowed overrun`
|
|
32
|
+
: `its ${percent}% allowed overrun`;
|
|
33
|
+
return `Out of budget: this run's ${usd(base)} budget and ${overrun} (${usd(runBudget)} in all) were used up.`;
|
|
34
|
+
}
|
|
17
35
|
const used = `Out of budget: this run's ${usd(runBudget)} budget was used up`;
|
|
18
36
|
// A run reserved less than the agent's own budget: its group had only that much left.
|
|
19
37
|
if (group && runBudget < facts.agentBudgetUsd) {
|
|
@@ -21,27 +39,47 @@ export function budgetSentence(facts) {
|
|
|
21
39
|
}
|
|
22
40
|
return `${used}.`;
|
|
23
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* For a run that finished over its base budget: what it spent and by how much
|
|
44
|
+
* it went over, and whether that stayed inside the allowed overrun. Undefined
|
|
45
|
+
* when the spend is within the base budget.
|
|
46
|
+
*/
|
|
47
|
+
export function overrunSentence(costUsd, baseUsd, limitUsd) {
|
|
48
|
+
if (!(baseUsd > 0) || !(costUsd > baseUsd))
|
|
49
|
+
return undefined;
|
|
50
|
+
const over = costUsd - baseUsd;
|
|
51
|
+
const percent = Math.round((over / baseUsd) * 100);
|
|
52
|
+
const within = costUsd <= limitUsd ? ", within its allowed overrun" : "";
|
|
53
|
+
return `Spent ${usd(costUsd)}, ${usd(over)} (${percent}%) over its ${usd(baseUsd)} budget${within}.`;
|
|
54
|
+
}
|
|
24
55
|
/**
|
|
25
56
|
* The sentence for a finished run, read from the database: a coding run's
|
|
26
57
|
* reserved budget, otherwise the agent's. Falls back to a sentence without
|
|
27
58
|
* amounts when they cannot be read. Never throws.
|
|
28
59
|
*/
|
|
29
60
|
export async function loadBudgetSentence(db, runId, status) {
|
|
61
|
+
const loaded = await loadBudgetEvent(db, runId);
|
|
62
|
+
if (loaded)
|
|
63
|
+
return hostBudgetSentence(loaded.event);
|
|
30
64
|
const refused = status === "refused";
|
|
31
65
|
try {
|
|
32
66
|
const row = await db.run.findUnique({
|
|
33
67
|
where: { id: runId },
|
|
34
68
|
select: {
|
|
35
69
|
agent: { select: { budgetUsd: true, budgetGroup: { select: { name: true } } } },
|
|
36
|
-
codingRun: { select: { budgetReservedUsd: true } },
|
|
70
|
+
codingRun: { select: { budgetReservedUsd: true, budgetBaseUsd: true, budgetLimitUsd: true } },
|
|
37
71
|
},
|
|
38
72
|
});
|
|
39
73
|
const agentBudgetUsd = Number(row?.agent?.budgetUsd);
|
|
40
74
|
if (!row?.agent || !Number.isFinite(agentBudgetUsd))
|
|
41
75
|
throw new Error("budget_facts_unavailable");
|
|
42
76
|
const reserved = row.codingRun ? Number(row.codingRun.budgetReservedUsd) : NaN;
|
|
77
|
+
const base = row.codingRun?.budgetBaseUsd == null ? NaN : Number(row.codingRun.budgetBaseUsd);
|
|
78
|
+
const limit = row.codingRun?.budgetLimitUsd == null ? NaN : Number(row.codingRun.budgetLimitUsd);
|
|
43
79
|
return budgetSentence({
|
|
44
80
|
runBudgetUsd: Number.isFinite(reserved) ? reserved : null,
|
|
81
|
+
baseBudgetUsd: Number.isFinite(base) ? base : null,
|
|
82
|
+
limitUsd: Number.isFinite(limit) ? limit : null,
|
|
45
83
|
agentBudgetUsd,
|
|
46
84
|
budgetGroupName: row.agent.budgetGroup?.name ?? null,
|
|
47
85
|
refused,
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* 1. fails queued runs that waited longer than CODING_QUEUE_TIMEOUT_SEC
|
|
7
7
|
* (coding_queue_timeout), with a conditional update so concurrent
|
|
8
|
-
* drains never double-fail a run
|
|
8
|
+
* drains never double-fail a run, then lets the executor clean up after
|
|
9
|
+
* each (Executor.cleanupQueueTimeout);
|
|
9
10
|
* 2. starts the oldest queued runs, at most as many as there are free
|
|
10
11
|
* slots, so order stays FIFO in practice. Starting is fire-and-forget,
|
|
11
12
|
* like dispatchRun: Executor.start resolves only when the run ends.
|
|
@@ -30,6 +30,13 @@ export async function drainCodingQueue(options) {
|
|
|
30
30
|
timedOut += 1;
|
|
31
31
|
// Only this drain made the row failed (a concurrent drain matched zero rows); bounded, never throws.
|
|
32
32
|
await fileSelfDefectForRun(options.selfDefects, runId);
|
|
33
|
+
// What a launch the cluster refused left behind (a continuation's in-progress check, its input).
|
|
34
|
+
try {
|
|
35
|
+
await executor.cleanupQueueTimeout?.(runId);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
queueLog.warn({ err, runId }, "queue-timeout cleanup failed");
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
const active = await db.codingRun.count({
|
package/dist/core/cron.d.ts
CHANGED
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
export interface DueCheckInput {
|
|
6
6
|
schedule: string;
|
|
7
7
|
timezone: string;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Start of the most recent window this agent already fired for, or the
|
|
10
|
+
* moment its schedule was set (see startsSchedule); null only for a
|
|
11
|
+
* schedule set before that was recorded.
|
|
12
|
+
*/
|
|
9
13
|
lastScheduledAt: Date | null;
|
|
10
14
|
now: Date;
|
|
11
15
|
}
|
|
@@ -26,6 +30,20 @@ export interface DueCheckInput {
|
|
|
26
30
|
* `now` that lands exactly on a boundary.
|
|
27
31
|
*/
|
|
28
32
|
export declare function dueWindow(input: DueCheckInput): Date | null;
|
|
33
|
+
export interface ScheduleState {
|
|
34
|
+
schedule: string | null;
|
|
35
|
+
timezone: string;
|
|
36
|
+
scheduleEnabled: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Whether a schedule change starts the schedule afresh. Setting, changing
|
|
40
|
+
* (expression or timezone) or re-enabling a schedule does, so it first fires
|
|
41
|
+
* at its next window after that, never for one that passed before it existed
|
|
42
|
+
* or while it was off (see scheduleStartFields). Saving the schedule it
|
|
43
|
+
* already has does not, keeping its firing history. `before` is null for a
|
|
44
|
+
* new agent.
|
|
45
|
+
*/
|
|
46
|
+
export declare function startsSchedule(before: ScheduleState | null, after: ScheduleState): boolean;
|
|
29
47
|
export declare function isDue(input: DueCheckInput): boolean;
|
|
30
48
|
/** Throws a descriptive error for an invalid cron expression or timezone. */
|
|
31
49
|
export declare function validateCronExpression(schedule: string, timezone: string): void;
|
package/dist/core/cron.js
CHANGED
|
@@ -31,6 +31,23 @@ export function dueWindow(input) {
|
|
|
31
31
|
}
|
|
32
32
|
return mostRecent;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Whether a schedule change starts the schedule afresh. Setting, changing
|
|
36
|
+
* (expression or timezone) or re-enabling a schedule does, so it first fires
|
|
37
|
+
* at its next window after that, never for one that passed before it existed
|
|
38
|
+
* or while it was off (see scheduleStartFields). Saving the schedule it
|
|
39
|
+
* already has does not, keeping its firing history. `before` is null for a
|
|
40
|
+
* new agent.
|
|
41
|
+
*/
|
|
42
|
+
export function startsSchedule(before, after) {
|
|
43
|
+
if (!after.schedule || !after.scheduleEnabled)
|
|
44
|
+
return false;
|
|
45
|
+
const unchanged = before !== null &&
|
|
46
|
+
before.scheduleEnabled &&
|
|
47
|
+
before.schedule === after.schedule &&
|
|
48
|
+
before.timezone === after.timezone;
|
|
49
|
+
return !unchanged;
|
|
50
|
+
}
|
|
34
51
|
export function isDue(input) {
|
|
35
52
|
return dueWindow(input) !== null;
|
|
36
53
|
}
|
package/dist/core/datastores.js
CHANGED
|
@@ -65,7 +65,7 @@ export function buildSharedDatastoreAccessor(agentId, datastore, db) {
|
|
|
65
65
|
const datastoreId = await resolveDatastoreId(agentId, boundName, db);
|
|
66
66
|
if (!datastoreId)
|
|
67
67
|
throw new Error("datastore_not_bound");
|
|
68
|
-
await datastore.setShared(datastoreId, key, value, opts);
|
|
68
|
+
await datastore.setShared(datastoreId, key, value, { ...opts, writerAgentId: agentId });
|
|
69
69
|
},
|
|
70
70
|
async delete(boundName, key) {
|
|
71
71
|
const datastoreId = await resolveDatastoreId(agentId, boundName, db);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PrismaClient } from "#prisma";
|
|
2
|
+
import type { Executor } from "../providers/executor/types.js";
|
|
3
|
+
export interface ResolveDeferredCodingInput {
|
|
4
|
+
db: PrismaClient;
|
|
5
|
+
/** The starting process's own executor: the one with the coding configuration. */
|
|
6
|
+
executor: Executor;
|
|
7
|
+
runId: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Coding inputs of a run the native gateway dispatched (DeferredExecutor): resolved here, on the
|
|
11
|
+
* process that starts it, with its own executor — the gateway holds no coding configuration.
|
|
12
|
+
* Marker: a pending coding run whose CodingRun.workerImage is null. False: the run was refused.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveDeferredCodingRun({ db, executor, runId }: ResolveDeferredCodingInput): Promise<boolean>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { composeCodingTask } from "../coding/protocol.js";
|
|
2
|
+
import { assertCodingProvider } from "../coding/provider.js";
|
|
3
|
+
import { parseAllowedServiceNames } from "../coding/services/catalog.js";
|
|
4
|
+
import { servicesInstructionNote } from "../coding/services/note.js";
|
|
5
|
+
import { knowledgeSection } from "../knowledge/note.js";
|
|
6
|
+
import { readKnowledgeIndexAt, readServiceDeclarationAt, resolveDispatchServices } from "./dispatch.js";
|
|
7
|
+
/**
|
|
8
|
+
* Coding inputs of a run the native gateway dispatched (DeferredExecutor): resolved here, on the
|
|
9
|
+
* process that starts it, with its own executor — the gateway holds no coding configuration.
|
|
10
|
+
* Marker: a pending coding run whose CodingRun.workerImage is null. False: the run was refused.
|
|
11
|
+
*/
|
|
12
|
+
export async function resolveDeferredCodingRun({ db, executor, runId }) {
|
|
13
|
+
const run = await db.run.findUnique({
|
|
14
|
+
where: { id: runId },
|
|
15
|
+
include: { codingRun: true, agent: { include: { codingProfile: true } } },
|
|
16
|
+
});
|
|
17
|
+
const coding = run?.codingRun;
|
|
18
|
+
// A native run, or a coding run dispatch already resolved: nothing to do.
|
|
19
|
+
if (!run || !coding || coding.workerImage !== null)
|
|
20
|
+
return true;
|
|
21
|
+
const profile = run.agent.codingProfile;
|
|
22
|
+
if (!profile)
|
|
23
|
+
throw new Error(`coding_profile_missing: coding agent "${run.agentId}" has no coding profile.`);
|
|
24
|
+
assertCodingProvider(coding.provider);
|
|
25
|
+
// The provider is the run's own (fixed at dispatch); the toolchain and image ref are the profile's,
|
|
26
|
+
// read as they are when the run starts.
|
|
27
|
+
const selector = {
|
|
28
|
+
provider: coding.provider,
|
|
29
|
+
toolchain: profile.toolchain,
|
|
30
|
+
toolchainVersion: profile.toolchainVersion,
|
|
31
|
+
workerImageRef: profile.workerImageRef,
|
|
32
|
+
};
|
|
33
|
+
// Services before images, in dispatch's order: a run with both a refused declaration and a bad
|
|
34
|
+
// image ends refused. As at dispatch, only an agent allowed some service reads the declaration,
|
|
35
|
+
// and any refusal dispatch would have raised refuses the run here instead.
|
|
36
|
+
let services = [];
|
|
37
|
+
if (parseAllowedServiceNames(profile.services).length > 0) {
|
|
38
|
+
const outcome = await readServiceDeclarationAt(executor, coding.repository, coding.baseRef);
|
|
39
|
+
const resolved = await resolveDispatchServices(db, outcome, profile.services, executor, coding.provider, coding.task, run.agent.systemPrompt);
|
|
40
|
+
if ("refusal" in resolved) {
|
|
41
|
+
await db.run.updateMany({
|
|
42
|
+
where: { id: runId, status: "pending" },
|
|
43
|
+
data: { status: "refused", error: resolved.refusal, finishedAt: new Date() },
|
|
44
|
+
});
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
services = resolved.services;
|
|
48
|
+
}
|
|
49
|
+
if (!executor.resolveCodingWorkerImage) {
|
|
50
|
+
throw new Error("coding_execution_not_configured: this process cannot start coding runs.");
|
|
51
|
+
}
|
|
52
|
+
const workerImage = executor.resolveCodingWorkerImage(selector);
|
|
53
|
+
const toolImage = executor.resolveCodingToolImage?.(selector) ?? null;
|
|
54
|
+
const knowledge = await readKnowledgeIndexAt(executor, coding.repository, coding.baseRef);
|
|
55
|
+
const task = composeCodingTask(run.agent.systemPrompt, coding.task, servicesInstructionNote(services), knowledge ? knowledgeSection(knowledge) : undefined);
|
|
56
|
+
// Conditional on the marker: of two racing starts, only one writes (both composed the same inputs).
|
|
57
|
+
await db.codingRun.updateMany({
|
|
58
|
+
where: { runId, workerImage: null },
|
|
59
|
+
data: { workerImage, toolImage, services, task },
|
|
60
|
+
});
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one lookup both delegation paths (control-plane `delegate_to_*` and the sandbox gateway's
|
|
3
|
+
* `durableDelegate`) use to find the child a delegation call already created, so a re-executed
|
|
4
|
+
* delegate step (a resume, or a takeover under a new version) waits on that child again instead
|
|
5
|
+
* of refusing it as a duplicate.
|
|
6
|
+
*/
|
|
7
|
+
import type { PrismaClient } from "#prisma";
|
|
8
|
+
export type DelegationChildDb = Pick<PrismaClient, "run">;
|
|
9
|
+
/**
|
|
10
|
+
* The child a delegation call already created, if any: exact key first (Run.parentCallId, the
|
|
11
|
+
* model's tool-call id), then the single child of that agent with no key. Two or more such
|
|
12
|
+
* children are ambiguous and adopt none.
|
|
13
|
+
*
|
|
14
|
+
* A caller with a call id is a re-run of a recorded step, so an unkeyed child can only be a
|
|
15
|
+
* legacy row created before parentCallId existed; it is adopted in any status, because it may
|
|
16
|
+
* have finished while the lead was between deploys and its result is what the step is owed. A
|
|
17
|
+
* caller without a call id cannot tell a re-run from a new call (its children are unkeyed too),
|
|
18
|
+
* so it adopts only a drivable child; a finished one leaves the call to the once-per-agent
|
|
19
|
+
* refusal. `createdAt` is the child row's creation time (Run.startedAt, set when the row is
|
|
20
|
+
* written and never rewritten), from which the caller measures its wait bound.
|
|
21
|
+
*/
|
|
22
|
+
export declare function findDelegationChild(db: DelegationChildDb, parentRunId: string, childAgentId: string, parentCallId: string | undefined): Promise<{
|
|
23
|
+
id: string;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
} | null>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { DRIVABLE } from "./run-status.js";
|
|
2
|
+
/**
|
|
3
|
+
* The child a delegation call already created, if any: exact key first (Run.parentCallId, the
|
|
4
|
+
* model's tool-call id), then the single child of that agent with no key. Two or more such
|
|
5
|
+
* children are ambiguous and adopt none.
|
|
6
|
+
*
|
|
7
|
+
* A caller with a call id is a re-run of a recorded step, so an unkeyed child can only be a
|
|
8
|
+
* legacy row created before parentCallId existed; it is adopted in any status, because it may
|
|
9
|
+
* have finished while the lead was between deploys and its result is what the step is owed. A
|
|
10
|
+
* caller without a call id cannot tell a re-run from a new call (its children are unkeyed too),
|
|
11
|
+
* so it adopts only a drivable child; a finished one leaves the call to the once-per-agent
|
|
12
|
+
* refusal. `createdAt` is the child row's creation time (Run.startedAt, set when the row is
|
|
13
|
+
* written and never rewritten), from which the caller measures its wait bound.
|
|
14
|
+
*/
|
|
15
|
+
export async function findDelegationChild(db, parentRunId, childAgentId, parentCallId) {
|
|
16
|
+
const select = { id: true, startedAt: true };
|
|
17
|
+
const found = (row) => ({ id: row.id, createdAt: row.startedAt });
|
|
18
|
+
if (parentCallId) {
|
|
19
|
+
// Same agent too: a call id is the same call only if it names the same sub-agent. A colliding
|
|
20
|
+
// id from another agent is never adopted: its create then fails on the unique key, which the
|
|
21
|
+
// delegate tool answers with a tool-result error (delegation_conflict), never a run failure.
|
|
22
|
+
const keyed = await db.run.findFirst({ where: { parentRunId, parentCallId, agentId: childAgentId }, select });
|
|
23
|
+
if (keyed)
|
|
24
|
+
return found(keyed);
|
|
25
|
+
}
|
|
26
|
+
const legacy = await db.run.findMany({
|
|
27
|
+
where: {
|
|
28
|
+
parentRunId,
|
|
29
|
+
agentId: childAgentId,
|
|
30
|
+
parentCallId: null,
|
|
31
|
+
...(parentCallId ? {} : { status: { in: [...DRIVABLE] } }),
|
|
32
|
+
},
|
|
33
|
+
select,
|
|
34
|
+
take: 2,
|
|
35
|
+
});
|
|
36
|
+
return legacy.length === 1 ? found(legacy[0]) : null;
|
|
37
|
+
}
|
package/dist/core/dispatch.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { Prisma, PrismaClient, Run, RunTrigger, Task } from "#prisma";
|
|
2
2
|
import type { Executor } from "../providers/executor/types.js";
|
|
3
|
+
import { type CodingProvider } from "../coding/provider.js";
|
|
4
|
+
import { type DeclaredService } from "../coding/services/declaration.js";
|
|
5
|
+
import { type ServiceResolution } from "../coding/services/resolve.js";
|
|
3
6
|
import { type AttributionIntent } from "./attribution.js";
|
|
4
7
|
import { type BudgetConstraint } from "./budget-groups.js";
|
|
8
|
+
import { type KnowledgeNoteInput } from "../knowledge/note.js";
|
|
5
9
|
import { type SelfDefectSink } from "./self-defects.js";
|
|
6
10
|
export type DispatchDb = Pick<PrismaClient, "agent" | "run" | "runHostCheck" | "codingRun" | "task" | "webhook" | "budgetGroup" | "$transaction" | "$queryRaw">;
|
|
7
11
|
export type DispatchTx = Pick<Prisma.TransactionClient, "agent" | "run" | "runHostCheck" | "runHostStatus" | "runIssueStatus" | "codingRun" | "codingService" | "task" | "webhook" | "budgetGroup" | "resourceGrant" | "workItem" | "localPullRequest" | "runAttribution" | "$queryRaw" | "$executeRawUnsafe">;
|
|
@@ -63,6 +67,12 @@ export interface DispatchRunOptions {
|
|
|
63
67
|
triggeredById?: string | null;
|
|
64
68
|
/** Sub-agent dispatch (see AgentSubAgent): links this run into a run tree. */
|
|
65
69
|
parentRunId?: string;
|
|
70
|
+
/**
|
|
71
|
+
* The parent's delegation call (the model's tool-call id) that dispatches this sub-agent run.
|
|
72
|
+
* Unique per parent, so a re-executed delegate step finds the child its call created
|
|
73
|
+
* (findDelegationChild) instead of starting a second one.
|
|
74
|
+
*/
|
|
75
|
+
parentCallId?: string;
|
|
66
76
|
/**
|
|
67
77
|
* Cost attribution for a run that starts a new attribution (issue event,
|
|
68
78
|
* linked PR, explicit key), resolved before the call (attribution.ts
|
|
@@ -148,6 +158,19 @@ export declare function markRunFailedFromExecutorError(db: Pick<DispatchDb, "run
|
|
|
148
158
|
* `run_tree_exhausted`, then a sentence for people.
|
|
149
159
|
*/
|
|
150
160
|
export declare function budgetExhaustedError(constraint: BudgetConstraint): string;
|
|
161
|
+
/**
|
|
162
|
+
* Serializes grouped coding dispatches (security review I1). Under
|
|
163
|
+
* Serializable, a row lock taken after the transaction's first read cannot
|
|
164
|
+
* queue anything: the snapshot is already fixed, so each waiter wakes up
|
|
165
|
+
* with a stale view and aborts. LOCK TABLE is the one statement that takes
|
|
166
|
+
* no snapshot, so as the transaction's first statement it makes a waiter's
|
|
167
|
+
* snapshot start only after the previous holder committed. SHARE ROW
|
|
168
|
+
* EXCLUSIVE conflicts with itself and with writes to BudgetGroup rows, but not
|
|
169
|
+
* with the ROW SHARE that foreign-key checks from Agent take, so attaching
|
|
170
|
+
* agents to groups is not blocked. It serializes grouped coding dispatches
|
|
171
|
+
* across all groups; each holds it only for one short transaction.
|
|
172
|
+
*/
|
|
173
|
+
export declare const GROUP_DISPATCH_LOCK_SQL = "LOCK TABLE \"BudgetGroup\" IN SHARE ROW EXCLUSIVE MODE";
|
|
151
174
|
/**
|
|
152
175
|
* Attempts for the persist transaction, and the jittered backoff between
|
|
153
176
|
* them, for serialization failures, deadlocks and transactions that could
|
|
@@ -189,6 +212,25 @@ export type ContinuationCheck = {
|
|
|
189
212
|
* run at all" (a user-facing refusal message, not a dispatch).
|
|
190
213
|
*/
|
|
191
214
|
export declare function checkContinuation(reader: Pick<DispatchTx, "codingRun">, runId: string, repository: string, dispatchingOwnerId?: string | null): Promise<ContinuationCheck>;
|
|
215
|
+
/** What dispatch learned about a coding run's .wardby/services.yaml before its transaction. */
|
|
216
|
+
export type DeclarationOutcome = {
|
|
217
|
+
kind: "none";
|
|
218
|
+
} | {
|
|
219
|
+
kind: "declared";
|
|
220
|
+
services: DeclaredService[];
|
|
221
|
+
} | {
|
|
222
|
+
kind: "refused";
|
|
223
|
+
refusal: string;
|
|
224
|
+
};
|
|
225
|
+
/** The bundle index at a known base ref; also how a deferred coding run reads it when it starts. */
|
|
226
|
+
export declare function readKnowledgeIndexAt(executor: Executor, repository: string, baseRef: string): Promise<KnowledgeNoteInput | undefined>;
|
|
227
|
+
/** The declaration at a known base ref, parsed; also how a deferred coding run reads it when it starts. */
|
|
228
|
+
export declare function readServiceDeclarationAt(executor: Executor, repository: string, baseRef: string): Promise<DeclarationOutcome>;
|
|
229
|
+
/**
|
|
230
|
+
* Inside the transaction: the run's services, or the refusal that stops it. Takes only the
|
|
231
|
+
* catalog, so a deferred coding run's start resolves them the same way with a plain client.
|
|
232
|
+
*/
|
|
233
|
+
export declare function resolveDispatchServices(tx: Pick<Prisma.TransactionClient, "codingService">, outcome: DeclarationOutcome, allowed: unknown, executor: Executor, provider: CodingProvider, request: string, instructions: string | null): Promise<ServiceResolution>;
|
|
192
234
|
/**
|
|
193
235
|
* Persists every detached run input in one transaction, then invokes the
|
|
194
236
|
* executor only after commit. A null result means the caller's transactional
|