mixdog 0.8.1 → 0.9.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/README.md +47 -23
- package/package.json +34 -28
- package/scripts/_test-folder-dialog.mjs +30 -0
- package/scripts/agent-parallel-smoke.mjs +388 -0
- package/scripts/agent-tag-reuse-smoke.mjs +183 -0
- package/scripts/background-task-meta-smoke.mjs +38 -0
- package/scripts/boot-smoke.mjs +52 -9
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/compact-active-turn-test.mjs +68 -0
- package/scripts/compact-smoke.mjs +859 -129
- package/scripts/compact-trigger-migration-smoke.mjs +187 -0
- package/scripts/fix-brief-fn.mjs +35 -0
- package/scripts/fix-format-tool-surface.mjs +24 -0
- package/scripts/fix-tool-exec-visible.mjs +42 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/hook-bus-test.mjs +330 -0
- package/scripts/lead-workflow-smoke.mjs +33 -39
- package/scripts/live-worker-smoke.mjs +43 -37
- package/scripts/llm-trace-summary.mjs +315 -0
- package/scripts/memory-meta-concurrency-test.mjs +20 -0
- package/scripts/output-style-smoke.mjs +56 -15
- package/scripts/parent-abort-link-test.mjs +44 -0
- package/scripts/patch-agent-brief.mjs +48 -0
- package/scripts/patch-app.mjs +21 -0
- package/scripts/patch-app2.mjs +18 -0
- package/scripts/patch-dist-brief.mjs +96 -0
- package/scripts/patch-tool-exec.mjs +70 -0
- package/scripts/pretool-ask-runtime-test.mjs +54 -0
- package/scripts/provider-toolcall-test.mjs +376 -0
- package/scripts/reactive-compact-persist-smoke.mjs +124 -0
- package/scripts/sanitize-tool-pairs-test.mjs +260 -0
- package/scripts/session-context-bench.mjs +205 -33
- package/scripts/session-ingest-smoke.mjs +177 -0
- package/scripts/set-effort-config-test.mjs +41 -0
- package/scripts/smoke-runtime-negative.ps1 +106 -0
- package/scripts/smoke-runtime-negative.sh +97 -0
- package/scripts/smoke.mjs +25 -0
- package/scripts/tool-result-hook-test.mjs +48 -0
- package/scripts/tool-smoke.mjs +1222 -90
- package/scripts/toolcall-args-test.mjs +150 -0
- package/scripts/tui-background-failure-smoke.mjs +73 -0
- package/scripts/usage-metrics-epoch-smoke.mjs +114 -0
- package/src/agents/debugger/AGENT.md +8 -0
- package/src/agents/explore/AGENT.md +4 -0
- package/src/agents/heavy-worker/AGENT.md +9 -3
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +8 -0
- package/src/agents/scheduler-task/AGENT.md +12 -0
- package/src/agents/scheduler-task/agent.json +6 -0
- package/src/agents/webhook-handler/AGENT.md +12 -0
- package/src/agents/webhook-handler/agent.json +6 -0
- package/src/agents/worker/AGENT.md +9 -3
- package/src/app.mjs +77 -3
- package/src/defaults/hidden-roles.json +17 -12
- package/src/headless-role.mjs +117 -0
- package/src/help.mjs +30 -0
- package/src/hooks/lib/permission-evaluator.cjs +11 -475
- package/src/lib/keychain-cjs.cjs +9 -1
- package/src/lib/mixdog-debug.cjs +0 -29
- package/src/lib/plugin-paths.cjs +1 -7
- package/src/lib/rules-builder.cjs +242 -98
- package/src/lib/text-utils.cjs +1 -1
- package/src/mixdog-session-runtime.mjs +2211 -446
- package/src/output-styles/default.md +12 -28
- package/src/output-styles/extreme-simple.md +9 -6
- package/src/output-styles/simple.md +22 -9
- package/src/repl.mjs +108 -59
- package/src/rules/agent/00-common.md +15 -0
- package/src/rules/{bridge → agent}/20-skip-protocol.md +1 -2
- package/src/rules/agent/30-explorer.md +22 -0
- package/src/rules/{bridge → agent}/40-cycle1-agent.md +7 -0
- package/src/rules/{bridge → agent}/41-cycle2-agent.md +7 -0
- package/src/rules/{bridge → agent}/42-cycle3-agent.md +7 -0
- package/src/rules/lead/01-general.md +9 -5
- package/src/rules/lead/04-workflow.md +51 -12
- package/src/rules/lead/lead-tool.md +6 -0
- package/src/rules/shared/01-tool.md +12 -1
- package/src/runtime/agent/orchestrator/activity-bus.mjs +7 -18
- package/src/runtime/agent/orchestrator/agent-owner.mjs +11 -0
- package/src/runtime/agent/orchestrator/{smart-bridge/bridge-llm.mjs → agent-runtime/agent-dispatch.mjs} +138 -111
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +94 -0
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/cache-strategy.mjs +32 -23
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/session-builder.mjs +33 -27
- package/src/runtime/agent/orchestrator/{bridge-trace.mjs → agent-trace.mjs} +132 -81
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +0 -21
- package/src/runtime/agent/orchestrator/config.mjs +174 -55
- package/src/runtime/agent/orchestrator/context/collect.mjs +195 -487
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-roles.mjs +77 -29
- package/src/runtime/agent/orchestrator/internal-tools.mjs +5 -6
- package/src/runtime/agent/orchestrator/mcp/client.mjs +15 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +380 -268
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +131 -93
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +236 -4
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +49 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +58 -13
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +67 -149
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +132 -2
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +61 -116
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +25 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +79 -255
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +203 -71
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +512 -312
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +343 -518
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/registry.mjs +88 -51
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +289 -11
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +41 -8
- package/src/runtime/agent/orchestrator/session/compact.mjs +1173 -267
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +199 -36
- package/src/runtime/agent/orchestrator/session/loop.mjs +840 -612
- package/src/runtime/agent/orchestrator/session/manager.mjs +1574 -459
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +107 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +67 -29
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +31 -16
- package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +3 -219
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +35 -8
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +19 -8
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -53
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +60 -37
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +21 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -7
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -3
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +36 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +5 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -36
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +2 -40
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +148 -27
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +43 -75
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +90 -20
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -5
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +86 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4106 -4019
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +33 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +90 -6
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +6 -4
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +8 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -4
- package/src/runtime/channels/index.mjs +149 -51
- package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
- package/src/runtime/channels/lib/config.mjs +0 -1
- package/src/runtime/channels/lib/drop-trace.mjs +1 -1
- package/src/runtime/channels/lib/executor.mjs +0 -3
- package/src/runtime/channels/lib/memory-client.mjs +0 -38
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -8
- package/src/runtime/channels/lib/runtime-paths.mjs +0 -6
- package/src/runtime/channels/lib/scheduler.mjs +18 -14
- package/src/runtime/channels/lib/session-discovery.mjs +3 -6
- package/src/runtime/channels/lib/tool-format.mjs +0 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -12
- package/src/runtime/channels/lib/webhook.mjs +1 -1
- package/src/runtime/channels/tool-defs.mjs +29 -29
- package/src/runtime/lib/keychain-cjs.cjs +0 -1
- package/src/runtime/memory/data/runtime-manifest.json +6 -7
- package/src/runtime/memory/index.mjs +519 -118
- package/src/runtime/memory/lib/agent-ipc.mjs +29 -12
- package/src/runtime/memory/lib/core-memory-store.mjs +2 -2
- package/src/runtime/memory/lib/embedding-model-config.mjs +55 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +31 -4
- package/src/runtime/memory/lib/embedding-worker.mjs +19 -10
- package/src/runtime/memory/lib/llm-worker-host.mjs +0 -4
- package/src/runtime/memory/lib/memory-cycle1.mjs +28 -7
- package/src/runtime/memory/lib/memory-cycle2.mjs +4 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +2 -2
- package/src/runtime/memory/lib/memory-ops-policy.mjs +2 -2
- package/src/runtime/memory/lib/memory-session-merge.mjs +38 -0
- package/src/runtime/memory/lib/memory.mjs +88 -9
- package/src/runtime/memory/lib/model-profile.mjs +1 -1
- package/src/runtime/memory/lib/pg/adapter.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +12 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +80 -21
- package/src/runtime/memory/lib/session-ingest.mjs +196 -0
- package/src/runtime/memory/lib/trace-store.mjs +96 -51
- package/src/runtime/memory/tool-defs.mjs +46 -37
- package/src/runtime/search/index.mjs +104 -473
- package/src/runtime/search/lib/config.mjs +0 -4
- package/src/runtime/search/lib/state.mjs +1 -15
- package/src/runtime/search/lib/web-tools.mjs +44 -25
- package/src/runtime/search/tool-defs.mjs +16 -23
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +4 -3
- package/src/runtime/shared/background-tasks.mjs +122 -11
- package/src/runtime/shared/child-spawn-gate.mjs +139 -0
- package/src/runtime/shared/config.mjs +7 -4
- package/src/runtime/shared/err-text.mjs +131 -4
- package/src/runtime/shared/llm/cost.mjs +2 -2
- package/src/runtime/shared/llm/http-agent.mjs +23 -7
- package/src/runtime/shared/llm/index.mjs +34 -11
- package/src/runtime/shared/llm/usage-log.mjs +4 -4
- package/src/runtime/shared/markdown-frontmatter.mjs +56 -0
- package/src/runtime/shared/singleton-owner.mjs +104 -0
- package/src/runtime/shared/tool-execution-contract.mjs +199 -20
- package/src/runtime/shared/tool-execution-contract.test.mjs +183 -0
- package/src/runtime/shared/tool-surface.mjs +624 -95
- package/src/runtime/shared/user-data-guard.mjs +0 -2
- package/src/standalone/agent-task-status.mjs +203 -0
- package/src/standalone/agent-task-status.test.mjs +76 -0
- package/src/standalone/agent-tool.mjs +1913 -0
- package/src/standalone/channel-worker.mjs +370 -14
- package/src/standalone/explore-tool.mjs +165 -70
- package/src/standalone/folder-dialog.mjs +314 -0
- package/src/standalone/hook-bus.mjs +898 -22
- package/src/standalone/memory-runtime-proxy.mjs +320 -0
- package/src/standalone/projects.mjs +226 -0
- package/src/standalone/provider-admin.mjs +41 -24
- package/src/standalone/seeds.mjs +1 -78
- package/src/standalone/usage-dashboard.mjs +96 -8
- package/src/tui/App.jsx +4800 -2140
- package/src/tui/components/AnsiText.jsx +39 -28
- package/src/tui/components/ContextPanel.jsx +14 -4
- package/src/tui/components/Markdown.jsx +43 -77
- package/src/tui/components/MarkdownTable.jsx +9 -184
- package/src/tui/components/Message.jsx +28 -11
- package/src/tui/components/Picker.jsx +95 -56
- package/src/tui/components/PromptInput.jsx +428 -239
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +27 -21
- package/src/tui/components/Spinner.jsx +67 -38
- package/src/tui/components/StatusLine.jsx +606 -38
- package/src/tui/components/TextEntryPanel.jsx +128 -9
- package/src/tui/components/ToolExecution.jsx +597 -362
- package/src/tui/components/TurnDone.jsx +3 -3
- package/src/tui/components/UsagePanel.jsx +3 -5
- package/src/tui/components/tool-output-format.mjs +499 -0
- package/src/tui/components/tool-output-format.test.mjs +312 -0
- package/src/tui/dist/index.mjs +9192 -2399
- package/src/tui/engine-runtime-notification.test.mjs +115 -0
- package/src/tui/engine-tool-result-text.test.mjs +75 -0
- package/src/tui/engine.mjs +1455 -279
- package/src/tui/figures.mjs +21 -40
- package/src/tui/index.jsx +75 -31
- package/src/tui/input-editing.mjs +25 -0
- package/src/tui/markdown/format-token.mjs +671 -69
- package/src/tui/markdown/format-token.test.mjs +312 -0
- package/src/tui/markdown/render-ansi.mjs +94 -0
- package/src/tui/markdown/render-ansi.test.mjs +108 -0
- package/src/tui/markdown/stream-fence.mjs +34 -0
- package/src/tui/markdown/stream-fence.test.mjs +26 -0
- package/src/tui/markdown/table-layout.mjs +250 -0
- package/src/tui/paste-attachments.mjs +0 -7
- package/src/tui/spinner-verbs.mjs +1 -2
- package/src/tui/statusline-ansi-bridge.mjs +172 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +159 -0
- package/src/tui/theme.mjs +756 -24
- package/src/tui/time-format.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +67 -0
- package/src/tui/transcript-tool-failures.test.mjs +111 -0
- package/src/ui/ansi.mjs +1 -2
- package/src/ui/markdown.mjs +85 -26
- package/src/ui/markdown.test.mjs +70 -0
- package/src/ui/model-display.mjs +121 -0
- package/src/ui/session-stats.mjs +44 -0
- package/src/ui/statusline-context-label.test.mjs +15 -0
- package/src/ui/statusline.mjs +386 -178
- package/src/ui/tool-card.mjs +2 -13
- package/src/vendor/statusline/bin/statusline-lib.mjs +1 -620
- package/src/vendor/statusline/bin/statusline-route.mjs +169 -37
- package/src/vendor/statusline/bin/statusline-route.test.mjs +80 -0
- package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +3 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +1 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +44 -6
- package/src/vendor/statusline/src/gateway/session-routes.mjs +1 -1
- package/src/workflows/default/WORKFLOW.md +12 -5
- package/src/workflows/default/workflow.json +0 -1
- package/src/workflows/solo/WORKFLOW.md +15 -0
- package/src/workflows/solo/workflow.json +7 -0
- package/vendor/ink/build/ink.js +54 -8
- package/vendor/ink/build/output.js +6 -1
- package/src/agents/scheduler-task.md +0 -3
- package/src/agents/web-researcher/AGENT.md +0 -3
- package/src/agents/web-researcher/agent.json +0 -6
- package/src/agents/webhook-handler.md +0 -3
- package/src/hooks/lib/permission-rules.cjs +0 -170
- package/src/hooks/lib/settings-loader.cjs +0 -112
- package/src/lib/hook-pipe-path.cjs +0 -10
- package/src/rules/bridge/00-common.md +0 -5
- package/src/rules/bridge/30-explorer.md +0 -4
- package/src/rules/lead/00-tool-lead.md +0 -5
- package/src/rules/shared/00-language.md +0 -3
- package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
- package/src/runtime/agent/orchestrator/tools/mutation-content-cache.mjs +0 -67
- package/src/runtime/channels/lib/hook-pipe-server.mjs +0 -671
- package/src/runtime/memory/lib/bridge-trace-queries.mjs +0 -120
- package/src/runtime/shared/llm/pid-cleanup.mjs +0 -27
- package/src/standalone/bridge-tool.mjs +0 -1414
- package/src/tui/runtime/shared/process-shutdown.mjs +0 -1
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
2
|
import { loadConfig } from '../config.mjs';
|
|
3
3
|
import { sanitizeToolPairs, sanitizeAnthropicContentPairs } from '../session/context-utils.mjs';
|
|
4
|
-
import { classifyError, withRetry } from './retry-classifier.mjs';
|
|
5
|
-
import {
|
|
4
|
+
import { classifyError, midstreamBackoffFor, sleepWithAbort, withRetry } from './retry-classifier.mjs';
|
|
5
|
+
import { traceAgentUsage } from '../agent-trace.mjs';
|
|
6
6
|
import {
|
|
7
7
|
PROVIDER_FIRST_BYTE_TIMEOUT_MS,
|
|
8
8
|
createTimeoutSignal,
|
|
9
9
|
createPassthroughSignal,
|
|
10
10
|
} from '../stall-policy.mjs';
|
|
11
11
|
import { createAbortController } from '../../../shared/abort-controller.mjs';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
ANTHROPIC_MAX_MIDSTREAM_RETRIES,
|
|
14
|
+
parseSSEStream,
|
|
15
|
+
_classifyMidstreamError,
|
|
16
|
+
} from './anthropic-oauth.mjs';
|
|
13
17
|
import { buildAnthropicBetaHeaders, supportsAnthropicFastMode } from './anthropic-betas.mjs';
|
|
14
18
|
import { normalizeContentForAnthropic } from './media-normalization.mjs';
|
|
15
19
|
import { enrichModels } from './model-catalog.mjs';
|
|
16
20
|
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
17
21
|
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
22
|
+
// Abort-aware mid-stream backoff sleep → shared sleepWithAbort
|
|
23
|
+
// (retry-classifier.mjs). abortMessage preserves the prior fallback text.
|
|
24
|
+
function _midstreamSleepWithAbort(ms, signal) {
|
|
25
|
+
return sleepWithAbort(ms, signal, undefined, 'Anthropic mid-stream retry backoff aborted');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 4-BP cache policy aligned with anthropic-oauth — system + tier3 +
|
|
29
|
+
// messages-tail. Tool schemas sit before system and are covered by the system
|
|
30
|
+
// breakpoint, so they do not spend a separate cache_control slot. 1h TTL
|
|
31
|
+
// requires the extended-cache-ttl beta header, which we set on the client via
|
|
32
|
+
// defaultHeaders below.
|
|
21
33
|
const CACHE_TTL_STABLE = { type: 'ephemeral', ttl: '1h' };
|
|
22
34
|
const CACHE_TTL_VOLATILE = { type: 'ephemeral' };
|
|
23
35
|
|
|
@@ -39,23 +51,9 @@ function appendCacheControl(content, ttl = CACHE_TTL_VOLATILE) {
|
|
|
39
51
|
return content;
|
|
40
52
|
}
|
|
41
53
|
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
// message) deliberately omits the sentinel so it stays on the message tail.
|
|
46
|
-
const BP3_SENTINEL = '<!-- bp3-sentinel -->';
|
|
47
|
-
|
|
48
|
-
function findTier3Index(chatMsgs) {
|
|
49
|
-
for (let i = 0; i < chatMsgs.length; i++) {
|
|
50
|
-
const m = chatMsgs[i];
|
|
51
|
-
if (m?.role === 'user' && typeof m.content === 'string'
|
|
52
|
-
&& m.content.startsWith('<system-reminder>')
|
|
53
|
-
&& m.content.includes(BP3_SENTINEL)) {
|
|
54
|
-
return i;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return -1;
|
|
58
|
-
}
|
|
54
|
+
// BP3 (tier3) rides its own `system` role block (the 3rd system block, tagged
|
|
55
|
+
// cacheTier:'tier3'). buildSystemBlocks applies the tier3 1h cache_control to
|
|
56
|
+
// that block; BP1/BP2 take the system TTL. Mirrors anthropic-oauth.mjs.
|
|
59
57
|
|
|
60
58
|
function resolveCacheTtls(opts) {
|
|
61
59
|
const strategy = opts?.cacheStrategy || {};
|
|
@@ -67,19 +65,40 @@ function resolveCacheTtls(opts) {
|
|
|
67
65
|
return fallback;
|
|
68
66
|
};
|
|
69
67
|
return {
|
|
70
|
-
tools: pick('tools',
|
|
68
|
+
tools: pick('tools', null),
|
|
71
69
|
system: pick('system', CACHE_TTL_STABLE),
|
|
72
70
|
tier3: pick('tier3', CACHE_TTL_STABLE),
|
|
73
71
|
messages: pick('messages', CACHE_TTL_STABLE),
|
|
74
72
|
};
|
|
75
73
|
}
|
|
76
74
|
|
|
75
|
+
function buildSystemBlocks(systemMsgs, systemTtl, tier3Ttl) {
|
|
76
|
+
// systemMsgs is an array of { content, cacheTier }. Each non-empty element
|
|
77
|
+
// becomes its own content block: cacheTier:'tier3' (BP3 sessionMarker) gets
|
|
78
|
+
// tier3Ttl, every other block (BP1/BP2) gets systemTtl. A null TTL leaves
|
|
79
|
+
// the corresponding block uncached.
|
|
80
|
+
const items = Array.isArray(systemMsgs)
|
|
81
|
+
? systemMsgs
|
|
82
|
+
.map(m => ({
|
|
83
|
+
text: typeof m?.content === 'string' ? m.content.trim() : '',
|
|
84
|
+
tier: m?.cacheTier === 'tier3' ? 'tier3' : 'system',
|
|
85
|
+
}))
|
|
86
|
+
.filter(it => it.text)
|
|
87
|
+
: [];
|
|
88
|
+
return items.map(it => {
|
|
89
|
+
const block = { type: 'text', text: it.text };
|
|
90
|
+
const ttl = it.tier === 'tier3' ? tier3Ttl : systemTtl;
|
|
91
|
+
if (ttl) block.cache_control = ttl;
|
|
92
|
+
return block;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
77
96
|
const MODELS = [
|
|
78
|
-
{ id: 'claude-opus-4-8', name: 'Claude Opus 4.8', provider: 'anthropic', contextWindow: 1000000 },
|
|
79
|
-
{ id: 'claude-opus-4-7', name: 'Claude Opus 4.7', provider: 'anthropic', contextWindow: 1000000 },
|
|
80
|
-
{ id: 'claude-opus-4-6', name: 'Claude Opus 4.6', provider: 'anthropic', contextWindow: 1000000 },
|
|
81
|
-
{ id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', provider: 'anthropic', contextWindow: 1000000 },
|
|
82
|
-
{ id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku 4.5', provider: 'anthropic', contextWindow: 200000 },
|
|
97
|
+
{ id: 'claude-opus-4-8', name: 'Claude Opus 4.8', provider: 'anthropic', family: 'opus', contextWindow: 1000000 },
|
|
98
|
+
{ id: 'claude-opus-4-7', name: 'Claude Opus 4.7', provider: 'anthropic', family: 'opus', contextWindow: 1000000 },
|
|
99
|
+
{ id: 'claude-opus-4-6', name: 'Claude Opus 4.6', provider: 'anthropic', family: 'opus', contextWindow: 1000000 },
|
|
100
|
+
{ id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', provider: 'anthropic', family: 'sonnet', contextWindow: 1000000 },
|
|
101
|
+
{ id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku 4.5', provider: 'anthropic', family: 'haiku', contextWindow: 200000 },
|
|
83
102
|
];
|
|
84
103
|
const ANTHROPIC_VERSION = '2023-06-01';
|
|
85
104
|
|
|
@@ -131,8 +150,21 @@ const EFFORT_BUDGET = {
|
|
|
131
150
|
low: 1024,
|
|
132
151
|
medium: 4096,
|
|
133
152
|
high: 16384,
|
|
153
|
+
xhigh: 32768,
|
|
134
154
|
max: 32768,
|
|
135
155
|
};
|
|
156
|
+
|
|
157
|
+
const MIN_THINKING_BUDGET = 1024;
|
|
158
|
+
const THINKING_OUTPUT_RESERVE = 1024;
|
|
159
|
+
|
|
160
|
+
function clampThinkingBudgetTokens(value, maxTokens) {
|
|
161
|
+
const desired = Math.floor(Number(value));
|
|
162
|
+
const max = Math.floor(Number(maxTokens));
|
|
163
|
+
if (!Number.isFinite(desired) || desired <= 0 || !Number.isFinite(max)) return null;
|
|
164
|
+
const ceiling = max - THINKING_OUTPUT_RESERVE;
|
|
165
|
+
if (ceiling < MIN_THINKING_BUDGET) return null;
|
|
166
|
+
return Math.max(MIN_THINKING_BUDGET, Math.min(desired, ceiling));
|
|
167
|
+
}
|
|
136
168
|
// Anthropic forbids oneOf / allOf / anyOf at the TOP level of input_schema.
|
|
137
169
|
// Mirror the same sanitizer as anthropic-oauth.mjs so both providers are safe.
|
|
138
170
|
function _sanitizeInputSchema(schema, toolName) {
|
|
@@ -169,9 +201,11 @@ function _sanitizeInputSchema(schema, toolName) {
|
|
|
169
201
|
if (addition) description = description ? `${description} ${addition}` : addition;
|
|
170
202
|
}
|
|
171
203
|
const mergedPropsCount = Object.keys(mergedProps).length;
|
|
172
|
-
process.
|
|
173
|
-
|
|
174
|
-
|
|
204
|
+
if (process.env.MIXDOG_DEBUG_SESSION_LOG) {
|
|
205
|
+
process.stderr.write(
|
|
206
|
+
`[anthropic-sanitizer] tool="${toolName ?? ''}" compound="${compoundKey}" branches=${Array.isArray(compound) ? compound.length : 0} mergedProps=${mergedPropsCount}\n`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
175
209
|
return {
|
|
176
210
|
type: 'object',
|
|
177
211
|
...(description ? { description } : {}),
|
|
@@ -180,11 +214,28 @@ function _sanitizeInputSchema(schema, toolName) {
|
|
|
180
214
|
}
|
|
181
215
|
|
|
182
216
|
function toAnthropicTools(tools) {
|
|
183
|
-
return tools.map((t) =>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
217
|
+
return tools.map((t) => {
|
|
218
|
+
const out = {
|
|
219
|
+
name: t.name,
|
|
220
|
+
description: t.description,
|
|
221
|
+
input_schema: _sanitizeInputSchema(t.inputSchema, t.name),
|
|
222
|
+
};
|
|
223
|
+
if (t.deferLoading === true || t.defer_loading === true) out.defer_loading = true;
|
|
224
|
+
return out;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function nativeAnthropicTools(opts) {
|
|
228
|
+
return Array.isArray(opts?.nativeTools)
|
|
229
|
+
? opts.nativeTools.filter(t => t && typeof t === 'object')
|
|
230
|
+
: [];
|
|
231
|
+
}
|
|
232
|
+
function deferredAnthropicTools(activeTools, opts) {
|
|
233
|
+
if (opts?.session?.deferredNativeTools !== true) return [];
|
|
234
|
+
const active = new Set((activeTools || []).map((tool) => String(tool?.name || '').trim()).filter(Boolean));
|
|
235
|
+
const catalog = Array.isArray(opts.session.deferredToolCatalog) ? opts.session.deferredToolCatalog : [];
|
|
236
|
+
return catalog
|
|
237
|
+
.filter((tool) => tool?.name && !active.has(String(tool.name)))
|
|
238
|
+
.map((tool) => ({ ...tool, deferLoading: true }));
|
|
188
239
|
}
|
|
189
240
|
function toAnthropicMessages(messages) {
|
|
190
241
|
// Marker-free lowering. cache_control is applied AFTER sanitization by
|
|
@@ -218,10 +269,15 @@ function toAnthropicMessages(messages) {
|
|
|
218
269
|
}
|
|
219
270
|
if (m.role === 'tool') {
|
|
220
271
|
const last = result[result.length - 1];
|
|
272
|
+
const refs = Array.isArray(m.nativeToolSearch?.toolReferences)
|
|
273
|
+
? m.nativeToolSearch.toolReferences.map((name) => String(name || '').trim()).filter(Boolean)
|
|
274
|
+
: [];
|
|
221
275
|
const block = {
|
|
222
276
|
type: 'tool_result',
|
|
223
277
|
tool_use_id: m.toolCallId || '',
|
|
224
|
-
content:
|
|
278
|
+
content: refs.length
|
|
279
|
+
? refs.map((name) => ({ type: 'tool_reference', tool_name: name }))
|
|
280
|
+
: normalizeContentForAnthropic(m.content),
|
|
225
281
|
};
|
|
226
282
|
if (last?.role === 'user' && Array.isArray(last.content)) {
|
|
227
283
|
last.content.push(block);
|
|
@@ -241,17 +297,15 @@ function toAnthropicMessages(messages) {
|
|
|
241
297
|
// sanitizeAnthropicContentPairs has already run (and must NOT run again
|
|
242
298
|
// after this), the blocks we mark here are exactly the blocks the provider
|
|
243
299
|
// sees, so the cache breakpoint is stable across turns.
|
|
244
|
-
// tier3: the user message whose first text block / string content
|
|
245
|
-
// startsWith '<system-reminder>' AND includes BP3_SENTINEL —
|
|
246
|
-
// mark its last content block with tier3Ttl.
|
|
247
300
|
// message-anchor: prefer a safe tool_result tail, then a previous real user
|
|
248
301
|
// text turn if another slot remains. Synthetic
|
|
249
302
|
// <system-reminder> messages and current pure-text prompts
|
|
250
303
|
// are excluded so per-call volatileTail/current prompt
|
|
251
304
|
// content never becomes a 1h prefix key.
|
|
252
|
-
// messageTtl === null disables the tail
|
|
305
|
+
// messageTtl === null disables the tail. BP3 (tier3) now rides a system block,
|
|
306
|
+
// so it is no longer marked here.
|
|
253
307
|
// ANTHROPIC_MSG_SLOTS=0 is honoured upstream by passing messageTtl = null.
|
|
254
|
-
function applyAnthropicCacheMarkers(sanitizedMessages, { messageTtl = CACHE_TTL_VOLATILE, messageSlots = 1
|
|
308
|
+
function applyAnthropicCacheMarkers(sanitizedMessages, { messageTtl = CACHE_TTL_VOLATILE, messageSlots = 1 } = {}) {
|
|
255
309
|
if (!Array.isArray(sanitizedMessages) || sanitizedMessages.length === 0) {
|
|
256
310
|
return sanitizedMessages;
|
|
257
311
|
}
|
|
@@ -265,25 +319,20 @@ function applyAnthropicCacheMarkers(sanitizedMessages, { messageTtl = CACHE_TTL_
|
|
|
265
319
|
return '';
|
|
266
320
|
};
|
|
267
321
|
const isSystemReminder = (content) => firstText(content).startsWith('<system-reminder>');
|
|
268
|
-
const isTier3SystemReminder = (content) => {
|
|
269
|
-
const text = firstText(content);
|
|
270
|
-
return text.startsWith('<system-reminder>') && text.includes(BP3_SENTINEL);
|
|
271
|
-
};
|
|
272
322
|
|
|
273
323
|
const markLast = (msg, ttl) => {
|
|
274
324
|
if (!msg) return;
|
|
275
325
|
msg.content = appendCacheControl(msg.content, ttl);
|
|
276
326
|
};
|
|
277
327
|
const ttlRank = (ttl) => ttl?.ttl === '1h' ? 2 : 1;
|
|
278
|
-
const canMarkMessageIdx = (idx
|
|
328
|
+
const canMarkMessageIdx = (idx) => {
|
|
329
|
+
// System-reminder messages (volatileTail / roleSpecific BP4) vary
|
|
330
|
+
// per-call, so never pin them with a 1h marker. The 1h system blocks
|
|
331
|
+
// (BP1/BP2/BP3) already satisfy Anthropic's "1h before 5m" ordering.
|
|
279
332
|
if (idx < 0) return false;
|
|
280
333
|
const msg = sanitizedMessages[idx];
|
|
281
334
|
if (ttlRank(messageTtl) > ttlRank(CACHE_TTL_VOLATILE)
|
|
282
|
-
&& isSystemReminder(msg?.content)
|
|
283
|
-
&& !isTier3SystemReminder(msg?.content)) {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
if (tier3Idx >= 0 && idx < tier3Idx && ttlRank(messageTtl) < ttlRank(tier3Ttl)) {
|
|
335
|
+
&& isSystemReminder(msg?.content)) {
|
|
287
336
|
return false;
|
|
288
337
|
}
|
|
289
338
|
return true;
|
|
@@ -312,29 +361,16 @@ function applyAnthropicCacheMarkers(sanitizedMessages, { messageTtl = CACHE_TTL_
|
|
|
312
361
|
return -1;
|
|
313
362
|
};
|
|
314
363
|
|
|
315
|
-
// tier3 — locate the sentinel-tagged system-reminder user message.
|
|
316
|
-
let tier3MsgIdx = -1;
|
|
317
|
-
if (tier3Ttl !== null) {
|
|
318
|
-
for (let i = 0; i < sanitizedMessages.length; i++) {
|
|
319
|
-
const m = sanitizedMessages[i];
|
|
320
|
-
if (m?.role === 'user' && isTier3SystemReminder(m.content)) {
|
|
321
|
-
tier3MsgIdx = i;
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (tier3MsgIdx >= 0) markLast(sanitizedMessages[tier3MsgIdx], tier3Ttl);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
364
|
if (messageTtl !== null) {
|
|
329
365
|
const slots = Math.max(0, Math.min(4, Number(messageSlots) || 0));
|
|
330
|
-
const marked = new Set(
|
|
366
|
+
const marked = new Set();
|
|
331
367
|
const candidates = [latestToolResultTailIdx(), previousUserTextAnchorIdx()];
|
|
332
368
|
for (const idx of candidates) {
|
|
333
369
|
if (slots <= 0) break;
|
|
334
|
-
if (idx < 0 || marked.has(idx) || !canMarkMessageIdx(idx
|
|
370
|
+
if (idx < 0 || marked.has(idx) || !canMarkMessageIdx(idx)) continue;
|
|
335
371
|
markLast(sanitizedMessages[idx], messageTtl);
|
|
336
372
|
marked.add(idx);
|
|
337
|
-
if (marked.size
|
|
373
|
+
if (marked.size >= slots) break;
|
|
338
374
|
}
|
|
339
375
|
}
|
|
340
376
|
|
|
@@ -352,7 +388,7 @@ export class AnthropicProvider {
|
|
|
352
388
|
constructor(config) {
|
|
353
389
|
this.config = config;
|
|
354
390
|
this.name = config.name || 'anthropic';
|
|
355
|
-
const betaHeaders = config.disableBetaHeaders ? null : buildAnthropicBetaHeaders();
|
|
391
|
+
const betaHeaders = config.disableBetaHeaders ? null : buildAnthropicBetaHeaders({ toolSearch: true });
|
|
356
392
|
this.client = new Anthropic({
|
|
357
393
|
apiKey: config.apiKey || process.env.ANTHROPIC_API_KEY,
|
|
358
394
|
...(config.baseURL ? { baseURL: config.baseURL } : {}),
|
|
@@ -366,7 +402,7 @@ export class AnthropicProvider {
|
|
|
366
402
|
const newKey = cfg?.apiKey || this.config.apiKey || (this.name === 'anthropic' ? process.env.ANTHROPIC_API_KEY : null);
|
|
367
403
|
if (newKey) {
|
|
368
404
|
this.config = { ...(this.config || {}), ...(cfg || {}), apiKey: newKey };
|
|
369
|
-
const betaHeaders = this.config.disableBetaHeaders ? null : buildAnthropicBetaHeaders();
|
|
405
|
+
const betaHeaders = this.config.disableBetaHeaders ? null : buildAnthropicBetaHeaders({ toolSearch: true });
|
|
370
406
|
this.client = new Anthropic({
|
|
371
407
|
apiKey: newKey,
|
|
372
408
|
...(this.config.baseURL ? { baseURL: this.config.baseURL } : {}),
|
|
@@ -402,17 +438,17 @@ export class AnthropicProvider {
|
|
|
402
438
|
|
|
403
439
|
const systemMsgs = messages.filter(m => m.role === 'system');
|
|
404
440
|
const chatMsgs = messages.filter(m => m.role !== 'system');
|
|
405
|
-
|
|
441
|
+
// BP1 baseRules + BP2 stableSystem at ttls.system; BP3 sessionMarker
|
|
442
|
+
// (cacheTier:'tier3') at ttls.tier3 — each its own system content block.
|
|
443
|
+
const systemBlocks = buildSystemBlocks(systemMsgs, ttls.system, ttls.tier3);
|
|
406
444
|
|
|
407
445
|
// 4-BP budget: aligned with anthropic-oauth. tools BP is dropped —
|
|
408
446
|
// system BP covers the tools prefix via Anthropic prefix semantics
|
|
409
447
|
// (order: tools → system → messages). That frees 1 slot for
|
|
410
448
|
// messages-tail.
|
|
411
449
|
const toolsBpUsed = 0;
|
|
412
|
-
const systemBpUsed =
|
|
413
|
-
const
|
|
414
|
-
const tier3BpUsed = tier3Idx >= 0 ? 1 : 0;
|
|
415
|
-
const usedSlots = toolsBpUsed + systemBpUsed + tier3BpUsed;
|
|
450
|
+
const systemBpUsed = systemBlocks.filter(b => b.cache_control).length;
|
|
451
|
+
const usedSlots = toolsBpUsed + systemBpUsed;
|
|
416
452
|
// Env override for BP strategy. ANTHROPIC_MSG_SLOTS=0 disables
|
|
417
453
|
// message caching entirely. Any value >=1 first marks the previous
|
|
418
454
|
// user text turn; a second free slot marks the tail. Mirrors
|
|
@@ -428,34 +464,32 @@ export class AnthropicProvider {
|
|
|
428
464
|
// or delete a marked block. NEVER sanitize again after this.
|
|
429
465
|
// msgSlots === 0 → message-tail disabled.
|
|
430
466
|
const tailTtl = msgSlots > 0 ? ttls.messages : null;
|
|
431
|
-
const tier3Ttl = tier3Idx >= 0 ? ttls.tier3 : null;
|
|
432
467
|
const anthropicMessages = applyAnthropicCacheMarkers(
|
|
433
468
|
toAnthropicMessages(chatMsgs),
|
|
434
|
-
{ messageTtl: tailTtl, messageSlots: msgSlots
|
|
469
|
+
{ messageTtl: tailTtl, messageSlots: msgSlots },
|
|
435
470
|
);
|
|
436
471
|
|
|
437
472
|
const params = {
|
|
438
473
|
model: useModel,
|
|
439
474
|
max_tokens: maxTokens,
|
|
440
|
-
system:
|
|
441
|
-
? [ttls.system
|
|
442
|
-
? { type: 'text', text: systemText, cache_control: ttls.system }
|
|
443
|
-
: { type: 'text', text: systemText }]
|
|
444
|
-
: undefined,
|
|
475
|
+
system: systemBlocks.length ? systemBlocks : undefined,
|
|
445
476
|
messages: anthropicMessages,
|
|
446
477
|
};
|
|
447
|
-
|
|
478
|
+
const nativeTools = nativeAnthropicTools(opts);
|
|
479
|
+
if (tools?.length || nativeTools.length) {
|
|
448
480
|
// No cache_control on tools — the system BP covers tools via
|
|
449
481
|
// Anthropic prefix semantics (order: tools → system → messages).
|
|
450
|
-
params.tools = toAnthropicTools(tools);
|
|
482
|
+
params.tools = [...nativeTools, ...toAnthropicTools([...(tools || []), ...deferredAnthropicTools(tools || [], opts)])];
|
|
451
483
|
}
|
|
452
484
|
// Effort → extended thinking budget. Gateway inherit mode may pass the
|
|
453
|
-
// exact
|
|
485
|
+
// exact OAuth client budget from the incoming Anthropic request.
|
|
454
486
|
const thinkingBudgetTokens = Number(opts.thinkingBudgetTokens);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
487
|
+
const requestedThinkingBudget = Number.isFinite(thinkingBudgetTokens) && thinkingBudgetTokens > 0
|
|
488
|
+
? thinkingBudgetTokens
|
|
489
|
+
: (opts.effort && EFFORT_BUDGET[opts.effort] ? EFFORT_BUDGET[opts.effort] : null);
|
|
490
|
+
const budgetTokens = clampThinkingBudgetTokens(requestedThinkingBudget, maxTokens);
|
|
491
|
+
if (budgetTokens) {
|
|
492
|
+
params.thinking = { type: 'enabled', budget_tokens: budgetTokens };
|
|
459
493
|
}
|
|
460
494
|
// Fast mode → speed: "fast" on models Anthropic marks as speed-capable.
|
|
461
495
|
if (opts.fast === true && supportsAnthropicFastMode(useModel)) {
|
|
@@ -479,7 +513,7 @@ export class AnthropicProvider {
|
|
|
479
513
|
// emitting SSE deltas must not be killed by a fixed total-lifetime timer.
|
|
480
514
|
// Mirrors the OAuth provider (Option A). Bounded instead by the
|
|
481
515
|
// per-attempt first-byte/HTTP-response timeout, the SSE idle watchdog,
|
|
482
|
-
// the
|
|
516
|
+
// the agent stall watchdog, and externalSignal (client disconnect /
|
|
483
517
|
// replaced-by-newer-request). totalSignal is a pure pass-through.
|
|
484
518
|
const externalSignal = opts.signal || null;
|
|
485
519
|
const totalTimeout = createPassthroughSignal(externalSignal);
|
|
@@ -493,10 +527,11 @@ export class AnthropicProvider {
|
|
|
493
527
|
const betaHeaders = {
|
|
494
528
|
'anthropic-beta': buildAnthropicBetaHeaders({
|
|
495
529
|
fastMode: this.fastModeBetaHeaderLatched,
|
|
530
|
+
toolSearch: true,
|
|
496
531
|
}),
|
|
497
532
|
};
|
|
498
533
|
|
|
499
|
-
const MAX_MIDSTREAM_RETRIES =
|
|
534
|
+
const MAX_MIDSTREAM_RETRIES = ANTHROPIC_MAX_MIDSTREAM_RETRIES;
|
|
500
535
|
let firstAttemptError = null;
|
|
501
536
|
let firstAttemptClassifier = null;
|
|
502
537
|
|
|
@@ -510,7 +545,7 @@ export class AnthropicProvider {
|
|
|
510
545
|
const liveModel = parseResult.model || useModel;
|
|
511
546
|
|
|
512
547
|
if (usageRaw || input || output || cacheRead || cacheWrite) {
|
|
513
|
-
|
|
548
|
+
traceAgentUsage({
|
|
514
549
|
sessionId: opts.sessionId || opts.session?.id || null,
|
|
515
550
|
iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
|
|
516
551
|
inputTokens: input,
|
|
@@ -694,6 +729,7 @@ export class AnthropicProvider {
|
|
|
694
729
|
`[${this.name}] empty stream (no message_start) — retry ${attemptIndex + 1}/${MAX_MIDSTREAM_RETRIES}\n`,
|
|
695
730
|
);
|
|
696
731
|
} catch {}
|
|
732
|
+
await _midstreamSleepWithAbort(midstreamBackoffFor(attemptIndex + 1), totalSignal);
|
|
697
733
|
continue;
|
|
698
734
|
}
|
|
699
735
|
if ((err?.truncatedStream === true || err?.code === 'TRUNCATED_STREAM')
|
|
@@ -708,6 +744,7 @@ export class AnthropicProvider {
|
|
|
708
744
|
`[${this.name}] truncated stream — retry ${attemptIndex + 1}/${MAX_MIDSTREAM_RETRIES}\n`,
|
|
709
745
|
);
|
|
710
746
|
} catch {}
|
|
747
|
+
await _midstreamSleepWithAbort(midstreamBackoffFor(attemptIndex + 1), totalSignal);
|
|
711
748
|
continue;
|
|
712
749
|
}
|
|
713
750
|
const classifier = _classifyMidstreamError(err, midState);
|
|
@@ -720,6 +757,7 @@ export class AnthropicProvider {
|
|
|
720
757
|
`[${this.name}] mid-stream recovered: retry ${attemptIndex + 1}/${MAX_MIDSTREAM_RETRIES} (cause: ${classifier})\n`,
|
|
721
758
|
);
|
|
722
759
|
} catch {}
|
|
760
|
+
await _midstreamSleepWithAbort(midstreamBackoffFor(attemptIndex + 1), totalSignal);
|
|
723
761
|
continue;
|
|
724
762
|
}
|
|
725
763
|
if (attemptIndex > 0 && firstAttemptError) {
|