@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,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A model request's hold: what the proxy reserves against the run's budget before forwarding it.
|
|
3
|
+
* After a mostly cached reply in the same conversation, the part of the prompt the previous reply
|
|
4
|
+
* read from (or wrote to) the cache is priced at the cache-read rate; everything else, including
|
|
5
|
+
* what the body grew by (one token per byte), at the input + cache-write rates. Capped at the
|
|
6
|
+
* ceiling, today's worst case (the whole body as uncached input), which a reply may never exceed.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { estimateReservationUsd } from "./metering.js";
|
|
10
|
+
/**
|
|
11
|
+
* Anthropic's prompt cache lives 5 minutes from when a request is processed, not from when its reply
|
|
12
|
+
* finishes: a previous request sent longer ago than this says nothing about the cache.
|
|
13
|
+
*/
|
|
14
|
+
export const CACHE_WINDOW_MS = 5 * 60_000;
|
|
15
|
+
export const MIN_CACHED_SHARE = 0.5;
|
|
16
|
+
function withoutCacheControl(value) {
|
|
17
|
+
if (Array.isArray(value))
|
|
18
|
+
return value.map(withoutCacheControl);
|
|
19
|
+
if (!value || typeof value !== "object")
|
|
20
|
+
return value;
|
|
21
|
+
return Object.fromEntries(Object.entries(value)
|
|
22
|
+
.filter(([key]) => key !== "cache_control")
|
|
23
|
+
.map(([key, inner]) => [key, withoutCacheControl(inner)]));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* What identifies one conversation within a run (Claude Code runs several: the main one and its
|
|
27
|
+
* sub-agents). Anthropic: the first message without cache markers (the system prompt carries a
|
|
28
|
+
* per-version billing line). OpenAI: prompt_cache_key, else instructions + the first input item.
|
|
29
|
+
*/
|
|
30
|
+
export function conversationKey(protocol, body) {
|
|
31
|
+
let basis;
|
|
32
|
+
if (protocol === "anthropic-messages") {
|
|
33
|
+
const messages = body.messages;
|
|
34
|
+
if (!Array.isArray(messages) || messages.length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
// Claude Code's first message can carry the date, so a conversation crossing midnight starts a
|
|
37
|
+
// new key (its next request falls back to the worst case once).
|
|
38
|
+
basis = ["anthropic", withoutCacheControl(messages[0])];
|
|
39
|
+
}
|
|
40
|
+
else if (typeof body.prompt_cache_key === "string" && body.prompt_cache_key) {
|
|
41
|
+
basis = ["openai-key", body.prompt_cache_key];
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const input = body.input;
|
|
45
|
+
const first = typeof input === "string" ? input : Array.isArray(input) ? input[0] : undefined;
|
|
46
|
+
if (first === undefined)
|
|
47
|
+
return null;
|
|
48
|
+
basis = ["openai-first", body.instructions ?? null, first];
|
|
49
|
+
}
|
|
50
|
+
return createHash("sha256").update(JSON.stringify(basis)).digest("base64url");
|
|
51
|
+
}
|
|
52
|
+
export function estimateHold(input) {
|
|
53
|
+
const ceilingUsd = estimateReservationUsd(input.bodyBytes, input.maxOutputTokens, input.pricing);
|
|
54
|
+
const full = (fallback) => ({ holdUsd: ceilingUsd, ceilingUsd, basis: "full", fallback });
|
|
55
|
+
const previous = input.previous;
|
|
56
|
+
if (!previous)
|
|
57
|
+
return full("no_previous");
|
|
58
|
+
if (previous.model !== input.model)
|
|
59
|
+
return full("model_changed");
|
|
60
|
+
if (previous.costEstimated)
|
|
61
|
+
return full("previous_estimated");
|
|
62
|
+
if (previous.status !== "completed" || !previous.usage)
|
|
63
|
+
return full("previous_not_completed");
|
|
64
|
+
if (previous.requestBytes === null)
|
|
65
|
+
return full("no_request_bytes");
|
|
66
|
+
if (input.now.getTime() - previous.startedAt.getTime() > CACHE_WINDOW_MS)
|
|
67
|
+
return full("cache_expired");
|
|
68
|
+
if (input.bodyBytes < previous.requestBytes)
|
|
69
|
+
return full("body_shrank");
|
|
70
|
+
const usage = previous.usage;
|
|
71
|
+
const prevPrompt = usage.inputTokens + usage.cacheWriteTokens;
|
|
72
|
+
const cachedTokens = input.protocol === "anthropic-messages"
|
|
73
|
+
? usage.cachedInputTokens + usage.cacheWriteTokens
|
|
74
|
+
: usage.cachedInputTokens;
|
|
75
|
+
if (prevPrompt <= 0 || cachedTokens < prevPrompt * MIN_CACHED_SHARE)
|
|
76
|
+
return full("low_cache_share");
|
|
77
|
+
const uncachedTokens = prevPrompt + (input.bodyBytes - previous.requestBytes) - cachedTokens;
|
|
78
|
+
const { pricing } = input;
|
|
79
|
+
const cacheReadRate = pricing.cachedInputPerMTok ?? pricing.inputPerMTok;
|
|
80
|
+
const cacheWriteRate = pricing.cacheWritePerMTok ?? pricing.inputPerMTok;
|
|
81
|
+
const holdUsd = (cachedTokens * cacheReadRate +
|
|
82
|
+
uncachedTokens * (pricing.inputPerMTok + cacheWriteRate) +
|
|
83
|
+
input.maxOutputTokens * pricing.outputPerMTok) /
|
|
84
|
+
1_000_000;
|
|
85
|
+
return { holdUsd: Math.min(holdUsd, ceilingUsd), ceilingUsd, basis: "cached", cachedTokens, uncachedTokens };
|
|
86
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type ModelPricing } from "../llm/pricing-core.js";
|
|
2
|
+
import type { PreviousReply, ProxyUsage } from "./types.js";
|
|
3
|
+
export interface InterruptedFacts {
|
|
4
|
+
/** Anthropic message_start usage already read (inputTokens includes cache reads, not writes). */
|
|
5
|
+
readUsage?: {
|
|
6
|
+
inputTokens: number;
|
|
7
|
+
cachedInputTokens: number;
|
|
8
|
+
cacheWriteTokens: number;
|
|
9
|
+
};
|
|
10
|
+
/** Output tokens the upstream reported so far (Anthropic message_delta), if any. */
|
|
11
|
+
reportedOutputTokens?: number;
|
|
12
|
+
/** message_start's output count: a placeholder (usually 1), so only a floor, never the count. */
|
|
13
|
+
outputFloorTokens?: number;
|
|
14
|
+
/** A stream that failed before its response started: the provider generated no output. */
|
|
15
|
+
beforeResponse?: boolean;
|
|
16
|
+
/** UTF-8 bytes of output relayed to the client before the break: text, tool input, thinking. */
|
|
17
|
+
relayedOutputBytes: number;
|
|
18
|
+
/** The input of the request's own prompt, from its conversation's previous reply (previousInput). */
|
|
19
|
+
previous?: ProxyUsage;
|
|
20
|
+
/** UTF-8 bytes of the request body the proxy forwarded, when known. */
|
|
21
|
+
bodyBytes?: number;
|
|
22
|
+
/** Median outputTokens of the session's completed replies for the same model, if any. */
|
|
23
|
+
medianOutputTokens?: number;
|
|
24
|
+
/** The request's hold and the output tokens it reserved for. */
|
|
25
|
+
reservationUsd: number;
|
|
26
|
+
maxOutputTokens: number;
|
|
27
|
+
/** The request's worst case (its ceiling); the estimate never exceeds it. Defaults to the hold. */
|
|
28
|
+
ceilingUsd?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface InterruptedEstimate {
|
|
31
|
+
usage: ProxyUsage;
|
|
32
|
+
costUsd: number;
|
|
33
|
+
}
|
|
34
|
+
/** Output tokens for relayed text: ceil(bytes / 3), a deliberately high count. */
|
|
35
|
+
export declare function relayedOutputTokens(bytes: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Prompt tokens for request-body bytes in a settled estimate: ceil(bytes / 3), the same high count
|
|
38
|
+
* as the native gateway's byte estimate. Coding-agent bodies are mostly code, JSON and English,
|
|
39
|
+
* which tokenize at about 3.5 to 4.5 bytes a token, so a token per 3 bytes stays above the real
|
|
40
|
+
* count. Text that tokenizes tighter is mostly multi-byte UTF-8 (3 bytes a character, rarely more
|
|
41
|
+
* than a token each), and base64 images are billed by size, not bytes, so both still lean high.
|
|
42
|
+
* The hold itself still counts a token per byte (hold.ts): this is only the settled estimate.
|
|
43
|
+
*/
|
|
44
|
+
export declare function bodyInputTokens(bytes: number): number;
|
|
45
|
+
/**
|
|
46
|
+
* The input of a cut request from its conversation's previous reply: that reply's prompt and cache
|
|
47
|
+
* split, plus the body's growth since (bodyInputTokens) as uncached input (uncachedInput).
|
|
48
|
+
* Undefined when that reply can't stand for this prompt, as for the hold (hold.ts): another model,
|
|
49
|
+
* estimated or unfinished, an unknown or larger body, or a cache that had expired by the time the
|
|
50
|
+
* request was reserved. The estimate then prices the whole body as uncached input.
|
|
51
|
+
*/
|
|
52
|
+
export declare function previousInput(input: {
|
|
53
|
+
model: string;
|
|
54
|
+
bodyBytes: number | undefined;
|
|
55
|
+
previous: PreviousReply | null;
|
|
56
|
+
pricing: ModelPricing;
|
|
57
|
+
/** When the request was reserved: the hold's own clock. */
|
|
58
|
+
now: Date;
|
|
59
|
+
}): ProxyUsage | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* The best known cost of a reply that broke before its final usage (spec PR 1
|
|
62
|
+
* › 1b): usage already read, else the input from its conversation's previous
|
|
63
|
+
* reply (previousInput), else the whole body as uncached input
|
|
64
|
+
* (bodyInputTokens), else (body size unknown) the input part of the hold; plus
|
|
65
|
+
* the output seen so far. With no output seen, the model's median completed
|
|
66
|
+
* reply, or none while there is no completed reply (a deliberate rule: one cut
|
|
67
|
+
* must not book a whole reserved reply). A stream that failed before its
|
|
68
|
+
* response started generated none. Never more than the request's worst case.
|
|
69
|
+
*/
|
|
70
|
+
export declare function estimateInterrupted(facts: InterruptedFacts, pricing: ModelPricing): InterruptedEstimate;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { computeCost } from "../llm/pricing-core.js";
|
|
2
|
+
import { CACHE_WINDOW_MS } from "./hold.js";
|
|
3
|
+
/** Output tokens for relayed text: ceil(bytes / 3), a deliberately high count. */
|
|
4
|
+
export function relayedOutputTokens(bytes) {
|
|
5
|
+
return bytes > 0 ? Math.ceil(bytes / 3) : 0;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Prompt tokens for request-body bytes in a settled estimate: ceil(bytes / 3), the same high count
|
|
9
|
+
* as the native gateway's byte estimate. Coding-agent bodies are mostly code, JSON and English,
|
|
10
|
+
* which tokenize at about 3.5 to 4.5 bytes a token, so a token per 3 bytes stays above the real
|
|
11
|
+
* count. Text that tokenizes tighter is mostly multi-byte UTF-8 (3 bytes a character, rarely more
|
|
12
|
+
* than a token each), and base64 images are billed by size, not bytes, so both still lean high.
|
|
13
|
+
* The hold itself still counts a token per byte (hold.ts): this is only the settled estimate.
|
|
14
|
+
*/
|
|
15
|
+
export function bodyInputTokens(bytes) {
|
|
16
|
+
return bytes > 0 ? Math.ceil(bytes / 3) : 0;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* New prompt tokens as usage, at the higher of the model's fresh-input and cache-write rates: the
|
|
20
|
+
* provider may write them to its cache (Claude Code marks the latest message; OpenAI GPT-5.6 and
|
|
21
|
+
* later bill cache writes above input), or bill them as input.
|
|
22
|
+
*/
|
|
23
|
+
function uncachedInput(tokens, pricing) {
|
|
24
|
+
const written = (pricing.cacheWritePerMTok ?? pricing.inputPerMTok) > pricing.inputPerMTok;
|
|
25
|
+
return { inputTokens: written ? 0 : tokens, cacheWriteTokens: written ? tokens : 0 };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The input of a cut request from its conversation's previous reply: that reply's prompt and cache
|
|
29
|
+
* split, plus the body's growth since (bodyInputTokens) as uncached input (uncachedInput).
|
|
30
|
+
* Undefined when that reply can't stand for this prompt, as for the hold (hold.ts): another model,
|
|
31
|
+
* estimated or unfinished, an unknown or larger body, or a cache that had expired by the time the
|
|
32
|
+
* request was reserved. The estimate then prices the whole body as uncached input.
|
|
33
|
+
*/
|
|
34
|
+
export function previousInput(input) {
|
|
35
|
+
const { previous, bodyBytes } = input;
|
|
36
|
+
if (!previous || previous.model !== input.model || previous.costEstimated)
|
|
37
|
+
return undefined;
|
|
38
|
+
if (previous.status !== "completed" || !previous.usage)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (bodyBytes === undefined || previous.requestBytes === null || bodyBytes < previous.requestBytes)
|
|
41
|
+
return undefined;
|
|
42
|
+
if (input.now.getTime() - previous.startedAt.getTime() > CACHE_WINDOW_MS)
|
|
43
|
+
return undefined;
|
|
44
|
+
const growth = uncachedInput(bodyInputTokens(bodyBytes - previous.requestBytes), input.pricing);
|
|
45
|
+
const usage = previous.usage;
|
|
46
|
+
return {
|
|
47
|
+
inputTokens: usage.inputTokens + growth.inputTokens,
|
|
48
|
+
cachedInputTokens: usage.cachedInputTokens,
|
|
49
|
+
cacheWriteTokens: usage.cacheWriteTokens + growth.cacheWriteTokens,
|
|
50
|
+
outputTokens: 0,
|
|
51
|
+
reasoningTokens: 0,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The best known cost of a reply that broke before its final usage (spec PR 1
|
|
56
|
+
* › 1b): usage already read, else the input from its conversation's previous
|
|
57
|
+
* reply (previousInput), else the whole body as uncached input
|
|
58
|
+
* (bodyInputTokens), else (body size unknown) the input part of the hold; plus
|
|
59
|
+
* the output seen so far. With no output seen, the model's median completed
|
|
60
|
+
* reply, or none while there is no completed reply (a deliberate rule: one cut
|
|
61
|
+
* must not book a whole reserved reply). A stream that failed before its
|
|
62
|
+
* response started generated none. Never more than the request's worst case.
|
|
63
|
+
*/
|
|
64
|
+
export function estimateInterrupted(facts, pricing) {
|
|
65
|
+
const relayed = relayedOutputTokens(facts.relayedOutputBytes);
|
|
66
|
+
const output = relayed > 0 || facts.beforeResponse ? relayed : (facts.medianOutputTokens ?? 0);
|
|
67
|
+
const clamp = (cost) => Math.max(0, Math.min(cost, facts.ceilingUsd ?? facts.reservationUsd));
|
|
68
|
+
if (facts.readUsage) {
|
|
69
|
+
const usage = {
|
|
70
|
+
...facts.readUsage,
|
|
71
|
+
outputTokens: facts.reportedOutputTokens ?? Math.max(facts.outputFloorTokens ?? 0, output),
|
|
72
|
+
reasoningTokens: 0,
|
|
73
|
+
};
|
|
74
|
+
return { usage, costUsd: clamp(computeCost(pricing, usage)) };
|
|
75
|
+
}
|
|
76
|
+
if (facts.previous) {
|
|
77
|
+
const usage = {
|
|
78
|
+
inputTokens: facts.previous.inputTokens,
|
|
79
|
+
cachedInputTokens: facts.previous.cachedInputTokens,
|
|
80
|
+
cacheWriteTokens: facts.previous.cacheWriteTokens,
|
|
81
|
+
outputTokens: output,
|
|
82
|
+
reasoningTokens: 0,
|
|
83
|
+
};
|
|
84
|
+
return { usage, costUsd: clamp(computeCost(pricing, usage)) };
|
|
85
|
+
}
|
|
86
|
+
if (facts.bodyBytes !== undefined) {
|
|
87
|
+
const usage = {
|
|
88
|
+
...uncachedInput(bodyInputTokens(facts.bodyBytes), pricing),
|
|
89
|
+
cachedInputTokens: 0,
|
|
90
|
+
outputTokens: output,
|
|
91
|
+
reasoningTokens: 0,
|
|
92
|
+
};
|
|
93
|
+
return { usage, costUsd: clamp(computeCost(pricing, usage)) };
|
|
94
|
+
}
|
|
95
|
+
const usage = {
|
|
96
|
+
inputTokens: 0,
|
|
97
|
+
cachedInputTokens: 0,
|
|
98
|
+
cacheWriteTokens: 0,
|
|
99
|
+
outputTokens: output,
|
|
100
|
+
reasoningTokens: 0,
|
|
101
|
+
};
|
|
102
|
+
const inputPart = facts.reservationUsd - (facts.maxOutputTokens * pricing.outputPerMTok) / 1_000_000;
|
|
103
|
+
return { usage, costUsd: clamp(inputPart + (usage.outputTokens * pricing.outputPerMTok) / 1_000_000) };
|
|
104
|
+
}
|
|
@@ -1,18 +1,31 @@
|
|
|
1
|
-
import { type CreateProxySessionInput, type ProxyLedger, type ProxyRequest, type ProxySession, type ProxyUsage, type ReserveProxyRequestInput, type ReserveProxyRequestResult } from "./types.js";
|
|
1
|
+
import { type PreviousReply, type CreateProxySessionInput, type ProxyLedger, type ProxyRefusalRecord, type ProxyRequest, type ProxySession, type ProxyUsage, type ReserveProxyRequestInput, type ReserveProxyRequestResult } from "./types.js";
|
|
2
2
|
/** Deterministic contract adapter. Sharing one instance simulates a proxy restart. */
|
|
3
3
|
export declare class MemoryProxyLedger implements ProxyLedger {
|
|
4
|
+
private readonly options;
|
|
4
5
|
private readonly sessions;
|
|
5
6
|
private readonly sessionByCapability;
|
|
6
7
|
private readonly requests;
|
|
7
8
|
private readonly requestBySessionKey;
|
|
9
|
+
private readonly startedAt;
|
|
10
|
+
constructor(options?: {
|
|
11
|
+
now?: () => Date;
|
|
12
|
+
});
|
|
8
13
|
createSession(input: CreateProxySessionInput): Promise<void>;
|
|
9
14
|
findSessionByCapabilityHash(capabilityHash: string): Promise<ProxySession | null>;
|
|
10
15
|
reserve(input: ReserveProxyRequestInput): Promise<ReserveProxyRequestResult>;
|
|
11
16
|
complete(requestId: string, usage: ProxyUsage, actualCostUsd: number, upstreamStatus: number): Promise<ProxyRequest>;
|
|
12
17
|
release(requestId: string, upstreamStatus: number): Promise<void>;
|
|
13
|
-
markUncertain(requestId: string, upstreamStatus?: number
|
|
18
|
+
markUncertain(requestId: string, upstreamStatus?: number, estimate?: {
|
|
19
|
+
usage: ProxyUsage;
|
|
20
|
+
costUsd: number;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
settlementHints(sessionId: string, model: string): Promise<{
|
|
23
|
+
medianOutputTokens?: number;
|
|
24
|
+
}>;
|
|
25
|
+
previousReply(sessionId: string, conversationKey: string): Promise<PreviousReply | null>;
|
|
14
26
|
cancelSession(sessionId: string): Promise<void>;
|
|
15
27
|
budgetExhausted(sessionId: string): Promise<boolean>;
|
|
28
|
+
budgetRefusal(sessionId: string): Promise<ProxyRefusalRecord | null>;
|
|
16
29
|
recordUpstreamFailure(sessionId: string, code: string): Promise<void>;
|
|
17
30
|
upstreamFailure(sessionId: string): Promise<string | null>;
|
|
18
31
|
getRequest(requestId: string): Promise<ProxyRequest | null>;
|
|
@@ -5,6 +5,7 @@ function cloneSession(session) {
|
|
|
5
5
|
allowedModels: [...session.allowedModels],
|
|
6
6
|
deadlineAt: new Date(session.deadlineAt),
|
|
7
7
|
budgetExhaustedAt: session.budgetExhaustedAt ? new Date(session.budgetExhaustedAt) : null,
|
|
8
|
+
budgetRefusal: session.budgetRefusal ? { ...session.budgetRefusal } : null,
|
|
8
9
|
upstreamFailure: session.upstreamFailure ?? null,
|
|
9
10
|
terms: session.terms
|
|
10
11
|
? { version: session.terms.version, entry: { ...session.terms.entry, efforts: [...session.terms.entry.efforts] } }
|
|
@@ -20,10 +21,15 @@ function cloneRequest(request) {
|
|
|
20
21
|
}
|
|
21
22
|
/** Deterministic contract adapter. Sharing one instance simulates a proxy restart. */
|
|
22
23
|
export class MemoryProxyLedger {
|
|
24
|
+
options;
|
|
23
25
|
sessions = new Map();
|
|
24
26
|
sessionByCapability = new Map();
|
|
25
27
|
requests = new Map();
|
|
26
28
|
requestBySessionKey = new Map();
|
|
29
|
+
startedAt = new Map();
|
|
30
|
+
constructor(options = {}) {
|
|
31
|
+
this.options = options;
|
|
32
|
+
}
|
|
27
33
|
async createSession(input) {
|
|
28
34
|
if ([...this.sessions.values()].some((session) => session.runId === input.runId)) {
|
|
29
35
|
throw new Error("proxy_session_exists");
|
|
@@ -54,22 +60,47 @@ export class MemoryProxyLedger {
|
|
|
54
60
|
const existingId = this.requestBySessionKey.get(lookupKey);
|
|
55
61
|
if (existingId)
|
|
56
62
|
return { outcome: "duplicate", request: cloneRequest(this.requests.get(existingId)) };
|
|
57
|
-
let
|
|
63
|
+
let spent = 0;
|
|
64
|
+
let heldReserved = 0;
|
|
65
|
+
let heldUncertain = 0;
|
|
66
|
+
let done = 0;
|
|
58
67
|
for (const request of this.requests.values()) {
|
|
59
68
|
if (request.sessionId !== input.sessionId)
|
|
60
69
|
continue;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
|
|
70
|
+
// An uncertain request settled at an estimate counts at it; one without an estimate keeps its hold.
|
|
71
|
+
const settled = request.status === "completed" || (request.status === "uncertain" && request.costEstimated);
|
|
72
|
+
if (settled) {
|
|
73
|
+
spent += request.actualCostUsd;
|
|
74
|
+
done += 1;
|
|
75
|
+
}
|
|
76
|
+
else if (request.status === "reserved")
|
|
77
|
+
heldReserved += request.reservationUsd;
|
|
78
|
+
else if (request.status === "uncertain")
|
|
79
|
+
heldUncertain += request.reservationUsd;
|
|
65
80
|
}
|
|
81
|
+
const committedOrHeld = spent + heldReserved + heldUncertain;
|
|
66
82
|
if (committedOrHeld + input.reservationUsd >= session.budgetUsd) {
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
const details = {
|
|
84
|
+
budgetUsd: session.budgetUsd,
|
|
85
|
+
spentUsd: spent,
|
|
86
|
+
heldReservedUsd: heldReserved,
|
|
87
|
+
heldUncertainUsd: heldUncertain,
|
|
88
|
+
refusedHoldUsd: input.reservationUsd,
|
|
89
|
+
...(input.reservationBasis ? { refusedHoldBasis: input.reservationBasis } : {}),
|
|
90
|
+
...(input.ceilingUsd !== undefined ? { refusedHoldCeilingUsd: input.ceilingUsd } : {}),
|
|
91
|
+
model: input.model,
|
|
92
|
+
turn: done + 1,
|
|
93
|
+
};
|
|
94
|
+
if (!session.budgetExhaustedAt) {
|
|
95
|
+
session.budgetExhaustedAt = new Date(input.now);
|
|
96
|
+
session.budgetRefusal = { source: "proxy", ...details };
|
|
97
|
+
}
|
|
98
|
+
return { outcome: "budget_exhausted", details };
|
|
69
99
|
}
|
|
70
100
|
const request = { ...input, pricing: { ...input.pricing }, status: "reserved" };
|
|
71
101
|
this.requests.set(request.id, request);
|
|
72
102
|
this.requestBySessionKey.set(lookupKey, request.id);
|
|
103
|
+
this.startedAt.set(request.id, new Date(input.now));
|
|
73
104
|
return { outcome: "reserved", request: cloneRequest(request) };
|
|
74
105
|
}
|
|
75
106
|
async complete(requestId, usage, actualCostUsd, upstreamStatus) {
|
|
@@ -86,6 +117,7 @@ export class MemoryProxyLedger {
|
|
|
86
117
|
request.actualCostUsd = actualCostUsd;
|
|
87
118
|
request.usage = { ...usage };
|
|
88
119
|
request.upstreamStatus = upstreamStatus;
|
|
120
|
+
request.costEstimated = false;
|
|
89
121
|
return cloneRequest(request);
|
|
90
122
|
}
|
|
91
123
|
async release(requestId, upstreamStatus) {
|
|
@@ -95,12 +127,52 @@ export class MemoryProxyLedger {
|
|
|
95
127
|
request.status = "released";
|
|
96
128
|
request.upstreamStatus = upstreamStatus;
|
|
97
129
|
}
|
|
98
|
-
async markUncertain(requestId, upstreamStatus) {
|
|
130
|
+
async markUncertain(requestId, upstreamStatus, estimate) {
|
|
99
131
|
const request = this.requiredRequest(requestId);
|
|
100
132
|
if (request.status !== "reserved")
|
|
101
133
|
return;
|
|
102
134
|
request.status = "uncertain";
|
|
103
135
|
request.upstreamStatus = upstreamStatus;
|
|
136
|
+
if (estimate) {
|
|
137
|
+
request.actualCostUsd = estimate.costUsd;
|
|
138
|
+
request.usage = { ...estimate.usage };
|
|
139
|
+
request.costEstimated = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async settlementHints(sessionId, model) {
|
|
143
|
+
const outputs = [];
|
|
144
|
+
for (const request of this.requests.values()) {
|
|
145
|
+
if (request.sessionId !== sessionId || request.model !== model)
|
|
146
|
+
continue;
|
|
147
|
+
if (request.status !== "completed" || !request.usage)
|
|
148
|
+
continue;
|
|
149
|
+
outputs.push(request.usage.outputTokens);
|
|
150
|
+
}
|
|
151
|
+
outputs.sort((a, b) => a - b);
|
|
152
|
+
return {
|
|
153
|
+
// The lower middle for an even count, as Postgres's percentile_disc(0.5).
|
|
154
|
+
...(outputs.length > 0 ? { medianOutputTokens: outputs[Math.ceil(outputs.length / 2) - 1] } : {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
async previousReply(sessionId, conversationKey) {
|
|
158
|
+
let latest;
|
|
159
|
+
// Map iteration follows insertion order: the last match is the latest request.
|
|
160
|
+
for (const request of this.requests.values()) {
|
|
161
|
+
if (request.sessionId !== sessionId || request.conversationKey !== conversationKey)
|
|
162
|
+
continue;
|
|
163
|
+
if (request.status === "completed" || request.status === "uncertain")
|
|
164
|
+
latest = request;
|
|
165
|
+
}
|
|
166
|
+
if (!latest)
|
|
167
|
+
return null;
|
|
168
|
+
return {
|
|
169
|
+
model: latest.model,
|
|
170
|
+
status: latest.status,
|
|
171
|
+
costEstimated: latest.costEstimated === true,
|
|
172
|
+
...(latest.usage ? { usage: { ...latest.usage } } : {}),
|
|
173
|
+
requestBytes: latest.requestBytes ?? null,
|
|
174
|
+
startedAt: this.startedAt.get(latest.id) ?? new Date(0),
|
|
175
|
+
};
|
|
104
176
|
}
|
|
105
177
|
async cancelSession(sessionId) {
|
|
106
178
|
const session = this.sessions.get(sessionId);
|
|
@@ -110,6 +182,10 @@ export class MemoryProxyLedger {
|
|
|
110
182
|
async budgetExhausted(sessionId) {
|
|
111
183
|
return Boolean(this.sessions.get(sessionId)?.budgetExhaustedAt);
|
|
112
184
|
}
|
|
185
|
+
async budgetRefusal(sessionId) {
|
|
186
|
+
const refusal = this.sessions.get(sessionId)?.budgetRefusal;
|
|
187
|
+
return refusal ? { ...refusal } : null;
|
|
188
|
+
}
|
|
113
189
|
async recordUpstreamFailure(sessionId, code) {
|
|
114
190
|
const session = this.sessions.get(sessionId);
|
|
115
191
|
if (session)
|
|
@@ -17,9 +17,25 @@ export declare function safeUpstreamErrorCode(record: Record<string, unknown>):
|
|
|
17
17
|
/** Accumulates Anthropic's split input/output usage until message_stop. */
|
|
18
18
|
export declare class AnthropicSseUsageTracker {
|
|
19
19
|
private startUsage?;
|
|
20
|
+
/** message_start's output count: a placeholder (usually 1), not a running count. */
|
|
21
|
+
private startOutputTokens?;
|
|
22
|
+
/** message_delta's running output count. */
|
|
20
23
|
private outputTokens?;
|
|
21
24
|
private stopped;
|
|
22
25
|
consume(frame: string): TerminalUsage;
|
|
26
|
+
/**
|
|
27
|
+
* What a cut stream reported before its message_stop: start usage (input incl. cache reads), the
|
|
28
|
+
* output count message_delta reported, and message_start's output count as a floor only.
|
|
29
|
+
*/
|
|
30
|
+
partial(): {
|
|
31
|
+
readUsage?: {
|
|
32
|
+
inputTokens: number;
|
|
33
|
+
cachedInputTokens: number;
|
|
34
|
+
cacheWriteTokens: number;
|
|
35
|
+
};
|
|
36
|
+
reportedOutputTokens?: number;
|
|
37
|
+
outputFloorTokens?: number;
|
|
38
|
+
};
|
|
23
39
|
}
|
|
24
40
|
/** The rates a request is billed at, tagged with their version. Picks only the price fields: a catalog entry's routing/shape fields stay out of the ledger. */
|
|
25
41
|
export declare function pricingSnapshot(version: string, pricing: ModelPricing): PricingSnapshot;
|
|
@@ -134,6 +134,9 @@ function sseEvent(frame) {
|
|
|
134
134
|
/** Accumulates Anthropic's split input/output usage until message_stop. */
|
|
135
135
|
export class AnthropicSseUsageTracker {
|
|
136
136
|
startUsage;
|
|
137
|
+
/** message_start's output count: a placeholder (usually 1), not a running count. */
|
|
138
|
+
startOutputTokens;
|
|
139
|
+
/** message_delta's running output count. */
|
|
137
140
|
outputTokens;
|
|
138
141
|
stopped = false;
|
|
139
142
|
consume(frame) {
|
|
@@ -156,8 +159,9 @@ export class AnthropicSseUsageTracker {
|
|
|
156
159
|
tokenCount(record.cache_read_input_tokens ?? 0, "cache_read_input_tokens");
|
|
157
160
|
tokenCount(record.cache_creation_input_tokens ?? 0, "cache_creation_input_tokens");
|
|
158
161
|
this.startUsage = record;
|
|
159
|
-
if (record.output_tokens !== undefined)
|
|
160
|
-
this.
|
|
162
|
+
if (record.output_tokens !== undefined) {
|
|
163
|
+
this.startOutputTokens = tokenCount(record.output_tokens, "output_tokens");
|
|
164
|
+
}
|
|
161
165
|
return { terminal: false };
|
|
162
166
|
}
|
|
163
167
|
case "message_delta": {
|
|
@@ -168,19 +172,38 @@ export class AnthropicSseUsageTracker {
|
|
|
168
172
|
return { terminal: false };
|
|
169
173
|
}
|
|
170
174
|
case "message_stop": {
|
|
171
|
-
|
|
175
|
+
const outputTokens = this.outputTokens ?? this.startOutputTokens;
|
|
176
|
+
if (this.stopped || !this.startUsage || outputTokens === undefined) {
|
|
172
177
|
return { terminal: true };
|
|
173
178
|
}
|
|
174
179
|
this.stopped = true;
|
|
175
180
|
return {
|
|
176
181
|
terminal: true,
|
|
177
|
-
usage: parseAnthropicAuthoritativeUsage({ ...this.startUsage, output_tokens:
|
|
182
|
+
usage: parseAnthropicAuthoritativeUsage({ ...this.startUsage, output_tokens: outputTokens }),
|
|
178
183
|
};
|
|
179
184
|
}
|
|
180
185
|
default:
|
|
181
186
|
return { terminal: false };
|
|
182
187
|
}
|
|
183
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* What a cut stream reported before its message_stop: start usage (input incl. cache reads), the
|
|
191
|
+
* output count message_delta reported, and message_start's output count as a floor only.
|
|
192
|
+
*/
|
|
193
|
+
partial() {
|
|
194
|
+
if (!this.startUsage)
|
|
195
|
+
return this.outputTokens === undefined ? {} : { reportedOutputTokens: this.outputTokens };
|
|
196
|
+
const cached = tokenCount(this.startUsage.cache_read_input_tokens ?? 0, "cache_read_input_tokens");
|
|
197
|
+
return {
|
|
198
|
+
readUsage: {
|
|
199
|
+
inputTokens: tokenCount(this.startUsage.input_tokens, "input_tokens") + cached,
|
|
200
|
+
cachedInputTokens: cached,
|
|
201
|
+
cacheWriteTokens: tokenCount(this.startUsage.cache_creation_input_tokens ?? 0, "cache_creation_input_tokens"),
|
|
202
|
+
},
|
|
203
|
+
...(this.outputTokens !== undefined ? { reportedOutputTokens: this.outputTokens } : {}),
|
|
204
|
+
...(this.startOutputTokens !== undefined ? { outputFloorTokens: this.startOutputTokens } : {}),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
184
207
|
}
|
|
185
208
|
/** The rates a request is billed at, tagged with their version. Picks only the price fields: a catalog entry's routing/shape fields stay out of the ledger. */
|
|
186
209
|
export function pricingSnapshot(version, pricing) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PrismaClient } from "#prisma";
|
|
2
|
-
import type { CreateProxySessionInput, ProxyLedger, ProxyRequest, ProxySession, ProxyUsage, ReserveProxyRequestInput, ReserveProxyRequestResult } from "./types.js";
|
|
2
|
+
import type { CreateProxySessionInput, PreviousReply, ProxyLedger, ProxyRefusalRecord, ProxyRequest, ProxySession, ProxyUsage, ReserveProxyRequestInput, ReserveProxyRequestResult } from "./types.js";
|
|
3
3
|
export type PrismaProxyLedgerDb = Pick<PrismaClient, "$transaction" | "$queryRaw" | "$executeRaw">;
|
|
4
4
|
/** How long a ledger transaction waits for a pool connection (Prisma's
|
|
5
5
|
* default is 2 s). A model request fails outright when this runs out, so it
|
|
@@ -22,10 +22,23 @@ export declare class PrismaProxyLedger implements ProxyLedger {
|
|
|
22
22
|
findSessionByCapabilityHash(capabilityHash: string): Promise<ProxySession | null>;
|
|
23
23
|
reserve(input: ReserveProxyRequestInput): Promise<ReserveProxyRequestResult>;
|
|
24
24
|
complete(requestId: string, usage: ProxyUsage, actualCostUsd: number, upstreamStatus: number): Promise<ProxyRequest>;
|
|
25
|
+
/**
|
|
26
|
+
* Recomputes the run's totals (Run) and this model's usage (RunModelUsage) from its settled
|
|
27
|
+
* requests: completed ones and uncertain ones settled at an estimate. Set, never incremented.
|
|
28
|
+
*/
|
|
29
|
+
private recomputeRunTotals;
|
|
25
30
|
release(requestId: string, upstreamStatus: number): Promise<void>;
|
|
26
|
-
markUncertain(requestId: string, upstreamStatus?: number
|
|
31
|
+
markUncertain(requestId: string, upstreamStatus?: number, estimate?: {
|
|
32
|
+
usage: ProxyUsage;
|
|
33
|
+
costUsd: number;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
settlementHints(sessionId: string, model: string): Promise<{
|
|
36
|
+
medianOutputTokens?: number;
|
|
37
|
+
}>;
|
|
38
|
+
previousReply(sessionId: string, conversationKey: string): Promise<PreviousReply | null>;
|
|
27
39
|
cancelSession(sessionId: string): Promise<void>;
|
|
28
40
|
budgetExhausted(sessionId: string): Promise<boolean>;
|
|
41
|
+
budgetRefusal(sessionId: string): Promise<ProxyRefusalRecord | null>;
|
|
29
42
|
recordUpstreamFailure(sessionId: string, code: string): Promise<void>;
|
|
30
43
|
upstreamFailure(sessionId: string): Promise<string | null>;
|
|
31
44
|
getRequest(requestId: string): Promise<ProxyRequest | null>;
|