mixdog 1.1.2 → 1.2.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 +8 -5
- package/package.json +2 -1
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +10 -0
- package/src/defaults/skills/pptx/SKILL.md +6 -6
- package/src/defaults/skills/pptx/references/review.md +6 -4
- package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
- package/src/defaults/skills/setup/references/actions.md +18 -5
- package/src/defaults/skills/visualize/SKILL.md +160 -0
- package/src/defaults/skills/visualize/references/craft.md +88 -0
- package/src/headless-command.mjs +56 -3
- package/src/headless-exec.mjs +17 -1
- package/src/help.mjs +2 -0
- package/src/rules/shared/60-verification.md +3 -1
- package/src/rules/shared/70-delivery.md +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
- package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +19 -5
- package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +133 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
- package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +444 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
- package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -3
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
- package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
- package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -12
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +202 -374
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +48 -9
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/attachments/store.mjs +38 -0
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
- package/src/runtime/channels/lib/worker-main.mjs +17 -14
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
- package/src/runtime/effort-judge/judge-client.mjs +56 -18
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/session-ingest.mjs +2 -2
- package/src/runtime/shared/atomic-file.mjs +33 -6
- package/src/runtime/shared/best-effort-stderr.mjs +8 -0
- package/src/runtime/shared/code-graph-state.mjs +12 -0
- package/src/runtime/shared/defaults-separation.mjs +2 -0
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
- package/src/runtime/shared/llm/default-context-window.mjs +6 -0
- package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
- package/src/runtime/shared/llm/model-catalog.mjs +240 -130
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
- package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
- package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
- package/src/runtime/shared/model-proxy-mode.mjs +19 -0
- package/src/runtime/shared/plugin-manifest.mjs +18 -9
- package/src/runtime/shared/pristine-execution-contract.json +9 -2
- package/src/runtime/shared/pristine-execution.mjs +28 -4
- package/src/runtime/shared/provider-accounts.mjs +125 -21
- package/src/runtime/shared/provider-api-key.mjs +33 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- package/src/runtime/shared/skill-mentions.d.mts +10 -0
- package/src/runtime/shared/skill-mentions.mjs +133 -0
- package/src/runtime/shared/skill-script-runtime.mjs +264 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/tool-surface.mjs +7 -0
- package/src/runtime/shared/tool-work-units.mjs +14 -0
- package/src/runtime/shared/transcript-metadata.mjs +17 -1
- package/src/runtime/shared/turn-changes.mjs +791 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
- package/src/runtime/shared/turn-snapshot.mjs +690 -81
- package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
- package/src/runtime/shared/worktrees/contract.mjs +551 -0
- package/src/runtime/shared/worktrees/disk.mjs +57 -0
- package/src/runtime/shared/worktrees/git.mjs +247 -0
- package/src/runtime/shared/worktrees/include.mjs +480 -0
- package/src/runtime/shared/worktrees/lock.mjs +46 -0
- package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
- package/src/runtime/shared/worktrees/manager.mjs +1215 -0
- package/src/runtime/shared/worktrees/merge.mjs +182 -0
- package/src/runtime/shared/worktrees/owner.mjs +46 -0
- package/src/runtime/shared/worktrees/paths.mjs +62 -0
- package/src/runtime/shared/worktrees/registry.mjs +110 -0
- package/src/runtime/shared/worktrees/settings.mjs +84 -0
- package/src/runtime/shared/worktrees/slug.mjs +62 -0
- package/src/runtime/shared/worktrees/test-support.mjs +96 -0
- package/src/runtime/visualize-bridge/client.mjs +181 -0
- package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +90 -0
- package/src/session-runtime/boot/config.mjs +7 -2
- package/src/session-runtime/boot/facade.mjs +21 -0
- package/src/session-runtime/boot/infrastructure.mjs +30 -18
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +4 -0
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- package/src/session-runtime/conversation-import/discovery.mjs +698 -0
- package/src/session-runtime/conversation-import/service.mjs +369 -0
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +21 -6
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/global-extensions.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
- package/src/session-runtime/internal-tool-executor.mjs +9 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
- package/src/session-runtime/mcp-glue/connect.mjs +68 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- package/src/session-runtime/mcp-glue.mjs +22 -2
- package/src/session-runtime/model-route/route-persist.mjs +3 -0
- package/src/session-runtime/model-route/set-route.mjs +15 -2
- package/src/session-runtime/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +18 -3
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
- package/src/session-runtime/provider-readiness.mjs +16 -10
- package/src/session-runtime/resource-extension-sync.mjs +45 -7
- package/src/session-runtime/resource-mcp-api.mjs +121 -84
- package/src/session-runtime/resource-plugins-api.mjs +29 -41
- package/src/session-runtime/resource-scope-decorate.mjs +6 -8
- package/src/session-runtime/resource-skills-api.mjs +23 -2
- package/src/session-runtime/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
- package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/daemon-candidate.mjs +3 -2
- package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
- package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
- package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
- package/src/session-runtime/services/provider-admin.mjs +64 -18
- package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
- package/src/session-runtime/session-create/session-options.mjs +10 -1
- package/src/session-runtime/session-turn-api.mjs +1 -0
- package/src/session-runtime/settings-api.mjs +4 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
- package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
- package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
- package/src/session-runtime/turn/turn-run.mjs +6 -7
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workspace/admission-gate.mjs +197 -0
- package/src/session-runtime/workspace/project-branches.mjs +136 -0
- package/src/session-runtime/workspace/transition-steps.mjs +364 -0
- package/src/session-runtime/workspace/transitions.mjs +651 -0
- package/src/session-runtime/workspace/workspace-state.mjs +112 -0
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-owner.mjs +372 -0
- package/src/standalone/daemon-stored-session-views.mjs +15 -4
- package/src/standalone/daemon.mjs +179 -8
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +11 -0
- package/src/standalone/session-client/attachment-calls.mjs +3 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
- package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
- package/src/standalone/session-client.mjs +104 -13
- package/src/standalone/session-protocol.mjs +21 -0
- package/src/standalone/session-proxy.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
- package/src/standalone/session-service/projection/revisions.mjs +2 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
- package/src/standalone/session-service/projection/workspace.mjs +14 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
- package/src/standalone/session-transport/call-route.mjs +13 -0
- package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
- package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
- package/src/standalone/session-transport/client-registry.mjs +20 -3
- package/src/standalone/session-transport/routes.mjs +79 -2
- package/src/standalone/session-transport/stack.mjs +2 -0
- package/src/standalone/session-transport.mjs +24 -1
- package/src/tui/App.jsx +9 -1
- package/src/tui/app/app-view/floating-panel.jsx +9 -1
- package/src/tui/app/app-view.jsx +6 -0
- package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
- package/src/tui/app/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +37 -5
- package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
- package/src/tui/app/model-picker.mjs +4 -2
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- package/src/tui/app/slash-palette.mjs +23 -7
- package/src/tui/app/transcript-row-estimate.mjs +11 -3
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
- package/src/tui/app/use-prompt-state.mjs +5 -0
- package/src/tui/components/Message.jsx +22 -1
- package/src/tui/components/PromptInput.jsx +21 -3
- package/src/tui/components/SlashCommandPalette.jsx +12 -3
- package/src/tui/components/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- package/src/tui/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +839 -207
- package/src/tui/index.jsx +10 -2
- package/src/tui/session/compaction-view.mjs +147 -0
- package/src/tui/session/context-state.mjs +6 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +2 -1
- package/src/tui/session/session-api/commands.mjs +10 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +4 -2
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +17 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
- package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
- package/src/tui/session/session-api/routes.mjs +10 -1
- package/src/tui/session/session-api/settings.mjs +9 -0
- package/src/tui/session/session-api/worktree.mjs +60 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +31 -12
- package/src/tui/session/session-flow/drain.mjs +27 -3
- package/src/tui/session/session-flow/session-reset.mjs +4 -3
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/transcript-intake.mjs +14 -5
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +56 -10
- package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
- package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// The MCP SDK Client compiles every tool's outputSchema with Ajv inside
|
|
2
|
+
// listTools(), synchronously: a server listing ~180 tools held the daemon's
|
|
3
|
+
// event loop for 1-2 s on every connect. This validator compiles each schema
|
|
4
|
+
// on the tool's first structured result instead, and creates the SDK's Ajv
|
|
5
|
+
// validator (same options and error text) on first use too.
|
|
6
|
+
// A schema declaring an `$id` anywhere registers it in the client's Ajv, and a
|
|
7
|
+
// schema referencing anything outside itself resolves against what is
|
|
8
|
+
// registered by then (failing the listing when it is not); both still compile
|
|
9
|
+
// when listed, in listing order, exactly as the SDK does.
|
|
10
|
+
const LISTING_ORDER_SCHEMA = /"\$id"|"\$ref":"(?!#)/;
|
|
11
|
+
|
|
12
|
+
export function createLazyOutputValidator(AjvJsonSchemaValidator) {
|
|
13
|
+
let provider = null;
|
|
14
|
+
const shared = () => (provider ??= new AjvJsonSchemaValidator());
|
|
15
|
+
return {
|
|
16
|
+
getValidator(schema) {
|
|
17
|
+
if (LISTING_ORDER_SCHEMA.test(JSON.stringify(schema))) return shared().getValidator(schema);
|
|
18
|
+
let validate = null;
|
|
19
|
+
return (input) => {
|
|
20
|
+
validate ??= shared().getValidator(schema);
|
|
21
|
+
return validate(input);
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp/plugin-placeholders.mjs — plugin root/data placeholders in an MCP server
|
|
3
|
+
* config. Pure: no filesystem access; the caller supplies the directories.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const ROOT_NAMES = ['CLAUDE_PLUGIN_ROOT', 'CODEX_PLUGIN_ROOT', 'PLUGIN_ROOT', 'MIXDOG_PLUGIN_ROOT'];
|
|
7
|
+
const DATA_NAMES = ['CLAUDE_PLUGIN_DATA', 'PLUGIN_DATA', 'MIXDOG_PLUGIN_DATA'];
|
|
8
|
+
const PLACEHOLDER_RE = new RegExp(`\\$\\{(${[...ROOT_NAMES, ...DATA_NAMES].join('|')})\\}`, 'g');
|
|
9
|
+
const CONFIG_FIELDS = ['command', 'args', 'env', 'url', 'headers', 'cwd'];
|
|
10
|
+
|
|
11
|
+
// Substituted paths use forward slashes on Windows so a path that lands in a
|
|
12
|
+
// command line or argument is not read as backslash escapes; Windows accepts
|
|
13
|
+
// them everywhere.
|
|
14
|
+
function normalizePath(path, platform) {
|
|
15
|
+
return platform === 'win32' ? path.replace(/\\/g, '/') : path;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function substitute(value, replacements) {
|
|
19
|
+
if (typeof value === 'string') {
|
|
20
|
+
// Function replacement: `$` sequences in paths are inserted literally.
|
|
21
|
+
return value.replace(PLACEHOLDER_RE, (match, name) => replacements.get(name) ?? match);
|
|
22
|
+
}
|
|
23
|
+
if (Array.isArray(value)) return value.map((v) => substitute(v, replacements));
|
|
24
|
+
if (value && typeof value === 'object') {
|
|
25
|
+
const out = {};
|
|
26
|
+
for (const [k, v] of Object.entries(value)) out[k] = substitute(v, replacements);
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns a copy of `config` with plugin root/data placeholders replaced in
|
|
34
|
+
* command, args, env, url, headers and cwd. A placeholder whose directory is
|
|
35
|
+
* not supplied is left as written. Run before ordinary env expansion.
|
|
36
|
+
*/
|
|
37
|
+
export function resolvePluginPlaceholders(config, { root, data, platform = process.platform } = {}) {
|
|
38
|
+
const replacements = new Map();
|
|
39
|
+
if (root) for (const name of ROOT_NAMES) replacements.set(name, normalizePath(String(root), platform));
|
|
40
|
+
if (data) for (const name of DATA_NAMES) replacements.set(name, normalizePath(String(data), platform));
|
|
41
|
+
const out = { ...config };
|
|
42
|
+
for (const field of CONFIG_FIELDS) {
|
|
43
|
+
if (out[field] !== undefined) out[field] = substitute(out[field], replacements);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Environment variables a plugin-owned server process receives (raw paths). */
|
|
49
|
+
export function pluginServerEnv({ root, data } = {}) {
|
|
50
|
+
const env = {};
|
|
51
|
+
if (root) for (const name of ['CLAUDE_PLUGIN_ROOT', 'MIXDOG_PLUGIN_ROOT', 'PLUGIN_ROOT']) env[name] = String(root);
|
|
52
|
+
if (data) for (const name of ['CLAUDE_PLUGIN_DATA', 'MIXDOG_PLUGIN_DATA', 'PLUGIN_DATA']) env[name] = String(data);
|
|
53
|
+
return env;
|
|
54
|
+
}
|
|
@@ -13,6 +13,10 @@ export function createKeyedSingleflight() {
|
|
|
13
13
|
pending.set(lane, tracked);
|
|
14
14
|
return tracked;
|
|
15
15
|
},
|
|
16
|
+
/** The in-flight task promise for `key`, or undefined. */
|
|
17
|
+
wait(key) {
|
|
18
|
+
return pending.get(String(key || ''));
|
|
19
|
+
},
|
|
16
20
|
has(key) {
|
|
17
21
|
return pending.has(String(key || ''));
|
|
18
22
|
},
|
|
@@ -3,9 +3,11 @@ import {
|
|
|
3
3
|
accountScopedSessionId,
|
|
4
4
|
readProviderAccountPool,
|
|
5
5
|
chooseProviderAccount,
|
|
6
|
-
|
|
6
|
+
selectProviderAccountIf,
|
|
7
7
|
blockProviderAccount,
|
|
8
8
|
providerAccountExhausted,
|
|
9
|
+
providerAccountExhaustedForModelOnly,
|
|
10
|
+
providerAccountPolicy,
|
|
9
11
|
providerAccountsResetAt,
|
|
10
12
|
} from '../../../shared/provider-accounts.mjs';
|
|
11
13
|
import { withProviderAccount, hasExplicitProviderAuthBinding } from '../../../shared/provider-auth-binding.mjs';
|
|
@@ -116,13 +118,82 @@ function boundAccountSend(providerName, row, messages, options) {
|
|
|
116
118
|
return { opts, history, emitted: () => emitted };
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
// Commit only a successful fallback, without overwriting a newer selection
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
// Commit only a successful fallback, without overwriting a newer selection:
|
|
122
|
+
// the selection is compared under the write's lock, not before it. A fallback
|
|
123
|
+
// forced by a model-scoped limit ("7D Fable" full, or a block attributed to
|
|
124
|
+
// one family) serves this request only: the selected account still serves
|
|
125
|
+
// every other model, so it stays the provider's account of record.
|
|
126
|
+
async function commitFallbackAccount(providerName, pool, row, model, refusalScoped, policy) {
|
|
127
|
+
if (row.id === pool.selectedId || refusalScoped) return null;
|
|
128
|
+
if (accountExhaustedForModelOnly(providerName, pool.selectedId, model)) return null;
|
|
129
|
+
return selectProviderAccountIf(providerName, pool.selectedId, row.id, policy);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// The account each session runs on under the headroom policy. Every answer
|
|
133
|
+
// records its provider and account in the assistant message's
|
|
134
|
+
// `providerMetadata` (and in provider state when the adapter keeps one), so
|
|
135
|
+
// the binding survives a restart and eviction from this map, which only
|
|
136
|
+
// spares the history walk. Bounded, oldest binding first out.
|
|
137
|
+
const SESSION_ACCOUNT_LIMIT = 1000;
|
|
138
|
+
const ROUTING_METADATA_KEY = 'accountRouting';
|
|
139
|
+
const sessionAccounts = new Map();
|
|
140
|
+
|
|
141
|
+
// Forget every in-memory binding, as a restart does (tests).
|
|
142
|
+
export function resetSessionAccountBindings() {
|
|
143
|
+
sessionAccounts.clear();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function rememberSessionAccount(key, id) {
|
|
147
|
+
sessionAccounts.delete(key);
|
|
148
|
+
sessionAccounts.set(key, id);
|
|
149
|
+
if (sessionAccounts.size > SESSION_ACCOUNT_LIMIT) sessionAccounts.delete(sessionAccounts.keys().next().value);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function accountExhaustedForModelOnly(providerName, id, model) {
|
|
153
|
+
const pool = readProviderAccountPool(providerName);
|
|
154
|
+
const row = pool.accounts.find((entry) => entry.id === id);
|
|
155
|
+
return (
|
|
156
|
+
Boolean(row) &&
|
|
157
|
+
providerAccountExhaustedForModelOnly(row, Date.now(), model, { useCredits: pool.useCredits === true })
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Only a binding recorded for THIS provider counts: a session that switched
|
|
162
|
+
// providers carries another roster's account ids (every roster has a `default`).
|
|
163
|
+
// The session's binding is read before the serving account, which differs
|
|
164
|
+
// when a model-scoped limit lent this one answer to another account.
|
|
165
|
+
function sessionAccountId(providerName, key, messages, options) {
|
|
166
|
+
if (key && sessionAccounts.has(key)) return sessionAccounts.get(key);
|
|
167
|
+
const state = options.providerState;
|
|
168
|
+
if (state?.providerAccountId && state.providerAccountProvider === providerName) {
|
|
169
|
+
return state.providerSessionAccountId || state.providerAccountId;
|
|
170
|
+
}
|
|
171
|
+
for (let index = (messages?.length || 0) - 1; index >= 0; index -= 1) {
|
|
172
|
+
const routing = messages[index]?.providerMetadata?.[ROUTING_METADATA_KEY];
|
|
173
|
+
if (routing?.accountId && routing.provider === providerName) return routing.sessionAccountId || routing.accountId;
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Stamp the serving account on the answer, independent of transport state,
|
|
179
|
+
// with the account the session stays bound to (`bindingId`).
|
|
180
|
+
function recordServingAccount(providerName, result, id, bindingId) {
|
|
181
|
+
if (!result || typeof result !== 'object') return;
|
|
182
|
+
if (result.providerReplay) result.providerReplay = { ...result.providerReplay, accountId: id };
|
|
183
|
+
if (result.providerState) {
|
|
184
|
+
result.providerState = {
|
|
185
|
+
...result.providerState,
|
|
186
|
+
providerAccountId: id,
|
|
187
|
+
providerSessionAccountId: bindingId,
|
|
188
|
+
providerAccountProvider: providerName,
|
|
189
|
+
};
|
|
125
190
|
}
|
|
191
|
+
const metadata =
|
|
192
|
+
result.providerMetadata && typeof result.providerMetadata === 'object' ? result.providerMetadata : {};
|
|
193
|
+
result.providerMetadata = {
|
|
194
|
+
...metadata,
|
|
195
|
+
[ROUTING_METADATA_KEY]: { provider: providerName, accountId: id, sessionAccountId: bindingId },
|
|
196
|
+
};
|
|
126
197
|
}
|
|
127
198
|
|
|
128
199
|
// Whether the failed account's quota window is exhausted, plus the server's
|
|
@@ -158,12 +229,18 @@ function poolSend(providerName, account) {
|
|
|
158
229
|
let lastError;
|
|
159
230
|
let probed = false;
|
|
160
231
|
const evidenced = new Set();
|
|
232
|
+
const sessionKey = options.sessionId ? `${providerName}:${options.sessionId}` : null;
|
|
233
|
+
const boundId = sessionAccountId(providerName, sessionKey, messages, options);
|
|
234
|
+
// Whether this send already left an account, and whether the latest quota
|
|
235
|
+
// refusal held only for this model's family.
|
|
236
|
+
let switched = false;
|
|
237
|
+
let refusalScoped = false;
|
|
161
238
|
// Mark `error` only when every account in `ids` (default: the roster) is
|
|
162
239
|
// exhausted with quota evidence: observed in this send, or a full window.
|
|
163
240
|
const markExhausted = (error, ids) => {
|
|
164
241
|
const pool = readProviderAccountPool(providerName);
|
|
165
|
-
//
|
|
166
|
-
const scope = ids || (pool
|
|
242
|
+
// Manual policy: the eligible set is the selected account alone.
|
|
243
|
+
const scope = ids || (providerAccountPolicy(pool) === 'manual' ? [pool.selectedId] : null);
|
|
167
244
|
const rows = scope ? pool.accounts.filter((entry) => scope.includes(entry.id)) : pool.accounts;
|
|
168
245
|
const opts = { useCredits: pool.useCredits === true };
|
|
169
246
|
const now = Date.now();
|
|
@@ -194,7 +271,8 @@ function poolSend(providerName, account) {
|
|
|
194
271
|
}
|
|
195
272
|
return account('default').send(messages, model, tools, options);
|
|
196
273
|
}
|
|
197
|
-
const
|
|
274
|
+
const policy = providerAccountPolicy(pool);
|
|
275
|
+
const row = chooseProviderAccount(pool, attempted, Date.now(), model, { sessionAccountId: boundId });
|
|
198
276
|
if (!row) {
|
|
199
277
|
// Once per send: a refusal built on a stale meter must not outlive the
|
|
200
278
|
// meter. Re-measuring can only widen the roster, so it is tried before
|
|
@@ -209,9 +287,18 @@ function poolSend(providerName, account) {
|
|
|
209
287
|
const bound = boundAccountSend(providerName, row, messages, options);
|
|
210
288
|
try {
|
|
211
289
|
const result = await account(row.id).send(bound.history, model, tools, bound.opts);
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
290
|
+
// Headroom policy: a session's first pick, or its move off its account
|
|
291
|
+
// on a limit, becomes the selection; continuing on its account does
|
|
292
|
+
// not, so concurrent sessions never flip the selection back and forth.
|
|
293
|
+
// A move forced by a model-scoped limit serves this request only.
|
|
294
|
+
const leftBound = Boolean(boundId) && row.id !== boundId;
|
|
295
|
+
const scoped = switched
|
|
296
|
+
? refusalScoped
|
|
297
|
+
: policy === 'headroom' && leftBound && accountExhaustedForModelOnly(providerName, boundId, model);
|
|
298
|
+
recordServingAccount(providerName, result, row.id, scoped && boundId ? boundId : row.id);
|
|
299
|
+
if (sessionKey && policy === 'headroom' && !scoped) rememberSessionAccount(sessionKey, row.id);
|
|
300
|
+
const commit = policy !== 'headroom' || !boundId || leftBound;
|
|
301
|
+
if (commit && (await commitFallbackAccount(providerName, pool, row, model, scoped, policy))) {
|
|
215
302
|
// Publish only a committed selection, never a speculative retry or
|
|
216
303
|
// one superseded by a manual switch. The existing progress channel
|
|
217
304
|
// carries this across runtime shards to the attached UI.
|
|
@@ -230,7 +317,7 @@ function poolSend(providerName, account) {
|
|
|
230
317
|
if (options.signal?.aborted) throw error;
|
|
231
318
|
if (error?.reauthRequired === true) {
|
|
232
319
|
if (
|
|
233
|
-
|
|
320
|
+
policy === 'manual' ||
|
|
234
321
|
bound.emitted() ||
|
|
235
322
|
error.unsafeToRetry ||
|
|
236
323
|
error.liveTextEmitted ||
|
|
@@ -238,13 +325,15 @@ function poolSend(providerName, account) {
|
|
|
238
325
|
)
|
|
239
326
|
throw error;
|
|
240
327
|
lastError = error;
|
|
328
|
+
switched = true;
|
|
329
|
+
refusalScoped = false;
|
|
241
330
|
options.onStageChange?.('reconnecting', { message: 'Sign-in expired — switching to the next account' });
|
|
242
331
|
continue;
|
|
243
332
|
}
|
|
244
333
|
const { exhausted, delay, evidence } = await accountQuotaExhausted(providerName, row, model, error, account);
|
|
245
334
|
if (options.signal?.aborted || !exhausted) throw error;
|
|
246
335
|
if (evidence) evidenced.add(row.id);
|
|
247
|
-
blockProviderAccount(
|
|
336
|
+
await blockProviderAccount(
|
|
248
337
|
providerName,
|
|
249
338
|
row.id,
|
|
250
339
|
Date.now() + (delay > 0 ? delay : 5 * 60_000),
|
|
@@ -253,9 +342,11 @@ function poolSend(providerName, account) {
|
|
|
253
342
|
{ quota: evidence === true }
|
|
254
343
|
);
|
|
255
344
|
if (bound.emitted() || error.unsafeToRetry || error.liveTextEmitted || error.emittedToolCall) throw error;
|
|
256
|
-
//
|
|
257
|
-
if (
|
|
345
|
+
// Manual policy: the eligible set is the selected account alone.
|
|
346
|
+
if (policy === 'manual') throw markExhausted(error, [row.id]);
|
|
258
347
|
lastError = error;
|
|
348
|
+
switched = true;
|
|
349
|
+
refusalScoped = accountExhaustedForModelOnly(providerName, row.id, model);
|
|
259
350
|
options.onStageChange?.('reconnecting', { message: 'Quota exhausted — switching to the next account' });
|
|
260
351
|
}
|
|
261
352
|
}
|
|
@@ -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.299';
|
|
14
14
|
export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
|
|
15
15
|
|
|
16
16
|
const CACHE_SCHEMA_VERSION = 1;
|
|
@@ -13,6 +13,7 @@ import { randomBytes } from 'node:crypto';
|
|
|
13
13
|
import { updateJsonAtomicSync, writeJsonAtomicSync, withFileLock } from '../../../shared/atomic-file.mjs';
|
|
14
14
|
import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
|
|
15
15
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
16
|
+
import { modelProxyClientMode, serverModelCredentialsDisabledError } from '../../../shared/model-proxy-mode.mjs';
|
|
16
17
|
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
17
18
|
import { claudeCliUserAgent, resolveCliVersion } from './anthropic-oauth-client-version.mjs';
|
|
18
19
|
import {
|
|
@@ -148,6 +149,7 @@ export function _credentialsMaxMtime() {
|
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
export function loadCredentials() {
|
|
152
|
+
if (modelProxyClientMode()) return null;
|
|
151
153
|
const loaded = credentialCandidates().map(_loadCredentialsFile).filter(Boolean);
|
|
152
154
|
if (!loaded.length) return null;
|
|
153
155
|
loaded.sort((a, b) => (Number(b.expiresAt) || 0) - (Number(a.expiresAt) || 0));
|
|
@@ -382,6 +384,7 @@ async function _refreshOAuthCredentialsUnlocked(creds) {
|
|
|
382
384
|
}
|
|
383
385
|
|
|
384
386
|
export async function refreshOAuthCredentials(creds) {
|
|
387
|
+
if (modelProxyClientMode()) throw serverModelCredentialsDisabledError('Anthropic OAuth credentials');
|
|
385
388
|
if (isAnthropicOAuthRefreshDisabled()) {
|
|
386
389
|
throw new Error(
|
|
387
390
|
'Anthropic OAuth refresh is disabled in this process; ' +
|
|
@@ -48,6 +48,7 @@ import { createAnthropicOAuthRecovery } from './anthropic-oauth-recovery.mjs';
|
|
|
48
48
|
import { createMidState, createMidstreamRecovery } from './anthropic-oauth-midstream.mjs';
|
|
49
49
|
import { assertAnthropicStreamNotEmpty } from './anthropic-midstream-recovery.mjs';
|
|
50
50
|
import { applyAnthropicEffortToBody, shouldIncludeEffortBeta } from './anthropic-effort.mjs';
|
|
51
|
+
import { ANTHROPIC_EFFORT_LEVELS, withEffortRejectionFallback } from './effort-rejection.mjs';
|
|
51
52
|
import { getLlmDispatcher, preconnect } from '../../../shared/llm/http-agent.mjs';
|
|
52
53
|
import {
|
|
53
54
|
applyAnthropicCacheMarkers,
|
|
@@ -408,6 +409,17 @@ export class AnthropicOAuthProvider {
|
|
|
408
409
|
}
|
|
409
410
|
|
|
410
411
|
async send(messages, model, tools, sendOpts) {
|
|
412
|
+
return withEffortRejectionFallback(
|
|
413
|
+
'anthropic-oauth',
|
|
414
|
+
model,
|
|
415
|
+
sendOpts || {},
|
|
416
|
+
undefined,
|
|
417
|
+
(opts) => this._sendOnce(messages, model, tools, opts),
|
|
418
|
+
{ levels: ANTHROPIC_EFFORT_LEVELS }
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
async _sendOnce(messages, model, tools, sendOpts) {
|
|
411
423
|
await warmCliVersion();
|
|
412
424
|
// Re-warm the kept-alive socket before the turn. preconnect() is a
|
|
413
425
|
// best-effort no-op while a socket is still hot (TTL gate), but after an
|
|
@@ -625,7 +637,9 @@ export class AnthropicOAuthProvider {
|
|
|
625
637
|
// without them (the request keeps its turn effort).
|
|
626
638
|
if (isEffortConfigurationRejection(response.status, scrubbedText) && !opts._effortConfigurationRetry) {
|
|
627
639
|
markEffortConfigurationUnsupported('anthropic-oauth', useModel);
|
|
628
|
-
process.stderr.write(
|
|
640
|
+
process.stderr.write(
|
|
641
|
+
`[anthropic-oauth] ${useModel} rejected the mid-conversation effort update; retrying once without it\n`
|
|
642
|
+
);
|
|
629
643
|
return this.send(messages, useModel, tools, {
|
|
630
644
|
...opts,
|
|
631
645
|
effortConfigurationEnabled: false,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
2
2
|
import { sanitizeToolPairs } from '../session/context-utils.mjs';
|
|
3
3
|
import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
|
|
4
4
|
import { readStreamOutcome } from './lib/stream-outcome.mjs';
|
|
@@ -8,6 +8,7 @@ import { ANTHROPIC_MAX_MIDSTREAM_RETRIES, parseSSEStream } from './anthropic-sse
|
|
|
8
8
|
import { buildAnthropicBetaHeaders } from './anthropic-betas.mjs';
|
|
9
9
|
import { buildAnthropicApiRequest } from './anthropic-api-request.mjs';
|
|
10
10
|
import { isCustomProviderName } from './custom-reasoning.mjs';
|
|
11
|
+
import { ANTHROPIC_EFFORT_LEVELS, withEffortRejectionFallback } from './effort-rejection.mjs';
|
|
11
12
|
import { armFirstByteWatchdog, createAnthropicApiTransport } from './anthropic-api-transport.mjs';
|
|
12
13
|
import { createAnthropicApiRecovery } from './anthropic-api-recovery.mjs';
|
|
13
14
|
import { buildAnthropicTurnResult } from './anthropic-turn-result.mjs';
|
|
@@ -41,9 +42,19 @@ export class AnthropicProvider {
|
|
|
41
42
|
constructor(config) {
|
|
42
43
|
this.config = config || {};
|
|
43
44
|
this.name = this.config.name || 'anthropic';
|
|
44
|
-
this.apiKey =
|
|
45
|
+
this.apiKey = resolveProviderApiKey(this.name, this.config) || null;
|
|
45
46
|
this.client = this._createClient(this.apiKey);
|
|
46
47
|
}
|
|
48
|
+
// Client for the currently resolved key; rebuilt when the key changed since
|
|
49
|
+
// it was built (e.g. a keyless-constructed instance).
|
|
50
|
+
_currentClient() {
|
|
51
|
+
const key = resolveProviderApiKey(this.name, this.config) || null;
|
|
52
|
+
if (key && key !== this.apiKey) {
|
|
53
|
+
this.apiKey = key;
|
|
54
|
+
this.client = this._createClient(key);
|
|
55
|
+
}
|
|
56
|
+
return this.client;
|
|
57
|
+
}
|
|
47
58
|
// Tool-search is a request capability, not an account capability. Keep it
|
|
48
59
|
// off the client defaults and add it only on turns that actually serialize
|
|
49
60
|
// defer_loading tools.
|
|
@@ -54,8 +65,10 @@ export class AnthropicProvider {
|
|
|
54
65
|
const custom = isCustomProviderName(this.name);
|
|
55
66
|
const keyless = custom && this.config.keyless === true;
|
|
56
67
|
const betaHeaders = this.config.disableBetaHeaders || custom ? null : buildAnthropicBetaHeaders();
|
|
68
|
+
let credentials = { apiKey };
|
|
69
|
+
if (custom) credentials = { apiKey: keyless ? '' : apiKey || '', authToken: null };
|
|
57
70
|
return new (loadAnthropic())({
|
|
58
|
-
...
|
|
71
|
+
...credentials,
|
|
59
72
|
...(this.config.baseURL ? { baseURL: this.config.baseURL } : {}),
|
|
60
73
|
defaultHeaders: {
|
|
61
74
|
...(betaHeaders ? { 'anthropic-beta': betaHeaders } : {}),
|
|
@@ -67,10 +80,7 @@ export class AnthropicProvider {
|
|
|
67
80
|
}
|
|
68
81
|
reloadApiKey() {
|
|
69
82
|
try {
|
|
70
|
-
const newKey =
|
|
71
|
-
getAgentApiKey(this.name) ||
|
|
72
|
-
this.config.apiKey ||
|
|
73
|
-
(this.name === 'anthropic' ? process.env.ANTHROPIC_API_KEY : null);
|
|
83
|
+
const newKey = reloadProviderApiKey(this.name, this.config);
|
|
74
84
|
if (newKey) {
|
|
75
85
|
this.config = { ...(this.config || {}), apiKey: newKey };
|
|
76
86
|
this.apiKey = newKey;
|
|
@@ -106,10 +116,21 @@ export class AnthropicProvider {
|
|
|
106
116
|
throw err;
|
|
107
117
|
}
|
|
108
118
|
}
|
|
119
|
+
// The `anthropic` API-key provider and every custom `anthropic`-protocol
|
|
120
|
+
// provider (a subclass of this one) share this send path.
|
|
109
121
|
async _doSend(messages, model, tools, sendOpts) {
|
|
122
|
+
return withEffortRejectionFallback(
|
|
123
|
+
this.name,
|
|
124
|
+
model,
|
|
125
|
+
sendOpts || {},
|
|
126
|
+
this.config?.reasoningEffort,
|
|
127
|
+
(opts) => this._sendOnce(messages, model, tools, opts),
|
|
128
|
+
{ levels: ANTHROPIC_EFFORT_LEVELS }
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
async _sendOnce(messages, model, tools, opts) {
|
|
110
132
|
if (!model) throw new Error(`[${this.name}] model is required — pass it from the caller preset`);
|
|
111
133
|
const useModel = model;
|
|
112
|
-
const opts = sendOpts || {};
|
|
113
134
|
// Wire request (system/cache layout, tools, effort, fast mode, images)
|
|
114
135
|
// and the per-request beta headers derived from that final body —
|
|
115
136
|
// anthropic-api-request.mjs. Fast mode latches on the provider instance.
|
|
@@ -148,7 +169,7 @@ export class AnthropicProvider {
|
|
|
148
169
|
// The SDK calls and their initial-response retry policy
|
|
149
170
|
// (anthropic-api-transport.mjs).
|
|
150
171
|
const transport = createAnthropicApiTransport({
|
|
151
|
-
client: this.
|
|
172
|
+
client: this._currentClient(),
|
|
152
173
|
label: this.name,
|
|
153
174
|
opts,
|
|
154
175
|
useModel,
|
|
@@ -284,8 +305,7 @@ export class AnthropicProvider {
|
|
|
284
305
|
}
|
|
285
306
|
}
|
|
286
307
|
async listModels() {
|
|
287
|
-
const apiKey =
|
|
288
|
-
this.apiKey || this.config?.apiKey || (this.name === 'anthropic' ? process.env.ANTHROPIC_API_KEY : null);
|
|
308
|
+
const apiKey = resolveProviderApiKey(this.name, this.config);
|
|
289
309
|
if (!apiKey) return MODELS;
|
|
290
310
|
try {
|
|
291
311
|
const base = String(this.config?.baseURL || 'https://api.anthropic.com').replace(/\/+$/, '');
|
|
@@ -317,6 +337,6 @@ export class AnthropicProvider {
|
|
|
317
337
|
async isAvailable() {
|
|
318
338
|
// Availability probes must not spend tokens or depend on a live
|
|
319
339
|
// network. Dispatch owns authentication validation and 401 reload.
|
|
320
|
-
return !!(this.
|
|
340
|
+
return !!resolveProviderApiKey(this.name, this.config);
|
|
321
341
|
}
|
|
322
342
|
}
|
|
@@ -18,6 +18,7 @@ import { join, resolve } from 'node:path';
|
|
|
18
18
|
import { getPluginData } from '../config.mjs';
|
|
19
19
|
import { writeJsonAtomicSync } from '../../../shared/atomic-file.mjs';
|
|
20
20
|
import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
|
|
21
|
+
import { modelProxyClientMode } from '../../../shared/model-proxy-mode.mjs';
|
|
21
22
|
import {
|
|
22
23
|
accountIdentityFields,
|
|
23
24
|
normalizeExpiresAtMs as _normalizeExpiresAt,
|
|
@@ -192,6 +193,7 @@ function mtimeMs(path) {
|
|
|
192
193
|
export { _normalizeExpiresAt };
|
|
193
194
|
|
|
194
195
|
export function loadTokens() {
|
|
196
|
+
if (modelProxyClientMode()) return null;
|
|
195
197
|
const path = getOwnTokenPath();
|
|
196
198
|
if (!existsSync(path)) return null;
|
|
197
199
|
try {
|
|
@@ -89,6 +89,15 @@ export function resolveAutoEffort({ base, options, probs }) {
|
|
|
89
89
|
const ladder = autoEffortLadder(options);
|
|
90
90
|
const at = ladder.indexOf(String(base ?? '').toLowerCase());
|
|
91
91
|
if (at < 0) return null;
|
|
92
|
+
return resolveOnLadder(ladder, at, probs);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** True when some judged outcome could apply: the base lies on the model's ladder. */
|
|
96
|
+
export function autoEffortApplicable({ base, options }) {
|
|
97
|
+
return autoEffortLadder(options).includes(String(base ?? '').toLowerCase());
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function resolveOnLadder(ladder, at, probs) {
|
|
92
101
|
const { step, level, confidence } = judgedStep(probs);
|
|
93
102
|
const effort = ladder[Math.max(0, Math.min(ladder.length - 1, at + step))];
|
|
94
103
|
return { base: ladder[at], effort, step, level, confidence: Number(confidence.toFixed(3)) };
|