mixdog 0.9.3 → 0.9.4
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/package.json +7 -3
- package/scripts/bench/lead-review-tasks-r3.json +20 -0
- package/scripts/bench/lead-review-tasks.json +20 -0
- package/scripts/bench/r4-mixed-tasks.json +20 -0
- package/scripts/bench/review-tasks.json +20 -0
- package/scripts/bench/round-codex.json +114 -0
- package/scripts/bench/round-mixdog-lead-r3.json +269 -0
- package/scripts/bench/round-mixdog-lead.json +269 -0
- package/scripts/bench/round-mixdog.json +126 -0
- package/scripts/bench/round-r10-bigsample.json +679 -0
- package/scripts/bench/round-r11-codexalign.json +257 -0
- package/scripts/bench/round-r4-codex.json +114 -0
- package/scripts/bench/round-r4-mixed.json +225 -0
- package/scripts/bench/round-r5-gpt-lead.json +259 -0
- package/scripts/bench/round-r6-codex.json +114 -0
- package/scripts/bench/round-r6-solo.json +257 -0
- package/scripts/bench/round-r7-full.json +254 -0
- package/scripts/bench/round-r8-fulldefault.json +255 -0
- package/scripts/bench-run.mjs +215 -29
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/internal-comms-bench.mjs +1 -0
- package/scripts/internal-comms-smoke.mjs +10 -9
- package/scripts/mouse-probe.mjs +45 -0
- package/scripts/output-style-bench.mjs +13 -6
- package/scripts/output-style-smoke.mjs +4 -4
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-usecase-cases.json +18 -0
- package/scripts/recall-usecase-probe.json +6 -0
- package/scripts/session-bench.mjs +152 -6
- package/scripts/tool-smoke.mjs +23 -63
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +4 -1
- package/src/agents/heavy-worker/AGENT.md +6 -5
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +2 -1
- package/src/agents/worker/AGENT.md +8 -4
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +632 -2042
- package/src/output-styles/default.md +34 -9
- package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
- package/src/output-styles/minimal.md +4 -1
- package/src/output-styles/simple.md +22 -7
- package/src/rules/agent/00-common.md +2 -0
- package/src/rules/lead/lead-brief.md +12 -0
- package/src/rules/lead/lead-tool.md +0 -11
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
- package/src/runtime/agent/orchestrator/config.mjs +69 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +297 -2123
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +130 -1002
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
- package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +251 -397
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +32 -41
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
- package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
- package/src/runtime/channels/backends/discord-access.mjs +32 -0
- package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
- package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
- package/src/runtime/channels/backends/discord.mjs +12 -292
- package/src/runtime/channels/index.mjs +229 -663
- package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
- package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
- package/src/runtime/channels/lib/event-queue.mjs +63 -4
- package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
- package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
- package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
- package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
- package/src/runtime/channels/lib/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
- package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
- package/src/runtime/channels/lib/webhook/deliveries.mjs +312 -0
- package/src/runtime/channels/lib/webhook/log.mjs +42 -0
- package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
- package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
- package/src/runtime/channels/lib/webhook.mjs +36 -570
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +201 -1948
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
- package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
- package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
- package/src/runtime/memory/lib/memory-embed.mjs +149 -0
- package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/query-handlers.mjs +780 -0
- package/src/runtime/memory/lib/recall-format.mjs +55 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
- package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
- package/src/runtime/memory/tool-defs.mjs +5 -13
- package/src/runtime/search/lib/http-fetch.mjs +274 -0
- package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
- package/src/runtime/search/lib/web-tools.mjs +24 -602
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +308 -0
- package/src/runtime/shared/tool-result-summary.mjs +515 -0
- package/src/runtime/shared/tool-surface.mjs +80 -898
- package/src/runtime/shared/transcript-writer.mjs +23 -0
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +84 -2
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-recency.mjs +111 -0
- package/src/session-runtime/native-search.mjs +247 -0
- package/src/session-runtime/output-styles.mjs +11 -9
- package/src/session-runtime/prewarm.mjs +142 -0
- package/src/session-runtime/provider-models.mjs +278 -0
- package/src/session-runtime/provider-usage.mjs +120 -0
- package/src/session-runtime/quick-model-rows.mjs +170 -0
- package/src/session-runtime/quick-search-models.mjs +46 -0
- package/src/session-runtime/session-hooks.mjs +93 -0
- package/src/session-runtime/settings-api.mjs +319 -0
- package/src/session-runtime/tool-catalog.mjs +29 -29
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/standalone/agent-tool/helpers.mjs +237 -0
- package/src/standalone/agent-tool/notify.mjs +107 -0
- package/src/standalone/agent-tool/provider-init.mjs +143 -0
- package/src/standalone/agent-tool/render.mjs +152 -0
- package/src/standalone/agent-tool/tool-def.mjs +55 -0
- package/src/standalone/agent-tool.mjs +110 -671
- package/src/standalone/channel-worker.mjs +4 -7
- package/src/standalone/explore-tool.mjs +30 -9
- package/src/standalone/hook-bus/config.mjs +207 -0
- package/src/standalone/hook-bus/constants.mjs +90 -0
- package/src/standalone/hook-bus/handlers.mjs +481 -0
- package/src/standalone/hook-bus/payload.mjs +31 -0
- package/src/standalone/hook-bus/rules.mjs +77 -0
- package/src/standalone/hook-bus.mjs +77 -870
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +5 -1
- package/src/standalone/provider-admin.mjs +1 -16
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +945 -8094
- package/src/tui/app/app-format.mjs +206 -0
- package/src/tui/app/channel-pickers.mjs +510 -0
- package/src/tui/app/clipboard.mjs +67 -0
- package/src/tui/app/core-memory-picker.mjs +210 -0
- package/src/tui/app/extension-pickers.mjs +506 -0
- package/src/tui/app/input-parsers.mjs +193 -0
- package/src/tui/app/maintenance-pickers.mjs +324 -0
- package/src/tui/app/model-options.mjs +330 -0
- package/src/tui/app/model-picker.mjs +365 -0
- package/src/tui/app/onboarding-steps.mjs +400 -0
- package/src/tui/app/project-picker.mjs +247 -0
- package/src/tui/app/provider-setup-picker.mjs +580 -0
- package/src/tui/app/resume-picker.mjs +55 -0
- package/src/tui/app/route-pickers.mjs +419 -0
- package/src/tui/app/settings-picker.mjs +490 -0
- package/src/tui/app/slash-commands.mjs +101 -0
- package/src/tui/app/slash-dispatch.mjs +427 -0
- package/src/tui/app/text-layout.mjs +46 -0
- package/src/tui/app/theme-effort-pickers.mjs +154 -0
- package/src/tui/app/transcript-window.mjs +671 -0
- package/src/tui/app/use-mouse-input.mjs +460 -0
- package/src/tui/app/use-prompt-handlers.mjs +310 -0
- package/src/tui/app/use-transcript-scroll.mjs +510 -0
- package/src/tui/app/use-transcript-window.mjs +589 -0
- package/src/tui/components/ConfirmBar.jsx +1 -1
- package/src/tui/components/Picker.jsx +32 -4
- package/src/tui/components/PromptInput.jsx +23 -101
- package/src/tui/components/SlashCommandPalette.jsx +8 -1
- package/src/tui/components/StatusLine.jsx +63 -12
- package/src/tui/components/TextEntryPanel.jsx +11 -0
- package/src/tui/components/ToolExecution.jsx +52 -594
- package/src/tui/components/TranscriptItem.jsx +105 -0
- package/src/tui/components/UsagePanel.jsx +18 -4
- package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
- package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
- package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
- package/src/tui/components/tool-execution/text-format.mjs +161 -0
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +19652 -18630
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-card-results.mjs +234 -0
- package/src/tui/engine/tool-result-status.mjs +135 -0
- package/src/tui/engine.mjs +122 -562
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +105 -0
- package/src/tui/input-editing.mjs +2 -2
- package/src/tui/markdown/format-token.mjs +4 -1
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/ui/statusline-agents.mjs +213 -0
- package/src/ui/statusline-format.mjs +146 -0
- package/src/ui/statusline-segments.mjs +148 -0
- package/src/ui/statusline.mjs +67 -501
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +1 -1
- package/src/workflows/sequential/WORKFLOW.md +1 -1
- package/vendor/ink/build/display-width.js +19 -3
- package/vendor/ink/build/ink.js +103 -6
- package/vendor/ink/build/log-update.js +17 -3
- package/vendor/ink/build/wrap-text.js +125 -0
- package/scripts/_test-folder-dialog.mjs +0 -30
- package/scripts/fix-brief-fn.mjs +0 -35
- package/scripts/fix-format-tool-surface.mjs +0 -24
- package/scripts/fix-tool-exec-visible.mjs +0 -42
- package/scripts/patch-agent-brief.mjs +0 -48
- package/scripts/patch-app.mjs +0 -21
- package/scripts/patch-app2.mjs +0 -18
- package/scripts/patch-dist-brief.mjs +0 -96
- package/scripts/patch-tool-exec.mjs +0 -70
- package/src/examples/schedules/SCHEDULE.example.md +0 -32
- package/src/examples/webhooks/WEBHOOK.example.md +0 -40
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
- package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
- package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
- package/src/standalone/agent-task-status.test.mjs +0 -76
- package/src/tui/components/tool-output-format.test.mjs +0 -399
- package/src/tui/display-width.test.mjs +0 -35
- package/src/tui/engine-runtime-notification.test.mjs +0 -115
- package/src/tui/engine-tool-result-text.test.mjs +0 -75
- package/src/tui/input-editing.selection.test.mjs +0 -75
- package/src/tui/markdown/format-token.test.mjs +0 -354
- package/src/tui/markdown/render-ansi.test.mjs +0 -108
- package/src/tui/markdown/stream-fence.test.mjs +0 -26
- package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
- package/src/tui/paste-fix.test.mjs +0 -119
- package/src/tui/prompt-history-store.test.mjs +0 -52
- package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
- package/src/tui/transcript-tool-failures.test.mjs +0 -111
- package/src/ui/markdown.test.mjs +0 -70
- package/src/ui/statusline-context-label.test.mjs +0 -15
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
- package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
|
@@ -231,6 +231,29 @@ function persistAgentConfig(build) {
|
|
|
231
231
|
updateSection('agent', (current) => build(hasKeys(current) ? current : {}));
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
// Recap toggle (recap.enabled, default true) gates ONLY the background memory
|
|
235
|
+
// cycles. The memory module itself is always-on. On load we fold a legacy
|
|
236
|
+
// `modules.memory === false` flag into recap.enabled=false one time; the caller
|
|
237
|
+
// (loadConfig) persists the migration so the legacy flag is dropped from disk.
|
|
238
|
+
let _migratedRecapLegacy = false;
|
|
239
|
+
function normalizeRecapConfig(rawRecap, rawModules) {
|
|
240
|
+
const recap = rawRecap && typeof rawRecap === 'object' ? { ...rawRecap } : {};
|
|
241
|
+
if (!('enabled' in recap)) {
|
|
242
|
+
const legacyMemory = rawModules && typeof rawModules === 'object' ? rawModules.memory : undefined;
|
|
243
|
+
const legacyDisabled = legacyMemory === false
|
|
244
|
+
|| (legacyMemory && typeof legacyMemory === 'object' && legacyMemory.enabled === false);
|
|
245
|
+
if (legacyDisabled) {
|
|
246
|
+
recap.enabled = false;
|
|
247
|
+
_migratedRecapLegacy = true;
|
|
248
|
+
} else {
|
|
249
|
+
recap.enabled = true;
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
recap.enabled = recap.enabled !== false;
|
|
253
|
+
}
|
|
254
|
+
return recap;
|
|
255
|
+
}
|
|
256
|
+
|
|
234
257
|
export function loadConfig(options = {}) {
|
|
235
258
|
const includeSecrets = options.secrets !== false;
|
|
236
259
|
const sectionRaw = readSection('agent');
|
|
@@ -353,6 +376,40 @@ export function loadConfig(options = {}) {
|
|
|
353
376
|
process.stderr.write(`[config] persist maintenance migration failed: ${err?.message}\n`);
|
|
354
377
|
}
|
|
355
378
|
}
|
|
379
|
+
// One-time recap migration: fold a legacy `modules.memory === false`
|
|
380
|
+
// flag into `recap.enabled=false` and drop the legacy flag on disk.
|
|
381
|
+
// Compute the recap shape here (before the return) so the
|
|
382
|
+
// _migratedRecapLegacy latch is set, then persist under the lock.
|
|
383
|
+
const recapConfig = normalizeRecapConfig(raw.recap, raw.modules);
|
|
384
|
+
if (_migratedRecapLegacy) {
|
|
385
|
+
_migratedRecapLegacy = false;
|
|
386
|
+
try {
|
|
387
|
+
persistAgentConfig((current) => {
|
|
388
|
+
const cur = { ...current };
|
|
389
|
+
const target = (cur.agent && cur.agent.providers)
|
|
390
|
+
? (cur.agent = { ...cur.agent })
|
|
391
|
+
: cur;
|
|
392
|
+
const recap = (target.recap && typeof target.recap === 'object') ? { ...target.recap } : {};
|
|
393
|
+
if (!('enabled' in recap)) recap.enabled = false;
|
|
394
|
+
target.recap = recap;
|
|
395
|
+
if (target.modules && typeof target.modules === 'object' && target.modules.memory === false) {
|
|
396
|
+
const modules = { ...target.modules };
|
|
397
|
+
delete modules.memory;
|
|
398
|
+
target.modules = modules;
|
|
399
|
+
} else if (target.modules && typeof target.modules === 'object' && target.modules.memory) {
|
|
400
|
+
const modules = { ...target.modules };
|
|
401
|
+
const memoryMod = { ...modules.memory };
|
|
402
|
+
delete memoryMod.enabled;
|
|
403
|
+
if (Object.keys(memoryMod).length === 0) delete modules.memory;
|
|
404
|
+
else modules.memory = memoryMod;
|
|
405
|
+
target.modules = modules;
|
|
406
|
+
}
|
|
407
|
+
return cur;
|
|
408
|
+
});
|
|
409
|
+
} catch (err) {
|
|
410
|
+
process.stderr.write(`[config] persist recap migration failed: ${err?.message}\n`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
356
413
|
const rawPresets = Array.isArray(raw.presets) ? raw.presets : [];
|
|
357
414
|
const normalizedPresets = rawPresets
|
|
358
415
|
.map(p => normalizePreset(p))
|
|
@@ -378,12 +435,18 @@ export function loadConfig(options = {}) {
|
|
|
378
435
|
workflow: raw.workflow && typeof raw.workflow === 'object' ? { active: String(raw.workflow.active || 'default') } : { active: 'default' },
|
|
379
436
|
agentMaintenance: { enabled: true, interval: '1h', ...raw.agentMaintenance },
|
|
380
437
|
profile: normalizeProfileConfig(raw.profile),
|
|
381
|
-
|
|
438
|
+
// No idleMs default here: absent idleMs means "provider default"
|
|
439
|
+
// (config-helpers normalizeAutoClearConfig custom:false path).
|
|
440
|
+
// Injecting a fixed 1h would mark every config custom:true and
|
|
441
|
+
// bypass the per-provider auto-clear table.
|
|
442
|
+
autoClear: { enabled: true, ...raw.autoClear },
|
|
382
443
|
compaction: raw.compaction && typeof raw.compaction === 'object' ? { ...raw.compaction } : {},
|
|
383
444
|
trajectory: { enabled: true, ...raw.trajectory },
|
|
384
445
|
runtime: raw.runtime && typeof raw.runtime === 'object' ? raw.runtime : {},
|
|
385
446
|
shell: raw.shell && typeof raw.shell === 'object' ? raw.shell : {},
|
|
386
447
|
update: raw.update && typeof raw.update === 'object' ? { ...raw.update } : {},
|
|
448
|
+
recap: recapConfig,
|
|
449
|
+
modules: raw.modules && typeof raw.modules === 'object' ? { ...raw.modules } : {},
|
|
387
450
|
};
|
|
388
451
|
}
|
|
389
452
|
catch { /* fall through */ }
|
|
@@ -404,12 +467,14 @@ export function loadConfig(options = {}) {
|
|
|
404
467
|
workflow: { active: 'default' },
|
|
405
468
|
agentMaintenance: { enabled: true, interval: '1h' },
|
|
406
469
|
profile: normalizeProfileConfig(null),
|
|
407
|
-
|
|
470
|
+
autoClear: { enabled: true },
|
|
408
471
|
compaction: {},
|
|
409
472
|
trajectory: { enabled: true },
|
|
410
473
|
runtime: {},
|
|
411
474
|
shell: {},
|
|
412
475
|
update: {},
|
|
476
|
+
recap: { enabled: true },
|
|
477
|
+
modules: {},
|
|
413
478
|
};
|
|
414
479
|
}
|
|
415
480
|
/**
|
|
@@ -485,6 +550,8 @@ export function saveConfig(config) {
|
|
|
485
550
|
runtime: config.runtime || {},
|
|
486
551
|
shell: config.shell || {},
|
|
487
552
|
update: config.update || {},
|
|
553
|
+
recap: config.recap || {},
|
|
554
|
+
modules: config.modules || existingRaw.modules || {},
|
|
488
555
|
}));
|
|
489
556
|
}
|
|
490
557
|
// --- Preset helpers ---
|
|
@@ -2,7 +2,20 @@
|
|
|
2
2
|
* Anthropic "effort" (extended-thinking budget) request parameter handling.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export const EFFORT_LEVELS = Object.freeze(['low', 'medium', 'high', 'max']);
|
|
5
|
+
export const EFFORT_LEVELS = Object.freeze(['low', 'medium', 'high', 'xhigh', 'max']);
|
|
6
|
+
|
|
7
|
+
// Canonical display/transport ordering for effort levels. Used only to sort
|
|
8
|
+
// whatever set the catalog actually advertises — NOT as an allowlist. The
|
|
9
|
+
// catalog (capabilities.effort) is the source of truth for which levels a
|
|
10
|
+
// model exposes; this array just keeps them in a stable low→max order.
|
|
11
|
+
const EFFORT_LEVEL_ORDER = Object.freeze(['none', 'low', 'medium', 'high', 'xhigh', 'max']);
|
|
12
|
+
function _sortEffortLevels(levels) {
|
|
13
|
+
const rank = (l) => {
|
|
14
|
+
const i = EFFORT_LEVEL_ORDER.indexOf(l);
|
|
15
|
+
return i === -1 ? EFFORT_LEVEL_ORDER.length : i;
|
|
16
|
+
};
|
|
17
|
+
return [...levels].sort((a, b) => rank(a) - rank(b));
|
|
18
|
+
}
|
|
6
19
|
|
|
7
20
|
export const EFFORT_BETA_HEADER = 'effort-2025-11-24';
|
|
8
21
|
|
|
@@ -10,6 +23,7 @@ export const LEGACY_EFFORT_BUDGET = Object.freeze({
|
|
|
10
23
|
low: 1024,
|
|
11
24
|
medium: 4096,
|
|
12
25
|
high: 16384,
|
|
26
|
+
xhigh: 32768,
|
|
13
27
|
max: 32768,
|
|
14
28
|
});
|
|
15
29
|
const _LOGGED_EFFORT_NORMALIZATION = new Set();
|
|
@@ -59,11 +73,28 @@ export function modelSupportsEffort(model) {
|
|
|
59
73
|
return false;
|
|
60
74
|
}
|
|
61
75
|
|
|
76
|
+
// @[MODEL LAUNCH]: extend when new models support xhigh effort.
|
|
77
|
+
// Per platform.claude.com/docs/en/build-with-claude/effort — xhigh is
|
|
78
|
+
// supported by: Fable 5, Mythos 5, Opus 4.8, Opus 4.7, Sonnet 5.
|
|
79
|
+
// NOT Opus 4.6 / Sonnet 4.6 (those support max but not xhigh).
|
|
80
|
+
export function modelSupportsXhighEffort(model) {
|
|
81
|
+
const m = normalizeModelId(model);
|
|
82
|
+
if (/^claude-opus-4-(7|8)(?:$|[-@])/.test(m)) return true;
|
|
83
|
+
if (/^claude-opus-5(?:$|[-@])/.test(m)) return true;
|
|
84
|
+
if (/^claude-sonnet-5(?:$|[-@])/.test(m)) return true;
|
|
85
|
+
if (/^claude-fable-5(?:$|[-@])/.test(m)) return true;
|
|
86
|
+
if (/^claude-mythos-5(?:$|[-@])/.test(m)) return true;
|
|
87
|
+
if (/^claude-mythos-preview(?:$|[-@])/.test(m)) return true;
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
62
91
|
// @[MODEL LAUNCH]: extend when new Opus models support max effort.
|
|
92
|
+
// Max list = xhigh list PLUS Opus 4.6, Sonnet 4.6, Opus 4.5.
|
|
63
93
|
export function modelSupportsMaxEffort(model) {
|
|
94
|
+
if (modelSupportsXhighEffort(model)) return true;
|
|
64
95
|
const m = normalizeModelId(model);
|
|
65
|
-
if (/^claude-opus-4-(6
|
|
66
|
-
if (/^claude-
|
|
96
|
+
if (/^claude-opus-4-(5|6)(?:$|[-@])/.test(m)) return true;
|
|
97
|
+
if (/^claude-sonnet-4-6(?:$|[-@])/.test(m)) return true;
|
|
67
98
|
return false;
|
|
68
99
|
}
|
|
69
100
|
|
|
@@ -79,26 +110,24 @@ function logOnce(key, write) {
|
|
|
79
110
|
}
|
|
80
111
|
|
|
81
112
|
/**
|
|
82
|
-
* Normalize user/config effort to API levels (low/medium/high/max).
|
|
83
|
-
*
|
|
113
|
+
* Normalize user/config effort to API levels (low/medium/high/xhigh/max).
|
|
114
|
+
* Accepts extra-high / very-high aliases as xhigh; clamps xhigh/max down to
|
|
115
|
+
* high on models that don't support the top Opus tiers.
|
|
84
116
|
*/
|
|
85
117
|
export function normalizeAnthropicEffortInput(raw, model, logTag = 'anthropic') {
|
|
86
118
|
if (raw === undefined || raw === null || raw === '') return undefined;
|
|
87
119
|
let level = String(raw).trim().toLowerCase();
|
|
88
120
|
if (level === 'extra-high' || level === 'very-high') level = 'xhigh';
|
|
89
121
|
|
|
90
|
-
if (level === 'xhigh') {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
process.stderr.write(
|
|
94
|
-
`[${logTag}] effort "xhigh" normalized to "${mapped}" (official levels: ${EFFORT_LEVELS.join(', ')})\n`,
|
|
95
|
-
);
|
|
122
|
+
if (level === 'xhigh' && !modelSupportsXhighEffort(model)) {
|
|
123
|
+
logOnce(`xhigh:high`, () => {
|
|
124
|
+
process.stderr.write(`[${logTag}] effort "xhigh" downgraded to "high" for model ${model}\n`);
|
|
96
125
|
});
|
|
97
|
-
return
|
|
126
|
+
return 'high';
|
|
98
127
|
}
|
|
99
128
|
|
|
100
129
|
if (level === 'max' && !modelSupportsMaxEffort(model)) {
|
|
101
|
-
logOnce(
|
|
130
|
+
logOnce(`max:high`, () => {
|
|
102
131
|
process.stderr.write(`[${logTag}] effort "max" downgraded to "high" for model ${model}\n`);
|
|
103
132
|
});
|
|
104
133
|
return 'high';
|
|
@@ -174,15 +203,28 @@ export function applyAnthropicEffortToBody(
|
|
|
174
203
|
|
|
175
204
|
export function effortValuesForModel(capabilities, modelId) {
|
|
176
205
|
const effort = capabilities?.effort;
|
|
206
|
+
if (!effort) return [];
|
|
207
|
+
// Catalog-first: when capabilities.effort enumerates per-level support,
|
|
208
|
+
// that map is the source of truth — expose exactly the levels the model
|
|
209
|
+
// advertises (xhigh, max, or anything future), no hardcoded allowlist.
|
|
210
|
+
if (effort !== true && typeof effort === 'object') {
|
|
211
|
+
const advertised = Object.keys(effort).filter(
|
|
212
|
+
(level) => effort[level] === true || effort[level]?.supported === true,
|
|
213
|
+
);
|
|
214
|
+
if (advertised.length) return _sortEffortLevels(advertised);
|
|
215
|
+
// Object with no per-level flags: fall through to the boolean/supported
|
|
216
|
+
// fallback below only when it explicitly marks blanket support.
|
|
217
|
+
if (effort.supported !== true) return [];
|
|
218
|
+
}
|
|
219
|
+
// Fallback (effort === true, or {supported:true} with no per-level map):
|
|
220
|
+
// the model supports effort but doesn't enumerate levels, so derive the
|
|
221
|
+
// set from the known level ladder, gated by the top-tier model check.
|
|
177
222
|
let levels = [...EFFORT_LEVELS];
|
|
178
223
|
if (!modelSupportsMaxEffort(modelId)) {
|
|
179
224
|
levels = levels.filter((level) => level !== 'max');
|
|
180
225
|
}
|
|
181
|
-
if (!
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
);
|
|
186
|
-
if (values.length) return values;
|
|
187
|
-
return effort.supported === true ? levels : [];
|
|
226
|
+
if (!modelSupportsXhighEffort(modelId)) {
|
|
227
|
+
levels = levels.filter((level) => level !== 'xhigh');
|
|
228
|
+
}
|
|
229
|
+
return levels;
|
|
188
230
|
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anthropic-model-resolve.mjs — Anthropic OAuth model-catalog cache + resolvers.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from anthropic-oauth.mjs. Owns the disk-backed catalog cache and
|
|
5
|
+
* its in-memory mirror (single instance; the provider imports every reader/
|
|
6
|
+
* writer from here so there is exactly ONE catalog state in the process).
|
|
7
|
+
*/
|
|
8
|
+
import { enrichModels } from './model-catalog.mjs';
|
|
9
|
+
import { sanitizeModelList } from './model-list-sanitize.mjs';
|
|
10
|
+
import { makeModelCache } from './model-cache.mjs';
|
|
11
|
+
import { effortValuesForModel } from './anthropic-effort.mjs';
|
|
12
|
+
|
|
13
|
+
// Disk-backed cache so repeated process starts (cron, tool calls) don't
|
|
14
|
+
// hammer /v1/models. 24h TTL matches the upstream client cadence.
|
|
15
|
+
const MODEL_CACHE_TTL_MS = 24 * 60 * 60_000;
|
|
16
|
+
// Bump when the on-disk cache shape changes so stale-shape entries are
|
|
17
|
+
// discarded instead of misread.
|
|
18
|
+
const ANTHROPIC_MODEL_CACHE_SCHEMA_VERSION = 1;
|
|
19
|
+
|
|
20
|
+
const _modelCache = makeModelCache({
|
|
21
|
+
fileName: 'anthropic-oauth-models.json',
|
|
22
|
+
ttlMs: MODEL_CACHE_TTL_MS,
|
|
23
|
+
version: ANTHROPIC_MODEL_CACHE_SCHEMA_VERSION,
|
|
24
|
+
onSave: (m) => { _inMemoryCatalog = Array.isArray(m) ? m.slice() : null; },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Async wrappers so callers can keep awaiting; the shared cache CRUD is sync.
|
|
28
|
+
export async function _loadModelCache() {
|
|
29
|
+
return _modelCache.loadSync();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function _saveModelCache(models) {
|
|
33
|
+
_modelCache.save(models);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// In-memory mirror of the disk catalog — populated on first listModels() and
|
|
37
|
+
// refreshed after every _saveModelCache. Used by _catalogHas and _displayModel
|
|
38
|
+
// so hot paths don't hit disk on every response.
|
|
39
|
+
let _inMemoryCatalog = null;
|
|
40
|
+
|
|
41
|
+
// The mirror is written both by this module (onSave) and by the provider's
|
|
42
|
+
// listModels() warm path, so expose a setter instead of the raw binding.
|
|
43
|
+
export function _setInMemoryCatalog(models) {
|
|
44
|
+
_inMemoryCatalog = Array.isArray(models) ? models.slice() : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function _catalogHas(id) {
|
|
48
|
+
if (!id || !Array.isArray(_inMemoryCatalog)) return false;
|
|
49
|
+
return _inMemoryCatalog.some(m => m.id === id);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Display-name normalization for trace / usage. Turns dated or version-alias
|
|
53
|
+
// ids into the version alias form: claude-opus-4-7 → claude-opus-4.7,
|
|
54
|
+
// claude-haiku-4-5-20251001 → claude-haiku-4.5. Falls back to the raw id.
|
|
55
|
+
export function _displayModel(id) {
|
|
56
|
+
if (!id || typeof id !== 'string') return id;
|
|
57
|
+
const m = id.match(/^claude-([a-z]+)-(\d+)(?:-(\d+))?(?:-\d{8})?$/i);
|
|
58
|
+
if (!m) return id;
|
|
59
|
+
return `claude-${m[1].toLowerCase()}-${m[2]}${m[3] ? `.${m[3]}` : ''}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function _capabilitySupported(capability) {
|
|
63
|
+
return capability === true || capability?.supported === true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Classify a model id into our common tier/family shape. Anthropic's catalog
|
|
67
|
+
// mixes dated ids (claude-opus-4-5-20251101), versioned aliases
|
|
68
|
+
// (claude-opus-4-6), and the raw family tokens resolved via env vars.
|
|
69
|
+
export function _normalizeAnthropicModel(raw) {
|
|
70
|
+
const id = raw?.id || raw?.name;
|
|
71
|
+
if (!id) return null;
|
|
72
|
+
const familyMatch = id.match(/^claude-([a-z]+)/i);
|
|
73
|
+
const family = familyMatch ? familyMatch[1].toLowerCase() : 'other';
|
|
74
|
+
// Dated: trailing -YYYYMMDD (8 digits).
|
|
75
|
+
const dated = /-\d{8}$/.test(id);
|
|
76
|
+
// Versioned alias: claude-<family>-<major>-<minor>[-...] with no dated suffix.
|
|
77
|
+
const versioned = !dated && /^claude-[a-z]+-\d+(?:-\d+)?$/i.test(id);
|
|
78
|
+
const tier = dated ? 'dated' : versioned ? 'version' : 'family';
|
|
79
|
+
const releaseDate = dated
|
|
80
|
+
? id.match(/-(\d{4})(\d{2})(\d{2})$/)
|
|
81
|
+
: null;
|
|
82
|
+
const effortValues = effortValuesForModel(raw?.capabilities, id);
|
|
83
|
+
return {
|
|
84
|
+
id,
|
|
85
|
+
display: raw?.display_name || _prettyName(id, family),
|
|
86
|
+
family,
|
|
87
|
+
provider: 'anthropic-oauth',
|
|
88
|
+
contextWindow: raw?.context_window || raw?.max_context_window || raw?.max_input_tokens || _defaultContextForModel(id, family),
|
|
89
|
+
outputTokens: raw?.max_tokens || raw?.max_output_tokens || null,
|
|
90
|
+
tier,
|
|
91
|
+
latest: false, // assigned in a second pass once full list is known
|
|
92
|
+
releaseDate: releaseDate ? `${releaseDate[1]}-${releaseDate[2]}-${releaseDate[3]}` : null,
|
|
93
|
+
supportsReasoning: effortValues.length > 0 || _capabilitySupported(raw?.capabilities?.thinking),
|
|
94
|
+
reasoningOptions: effortValues.length ? [{ type: 'effort', values: effortValues }] : [],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function _prettyName(id, family) {
|
|
99
|
+
const v = id.match(/^claude-[a-z]+-(\d+)(?:-(\d+))?/i);
|
|
100
|
+
const base = family[0].toUpperCase() + family.slice(1);
|
|
101
|
+
return v ? `${base} ${v[1]}${v[2] ? `.${v[2]}` : ''}` : base;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function _defaultContextForModel(id, family) {
|
|
105
|
+
const text = String(id || '');
|
|
106
|
+
const version = text.match(/^claude-[a-z]+-(\d+)(?:-(\d+))?/i);
|
|
107
|
+
if (Number(version?.[1] || 0) >= 5) return 1000000;
|
|
108
|
+
if (/^claude-(opus|sonnet)-4-(6|7|8)(?:$|-)/i.test(text)) return 1000000;
|
|
109
|
+
if (family && family !== 'other') return 200000;
|
|
110
|
+
return 200000;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Mark the highest-numbered version per family as `latest: true`. Uses a simple
|
|
114
|
+
// lexicographic comparison on the numeric parts embedded in the id.
|
|
115
|
+
export function _markLatestByFamily(models) {
|
|
116
|
+
const byFamily = new Map();
|
|
117
|
+
for (const m of models) {
|
|
118
|
+
if (m.tier !== 'version') continue;
|
|
119
|
+
const cur = byFamily.get(m.family);
|
|
120
|
+
if (!cur || _compareVersion(m.id, cur.id) > 0) {
|
|
121
|
+
byFamily.set(m.family, m);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
for (const m of byFamily.values()) m.latest = true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function _compareVersion(a, b) {
|
|
128
|
+
const na = (a.match(/^claude-[a-z]+-(\d+)(?:-(\d+))?/i) || []).slice(1).map(Number);
|
|
129
|
+
const nb = (b.match(/^claude-[a-z]+-(\d+)(?:-(\d+))?/i) || []).slice(1).map(Number);
|
|
130
|
+
for (let i = 0; i < Math.max(na.length, nb.length); i++) {
|
|
131
|
+
if ((na[i] || 0) !== (nb[i] || 0)) return (na[i] || 0) - (nb[i] || 0);
|
|
132
|
+
}
|
|
133
|
+
return a.localeCompare(b);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Newest HIGH-TIER chat model by version, read from the SYNC in-memory catalog
|
|
137
|
+
// mirror. Anthropic ships three families: opus / sonnet / haiku. "Latest" is the
|
|
138
|
+
// highest version across opus + sonnet only — haiku is the cheap tier and is
|
|
139
|
+
// never the flagship default. Returns null until listModels() populates the
|
|
140
|
+
// mirror; callers must warm the catalog (ensureLatestAnthropicModel) when null.
|
|
141
|
+
export function resolveLatestAnthropicModel() {
|
|
142
|
+
if (!Array.isArray(_inMemoryCatalog)) return null;
|
|
143
|
+
let best = null;
|
|
144
|
+
for (const m of _inMemoryCatalog) {
|
|
145
|
+
if (!m?.id || (m.family !== 'opus' && m.family !== 'sonnet')) continue;
|
|
146
|
+
if (!best || _compareVersion(m.id, best.id) > 0) best = m;
|
|
147
|
+
}
|
|
148
|
+
return best?.id || null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function resolveAnthropicModelAfter404(requested) {
|
|
152
|
+
if (!Array.isArray(_inMemoryCatalog)) return null;
|
|
153
|
+
const wanted = String(requested || '');
|
|
154
|
+
const family = (wanted.match(/^claude-([a-z]+)/i) || [])[1]?.toLowerCase() || null;
|
|
155
|
+
let best = null;
|
|
156
|
+
for (const m of _inMemoryCatalog) {
|
|
157
|
+
if (!m?.id) continue;
|
|
158
|
+
if (family && m.family !== family) continue;
|
|
159
|
+
if (!family && m.family !== 'opus' && m.family !== 'sonnet') continue;
|
|
160
|
+
if (!best || _compareVersion(m.id, best.id) > 0) best = m;
|
|
161
|
+
}
|
|
162
|
+
if (best?.id && best.id !== wanted) return best.id;
|
|
163
|
+
if (family === 'opus') {
|
|
164
|
+
const flagship = resolveLatestAnthropicModel();
|
|
165
|
+
if (flagship && flagship !== wanted) return flagship;
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export async function ensureLatestAnthropicModel(provider) {
|
|
171
|
+
let m = resolveLatestAnthropicModel();
|
|
172
|
+
if (m) return m;
|
|
173
|
+
await provider._refreshModelCache();
|
|
174
|
+
m = resolveLatestAnthropicModel();
|
|
175
|
+
if (m) return m;
|
|
176
|
+
throw new Error('[anthropic-oauth] model catalog unavailable after warmup — cannot resolve default model');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Catalog-reported outputTokens for a model id, read from the in-memory
|
|
180
|
+
// catalog mirror (lazily populated from the disk cache if the mirror hasn't
|
|
181
|
+
// been warmed yet by listModels()). Never throws — any failure just means
|
|
182
|
+
// "no catalog data", and callers fall back to the static heuristics.
|
|
183
|
+
export function _catalogOutputTokens(model) {
|
|
184
|
+
if (!model) return null;
|
|
185
|
+
try {
|
|
186
|
+
if (!Array.isArray(_inMemoryCatalog)) {
|
|
187
|
+
const cached = _modelCache.loadSync();
|
|
188
|
+
if (Array.isArray(cached)) _inMemoryCatalog = cached.slice();
|
|
189
|
+
}
|
|
190
|
+
if (!Array.isArray(_inMemoryCatalog)) return null;
|
|
191
|
+
const entry = _inMemoryCatalog.find(m => m?.id === model);
|
|
192
|
+
const out = Number(entry?.outputTokens);
|
|
193
|
+
return Number.isFinite(out) && out > 0 ? out : null;
|
|
194
|
+
} catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Normalize + mark-latest + LiteLLM-enrich + persist one fetched /v1/models
|
|
200
|
+
// payload. Shared by the provider's listModels() and _refreshModelCache().
|
|
201
|
+
export async function normalizeAndSaveCatalog(items) {
|
|
202
|
+
const normalized = (Array.isArray(items) ? items : [])
|
|
203
|
+
.map(m => _normalizeAnthropicModel(m))
|
|
204
|
+
.filter(Boolean);
|
|
205
|
+
_markLatestByFamily(normalized);
|
|
206
|
+
const enriched = sanitizeModelList(await enrichModels(normalized), { provider: 'anthropic' });
|
|
207
|
+
await _saveModelCache(enriched);
|
|
208
|
+
return enriched;
|
|
209
|
+
}
|