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,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Code provider (commandcode.ai Provider API).
|
|
3
|
+
*
|
|
4
|
+
* Credentials are a Studio-issued API key (command-code-oauth-tokens.mjs).
|
|
5
|
+
* Each model is served on the endpoint its /models row declares: Chat
|
|
6
|
+
* Completions through the OpenAI-compatible engine, Messages-only models
|
|
7
|
+
* (Claude) through the Anthropic engine. Both clients are pinned to the
|
|
8
|
+
* Command Code API host. The key never expires and has no refresh grant: a
|
|
9
|
+
* 401 means the user must sign in again.
|
|
10
|
+
*/
|
|
11
|
+
import { noteErrorUsage } from './lib/note-error-usage.mjs';
|
|
12
|
+
import { fileMtimeMs, normalizeExpiresAtMs, scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
|
|
13
|
+
import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
|
|
14
|
+
import { listCompatModels } from './openai-compat-models.mjs';
|
|
15
|
+
import { AnthropicProvider } from './anthropic.mjs';
|
|
16
|
+
import { toInclusiveOpenCodeGoUsage as toInclusiveUsage } from './opencode-go.mjs';
|
|
17
|
+
import { sanitizeToolPairs } from '../session/context-utils.mjs';
|
|
18
|
+
import { preparePdfTextForProvider } from './media-normalization.mjs';
|
|
19
|
+
import { currentUsageContext } from '../../../shared/llm/usage-context.mjs';
|
|
20
|
+
import { makeModelCache } from './model-cache.mjs';
|
|
21
|
+
import {
|
|
22
|
+
API_ORIGIN,
|
|
23
|
+
CREDITS_URL,
|
|
24
|
+
PROVIDER_BASE_URL,
|
|
25
|
+
PROVIDER_ID,
|
|
26
|
+
commandCodeReauthError,
|
|
27
|
+
getOwnTokenPath,
|
|
28
|
+
loadTokens,
|
|
29
|
+
requestCommandCodeJson,
|
|
30
|
+
} from './command-code-oauth-tokens.mjs';
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
hasCommandCodeOAuthCredentials,
|
|
34
|
+
describeCommandCodeOAuthCredentials,
|
|
35
|
+
forgetCommandCodeOAuthCredentials,
|
|
36
|
+
} from './command-code-oauth-tokens.mjs';
|
|
37
|
+
export { beginOAuthLogin, loginOAuth } from './command-code-oauth-login.mjs';
|
|
38
|
+
|
|
39
|
+
export const DEFAULT_MODEL = 'deepseek/deepseek-v4-flash';
|
|
40
|
+
const CHAT_ENDPOINT = '/chat/completions';
|
|
41
|
+
const MESSAGES_ENDPOINT = '/messages';
|
|
42
|
+
// The Anthropic SDK appends /v1/messages itself.
|
|
43
|
+
const MESSAGES_BASE_URL = `${API_ORIGIN}/provider`;
|
|
44
|
+
const FIVE_HOURS_MS = 5 * 60 * 60 * 1000;
|
|
45
|
+
const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
46
|
+
|
|
47
|
+
const isUnauthorized = (err) => Number(err?.httpStatus || err?.status) === 401;
|
|
48
|
+
|
|
49
|
+
// The discovered roster (what /models returned) is persisted so the shared
|
|
50
|
+
// sync lookup sees what listModels found.
|
|
51
|
+
const commandCodeModelCache = makeModelCache({
|
|
52
|
+
fileName: 'command-code-oauth-models.json',
|
|
53
|
+
ttlMs: 24 * 60 * 60 * 1000,
|
|
54
|
+
version: 1,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The wire a /models row is served on: 'chat' when it declares Chat
|
|
59
|
+
* Completions or declares no endpoints at all, 'messages' when it declares
|
|
60
|
+
* only Messages, null when it declares neither.
|
|
61
|
+
*/
|
|
62
|
+
export function modelWire(item) {
|
|
63
|
+
if (typeof item?.id !== 'string' || !item.id) return null;
|
|
64
|
+
const endpoints = item.supported_endpoints;
|
|
65
|
+
if (!Array.isArray(endpoints)) return 'chat';
|
|
66
|
+
const declared = endpoints.map((endpoint) => String(endpoint).replace(/^\/?(?:provider\/)?(?:v1\/)?/, '/'));
|
|
67
|
+
if (declared.includes(CHAT_ENDPOINT)) return 'chat';
|
|
68
|
+
if (declared.includes(MESSAGES_ENDPOINT)) return 'messages';
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Every request either engine makes goes through this fetch: anything outside
|
|
73
|
+
// the Command Code API origin is refused before the key leaves the process,
|
|
74
|
+
// and redirects are never followed (any 3xx is an error).
|
|
75
|
+
function apiOnlyFetch(fetchImpl) {
|
|
76
|
+
return async (input, init) => {
|
|
77
|
+
const url = new URL(String(input?.url ?? input));
|
|
78
|
+
if (url.origin !== API_ORIGIN) {
|
|
79
|
+
throw new Error(`[command-code-oauth] refusing to send the API key to ${url.host}`);
|
|
80
|
+
}
|
|
81
|
+
const res = await (fetchImpl || globalThis.fetch)(input, { ...init, redirect: 'manual' });
|
|
82
|
+
if (res.status >= 300 && res.status < 400) {
|
|
83
|
+
throw new Error(`[command-code-oauth] refusing to follow a redirect from ${url.host}`);
|
|
84
|
+
}
|
|
85
|
+
return res;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Anthropic engine bound to this credential: only the Command Code key is
|
|
90
|
+
// sent (never an ANTHROPIC_AUTH_TOKEN from the environment) and only to the
|
|
91
|
+
// Command Code API host.
|
|
92
|
+
class CommandCodeMessagesEngine extends AnthropicProvider {
|
|
93
|
+
nativePdf = false;
|
|
94
|
+
_createClient(apiKey) {
|
|
95
|
+
const client = super._createClient(apiKey);
|
|
96
|
+
client.authToken = null;
|
|
97
|
+
client.fetch = apiOnlyFetch(this.config.fetchImpl);
|
|
98
|
+
return client;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const normalizeUsageError = (err) => {
|
|
103
|
+
if (err && typeof err === 'object') {
|
|
104
|
+
if (err.usage) err.usage = toInclusiveUsage(err.usage);
|
|
105
|
+
if (err.partialUsage) err.partialUsage = toInclusiveUsage(err.partialUsage);
|
|
106
|
+
}
|
|
107
|
+
return err;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
function rosterRow(item) {
|
|
111
|
+
const contextWindow = Number(item.context_window ?? item.max_context_window ?? item.context_length ?? 0);
|
|
112
|
+
const outputTokens = Number(item.max_output_tokens ?? item.output_tokens ?? 0);
|
|
113
|
+
const name = [item.display_name, item.name].find((v) => typeof v === 'string' && v.trim());
|
|
114
|
+
return {
|
|
115
|
+
id: item.id,
|
|
116
|
+
provider: PROVIDER_ID,
|
|
117
|
+
...(name ? { name: name.trim() } : {}),
|
|
118
|
+
...(contextWindow > 0 ? { contextWindow } : {}),
|
|
119
|
+
...(outputTokens > 0 ? { outputTokens } : {}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function chooseDefaultModel(ids) {
|
|
124
|
+
const list = ids || [];
|
|
125
|
+
return list.includes(DEFAULT_MODEL) ? DEFAULT_MODEL : list[0] || DEFAULT_MODEL;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Strip the key from an error (message plus any echoed gateway body).
|
|
129
|
+
function scrubErrorSecrets(err, apiKey) {
|
|
130
|
+
if (!err || typeof err !== 'object' || !apiKey) return err;
|
|
131
|
+
const seen = new Set();
|
|
132
|
+
const walk = (obj, depth) => {
|
|
133
|
+
if (!obj || typeof obj !== 'object' || seen.has(obj) || depth > 4) return;
|
|
134
|
+
seen.add(obj);
|
|
135
|
+
for (const k of Object.keys(obj)) {
|
|
136
|
+
const v = obj[k];
|
|
137
|
+
if (typeof v === 'string') {
|
|
138
|
+
if (v.includes(apiKey)) obj[k] = scrubOAuthSecrets(v, [apiKey]);
|
|
139
|
+
} else walk(v, depth + 1);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
if (typeof err.message === 'string') err.message = scrubOAuthSecrets(err.message, [apiKey]);
|
|
143
|
+
walk(err.error, 0);
|
|
144
|
+
walk(err.body, 0);
|
|
145
|
+
return err;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Redact where the transport first surfaces errors (request open and stream
|
|
149
|
+
// iteration), so the shared retry reporter never logs the key.
|
|
150
|
+
function redactClientErrors(client, apiKey) {
|
|
151
|
+
const completions = client?.chat?.completions;
|
|
152
|
+
if (!completions || !apiKey || completions.create?.commandCodeRedacting === apiKey) return;
|
|
153
|
+
const create = completions.create.bind(completions);
|
|
154
|
+
const wrapped = async (...args) => {
|
|
155
|
+
try {
|
|
156
|
+
const stream = await create(...args);
|
|
157
|
+
if (stream && typeof stream[Symbol.asyncIterator] === 'function') {
|
|
158
|
+
const iterate = stream[Symbol.asyncIterator].bind(stream);
|
|
159
|
+
stream[Symbol.asyncIterator] = () => {
|
|
160
|
+
const it = iterate();
|
|
161
|
+
return {
|
|
162
|
+
next: async (...a) => {
|
|
163
|
+
try {
|
|
164
|
+
return await it.next(...a);
|
|
165
|
+
} catch (err) {
|
|
166
|
+
throw scrubErrorSecrets(err, apiKey);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
return: (...a) => it.return?.(...a),
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return stream;
|
|
174
|
+
} catch (err) {
|
|
175
|
+
throw scrubErrorSecrets(err, apiKey);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
wrapped.commandCodeRedacting = apiKey;
|
|
179
|
+
completions.create = wrapped;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Same for the Anthropic client's streaming request (read through
|
|
183
|
+
// `.asResponse()`); every other failure is scrubbed by _shapeError.
|
|
184
|
+
function redactMessagesErrors(client, apiKey) {
|
|
185
|
+
const messages = client?.messages;
|
|
186
|
+
if (!messages || !apiKey || messages.create?.commandCodeRedacting === apiKey) return;
|
|
187
|
+
const create = messages.create.bind(messages);
|
|
188
|
+
const wrapped = (...args) => {
|
|
189
|
+
const request = create(...args);
|
|
190
|
+
const asResponse = request?.asResponse?.bind(request);
|
|
191
|
+
if (asResponse) {
|
|
192
|
+
request.asResponse = () =>
|
|
193
|
+
asResponse().catch((err) => {
|
|
194
|
+
throw scrubErrorSecrets(err, apiKey);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return request;
|
|
198
|
+
};
|
|
199
|
+
wrapped.commandCodeRedacting = apiKey;
|
|
200
|
+
messages.create = wrapped;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function usageStatus(usedFraction) {
|
|
204
|
+
if (usedFraction >= 1) return 'exhausted';
|
|
205
|
+
if (usedFraction >= 0.9) return 'warning';
|
|
206
|
+
return 'ok';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function creditWindow({ id, label, longLabel, durationMs }, entry) {
|
|
210
|
+
const cap = Number(entry?.cap);
|
|
211
|
+
const used = Number(entry?.used);
|
|
212
|
+
if (!entry || !Number.isFinite(cap) || cap <= 0 || !Number.isFinite(used) || used < 0) return null;
|
|
213
|
+
const usedPct = Math.min(100, (used / cap) * 100);
|
|
214
|
+
const usedFraction = usedPct / 100;
|
|
215
|
+
const resetAt = normalizeExpiresAtMs(entry.resetAt);
|
|
216
|
+
return {
|
|
217
|
+
id,
|
|
218
|
+
label,
|
|
219
|
+
longLabel,
|
|
220
|
+
source: 'command-code-credits',
|
|
221
|
+
usedPct: Math.round(usedPct * 100) / 100,
|
|
222
|
+
usedFraction,
|
|
223
|
+
remainingFraction: 1 - usedFraction,
|
|
224
|
+
status: usageStatus(usedFraction),
|
|
225
|
+
durationMs,
|
|
226
|
+
...(resetAt ? { resetAt } : {}),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Map `/alpha/billing/credits` windowLimits onto the shared quota-window shape. */
|
|
231
|
+
export function quotaWindowsFromCredits(body) {
|
|
232
|
+
const limits = (body?.data ?? body)?.windowLimits;
|
|
233
|
+
return [
|
|
234
|
+
creditWindow({ id: '5h', label: '5H', longLabel: '5 Hours', durationMs: FIVE_HOURS_MS }, limits?.fiveHour),
|
|
235
|
+
creditWindow({ id: '1w', label: '7D', longLabel: 'Weekly', durationMs: WEEK_MS }, limits?.weekly),
|
|
236
|
+
].filter(Boolean);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export class CommandCodeOAuthProvider {
|
|
240
|
+
// No document block on this wire: a PDF is lowered to text before the request is built.
|
|
241
|
+
nativePdf = false;
|
|
242
|
+
// OpenAI-compatible usage: prompt_tokens includes cached. See registry.mjs.
|
|
243
|
+
static inputExcludesCache = false;
|
|
244
|
+
name = PROVIDER_ID;
|
|
245
|
+
config;
|
|
246
|
+
tokens = null;
|
|
247
|
+
_inner = null;
|
|
248
|
+
_innerKey = null;
|
|
249
|
+
_defaultModel = null;
|
|
250
|
+
_defaultModelKey = null;
|
|
251
|
+
_messages = null;
|
|
252
|
+
_messagesKey = null;
|
|
253
|
+
// Model id → wire ('chat' | 'messages') from the roster fetched with `_wiresKey`.
|
|
254
|
+
_wires = new Map();
|
|
255
|
+
_wiresKey = null;
|
|
256
|
+
|
|
257
|
+
constructor(config) {
|
|
258
|
+
this.config = config || {};
|
|
259
|
+
this.tokens = loadTokens();
|
|
260
|
+
try {
|
|
261
|
+
preloadOpenAICompatRuntime();
|
|
262
|
+
} catch {
|
|
263
|
+
/* authoritative send surfaces load failures */
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
ensureAuth() {
|
|
268
|
+
// Re-read when the token file changed (sign-in from another process).
|
|
269
|
+
const mtime = fileMtimeMs(getOwnTokenPath());
|
|
270
|
+
if (!mtime) {
|
|
271
|
+
// File gone (signed out / forgotten): drop every cached credential.
|
|
272
|
+
this.tokens = null;
|
|
273
|
+
this._inner = null;
|
|
274
|
+
this._innerKey = null;
|
|
275
|
+
this._messages = null;
|
|
276
|
+
this._messagesKey = null;
|
|
277
|
+
}
|
|
278
|
+
if (!this.tokens || mtime > (this.tokens.mtimeMs || 0)) this.tokens = loadTokens() || this.tokens;
|
|
279
|
+
if (!this.tokens?.apiKey) {
|
|
280
|
+
throw new Error('[command-code-oauth] credentials not found — open /providers in mixdog to sign in first');
|
|
281
|
+
}
|
|
282
|
+
return this.tokens;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
_ensureInner() {
|
|
286
|
+
const { apiKey } = this.ensureAuth();
|
|
287
|
+
if (this._inner && this._innerKey === apiKey) return this._inner;
|
|
288
|
+
const { fetchImpl, baseURL: _ignored, ...config } = this.config;
|
|
289
|
+
const inner = new OpenAICompatProvider(PROVIDER_ID, {
|
|
290
|
+
...config,
|
|
291
|
+
apiKey,
|
|
292
|
+
// Fixed: the key is only ever sent to the Command Code API host.
|
|
293
|
+
baseURL: PROVIDER_BASE_URL,
|
|
294
|
+
// Explicit nulls keep OPENAI_ORG_ID / OPENAI_PROJECT_ID out of the requests.
|
|
295
|
+
clientOptions: { organization: null, project: null, fetch: apiOnlyFetch(fetchImpl) },
|
|
296
|
+
extraHeaders: { Accept: 'application/json' },
|
|
297
|
+
});
|
|
298
|
+
inner._fetchModelItems = ({ signal } = {}) => this._fetchRoster(apiKey, signal);
|
|
299
|
+
redactClientErrors(inner.client, apiKey);
|
|
300
|
+
this._inner = inner;
|
|
301
|
+
this._innerKey = apiKey;
|
|
302
|
+
return inner;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// The Anthropic engine for Messages-only models, on the same key and host.
|
|
306
|
+
_ensureMessages(apiKey) {
|
|
307
|
+
if (this._messages && this._messagesKey === apiKey) return this._messages;
|
|
308
|
+
const { baseURL: _ignored, ...config } = this.config;
|
|
309
|
+
const engine = new CommandCodeMessagesEngine({
|
|
310
|
+
...config,
|
|
311
|
+
name: PROVIDER_ID,
|
|
312
|
+
apiKey,
|
|
313
|
+
baseURL: MESSAGES_BASE_URL,
|
|
314
|
+
disableBetaHeaders: true,
|
|
315
|
+
// x-api-key from the SDK plus the bearer form of the same key.
|
|
316
|
+
extraHeaders: { Authorization: `Bearer ${apiKey}` },
|
|
317
|
+
});
|
|
318
|
+
redactMessagesErrors(engine.client, apiKey);
|
|
319
|
+
this._messages = engine;
|
|
320
|
+
this._messagesKey = apiKey;
|
|
321
|
+
return engine;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Servable rows from /models; only the latest fetch with the still-active
|
|
325
|
+
// key publishes the roster and the per-model wire map.
|
|
326
|
+
async _fetchRoster(apiKey, signal = null) {
|
|
327
|
+
const publish = commandCodeModelCache.beginSave(() => loadTokens()?.apiKey === apiKey);
|
|
328
|
+
const body = await requestCommandCodeJson(`${PROVIDER_BASE_URL}/models`, apiKey, {
|
|
329
|
+
fetchImpl: this.config.fetchImpl,
|
|
330
|
+
signal,
|
|
331
|
+
});
|
|
332
|
+
let list = [];
|
|
333
|
+
if (Array.isArray(body?.data)) list = body.data;
|
|
334
|
+
else if (Array.isArray(body)) list = body;
|
|
335
|
+
const items = list.filter((item) => modelWire(item));
|
|
336
|
+
publish(items.map(rosterRow));
|
|
337
|
+
if (this.tokens?.apiKey === apiKey) {
|
|
338
|
+
this._wires = new Map(items.map((item) => [item.id, modelWire(item)]));
|
|
339
|
+
this._wiresKey = apiKey;
|
|
340
|
+
}
|
|
341
|
+
return items;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// The wire for a model, from this credential's roster (fetched once when
|
|
345
|
+
// missing). A model the roster does not know, or a roster that cannot be
|
|
346
|
+
// read right now, stays on Chat Completions; a rejected key is surfaced.
|
|
347
|
+
async _wireFor(inner, model) {
|
|
348
|
+
if (this._wiresKey !== inner.apiKey) {
|
|
349
|
+
try {
|
|
350
|
+
await listCompatModels(inner, { throwOnError: true });
|
|
351
|
+
} catch (err) {
|
|
352
|
+
if (isUnauthorized(err)) throw err;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return (this._wiresKey === inner.apiKey && this._wires.get(model)) || 'chat';
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// A rejected key needs a fresh sign-in; the gateway's own detail stays attached.
|
|
359
|
+
_shapeError(err, apiKey) {
|
|
360
|
+
noteErrorUsage(err);
|
|
361
|
+
scrubErrorSecrets(err, apiKey);
|
|
362
|
+
if (isUnauthorized(err) && !err?.reauthRequired) return commandCodeReauthError(String(err?.message || ''));
|
|
363
|
+
return err;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async _pickDefaultModel(inner) {
|
|
367
|
+
if (this._defaultModel && this._defaultModelKey === this._innerKey) return this._defaultModel;
|
|
368
|
+
const rows = await listCompatModels(inner, { throwOnError: true });
|
|
369
|
+
this._defaultModel = chooseDefaultModel(rows.map((row) => row.id));
|
|
370
|
+
this._defaultModelKey = this._innerKey;
|
|
371
|
+
return this._defaultModel;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async send(messages, model, tools, sendOpts) {
|
|
375
|
+
let inner;
|
|
376
|
+
try {
|
|
377
|
+
inner = this._ensureInner();
|
|
378
|
+
} catch (err) {
|
|
379
|
+
throw this._shapeError(err, this.tokens?.apiKey);
|
|
380
|
+
}
|
|
381
|
+
const apiKey = this._innerKey;
|
|
382
|
+
// The model's declared endpoint picks the wire; a caller cannot move a
|
|
383
|
+
// model to Responses.
|
|
384
|
+
const { compatWireApi: _wire, responsesTransport: _transport, ...opts } = sendOpts || {};
|
|
385
|
+
try {
|
|
386
|
+
const useModel = model || (await this._pickDefaultModel(inner));
|
|
387
|
+
if ((await this._wireFor(inner, useModel)) === 'messages') {
|
|
388
|
+
return await this._sendMessages(apiKey, messages, useModel, tools, opts);
|
|
389
|
+
}
|
|
390
|
+
// _doSend directly: the compat wrapper's 401 handler reloads a static
|
|
391
|
+
// config key, which does not apply to this credential.
|
|
392
|
+
return await inner._doSend(messages, useModel, tools, opts);
|
|
393
|
+
} catch (err) {
|
|
394
|
+
throw this._shapeError(err, apiKey);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Messages wire. Same request preparation as the Anthropic engine's own
|
|
399
|
+
// send, but straight to _doSend: its 401 handler re-reads a static config
|
|
400
|
+
// key and replays, which does not apply to this credential. Anthropic usage
|
|
401
|
+
// excludes cached input; it is reported in this provider's inclusive form.
|
|
402
|
+
async _sendMessages(apiKey, messages, model, tools, opts) {
|
|
403
|
+
const engine = this._ensureMessages(apiKey);
|
|
404
|
+
const prepared = await preparePdfTextForProvider(sanitizeToolPairs(messages), engine);
|
|
405
|
+
const identity = currentUsageContext();
|
|
406
|
+
if (identity) identity.normalizeAbandonedUsage = toInclusiveUsage;
|
|
407
|
+
try {
|
|
408
|
+
const result = await engine._doSend(prepared, model, tools, opts);
|
|
409
|
+
return result?.usage ? { ...result, usage: toInclusiveUsage(result.usage) } : result;
|
|
410
|
+
} catch (err) {
|
|
411
|
+
throw normalizeUsageError(err);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
async listModels() {
|
|
416
|
+
let inner;
|
|
417
|
+
try {
|
|
418
|
+
inner = this._ensureInner();
|
|
419
|
+
return await listCompatModels(inner, { throwOnError: true });
|
|
420
|
+
} catch (err) {
|
|
421
|
+
throw this._shapeError(err, this.tokens?.apiKey);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** 5-hour and weekly credit windows for this account's key. */
|
|
426
|
+
async getUsageSnapshot() {
|
|
427
|
+
const { apiKey, userId } = this.ensureAuth();
|
|
428
|
+
const body = await requestCommandCodeJson(CREDITS_URL, apiKey, { fetchImpl: this.config.fetchImpl });
|
|
429
|
+
const quotaWindows = quotaWindowsFromCredits(body);
|
|
430
|
+
if (!quotaWindows.length) return null;
|
|
431
|
+
return {
|
|
432
|
+
provider: PROVIDER_ID,
|
|
433
|
+
model: null,
|
|
434
|
+
source: 'command-code-credits',
|
|
435
|
+
fetchedAt: Date.now(),
|
|
436
|
+
quotaWindows,
|
|
437
|
+
...(userId ? { accountId: userId } : {}),
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
async isAvailable() {
|
|
442
|
+
return loadTokens() !== null;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
@@ -4,6 +4,7 @@ import { join, resolve } from 'node:path';
|
|
|
4
4
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
5
5
|
import { writeJsonAtomicSync, withFileLock } from '../../../shared/atomic-file.mjs';
|
|
6
6
|
import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
|
|
7
|
+
import { modelProxyClientMode } from '../../../shared/model-proxy-mode.mjs';
|
|
7
8
|
import { openInBrowser } from '../../../shared/open-url.mjs';
|
|
8
9
|
import { createOAuthPkce } from './lib/oauth-pkce.mjs';
|
|
9
10
|
import { accountIdentityFields, normalizeAccountIdentity } from './lib/oauth-token-utils.mjs';
|
|
@@ -75,6 +76,7 @@ export function cursorTokenIdentity(token) {
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
function loadStoredCredentials() {
|
|
79
|
+
if (modelProxyClientMode()) return null;
|
|
78
80
|
if (process.env.CURSOR_ACCESS_TOKEN && !boundProviderAuthPath('cursor-oauth')) {
|
|
79
81
|
return {
|
|
80
82
|
access_token: process.env.CURSOR_ACCESS_TOKEN,
|
|
@@ -4,7 +4,7 @@ import { createRemoteVersionSource } from './npm-cli-version.mjs';
|
|
|
4
4
|
// documented version endpoint; the official installer script embeds the
|
|
5
5
|
// current build (…/lab/<build>/…), parsed best-effort. Any format change or
|
|
6
6
|
// failure falls back to the floor.
|
|
7
|
-
export const CURSOR_CLIENT_VERSION_FLOOR = 'cli-2026.10.
|
|
7
|
+
export const CURSOR_CLIENT_VERSION_FLOOR = 'cli-2026.10.12-d47ca18';
|
|
8
8
|
const BUILD_PATTERN = /downloads\.cursor\.com\/lab\/(\d{4}\.\d{2}\.\d{2}-[0-9a-f]{6,40})\//;
|
|
9
9
|
export const CURSOR_INSTALL_URL = 'https://cursor.com/install';
|
|
10
10
|
|
|
@@ -83,8 +83,9 @@ export function normalizeModels(models) {
|
|
|
83
83
|
name: isCursorAutoModelId(rawId)
|
|
84
84
|
? 'Auto'
|
|
85
85
|
: model.displayName || model.displayNameShort || model.displayModelId || aliases[0] || id,
|
|
86
|
+
// GetUsableModels publishes no window; the provider default applies
|
|
87
|
+
// after any described window instead of a seeded constant.
|
|
86
88
|
reasoning: Boolean(model.thinkingDetails),
|
|
87
|
-
contextWindow: 200_000,
|
|
88
89
|
});
|
|
89
90
|
}
|
|
90
91
|
return [...byId.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// runtime reuses the existing OpenAI-compat / Anthropic engines, constructed
|
|
5
5
|
// under the custom id so model routes and provider identity stay `custom-…`.
|
|
6
6
|
|
|
7
|
+
import { resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
7
8
|
import { effectiveCustomModelRows, normalizeCustomProviderConfig } from './custom-provider-config.mjs';
|
|
8
9
|
import { ANTHROPIC_VERSION } from './lib/anthropic-models.mjs';
|
|
9
10
|
import { enrichModels } from './model-catalog.mjs';
|
|
@@ -39,8 +40,11 @@ function withCustomModels(Base, discover) {
|
|
|
39
40
|
customConfig = null;
|
|
40
41
|
customDiscoveryError = null;
|
|
41
42
|
_customDiscovered = null;
|
|
42
|
-
_customApiKey = '';
|
|
43
43
|
_customKeyless = false;
|
|
44
|
+
// The key for discovery and error redaction, resolved per use like sends.
|
|
45
|
+
_customKey() {
|
|
46
|
+
return this._customKeyless ? '' : resolveProviderApiKey(this.name, this.config);
|
|
47
|
+
}
|
|
44
48
|
_customRows() {
|
|
45
49
|
return effectiveCustomModelRows(this.customConfig, this._customDiscovered || [], { providerId: this.name });
|
|
46
50
|
}
|
|
@@ -57,7 +61,7 @@ function withCustomModels(Base, discover) {
|
|
|
57
61
|
this.customDiscoveryError = null;
|
|
58
62
|
} catch (error) {
|
|
59
63
|
if (signal?.aborted) throw error;
|
|
60
|
-
failure = sanitizeDiscoveryError(error, this.
|
|
64
|
+
failure = sanitizeDiscoveryError(error, this._customKey());
|
|
61
65
|
this.customDiscoveryError = failure;
|
|
62
66
|
}
|
|
63
67
|
const rows = this._customRows();
|
|
@@ -82,7 +86,7 @@ async function discoverAnthropicModels(provider, signal) {
|
|
|
82
86
|
method: 'GET',
|
|
83
87
|
signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
|
|
84
88
|
headers: {
|
|
85
|
-
...(provider._customKeyless ? {} : { 'x-api-key': provider.
|
|
89
|
+
...(provider._customKeyless ? {} : { 'x-api-key': provider._customKey() }),
|
|
86
90
|
'anthropic-version': ANTHROPIC_VERSION,
|
|
87
91
|
},
|
|
88
92
|
});
|
|
@@ -141,7 +145,6 @@ export async function createCustomProvider(id, config) {
|
|
|
141
145
|
provider = new Custom(providerId, engine);
|
|
142
146
|
}
|
|
143
147
|
provider.customConfig = cfg;
|
|
144
|
-
provider._customApiKey = apiKey;
|
|
145
148
|
provider._customKeyless = keyless;
|
|
146
149
|
provider._applyCustomRows(provider._customRows());
|
|
147
150
|
return provider;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { normalizeAnthropicEffortInput } from './anthropic-effort.mjs';
|
|
1
|
+
import { anthropicEffortLevelsFor, normalizeAnthropicEffortInput } from './anthropic-effort.mjs';
|
|
2
2
|
import { CUSTOM_EFFORT_LEVELS, customEffortLevels, isCustomProviderName } from './custom-reasoning.mjs';
|
|
3
3
|
import { codexModelSupportsEffortUpdates } from './openai-oauth-catalog.mjs';
|
|
4
4
|
|
|
@@ -43,10 +43,18 @@ export function markEffortConfigurationUnsupported(provider, model) {
|
|
|
43
43
|
|
|
44
44
|
/** True for a provider error that names the mid-conversation effort update. */
|
|
45
45
|
export function isEffortConfigurationRejection(status, text) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
46
|
+
const message = String(text || '');
|
|
47
|
+
if (status !== 400) return false;
|
|
48
|
+
if (/mid-conversation|configuration_update|reasoning_effort_update/i.test(message)) return true;
|
|
49
|
+
// A rejected `output_config.effort` VALUE (the error quotes a level) belongs
|
|
50
|
+
// to the effort-rejection fallback (effort-rejection.mjs); a rejected field
|
|
51
|
+
// ("output_config.effort is not supported") is still the update case.
|
|
52
|
+
if (
|
|
53
|
+
/output_config\.effort\b(?!_)/i.test(message) &&
|
|
54
|
+
/['"`](?:none|minimal|low|medium|high|xhigh|max|ultra)['"`]/i.test(message)
|
|
55
|
+
)
|
|
56
|
+
return false;
|
|
57
|
+
return /output_config/i.test(message);
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
/**
|
|
@@ -139,8 +147,15 @@ export function customAutoEffortCapable(provider, protocol, model) {
|
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
/** The model auto effort reads its effort options from: a custom provider's
|
|
142
|
-
* effective row (its declared levels)
|
|
150
|
+
* effective row (its declared levels); an Anthropic route's id with the
|
|
151
|
+
* levels the wire builder accepts (provider rows ignored); the bare id for every other route. */
|
|
143
152
|
export function autoEffortModel(providerName, providerImpl, model) {
|
|
153
|
+
if (ANTHROPIC_PROVIDERS.has(providerName)) {
|
|
154
|
+
// The wire builder ignores provider rows on first-party routes, so the
|
|
155
|
+
// ladder is exactly what it accepts. `customReasoning` keeps an empty
|
|
156
|
+
// list from falling back to a family ladder.
|
|
157
|
+
return { id: model, reasoningLevels: anthropicEffortLevelsFor(model), customReasoning: true };
|
|
158
|
+
}
|
|
144
159
|
if (!isCustomProviderName(providerName)) return { id: model };
|
|
145
160
|
return { ...(providerImpl?.getCachedModelInfo?.(model) || {}), id: model };
|
|
146
161
|
}
|