mixdog 1.3.5 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +35 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/provider-admin.mjs +2 -1
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +142 -190
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// anthropic-cache-warm.mjs — the cache-warm mode both Anthropic providers
|
|
2
|
+
// expose as `sendCacheWarm` (session/cache-warm.mjs): one POST of the
|
|
3
|
+
// request the provider's own builder produces, no retry, fallback, re-send,
|
|
4
|
+
// wait or account rotation, and the stream cut at the first content block
|
|
5
|
+
// once the usage (cache read / write) has been reported. Right before the
|
|
6
|
+
// POST the account gate (cache-warm-admission.mjs) may skip it; a refusal is
|
|
7
|
+
// fed into the shared rate-limit and roster state. The request is bounded by
|
|
8
|
+
// the providers' own watchdogs: the first-byte timeout until the usage
|
|
9
|
+
// arrives, then the SSE idle timeout between events. Usage is handed to
|
|
10
|
+
// `onUsage` as it arrives, so a warm that fails or is aborted after the
|
|
11
|
+
// provider accepted it is still accounted. Every exit cancels the stream and
|
|
12
|
+
// aborts the transport.
|
|
13
|
+
import { PROVIDER_FIRST_BYTE_TIMEOUT_MS, PROVIDER_SSE_IDLE_TIMEOUT_MS } from '../stall-policy.mjs';
|
|
14
|
+
import { updateTurnUsage } from './anthropic-sse-turn/turn-state.mjs';
|
|
15
|
+
import { _anthropicSseError } from './anthropic-sse.mjs';
|
|
16
|
+
import { anthropicQuotaError } from './anthropic-oauth-request/initial-status.mjs';
|
|
17
|
+
import { cacheWarmAccountBlock, cacheWarmBlockedError, recordCacheWarmRefusal } from './cache-warm-admission.mjs';
|
|
18
|
+
import { scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
|
|
19
|
+
|
|
20
|
+
const SSE_LABELS = Object.freeze({ display: 'Anthropic cache warm' });
|
|
21
|
+
|
|
22
|
+
function usageSnapshot(usage) {
|
|
23
|
+
const { raw: _raw, ...rest } = usage;
|
|
24
|
+
return { ...rest };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// An abort deadline: `arm(ms)` (re)starts it; it fires `controller.abort`.
|
|
28
|
+
function watchdog(controller) {
|
|
29
|
+
let timer = null;
|
|
30
|
+
return {
|
|
31
|
+
arm(ms, what) {
|
|
32
|
+
if (timer) clearTimeout(timer);
|
|
33
|
+
timer = setTimeout(() => controller.abort(new Error(`cache warm ${what} timed out after ${ms}ms`)), ms);
|
|
34
|
+
timer.unref?.();
|
|
35
|
+
},
|
|
36
|
+
clear() {
|
|
37
|
+
if (timer) clearTimeout(timer);
|
|
38
|
+
timer = null;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Read a warm's SSE stream until usage is known and the first content block
|
|
45
|
+
* starts, or the message ends. Resolves the usage; a stream error rejects
|
|
46
|
+
* with `error.usage` set to what was reported before it. `onChunk` hears
|
|
47
|
+
* every chunk (the idle watchdog). The stream is cancelled on every exit.
|
|
48
|
+
*/
|
|
49
|
+
export async function readCacheWarmStream(response, { onUsage = () => {}, onChunk = () => {} } = {}) {
|
|
50
|
+
const usage = { inputTokens: 0, outputTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, raw: null };
|
|
51
|
+
let reported = false;
|
|
52
|
+
const report = (raw) => {
|
|
53
|
+
if (!raw || typeof raw !== 'object') return;
|
|
54
|
+
updateTurnUsage(usage, raw);
|
|
55
|
+
reported = true;
|
|
56
|
+
onUsage(usageSnapshot(usage));
|
|
57
|
+
};
|
|
58
|
+
const reader = response.body.getReader();
|
|
59
|
+
const decoder = new TextDecoder();
|
|
60
|
+
let buffer = '';
|
|
61
|
+
try {
|
|
62
|
+
for (;;) {
|
|
63
|
+
const { value, done } = await reader.read();
|
|
64
|
+
if (done) break;
|
|
65
|
+
buffer += decoder.decode(value, { stream: true });
|
|
66
|
+
let cut = buffer.indexOf('\n\n');
|
|
67
|
+
while (cut >= 0) {
|
|
68
|
+
const frame = buffer.slice(0, cut);
|
|
69
|
+
buffer = buffer.slice(cut + 2);
|
|
70
|
+
cut = buffer.indexOf('\n\n');
|
|
71
|
+
const data = frame
|
|
72
|
+
.split('\n')
|
|
73
|
+
.filter((line) => line.startsWith('data:'))
|
|
74
|
+
.map((line) => line.slice(5).trimStart())
|
|
75
|
+
.join('\n');
|
|
76
|
+
if (!data) continue;
|
|
77
|
+
let event;
|
|
78
|
+
try {
|
|
79
|
+
event = JSON.parse(data);
|
|
80
|
+
} catch {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (event?.type === 'error' || event?.error) throw _anthropicSseError(event, SSE_LABELS);
|
|
84
|
+
if (event.type === 'message_start') report(event.message?.usage);
|
|
85
|
+
else if (event.type === 'message_delta') report(event.usage);
|
|
86
|
+
else if (event.type === 'content_block_start' && reported) {
|
|
87
|
+
// The prefix was read (and the cache refreshed) before any content:
|
|
88
|
+
// nothing generated after this point is needed.
|
|
89
|
+
return usageSnapshot(usage);
|
|
90
|
+
} else if (event.type === 'message_stop') return usageSnapshot(usage);
|
|
91
|
+
}
|
|
92
|
+
onChunk(reported);
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (error && typeof error === 'object' && error.usage === undefined) {
|
|
96
|
+
error.usage = reported ? usageSnapshot(usage) : null;
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
} finally {
|
|
100
|
+
await reader.cancel().catch(() => {});
|
|
101
|
+
}
|
|
102
|
+
return usageSnapshot(usage);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* One warm on account instance `instance` (roster account `accountId`, empty
|
|
107
|
+
* for a provider without a roster) of `providerName`: the account gate, then
|
|
108
|
+
* `post(signal)` (the provider's single POST of its built body), then the
|
|
109
|
+
* stream. A refusal reaches the shared rate-limit and roster state; the
|
|
110
|
+
* transport is aborted on every exit.
|
|
111
|
+
*/
|
|
112
|
+
export async function sendAnthropicCacheWarm({
|
|
113
|
+
providerName,
|
|
114
|
+
instance,
|
|
115
|
+
accountId = '',
|
|
116
|
+
model,
|
|
117
|
+
opts = {},
|
|
118
|
+
post,
|
|
119
|
+
onUsage,
|
|
120
|
+
}) {
|
|
121
|
+
const blocked = cacheWarmAccountBlock(providerName, instance, {
|
|
122
|
+
accountId,
|
|
123
|
+
model,
|
|
124
|
+
sessionId: opts.session?.id || opts.sessionId || '',
|
|
125
|
+
});
|
|
126
|
+
if (blocked) throw cacheWarmBlockedError(blocked);
|
|
127
|
+
const controller = new AbortController();
|
|
128
|
+
const callerSignal = opts.signal;
|
|
129
|
+
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
130
|
+
if (callerSignal?.aborted) controller.abort(callerSignal.reason);
|
|
131
|
+
else callerSignal?.addEventListener?.('abort', onCallerAbort, { once: true });
|
|
132
|
+
const deadline = watchdog(controller);
|
|
133
|
+
deadline.arm(PROVIDER_FIRST_BYTE_TIMEOUT_MS, 'first byte');
|
|
134
|
+
try {
|
|
135
|
+
const response = await post(controller.signal);
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
const bodyText = await response.text().catch(() => '');
|
|
138
|
+
throw anthropicQuotaError(response.status, response.headers, bodyText);
|
|
139
|
+
}
|
|
140
|
+
return await readCacheWarmStream(response, {
|
|
141
|
+
onUsage,
|
|
142
|
+
onChunk: (reported) => {
|
|
143
|
+
if (reported) deadline.arm(PROVIDER_SSE_IDLE_TIMEOUT_MS, 'stream');
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
} catch (error) {
|
|
147
|
+
// The warm's own error is what the caller needs; a failure to persist the
|
|
148
|
+
// refusal (quota / roster state) is reported, scrubbed, like the other
|
|
149
|
+
// credential and account-state write failures of the Anthropic providers.
|
|
150
|
+
await recordCacheWarmRefusal(providerName, instance, error, {
|
|
151
|
+
accountId,
|
|
152
|
+
model,
|
|
153
|
+
aborted: Boolean(callerSignal?.aborted),
|
|
154
|
+
}).catch((recordError) => {
|
|
155
|
+
process.stderr.write(
|
|
156
|
+
`[anthropic-cache-warm] refusal record failed: ${scrubOAuthSecrets(recordError?.message || String(recordError))}\n`
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
throw error;
|
|
160
|
+
} finally {
|
|
161
|
+
callerSignal?.removeEventListener?.('abort', onCallerAbort);
|
|
162
|
+
deadline.clear();
|
|
163
|
+
controller.abort(new Error('cache warm finished'));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -22,11 +22,15 @@ export function parseMaxTokensContextOverflow(status, message) {
|
|
|
22
22
|
const match = OVERFLOW_RE.exec(String(message || ''));
|
|
23
23
|
if (!match) return null;
|
|
24
24
|
const [inputTokens, maxTokens, contextLimit] = match.slice(1).map((value) => Number.parseInt(value, 10));
|
|
25
|
-
return [inputTokens, maxTokens, contextLimit].every(Number.isFinite)
|
|
25
|
+
return [inputTokens, maxTokens, contextLimit].every(Number.isFinite)
|
|
26
|
+
? { inputTokens, maxTokens, contextLimit }
|
|
27
|
+
: null;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
const thinkingBudget = (body) =>
|
|
29
|
-
body?.thinking?.type === 'enabled' && Number(body.thinking.budget_tokens) > 0
|
|
31
|
+
body?.thinking?.type === 'enabled' && Number(body.thinking.budget_tokens) > 0
|
|
32
|
+
? Number(body.thinking.budget_tokens)
|
|
33
|
+
: 0;
|
|
30
34
|
|
|
31
35
|
/**
|
|
32
36
|
* Shrink `body.max_tokens` to fit the reported context. Returns true when the
|
|
@@ -159,8 +159,8 @@ function deferredAnthropicTools(activeTools, messages, opts, provider = 'anthrop
|
|
|
159
159
|
return sharedDeferredAnthropicTools(activeTools, messages, opts, provider);
|
|
160
160
|
}
|
|
161
161
|
// `provider`: the engine's name (a gateway Messages engine runs under its gateway's).
|
|
162
|
-
export function requestAnthropicTools(tools, messages, opts, provider = 'anthropic') {
|
|
163
|
-
return sharedRequestAnthropicTools(tools, messages, opts, provider);
|
|
162
|
+
export function requestAnthropicTools(tools, messages, opts, provider = 'anthropic', config = {}) {
|
|
163
|
+
return sharedRequestAnthropicTools(tools, messages, opts, provider, config);
|
|
164
164
|
}
|
|
165
165
|
// Test-only: expose the lowering so the steering-provenance test can assert
|
|
166
166
|
// the API-key provider keeps steering-tagged user turns distinct (mirrors
|
|
@@ -10,7 +10,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
|
|
|
10
10
|
// source release just to advance the user-agent version.
|
|
11
11
|
// Claude Opus 5.5 requires 2.1.280 or newer. The release workflow raises this
|
|
12
12
|
// to the published CLI version (scripts/sync-client-version-floors.mjs).
|
|
13
|
-
export const DEFAULT_CLI_VERSION = '2.1.
|
|
13
|
+
export const DEFAULT_CLI_VERSION = '2.1.311';
|
|
14
14
|
export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
|
|
15
15
|
|
|
16
16
|
const CACHE_SCHEMA_VERSION = 1;
|
|
@@ -15,6 +15,7 @@ import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs
|
|
|
15
15
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
16
16
|
import { modelProxyClientMode, serverModelCredentialsDisabledError } from '../../../shared/model-proxy-mode.mjs';
|
|
17
17
|
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
18
|
+
import { TIMEOUT_PHASE } from '../../../shared/provider-timeout-phase.mjs';
|
|
18
19
|
import { claudeCliUserAgent, resolveCliVersion } from './anthropic-oauth-client-version.mjs';
|
|
19
20
|
import {
|
|
20
21
|
accountIdentityFields,
|
|
@@ -375,7 +376,9 @@ async function _refreshOAuthCredentialsUnlocked(creds) {
|
|
|
375
376
|
return refreshed;
|
|
376
377
|
} catch (err) {
|
|
377
378
|
if (err?.name === 'AbortError') {
|
|
378
|
-
throw new Error('Anthropic OAuth token refresh timed out after 30000ms')
|
|
379
|
+
throw Object.assign(new Error('Anthropic OAuth token refresh timed out after 30000ms'), {
|
|
380
|
+
timeoutPhase: TIMEOUT_PHASE.AUTH,
|
|
381
|
+
});
|
|
379
382
|
}
|
|
380
383
|
throw err;
|
|
381
384
|
} finally {
|
|
@@ -12,7 +12,9 @@ import { sendGzipCompressed } from '../lib/request-compression.mjs';
|
|
|
12
12
|
const API_URL = 'https://api.anthropic.com/v1/messages';
|
|
13
13
|
export { ANTHROPIC_VERSION };
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// `plain`: exactly one uncompressed POST (a cache warm), so no compression
|
|
16
|
+
// rejection resend can follow.
|
|
17
|
+
export async function postMessages({ accessToken, requestBody, betaHeaders, signal, compress, plain = false }) {
|
|
16
18
|
const headers = {
|
|
17
19
|
Authorization: `Bearer ${accessToken}`,
|
|
18
20
|
'anthropic-version': ANTHROPIC_VERSION,
|
|
@@ -22,17 +24,15 @@ export async function postMessages({ accessToken, requestBody, betaHeaders, sign
|
|
|
22
24
|
'x-app': 'cli',
|
|
23
25
|
'Content-Type': 'application/json',
|
|
24
26
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}),
|
|
37
|
-
});
|
|
27
|
+
const raw = Buffer.from(JSON.stringify(requestBody));
|
|
28
|
+
const send = (body, sendHeaders) =>
|
|
29
|
+
fetch(API_URL, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: sendHeaders,
|
|
32
|
+
body,
|
|
33
|
+
signal,
|
|
34
|
+
dispatcher: getLlmDispatcher(),
|
|
35
|
+
});
|
|
36
|
+
if (plain) return send(raw, headers);
|
|
37
|
+
return sendGzipCompressed({ raw, headers, compress, send });
|
|
38
38
|
}
|
|
@@ -50,7 +50,9 @@ export function anthropicQuotaError(status, headers, bodyText = '') {
|
|
|
50
50
|
const detail = bodyText ? `: ${String(bodyText).slice(0, 200)}` : '';
|
|
51
51
|
const retry = retryAfter ? ` retryAfter=${retryAfter}` : '';
|
|
52
52
|
const quota = hasQuotaHeaders(headers);
|
|
53
|
-
const err = new Error(
|
|
53
|
+
const err = new Error(
|
|
54
|
+
`Anthropic OAuth API ${status} ${quota ? 'quota/rate limit' : 'request rejected'}${retry}${detail}`
|
|
55
|
+
);
|
|
54
56
|
err.name = quota ? 'ProviderQuotaError' : 'ProviderRequestRejectedError';
|
|
55
57
|
err.headers = headers;
|
|
56
58
|
err.response = { status, headers };
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { traceAgentSse, traceAgentUsage } from '../agent-trace.mjs';
|
|
9
9
|
import {
|
|
10
10
|
anthropicPrefixFingerprint,
|
|
11
|
+
anthropicPrefixSessionId,
|
|
11
12
|
latestAnthropicPrefix,
|
|
12
13
|
recordAnthropicPrefix,
|
|
13
14
|
} from './lib/anthropic-prefix-trace.mjs';
|
|
@@ -43,16 +44,17 @@ import {
|
|
|
43
44
|
} from './anthropic-oauth-credentials.mjs';
|
|
44
45
|
import { claudeCliUserAgent, learnRequiredCliVersion, warmCliVersion } from './anthropic-oauth-client-version.mjs';
|
|
45
46
|
import { createPassthroughSignal } from '../stall-policy.mjs';
|
|
46
|
-
import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
|
|
47
47
|
import { ANTHROPIC_MAX_MIDSTREAM_RETRIES, parseSSEStream, _classifyMidstreamError } from './anthropic-sse.mjs';
|
|
48
48
|
import { buildAnthropicBetaHeaders, supportsAnthropicFastMode } from './anthropic-betas.mjs';
|
|
49
49
|
import { applyAnthropicServerFallback } from './anthropic-server-fallback.mjs';
|
|
50
50
|
import { fastModeAvailable, fastModeDowngraded, noteFastModeCapacityError } from './anthropic-fast-mode.mjs';
|
|
51
51
|
import { ANTHROPIC_VERSION, anthropicQuotaError, createAnthropicOAuthRequest } from './anthropic-oauth-request.mjs';
|
|
52
52
|
import { isRefreshableAuthRejection } from './anthropic-oauth-request/initial-status.mjs';
|
|
53
|
+
import { postMessages } from './anthropic-oauth-request/gzip-post.mjs';
|
|
54
|
+
import { sendAnthropicCacheWarm } from './anthropic-cache-warm.mjs';
|
|
53
55
|
import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
|
|
54
56
|
import { adjustMaxTokensForContextOverflow } from './anthropic-max-tokens-recovery.mjs';
|
|
55
|
-
import {
|
|
57
|
+
import { createAnthropicOverloadTracker, takeAnthropicModelFallback } from './anthropic-overload-fallback.mjs';
|
|
56
58
|
import { createAnthropicOAuthRecovery } from './anthropic-oauth-recovery.mjs';
|
|
57
59
|
import { createMidState, createMidstreamRecovery } from './anthropic-oauth-midstream.mjs';
|
|
58
60
|
import { assertAnthropicStreamNotEmpty } from './anthropic-midstream-recovery.mjs';
|
|
@@ -302,6 +304,28 @@ function buildRequestBody(requestMessages, model, tools, sendOpts) {
|
|
|
302
304
|
return markAnthropicEffortBody(body, effortProjection);
|
|
303
305
|
}
|
|
304
306
|
|
|
307
|
+
// Known tool names for the leaked-tool-call guard in parseSSEStream:
|
|
308
|
+
// recovered leaked calls are only synthesized when they name a tool
|
|
309
|
+
// actually offered to this request (native + lowered). Derived from the
|
|
310
|
+
// final request body so it matches exactly what the model was given.
|
|
311
|
+
function requestToolNames(body) {
|
|
312
|
+
return new Set(
|
|
313
|
+
(Array.isArray(body.tools) ? body.tools : [])
|
|
314
|
+
.map((t) => (t && typeof t.name === 'string' ? t.name : null))
|
|
315
|
+
.filter(Boolean)
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// The number of mid-stream retries a streamed turn took, as a hidden field of
|
|
320
|
+
// the result.
|
|
321
|
+
function tagMidstreamRetries(result, attemptIndex) {
|
|
322
|
+
try {
|
|
323
|
+
Object.defineProperty(result, '__midstreamRetries', { value: attemptIndex, enumerable: false });
|
|
324
|
+
} catch {
|
|
325
|
+
/* ignore non-extensible result */
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
305
329
|
export function _buildRequestBodyForCacheSmoke(messages, model, tools = [], sendOpts = {}) {
|
|
306
330
|
return buildRequestBody(messages, model, tools, sendOpts);
|
|
307
331
|
}
|
|
@@ -466,6 +490,41 @@ export class AnthropicOAuthProvider {
|
|
|
466
490
|
);
|
|
467
491
|
}
|
|
468
492
|
|
|
493
|
+
/**
|
|
494
|
+
* Cache-warm mode (anthropic-cache-warm.mjs): the body `send` would build
|
|
495
|
+
* for these arguments, POSTed once — no retry, credential replay, fallback
|
|
496
|
+
* model or re-send — and cut at the first content block. `onUsage` receives
|
|
497
|
+
* the reported usage as it arrives; resolves the final usage.
|
|
498
|
+
*/
|
|
499
|
+
async sendCacheWarm(messages, model, tools, sendOpts = {}, { onUsage, accountId = '' } = {}) {
|
|
500
|
+
await warmCliVersion();
|
|
501
|
+
const opts = sendOpts || {};
|
|
502
|
+
const creds = await this.ensureAuth();
|
|
503
|
+
const body = buildRequestBody(sanitizeToolPairs(messages), model, tools, opts);
|
|
504
|
+
body.messages = await prepareAnthropicImages(body.messages, { signal: opts.signal });
|
|
505
|
+
return sendAnthropicCacheWarm({
|
|
506
|
+
providerName: this.name,
|
|
507
|
+
instance: this,
|
|
508
|
+
accountId,
|
|
509
|
+
model,
|
|
510
|
+
opts,
|
|
511
|
+
onUsage,
|
|
512
|
+
post: (signal) =>
|
|
513
|
+
postMessages({
|
|
514
|
+
accessToken: creds.accessToken,
|
|
515
|
+
requestBody: body,
|
|
516
|
+
betaHeaders: buildOAuthBetaHeaders(body, {
|
|
517
|
+
fastMode: this.fastModeBetaHeaderLatched,
|
|
518
|
+
toolSearch: Array.isArray(body.tools) && body.tools.some((t) => t?.defer_loading === true),
|
|
519
|
+
model,
|
|
520
|
+
opts,
|
|
521
|
+
}),
|
|
522
|
+
signal,
|
|
523
|
+
plain: true,
|
|
524
|
+
}),
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
|
|
469
528
|
async _sendOnce(messages, model, tools, sendOpts) {
|
|
470
529
|
await warmCliVersion();
|
|
471
530
|
// Re-warm the kept-alive socket before the turn. preconnect() is a
|
|
@@ -497,7 +556,7 @@ export class AnthropicOAuthProvider {
|
|
|
497
556
|
const body = buildRequestBody(messages, useModel, tools, sendOpts);
|
|
498
557
|
body.messages = await prepareAnthropicImages(body.messages, { signal: externalSignal });
|
|
499
558
|
// Diagnostic: per-block prefix hashes of exactly what is sent.
|
|
500
|
-
recordAnthropicPrefix(opts
|
|
559
|
+
recordAnthropicPrefix(anthropicPrefixSessionId(opts), anthropicPrefixFingerprint(body));
|
|
501
560
|
if (body.speed === 'fast') {
|
|
502
561
|
this.fastModeBetaHeaderLatched = true;
|
|
503
562
|
}
|
|
@@ -505,15 +564,7 @@ export class AnthropicOAuthProvider {
|
|
|
505
564
|
// actually carries deferred (defer_loading) tools — gate the header on
|
|
506
565
|
// that instead of sending it unconditionally on every request.
|
|
507
566
|
const hasDeferredTools = Array.isArray(body.tools) && body.tools.some((t) => t && t.defer_loading === true);
|
|
508
|
-
|
|
509
|
-
// recovered leaked calls are only synthesized when they name a tool
|
|
510
|
-
// actually offered to this request (native + lowered). Derived from the
|
|
511
|
-
// final request body so it matches exactly what the model was given.
|
|
512
|
-
const knownToolNames = new Set(
|
|
513
|
-
(Array.isArray(body.tools) ? body.tools : [])
|
|
514
|
-
.map((t) => (t && typeof t.name === 'string' ? t.name : null))
|
|
515
|
-
.filter(Boolean)
|
|
516
|
-
);
|
|
567
|
+
const knownToolNames = requestToolNames(body);
|
|
517
568
|
const sessionId = opts.sessionId || null;
|
|
518
569
|
const iteration = Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null;
|
|
519
570
|
// Option A: no absolute wall-clock cap on streaming generation. A stream
|
|
@@ -530,51 +581,17 @@ export class AnthropicOAuthProvider {
|
|
|
530
581
|
// totalSignal is therefore a pure pass-through of externalSignal with no timer.
|
|
531
582
|
const totalTimeout = createPassthroughSignal(externalSignal);
|
|
532
583
|
const totalSignal = totalTimeout.signal;
|
|
533
|
-
|
|
534
|
-
// limit the configured fallback model takes over the whole send.
|
|
535
|
-
const overload = createAnthropicOverloadTracker({
|
|
536
|
-
model: useModel,
|
|
537
|
-
fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
|
|
538
|
-
});
|
|
539
|
-
const { requestWithRetry, cleanupCancelHandler } = createAnthropicOAuthRequest({
|
|
540
|
-
provider: this,
|
|
584
|
+
const { requestWithRetry, cleanupCancelHandler, midstream } = this._createSendRecovery({
|
|
541
585
|
opts,
|
|
542
586
|
body,
|
|
543
587
|
useModel,
|
|
544
588
|
sessionId,
|
|
545
|
-
totalSignal,
|
|
546
|
-
overload,
|
|
547
|
-
betaHeadersFor: (requestBody) =>
|
|
548
|
-
buildOAuthBetaHeaders(requestBody, {
|
|
549
|
-
fastMode: this.fastModeBetaHeaderLatched,
|
|
550
|
-
toolSearch: hasDeferredTools,
|
|
551
|
-
model: useModel,
|
|
552
|
-
opts,
|
|
553
|
-
}),
|
|
554
|
-
onStageChange,
|
|
555
|
-
});
|
|
556
|
-
const recovery = createAnthropicOAuthRecovery({
|
|
557
|
-
provider: this,
|
|
558
|
-
opts,
|
|
559
|
-
body,
|
|
560
|
-
useModel,
|
|
561
589
|
auth,
|
|
562
590
|
totalSignal,
|
|
563
|
-
|
|
564
|
-
cleanupCancelHandler,
|
|
591
|
+
hasDeferredTools,
|
|
565
592
|
onStageChange,
|
|
566
593
|
onTextReset,
|
|
567
594
|
});
|
|
568
|
-
// Bounded mid-stream retries for transient stream loss; jittered backoff
|
|
569
|
-
// between attempts (anthropic-oauth-midstream.mjs).
|
|
570
|
-
const midstream = createMidstreamRecovery({
|
|
571
|
-
maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
|
|
572
|
-
totalSignal,
|
|
573
|
-
recovery,
|
|
574
|
-
onStageChange,
|
|
575
|
-
retry529: opts.retry529 !== false,
|
|
576
|
-
overload,
|
|
577
|
-
});
|
|
578
595
|
|
|
579
596
|
let maxTokensAdjusted = false;
|
|
580
597
|
try {
|
|
@@ -605,7 +622,9 @@ export class AnthropicOAuthProvider {
|
|
|
605
622
|
if (SSE_VERBOSE) process.stderr.write(`[anthropic-oauth] Response ${response.status}, parsing SSE...\n`);
|
|
606
623
|
try {
|
|
607
624
|
onStageChange?.('streaming');
|
|
608
|
-
} catch {
|
|
625
|
+
} catch {
|
|
626
|
+
// the stage observer is advisory
|
|
627
|
+
}
|
|
609
628
|
|
|
610
629
|
const midState = createMidState(attemptIndex);
|
|
611
630
|
try {
|
|
@@ -623,7 +642,9 @@ export class AnthropicOAuthProvider {
|
|
|
623
642
|
);
|
|
624
643
|
try {
|
|
625
644
|
controller?.abort?.('Anthropic SSE complete');
|
|
626
|
-
} catch {
|
|
645
|
+
} catch {
|
|
646
|
+
// the stream is complete; the controller may already be aborted
|
|
647
|
+
}
|
|
627
648
|
this._settleStreamedTurn({
|
|
628
649
|
result,
|
|
629
650
|
midState,
|
|
@@ -632,12 +653,9 @@ export class AnthropicOAuthProvider {
|
|
|
632
653
|
iteration,
|
|
633
654
|
useModel,
|
|
634
655
|
requestKind: opts.requestKind || null,
|
|
656
|
+
prefixSessionId: anthropicPrefixSessionId(opts),
|
|
635
657
|
});
|
|
636
|
-
|
|
637
|
-
Object.defineProperty(result, '__midstreamRetries', { value: attemptIndex, enumerable: false });
|
|
638
|
-
} catch {
|
|
639
|
-
/* ignore non-extensible result */
|
|
640
|
-
}
|
|
658
|
+
tagMidstreamRetries(result, attemptIndex);
|
|
641
659
|
return result;
|
|
642
660
|
} catch (err) {
|
|
643
661
|
const decision = await midstream.onStreamError({ err, midState, controller, response, attemptIndex });
|
|
@@ -649,22 +667,81 @@ export class AnthropicOAuthProvider {
|
|
|
649
667
|
}
|
|
650
668
|
throw midstream.exhaustedError();
|
|
651
669
|
} catch (err) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
return await this.send(messages, err.fallbackModel, tools, {
|
|
659
|
-
...opts,
|
|
660
|
-
fallbackModel: undefined,
|
|
661
|
-
_fallbackTriggered: true,
|
|
670
|
+
const fallbackOpts = takeAnthropicModelFallback(err, {
|
|
671
|
+
tag: 'anthropic-oauth',
|
|
672
|
+
model: useModel,
|
|
673
|
+
opts,
|
|
674
|
+
onStageChange,
|
|
675
|
+
displayModel: _displayModel,
|
|
662
676
|
});
|
|
677
|
+
return await this.send(messages, err.fallbackModel, tools, fallbackOpts);
|
|
663
678
|
} finally {
|
|
664
679
|
totalTimeout.cleanup();
|
|
665
680
|
}
|
|
666
681
|
}
|
|
667
682
|
|
|
683
|
+
// The request and recovery pipeline of one send over its fixed body: the
|
|
684
|
+
// shared overload counter, the retried request with its per-request beta
|
|
685
|
+
// headers, the non-streaming recovery and the bounded mid-stream retries.
|
|
686
|
+
_createSendRecovery({
|
|
687
|
+
opts,
|
|
688
|
+
body,
|
|
689
|
+
useModel,
|
|
690
|
+
sessionId,
|
|
691
|
+
auth,
|
|
692
|
+
totalSignal,
|
|
693
|
+
hasDeferredTools,
|
|
694
|
+
onStageChange,
|
|
695
|
+
onTextReset,
|
|
696
|
+
}) {
|
|
697
|
+
// Request-loop 529s and SSE overload events share one counter; at the
|
|
698
|
+
// limit the configured fallback model takes over the whole send.
|
|
699
|
+
const overload = createAnthropicOverloadTracker({
|
|
700
|
+
model: useModel,
|
|
701
|
+
fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
|
|
702
|
+
});
|
|
703
|
+
const { requestWithRetry, cleanupCancelHandler } = createAnthropicOAuthRequest({
|
|
704
|
+
provider: this,
|
|
705
|
+
opts,
|
|
706
|
+
body,
|
|
707
|
+
useModel,
|
|
708
|
+
sessionId,
|
|
709
|
+
totalSignal,
|
|
710
|
+
overload,
|
|
711
|
+
betaHeadersFor: (requestBody) =>
|
|
712
|
+
buildOAuthBetaHeaders(requestBody, {
|
|
713
|
+
fastMode: this.fastModeBetaHeaderLatched,
|
|
714
|
+
toolSearch: hasDeferredTools,
|
|
715
|
+
model: useModel,
|
|
716
|
+
opts,
|
|
717
|
+
}),
|
|
718
|
+
onStageChange,
|
|
719
|
+
});
|
|
720
|
+
const recovery = createAnthropicOAuthRecovery({
|
|
721
|
+
provider: this,
|
|
722
|
+
opts,
|
|
723
|
+
body,
|
|
724
|
+
useModel,
|
|
725
|
+
auth,
|
|
726
|
+
totalSignal,
|
|
727
|
+
requestWithRetry,
|
|
728
|
+
cleanupCancelHandler,
|
|
729
|
+
onStageChange,
|
|
730
|
+
onTextReset,
|
|
731
|
+
});
|
|
732
|
+
// Bounded mid-stream retries for transient stream loss; jittered backoff
|
|
733
|
+
// between attempts (anthropic-oauth-midstream.mjs).
|
|
734
|
+
const midstream = createMidstreamRecovery({
|
|
735
|
+
maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
|
|
736
|
+
totalSignal,
|
|
737
|
+
recovery,
|
|
738
|
+
onStageChange,
|
|
739
|
+
retry529: opts.retry529 !== false,
|
|
740
|
+
overload,
|
|
741
|
+
});
|
|
742
|
+
return { requestWithRetry, cleanupCancelHandler, midstream };
|
|
743
|
+
}
|
|
744
|
+
|
|
668
745
|
// One attempt's initial response: a 401 (or Anthropic's exact revoked-token
|
|
669
746
|
// 403) refreshes the credentials in `auth` and replays once; a context
|
|
670
747
|
// overflow 400 shrinks `body.max_tokens` and replays once per send
|
|
@@ -687,7 +764,9 @@ export class AnthropicOAuthProvider {
|
|
|
687
764
|
// resources before the credential-refresh replay.
|
|
688
765
|
try {
|
|
689
766
|
controller?.abort?.();
|
|
690
|
-
} catch {
|
|
767
|
+
} catch {
|
|
768
|
+
// the controller may already be aborted before the credential-refresh replay
|
|
769
|
+
}
|
|
691
770
|
auth.creds = await this.ensureAuth({ forceRefresh: true, reason: String(response.status) });
|
|
692
771
|
({ response, controller, cancelHandler } = await requestWithRetry(auth.creds.accessToken));
|
|
693
772
|
rejectedAuthBody = null;
|
|
@@ -702,7 +781,9 @@ export class AnthropicOAuthProvider {
|
|
|
702
781
|
cleanupCancelHandler(cancelHandler);
|
|
703
782
|
try {
|
|
704
783
|
controller?.abort?.();
|
|
705
|
-
} catch {
|
|
784
|
+
} catch {
|
|
785
|
+
// the controller may already be aborted before the max-tokens replay
|
|
786
|
+
}
|
|
706
787
|
({ response, controller, cancelHandler } = await requestWithRetry(auth.creds.accessToken));
|
|
707
788
|
rejectedAuthBody = null;
|
|
708
789
|
}
|
|
@@ -808,7 +889,16 @@ export class AnthropicOAuthProvider {
|
|
|
808
889
|
}
|
|
809
890
|
|
|
810
891
|
// Traces + catalog upkeep for a streamed turn, then the empty-stream guard.
|
|
811
|
-
_settleStreamedTurn({
|
|
892
|
+
_settleStreamedTurn({
|
|
893
|
+
result,
|
|
894
|
+
midState,
|
|
895
|
+
sseStartedAt,
|
|
896
|
+
sessionId,
|
|
897
|
+
iteration,
|
|
898
|
+
useModel,
|
|
899
|
+
requestKind,
|
|
900
|
+
prefixSessionId,
|
|
901
|
+
}) {
|
|
812
902
|
const ttftMs = midState.ttftAt ? midState.ttftAt - sseStartedAt : null;
|
|
813
903
|
const liveModel = result.model || useModel;
|
|
814
904
|
traceAgentSse({
|
|
@@ -833,7 +923,7 @@ export class AnthropicOAuthProvider {
|
|
|
833
923
|
rawUsage: result.usage?.raw || null,
|
|
834
924
|
provider: 'anthropic-oauth',
|
|
835
925
|
requestKind,
|
|
836
|
-
prefixBlocks: latestAnthropicPrefix(
|
|
926
|
+
prefixBlocks: latestAnthropicPrefix(prefixSessionId),
|
|
837
927
|
});
|
|
838
928
|
|
|
839
929
|
// Phase I: if the live response surfaced a model id we don't know
|
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
import { ANTHROPIC_MAX_CONSECUTIVE_529 } from './retry-backoff.mjs';
|
|
13
13
|
import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const OVERLOADED_ERROR_CODE = 'overloaded_error';
|
|
16
16
|
|
|
17
17
|
/** Consecutive 529s end the request only for API-key (non-subscriber) first-party Opus. */
|
|
18
18
|
export function isTerminalOverloadModel(model) {
|
|
19
|
-
return /^claude-opus-/.test(
|
|
19
|
+
return /^claude-opus-/.test(
|
|
20
|
+
String(model || '')
|
|
21
|
+
.trim()
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
);
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export function isAnthropicOverloadError(err) {
|
|
@@ -56,8 +60,26 @@ export function createAnthropicOverloadTracker({ model, fallbackModel, terminalA
|
|
|
56
60
|
};
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
/**
|
|
64
|
+
* The catch around a whole Anthropic send. The fallback trigger can surface
|
|
65
|
+
* from the request loop, a mid-stream overload, or the non-streaming
|
|
66
|
+
* recovery; any other error is rethrown unchanged. For the trigger it logs,
|
|
67
|
+
* announces the model switch, and returns the options of the single re-send
|
|
68
|
+
* on `err.fallbackModel` (no second hop).
|
|
69
|
+
*/
|
|
70
|
+
export function takeAnthropicModelFallback(err, { tag, model, opts, onStageChange, displayModel = (id) => id }) {
|
|
71
|
+
if (!(err instanceof AnthropicFallbackTriggeredError)) throw err;
|
|
72
|
+
process.stderr.write(`[${tag}] ${err.message}\n`);
|
|
73
|
+
announceAnthropicModelFallback(onStageChange, displayModel(model), displayModel(err.fallbackModel));
|
|
74
|
+
return {
|
|
75
|
+
...opts,
|
|
76
|
+
fallbackModel: undefined,
|
|
77
|
+
_fallbackTriggered: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
59
81
|
/** Visible model-switch notice on the existing display-only stage channel. */
|
|
60
|
-
|
|
82
|
+
function announceAnthropicModelFallback(onStageChange, fromLabel, toLabel) {
|
|
61
83
|
if (typeof onStageChange !== 'function') return;
|
|
62
84
|
try {
|
|
63
85
|
onStageChange('reconnecting', {
|