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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { noteErrorUsage } from './lib/note-error-usage.mjs';
|
|
3
|
-
import {
|
|
3
|
+
import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
4
4
|
import { getLlmDispatcher, preconnect } from '../../../shared/llm/http-agent.mjs';
|
|
5
5
|
import { appendAgentTrace } from '../agent-trace.mjs';
|
|
6
6
|
import { OPENAI_COMPAT_PRESETS } from './openai-compat-presets.mjs';
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
useXaiResponsesWebSocket as preferXaiResponsesWebSocket,
|
|
13
13
|
_shouldFallbackXaiWsToHttp,
|
|
14
14
|
} from './openai-compat-xai.mjs';
|
|
15
|
+
import { withEffortRejectionFallback } from './effort-rejection.mjs';
|
|
15
16
|
import { sendCompatResponses } from './openai-compat-responses.mjs';
|
|
16
17
|
import { sendCompatChat, recoverCompatNonStreaming } from './openai-compat-chat-send.mjs';
|
|
17
18
|
import { sendXaiResponses, sendXaiResponsesWebSocket } from './openai-compat-xai-send.mjs';
|
|
@@ -68,7 +69,7 @@ export class OpenAICompatProvider {
|
|
|
68
69
|
constructor(name, config) {
|
|
69
70
|
const preset = PRESETS[name];
|
|
70
71
|
const baseURL = assertSafeBaseURL(config.baseURL || preset?.baseURL || 'http://localhost:8080/v1', name);
|
|
71
|
-
const apiKey = config
|
|
72
|
+
const apiKey = resolveProviderApiKey(name, config) || 'no-key';
|
|
72
73
|
this.name = name;
|
|
73
74
|
this.config = config;
|
|
74
75
|
this.baseURL = baseURL;
|
|
@@ -120,7 +121,7 @@ export class OpenAICompatProvider {
|
|
|
120
121
|
reloadApiKey() {
|
|
121
122
|
try {
|
|
122
123
|
const preset = PRESETS[this.name];
|
|
123
|
-
const newKey =
|
|
124
|
+
const newKey = reloadProviderApiKey(this.name, this.config);
|
|
124
125
|
const baseURL = assertSafeBaseURL(
|
|
125
126
|
this.config.baseURL || preset?.baseURL || 'http://localhost:8080/v1',
|
|
126
127
|
this.name
|
|
@@ -137,6 +138,12 @@ export class OpenAICompatProvider {
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
async send(messages, model, tools, sendOpts) {
|
|
141
|
+
// A keyless-constructed instance picks up the key once it is available.
|
|
142
|
+
const resolvedKey = resolveProviderApiKey(this.name, this.config) || 'no-key';
|
|
143
|
+
if (resolvedKey !== this.apiKey) {
|
|
144
|
+
this.apiKey = resolvedKey;
|
|
145
|
+
this.client = this._createClient(resolvedKey);
|
|
146
|
+
}
|
|
140
147
|
try {
|
|
141
148
|
return await this._doSend(messages, model, tools, sendOpts);
|
|
142
149
|
} catch (err) {
|
|
@@ -161,7 +168,11 @@ export class OpenAICompatProvider {
|
|
|
161
168
|
}
|
|
162
169
|
async _doSend(messages, model, tools, sendOpts) {
|
|
163
170
|
const useModel = model || this.defaultModel;
|
|
164
|
-
|
|
171
|
+
return withEffortRejectionFallback(this.name, useModel, sendOpts || {}, this.config?.reasoningEffort, (opts) =>
|
|
172
|
+
this._sendWithOpts(messages, useModel, tools, opts)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
async _sendWithOpts(messages, useModel, tools, opts) {
|
|
165
176
|
// Re-warm a kept-alive socket to the provider origin before the turn so
|
|
166
177
|
// the request hot path lands on a live socket instead of paying a cold
|
|
167
178
|
// TLS handshake after an idle gap. Fire-and-forget; never awaited.
|
|
@@ -13,7 +13,7 @@ import { formatScheduleModelRef, parseScheduleModelRef } from '../../../shared/s
|
|
|
13
13
|
export const CODEX_MODEL_CACHE_OPTIONS = Object.freeze({
|
|
14
14
|
fileName: 'openai-oauth-models.json',
|
|
15
15
|
ttlMs: 24 * 60 * 60_000,
|
|
16
|
-
version:
|
|
16
|
+
version: 7,
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
export const CODEX_PROVIDER_ID = 'openai-oauth';
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
import { makeModelCache } from './model-cache.mjs';
|
|
14
14
|
import { CODEX_MODEL_CACHE_OPTIONS } from './openai-oauth-catalog-store.mjs';
|
|
15
15
|
import { enrichModels } from './model-catalog.mjs';
|
|
16
|
-
import { sanitizeModelList } from './model-list-sanitize.mjs';
|
|
17
16
|
import { modelSupportsServiceTier } from './model-service-tiers.mjs';
|
|
18
17
|
import { codexClientVersionSync, warmCodexClientVersion } from './codex-client-meta.mjs';
|
|
19
18
|
import { compareSemver, maxSemver } from './npm-cli-version.mjs';
|
|
@@ -131,7 +130,11 @@ async function fetchCodexCatalog(ensureAuth, label) {
|
|
|
131
130
|
const items = Array.isArray(data?.models) ? data.models : [];
|
|
132
131
|
const normalized = items.map((m) => _normalizeCodexModel(m));
|
|
133
132
|
_markLatestCodex(normalized);
|
|
134
|
-
|
|
133
|
+
// The backend curates this list per account and client version and marks
|
|
134
|
+
// each row's picker visibility itself, so every row is kept: generic list
|
|
135
|
+
// pruning (external release dates, id patterns) dropped models it still
|
|
136
|
+
// serves, along with their access programs.
|
|
137
|
+
const enriched = (await enrichModels(normalized)).filter(Boolean);
|
|
135
138
|
_modelCache.save(enriched, { clientVersion });
|
|
136
139
|
return enriched;
|
|
137
140
|
}
|
|
@@ -18,6 +18,7 @@ import { getPluginData } from '../config.mjs';
|
|
|
18
18
|
import { writeJsonAtomicSync, withFileLock } from '../../../shared/atomic-file.mjs';
|
|
19
19
|
import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
|
|
20
20
|
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
21
|
+
import { modelProxyClientMode, serverModelCredentialsDisabledError } from '../../../shared/model-proxy-mode.mjs';
|
|
21
22
|
import {
|
|
22
23
|
accountIdentityFields,
|
|
23
24
|
decodeJwtPayload,
|
|
@@ -101,6 +102,7 @@ export function tokensFileMtimeMs() {
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
export function loadTokens() {
|
|
105
|
+
if (modelProxyClientMode()) return null;
|
|
104
106
|
const ownPath = getOwnTokenPath();
|
|
105
107
|
if (!existsSync(ownPath)) return null;
|
|
106
108
|
try {
|
|
@@ -322,6 +324,7 @@ async function refreshUnderLock({ currentToken, force, reason, startingTokens })
|
|
|
322
324
|
* the provider can hold off re-attempting until the expiry skew.
|
|
323
325
|
*/
|
|
324
326
|
export async function refreshStoredTokens({ current = null, force = false, reason = 'preemptive' } = {}) {
|
|
327
|
+
if (modelProxyClientMode()) throw serverModelCredentialsDisabledError('OpenAI OAuth credentials');
|
|
325
328
|
const currentToken = current?.access_token || null;
|
|
326
329
|
const disk = loadTokens();
|
|
327
330
|
const adopted = adoptableDiskTokens(currentToken, disk, force);
|
|
@@ -23,7 +23,7 @@ import { resolveOpenAiTransportPolicy } from './openai-transport-policy.mjs';
|
|
|
23
23
|
import { applyOpenAIDirectCachePolicy } from './openai-direct-request.mjs';
|
|
24
24
|
import { streamCallbacks } from './lib/send-callbacks.mjs';
|
|
25
25
|
import { noteErrorUsage } from './lib/note-error-usage.mjs';
|
|
26
|
-
import {
|
|
26
|
+
import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
27
27
|
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
28
28
|
import { noteRequestServiceTier } from '../../../shared/llm/usage-context.mjs';
|
|
29
29
|
import { resolveProviderCacheKey, resolveProviderPromptCacheLane } from '../agent-runtime/cache-strategy.mjs';
|
|
@@ -86,7 +86,7 @@ export class OpenAIDirectProvider {
|
|
|
86
86
|
this.config = config || {};
|
|
87
87
|
}
|
|
88
88
|
_ensureKey() {
|
|
89
|
-
const k = this.config
|
|
89
|
+
const k = resolveProviderApiKey('openai', this.config);
|
|
90
90
|
if (!k) throw new Error('OPENAI_API_KEY not configured (providers.openai.apiKey)');
|
|
91
91
|
return k;
|
|
92
92
|
}
|
|
@@ -97,7 +97,7 @@ export class OpenAIDirectProvider {
|
|
|
97
97
|
// the WS/HTTP transports take the key per-call via the `auth` object.
|
|
98
98
|
reloadApiKey() {
|
|
99
99
|
try {
|
|
100
|
-
const newKey =
|
|
100
|
+
const newKey = reloadProviderApiKey('openai', this.config);
|
|
101
101
|
if (newKey) {
|
|
102
102
|
this.config = { ...(this.config || {}), apiKey: newKey };
|
|
103
103
|
return newKey;
|
|
@@ -295,6 +295,6 @@ export class OpenAIDirectProvider {
|
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
async isAvailable() {
|
|
298
|
-
return !!this.config
|
|
298
|
+
return !!resolveProviderApiKey('openai', this.config);
|
|
299
299
|
}
|
|
300
300
|
}
|
|
@@ -6,6 +6,8 @@ import { createAccountPoolProvider } from './account-pool.mjs';
|
|
|
6
6
|
import { isInclusiveProvider } from '../../../shared/llm/cost.mjs';
|
|
7
7
|
import { noEnabledProvidersError } from './registry-errors.mjs';
|
|
8
8
|
import { providerTakesNativePdf } from '../../../attachments/store.mjs';
|
|
9
|
+
import { modelProxyClientMode } from '../../../shared/model-proxy-mode.mjs';
|
|
10
|
+
import { getModelProxyChannel } from './model-proxy-channel.mjs';
|
|
9
11
|
// OpenAI-compat provider names are self-declared by openai-compat-presets.mjs via
|
|
10
12
|
// OPENAI_COMPAT_PRESETS. No parallel list maintained here.
|
|
11
13
|
const providers = new Map();
|
|
@@ -27,6 +29,7 @@ const OAUTH_PROVIDER_NAMES = new Set([
|
|
|
27
29
|
'openai-oauth',
|
|
28
30
|
'grok-oauth',
|
|
29
31
|
'muse-code-oauth',
|
|
32
|
+
'command-code-oauth',
|
|
30
33
|
'mimo-oauth',
|
|
31
34
|
'cursor-oauth',
|
|
32
35
|
'antigravity-oauth',
|
|
@@ -95,6 +98,28 @@ function configSignature(cfg) {
|
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
100
|
|
|
101
|
+
// Remote mode: a proxy provider sends through the channel it was built on. A
|
|
102
|
+
// headless boundary installs a fresh channel per run (model-proxy-bridge.mjs)
|
|
103
|
+
// and closes it afterwards, so the channel's identity is part of every reuse
|
|
104
|
+
// signature — an identical PC config behind a new channel is a rebuild, never
|
|
105
|
+
// a provider bound to a closed channel. Local mode: '' (signatures unchanged).
|
|
106
|
+
const _proxyChannelIds = new WeakMap();
|
|
107
|
+
let _proxyChannelSeq = 0;
|
|
108
|
+
function proxyChannelTag(channel) {
|
|
109
|
+
if (!channel) return '';
|
|
110
|
+
let id = _proxyChannelIds.get(channel);
|
|
111
|
+
if (!id) {
|
|
112
|
+
_proxyChannelSeq += 1;
|
|
113
|
+
id = _proxyChannelSeq;
|
|
114
|
+
_proxyChannelIds.set(channel, id);
|
|
115
|
+
}
|
|
116
|
+
return `\u0000model-proxy-channel:${id}`;
|
|
117
|
+
}
|
|
118
|
+
function reuseSignature(cfg, proxyChannel) {
|
|
119
|
+
const sig = configSignature(cfg);
|
|
120
|
+
return sig === null ? null : sig + proxyChannelTag(proxyChannel);
|
|
121
|
+
}
|
|
122
|
+
|
|
98
123
|
function abortError(signal) {
|
|
99
124
|
return signal?.reason instanceof Error
|
|
100
125
|
? signal.reason
|
|
@@ -146,6 +171,7 @@ const PROVIDER_MODULES = {
|
|
|
146
171
|
'anthropic-oauth': ['./anthropic-oauth.mjs', 'AnthropicOAuthProvider'],
|
|
147
172
|
'grok-oauth': ['./grok-oauth.mjs', 'GrokOAuthProvider'],
|
|
148
173
|
'muse-code-oauth': ['./muse-code-oauth.mjs', 'MuseCodeOAuthProvider'],
|
|
174
|
+
'command-code-oauth': ['./command-code-oauth.mjs', 'CommandCodeOAuthProvider'],
|
|
149
175
|
'mimo-oauth': ['./mimo-oauth.mjs', 'MimoOAuthProvider'],
|
|
150
176
|
'cursor-oauth': ['./cursor.mjs', 'CursorOAuthProvider'],
|
|
151
177
|
'antigravity-oauth': ['./antigravity-oauth.mjs', 'AntigravityOAuthProvider'],
|
|
@@ -175,7 +201,13 @@ async function loadProviderCtor(name, signal = null, cfg = null) {
|
|
|
175
201
|
throw new Error(`unknown enabled provider: ${name}`);
|
|
176
202
|
}
|
|
177
203
|
|
|
178
|
-
async function instantiateProvider(name, Ctor, cfg) {
|
|
204
|
+
async function instantiateProvider(name, Ctor, cfg, proxyChannel = null) {
|
|
205
|
+
// Remote mode: the client PC executes the call with its own credentials.
|
|
206
|
+
// Admission and usage accounting still wrap the daemon-side stand-in.
|
|
207
|
+
if (modelProxyClientMode()) {
|
|
208
|
+
const { createModelProxyProvider } = await import('./model-proxy-provider.mjs');
|
|
209
|
+
return wrapProviderAdmission(createModelProxyProvider(name, cfg, proxyChannel ?? getModelProxyChannel()), name);
|
|
210
|
+
}
|
|
179
211
|
if (isCustomProviderConfig(name, cfg)) return wrapProviderAdmission(await Ctor(name, cfg), name);
|
|
180
212
|
if (Object.hasOwn(OPENAI_COMPAT_PRESETS, name) && name !== 'opencode-go') {
|
|
181
213
|
return wrapProviderAdmission(new Ctor(name, cfg), name);
|
|
@@ -185,7 +217,14 @@ async function instantiateProvider(name, Ctor, cfg) {
|
|
|
185
217
|
|
|
186
218
|
export async function initProviders(config, { signal = null } = {}) {
|
|
187
219
|
throwIfAborted(signal);
|
|
188
|
-
|
|
220
|
+
// Remote mode: provider availability and config are the PC's, never this
|
|
221
|
+
// server's credential probes. No connected client fails here, clearly.
|
|
222
|
+
const proxyChannel = modelProxyClientMode() ? getModelProxyChannel() : null;
|
|
223
|
+
if (proxyChannel) {
|
|
224
|
+
const { loadModelProxyProviderConfig } = await import('./model-proxy-provider.mjs');
|
|
225
|
+
config = await awaitWithAbort(loadModelProxyProviderConfig({ channel: proxyChannel }), signal);
|
|
226
|
+
}
|
|
227
|
+
const sig = reuseSignature(config, proxyChannel);
|
|
189
228
|
// Coalesce: an identical config is already mid-init — attach to it.
|
|
190
229
|
if (sig !== null && _inFlightPromise && _inFlightSig === sig) {
|
|
191
230
|
return awaitWithAbort(_inFlightPromise, signal);
|
|
@@ -199,7 +238,7 @@ export async function initProviders(config, { signal = null } = {}) {
|
|
|
199
238
|
// signatures can never run their clear()+rebuild concurrently, regardless
|
|
200
239
|
// of caller-side gating (agent-tool gateOnPrior may release a queued init
|
|
201
240
|
// before the prior one settled). Errors do not poison the chain.
|
|
202
|
-
const run = () => _initProvidersUnsynchronized(config, signal);
|
|
241
|
+
const run = () => _initProvidersUnsynchronized(config, signal, proxyChannel);
|
|
203
242
|
const next = _initChain.then(run, run);
|
|
204
243
|
_initChain = next.then(
|
|
205
244
|
() => {},
|
|
@@ -228,7 +267,7 @@ export async function initProviders(config, { signal = null } = {}) {
|
|
|
228
267
|
return awaitWithAbort(tracked, signal);
|
|
229
268
|
}
|
|
230
269
|
|
|
231
|
-
async function _initProvidersUnsynchronized(config, signal = null) {
|
|
270
|
+
async function _initProvidersUnsynchronized(config, signal = null, proxyChannel = null) {
|
|
232
271
|
throwIfAborted(signal);
|
|
233
272
|
// Invariant: never wipe the live registry based on an empty / all-disabled
|
|
234
273
|
// config. Without this guard, a stale `loadAgentConfig()` (e.g. mid-reload
|
|
@@ -249,14 +288,15 @@ async function _initProvidersUnsynchronized(config, signal = null) {
|
|
|
249
288
|
// Idempotent reuse: an enabled provider whose config signature is
|
|
250
289
|
// unchanged from the live registry is carried forward as-is. Only
|
|
251
290
|
// added or changed providers are (re)constructed below.
|
|
252
|
-
const sig =
|
|
291
|
+
const sig = reuseSignature(cfg, proxyChannel);
|
|
253
292
|
if (sig !== null && providers.has(name) && signatures.get(name) === sig) {
|
|
254
293
|
return { name, inst: providers.get(name), sig };
|
|
255
294
|
}
|
|
256
295
|
try {
|
|
257
|
-
|
|
296
|
+
// A proxied provider never loads the real adapter module.
|
|
297
|
+
const Ctor = modelProxyClientMode() ? null : await loadProviderCtor(name, signal, cfg);
|
|
258
298
|
throwIfAborted(signal);
|
|
259
|
-
const inst = await instantiateProvider(name, Ctor, cfg);
|
|
299
|
+
const inst = await instantiateProvider(name, Ctor, cfg, proxyChannel);
|
|
260
300
|
return { name, inst, sig };
|
|
261
301
|
} catch (err) {
|
|
262
302
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -30,6 +30,7 @@ import { setBuiltinInstalledInConfig, withGrandfatheredBuiltins } from '../../..
|
|
|
30
30
|
const BROWSER_BRIDGE_DISCOVERY_FILE = 'browser-bridge.json';
|
|
31
31
|
const COMPUTER_BRIDGE_DISCOVERY_FILE = 'computer-bridge.json';
|
|
32
32
|
const TERMINAL_BRIDGE_DISCOVERY_FILE = 'terminal-bridge.json';
|
|
33
|
+
const VISUALIZE_BRIDGE_DISCOVERY_FILE = 'visualize-bridge.json';
|
|
33
34
|
|
|
34
35
|
function bridgePresent(file) {
|
|
35
36
|
try {
|
|
@@ -116,6 +117,14 @@ export function builtinFeatureActive(configLike, id) {
|
|
|
116
117
|
if (id === 'terminal') {
|
|
117
118
|
return featureEnvOverride('MIXDOG_FEATURE_TERMINAL') ?? bridgePresent(TERMINAL_BRIDGE_DISCOVERY_FILE);
|
|
118
119
|
}
|
|
120
|
+
// Visualize shows artifacts in the desktop side panel: no install step, on
|
|
121
|
+
// unless the user turns it off, and only while the desktop bridge is up.
|
|
122
|
+
if (id === 'visualize') {
|
|
123
|
+
return (
|
|
124
|
+
featureEnvOverride('MIXDOG_FEATURE_VISUALIZE') ??
|
|
125
|
+
(moduleEnabled(configLike, 'visualize', true) && bridgePresent(VISUALIZE_BRIDGE_DISCOVERY_FILE))
|
|
126
|
+
);
|
|
127
|
+
}
|
|
119
128
|
return false;
|
|
120
129
|
}
|
|
121
130
|
|
|
@@ -148,6 +157,7 @@ export function featureDisallowedToolsFor(
|
|
|
148
157
|
...(builtinFeatureActive(configLike, 'office') ? [] : ['office']),
|
|
149
158
|
...(builtinFeatureActive(configLike, 'media') ? [] : ['media']),
|
|
150
159
|
...(builtinFeatureActive(configLike, 'tidy') ? [] : ['tidy']),
|
|
160
|
+
...(builtinFeatureActive(configLike, 'visualize') ? [] : ['visualize']),
|
|
151
161
|
];
|
|
152
162
|
// Headless exec uses the Lead surface and excludes Skill/MCP tools. When
|
|
153
163
|
// only its eager defaults remain, neither schemas nor loader guidance help.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { clean, hasOwn } from './session-text.mjs';
|
|
4
4
|
import { normalizeEffortInput, normalizeSavedEffort } from './effort.mjs';
|
|
5
5
|
import { routeFastKey, fastPreferenceFor } from './model-capabilities.mjs';
|
|
6
|
+
import { normalizeContextTokens } from '../../../shared/llm/default-context-window.mjs';
|
|
6
7
|
|
|
7
8
|
const DEFAULT_PROVIDER = 'anthropic-oauth';
|
|
8
9
|
export const DEFAULT_MODEL = '';
|
|
@@ -53,6 +54,14 @@ function cleanContextPercent(value) {
|
|
|
53
54
|
return Math.max(10, Math.min(100, Math.round(percent / 10) * 10));
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
/** The route's exact window in tokens: an explicit request, else none when a
|
|
58
|
+
* percent is chosen instead, else the saved or preset selection. */
|
|
59
|
+
function resolveContextTokens({ contextTokens, hasExplicitContextPercent, saved, preset = null }) {
|
|
60
|
+
if (contextTokens !== undefined) return normalizeContextTokens(contextTokens);
|
|
61
|
+
if (hasExplicitContextPercent) return undefined;
|
|
62
|
+
return normalizeContextTokens(saved.contextTokens ?? preset?.contextTokens);
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
/** The route's fast flag: an explicit request, else the saved choice, else the preset or the provider preference. */
|
|
57
66
|
function resolveFast({ hasExplicitFast, explicitFast, saved, presetFast = false, preference }) {
|
|
58
67
|
if (hasExplicitFast) return explicitFast;
|
|
@@ -60,8 +69,19 @@ function resolveFast({ hasExplicitFast, explicitFast, saved, presetFast = false,
|
|
|
60
69
|
return presetFast || preference();
|
|
61
70
|
}
|
|
62
71
|
|
|
72
|
+
/** The route's Auto effort flag: an explicit request, else the saved choice,
|
|
73
|
+
* else the preset. Absent means on; only `false` turns it off. */
|
|
74
|
+
function resolveAutoEffort({ autoEffort, saved, preset = null }) {
|
|
75
|
+
if (autoEffort !== undefined) return autoEffort !== false;
|
|
76
|
+
if (hasOwn(saved, 'autoEffort')) return saved.autoEffort !== false;
|
|
77
|
+
return preset?.autoEffort !== false;
|
|
78
|
+
}
|
|
79
|
+
|
|
63
80
|
export function makeResolveRoute(resolveDefaultProvider) {
|
|
64
|
-
return function resolveRoute(
|
|
81
|
+
return function resolveRoute(
|
|
82
|
+
config,
|
|
83
|
+
{ provider, model, effort, fast, autoEffort, modelParameters, contextPercent, contextTokens } = {}
|
|
84
|
+
) {
|
|
65
85
|
const explicitProvider = clean(provider);
|
|
66
86
|
const explicitModel = clean(model);
|
|
67
87
|
const hasExplicitEffort = effort !== undefined;
|
|
@@ -70,6 +90,9 @@ export function makeResolveRoute(resolveDefaultProvider) {
|
|
|
70
90
|
const explicitFast = fast === true;
|
|
71
91
|
const hasExplicitModelParameters = modelParameters !== undefined;
|
|
72
92
|
const hasExplicitContextPercent = contextPercent !== undefined;
|
|
93
|
+
// An exact token selection replaces a saved percent unless a percent is
|
|
94
|
+
// requested alongside it.
|
|
95
|
+
const keepsSavedPercent = contextTokens === undefined;
|
|
73
96
|
|
|
74
97
|
if (!explicitProvider) {
|
|
75
98
|
const preset = findPreset(config, explicitModel || config?.default);
|
|
@@ -78,6 +101,7 @@ export function makeResolveRoute(resolveDefaultProvider) {
|
|
|
78
101
|
const m = clean(preset.model) || DEFAULT_MODEL;
|
|
79
102
|
if (p && m) {
|
|
80
103
|
const saved = modelSettingsFor(config, p, m);
|
|
104
|
+
const tokens = resolveContextTokens({ contextTokens, hasExplicitContextPercent, saved, preset });
|
|
81
105
|
return {
|
|
82
106
|
provider: p,
|
|
83
107
|
model: m,
|
|
@@ -90,12 +114,16 @@ export function makeResolveRoute(resolveDefaultProvider) {
|
|
|
90
114
|
presetFast: preset.fast === true,
|
|
91
115
|
preference: () => fastPreferenceFor(config, p, m),
|
|
92
116
|
}),
|
|
117
|
+
autoEffort: resolveAutoEffort({ autoEffort, saved, preset }),
|
|
93
118
|
modelParameters: hasExplicitModelParameters
|
|
94
119
|
? cleanModelParameters(modelParameters)
|
|
95
120
|
: cleanModelParameters(saved.modelParameters ?? preset.modelParameters),
|
|
96
121
|
contextPercent: hasExplicitContextPercent
|
|
97
122
|
? cleanContextPercent(contextPercent)
|
|
98
|
-
:
|
|
123
|
+
: keepsSavedPercent
|
|
124
|
+
? cleanContextPercent(saved.contextPercent ?? preset.contextPercent)
|
|
125
|
+
: undefined,
|
|
126
|
+
...(tokens ? { contextTokens: tokens } : {}),
|
|
99
127
|
};
|
|
100
128
|
}
|
|
101
129
|
}
|
|
@@ -104,18 +132,23 @@ export function makeResolveRoute(resolveDefaultProvider) {
|
|
|
104
132
|
const p = explicitProvider || resolveDefaultProvider(config);
|
|
105
133
|
const m = explicitModel || DEFAULT_MODEL;
|
|
106
134
|
const saved = modelSettingsFor(config, p, m);
|
|
135
|
+
const tokens = resolveContextTokens({ contextTokens, hasExplicitContextPercent, saved });
|
|
107
136
|
return {
|
|
108
137
|
provider: p,
|
|
109
138
|
model: m,
|
|
110
139
|
preset: null,
|
|
111
140
|
effort: hasExplicitEffort ? explicitEffort : normalizeSavedEffort(saved.effort),
|
|
112
141
|
fast: resolveFast({ hasExplicitFast, explicitFast, saved, preference: () => fastPreferenceFor(config, p, m) }),
|
|
142
|
+
autoEffort: resolveAutoEffort({ autoEffort, saved }),
|
|
113
143
|
modelParameters: hasExplicitModelParameters
|
|
114
144
|
? cleanModelParameters(modelParameters)
|
|
115
145
|
: cleanModelParameters(saved.modelParameters),
|
|
116
146
|
contextPercent: hasExplicitContextPercent
|
|
117
147
|
? cleanContextPercent(contextPercent)
|
|
118
|
-
:
|
|
148
|
+
: keepsSavedPercent
|
|
149
|
+
? cleanContextPercent(saved.contextPercent)
|
|
150
|
+
: undefined,
|
|
151
|
+
...(tokens ? { contextTokens: tokens } : {}),
|
|
119
152
|
};
|
|
120
153
|
};
|
|
121
154
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Reasoning-effort catalogs and coercion. Pure helpers.
|
|
2
2
|
import { clean } from './session-text.mjs';
|
|
3
3
|
import { customEffortLevels, snapCustomEffort } from '../providers/custom-reasoning.mjs';
|
|
4
|
+
import { rejectedEffortLevelsSync } from '../providers/effort-rejection.mjs';
|
|
4
5
|
|
|
5
6
|
const TOOL_MODES = new Set(['full', 'readonly', 'lead']);
|
|
6
7
|
const ALL_EFFORT_LEVELS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra']);
|
|
@@ -15,22 +16,18 @@ const EFFORT_LABELS = {
|
|
|
15
16
|
ultra: 'Ultra',
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
// Last-resort ladders for routes whose endpoints publish no effort metadata
|
|
20
|
+
// (no per-model levels on /models, no same-endpoint catalog row). Every other
|
|
21
|
+
// provider's ladder comes from its own catalog rows (live roster, models.dev
|
|
22
|
+
// via provider-catalog-registry, seeds); a route with none offers no effort.
|
|
18
23
|
const EFFORT_OPTIONS_BY_PROVIDER = {
|
|
19
24
|
openai: ['none', 'low', 'medium', 'high', 'xhigh'],
|
|
20
|
-
// gpt-5.6+ catalogs declare max/ultra; the openai-oauth transport folds
|
|
21
|
-
// ultra -> max on the wire (openai-oauth.mjs _normalizeReasoningEffort).
|
|
22
|
-
'openai-oauth': ['none', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
|
|
23
|
-
anthropic: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
24
|
-
'anthropic-oauth': ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
25
25
|
// xAI Grok 4.6+: low/medium/high/xhigh. Reasoning cannot be disabled.
|
|
26
26
|
xai: ['low', 'medium', 'high', 'xhigh'],
|
|
27
|
-
'grok-oauth': ['low', 'medium', 'high', 'xhigh'],
|
|
28
|
-
'muse-code-oauth': ['minimal', 'low', 'medium', 'high', 'xhigh'],
|
|
29
27
|
'mimo-oauth': ['minimal', 'low', 'medium', 'high'],
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
'
|
|
33
|
-
'opencode-go': ['high', 'max'],
|
|
28
|
+
// Command Code relays several vendors over Chat Completions; the common
|
|
29
|
+
// `reasoning_effort` levels are the fallback when no catalog row declares any.
|
|
30
|
+
'command-code-oauth': ['low', 'medium', 'high'],
|
|
34
31
|
};
|
|
35
32
|
const EFFORT_BY_FAMILY = {
|
|
36
33
|
opus: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
@@ -73,7 +70,14 @@ export function normalizeEffortInput(value) {
|
|
|
73
70
|
return v;
|
|
74
71
|
}
|
|
75
72
|
|
|
73
|
+
// Levels the endpoint has rejected for this route stop being offered.
|
|
76
74
|
export function effortOptionsFor(provider, model) {
|
|
75
|
+
const options = catalogEffortOptions(provider, model);
|
|
76
|
+
const rejected = model?.id ? rejectedEffortLevelsSync(provider, model.id) : null;
|
|
77
|
+
return rejected?.size ? options.filter((level) => !rejected.has(level)) : options;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function catalogEffortOptions(provider, model) {
|
|
77
81
|
// Custom-provider rows declare their levels authoritatively: an explicit []
|
|
78
82
|
// (or no declaration) means none, with no family/provider fallback.
|
|
79
83
|
if (model?.customReasoning) return customEffortLevels(model) || [];
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
// extension-scopes.mjs — plugin-aware layer over the shared scope model. A
|
|
2
2
|
// plugin's scope cascades to the skills it owns and to the MCP server(s) it
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { pluginMcpServerName, pluginServerMatcher } from './plugin-mcp.mjs';
|
|
8
|
-
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
3
|
+
// declares, so limiting the plugin limits everything it brought along. MCP
|
|
4
|
+
// ownership comes from the tool's `mcpPluginId`, set when the plugin's server
|
|
5
|
+
// connected, never from the server name.
|
|
9
6
|
import { loadConfig } from '../config.mjs';
|
|
10
7
|
import {
|
|
11
8
|
extensionAllowedForCwd,
|
|
@@ -28,66 +25,29 @@ export {
|
|
|
28
25
|
withExtensionScope,
|
|
29
26
|
} from '../../../shared/extension-scopes.mjs';
|
|
30
27
|
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
export function pluginIdForMcpServer(serverName, plugins) {
|
|
34
|
-
const name = clean(serverName);
|
|
35
|
-
if (!name) return '';
|
|
36
|
-
for (const plugin of Array.isArray(plugins) ? plugins : []) {
|
|
37
|
-
if (pluginServerMatcher(pluginMcpServerName(plugin))(name)) return clean(plugin?.id || plugin?.name);
|
|
38
|
-
}
|
|
39
|
-
return '';
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function mcpServerAllowedForCwd(scopes, serverName, cwd, { plugins = [] } = {}) {
|
|
28
|
+
/** Server scope ∩ owning plugin's scope (`pluginId` from owner metadata). */
|
|
29
|
+
export function mcpServerAllowedForCwd(scopes, serverName, cwd, { pluginId = '' } = {}) {
|
|
43
30
|
if (!extensionAllowedForCwd(scopes, 'mcp', serverName, cwd)) return false;
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
31
|
+
const owner = clean(pluginId);
|
|
32
|
+
if (owner && !extensionAllowedForCwd(scopes, 'plugins', owner, cwd)) return false;
|
|
46
33
|
return true;
|
|
47
34
|
}
|
|
48
35
|
|
|
49
36
|
/** Drop tools of MCP servers whose scope excludes cwd; non-MCP tools pass. */
|
|
50
|
-
export function filterMcpToolsForCwd(tools, scopes, cwd
|
|
37
|
+
export function filterMcpToolsForCwd(tools, scopes, cwd) {
|
|
51
38
|
const list = Array.isArray(tools) ? tools : [];
|
|
52
39
|
const verdicts = new Map();
|
|
53
40
|
return list.filter((tool) => {
|
|
54
|
-
|
|
41
|
+
// A name shortened for provider limits carries its server explicitly.
|
|
42
|
+
const server = mcpServerNameOfTool(tool);
|
|
55
43
|
if (!server) return true;
|
|
56
|
-
|
|
57
|
-
|
|
44
|
+
const pluginId = clean(tool?.mcpPluginId);
|
|
45
|
+
const key = `${server}\0${pluginId}`;
|
|
46
|
+
if (!verdicts.has(key)) verdicts.set(key, mcpServerAllowedForCwd(scopes, server, cwd, { pluginId }));
|
|
47
|
+
return verdicts.get(key);
|
|
58
48
|
});
|
|
59
49
|
}
|
|
60
50
|
|
|
61
|
-
// `{ id, name }` of every registered plugin, from <data>/plugins/registry.json.
|
|
62
|
-
// mtime-cached: this runs on every session create and MCP catalog fold.
|
|
63
|
-
let _registryCache = { path: '', mtime: -1, plugins: [] };
|
|
64
|
-
export function registeredPluginIdentities(dataDir = null) {
|
|
65
|
-
let path = '';
|
|
66
|
-
try {
|
|
67
|
-
path = join(dataDir || resolvePluginData(), 'plugins', 'registry.json');
|
|
68
|
-
} catch {
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
let mtime = -1;
|
|
72
|
-
try {
|
|
73
|
-
mtime = statSync(path).mtimeMs;
|
|
74
|
-
} catch {
|
|
75
|
-
return [];
|
|
76
|
-
}
|
|
77
|
-
if (_registryCache.path === path && _registryCache.mtime === mtime) return _registryCache.plugins;
|
|
78
|
-
let plugins = [];
|
|
79
|
-
try {
|
|
80
|
-
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
81
|
-
plugins = (Array.isArray(parsed?.plugins) ? parsed.plugins : [])
|
|
82
|
-
.map((entry) => ({ id: clean(entry?.id || entry?.name), name: clean(entry?.name || entry?.id) }))
|
|
83
|
-
.filter((entry) => entry.id);
|
|
84
|
-
} catch {
|
|
85
|
-
plugins = [];
|
|
86
|
-
}
|
|
87
|
-
_registryCache = { path, mtime, plugins };
|
|
88
|
-
return plugins;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
51
|
/** The MCP tools a session at `cwd` may see. No scopes configured → input
|
|
92
52
|
* returned as-is, so the global-only fast path costs one config read. */
|
|
93
53
|
export function filterMcpToolsForSession(tools, cwd, config = null) {
|
|
@@ -95,5 +55,5 @@ export function filterMcpToolsForSession(tools, cwd, config = null) {
|
|
|
95
55
|
if (!list.length) return list;
|
|
96
56
|
const scopes = extensionScopesFromConfig(config || loadConfig({ secrets: false }));
|
|
97
57
|
if (!hasExtensionScopes(scopes)) return list;
|
|
98
|
-
return filterMcpToolsForCwd(list, scopes, cwd
|
|
58
|
+
return filterMcpToolsForCwd(list, scopes, cwd);
|
|
99
59
|
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
stopActiveClock,
|
|
20
20
|
validateObjective,
|
|
21
21
|
} from './goal-state.mjs';
|
|
22
|
-
import { assertExpectedGoal } from './goal-mutations.mjs';
|
|
22
|
+
import { assertExpectedGoal, goalFinished } from './goal-mutations.mjs';
|
|
23
23
|
import { clean } from '../../../shared/clean.mjs';
|
|
24
24
|
|
|
25
25
|
/** "12m remaining" for a budgeted Goal, "3m elapsed" for an open-ended one. */
|
|
@@ -109,6 +109,17 @@ const GOAL_CONTROL_ACTIONS = {
|
|
|
109
109
|
const goal = await ctx.updateGoal(id, { status: 'complete' }, { user: true });
|
|
110
110
|
return reply(action, goal, `Goal complete · ${goal.objective} · ${durationLabel(goal.timeUsedMs)} elapsed`);
|
|
111
111
|
},
|
|
112
|
+
async dismiss(ctx, { id, goal, at, action }) {
|
|
113
|
+
// The user's acknowledgement of finished work: the same archive a new
|
|
114
|
+
// prompt applies, so the chrome lets go while the record stays.
|
|
115
|
+
if (!goalFinished(goal)) throw new Error('only a finished Goal can be dismissed; stop or complete it first');
|
|
116
|
+
if (!goal.archivedAt) {
|
|
117
|
+
goal.archivedAt = at;
|
|
118
|
+
goal.updatedAt = at;
|
|
119
|
+
await ctx.commit(id, goal);
|
|
120
|
+
}
|
|
121
|
+
return reply(action, null, `Goal dismissed · ${goal.objective}`);
|
|
122
|
+
},
|
|
112
123
|
};
|
|
113
124
|
|
|
114
125
|
export async function runGoalControl(ctx, sessionId, rawArgs = {}) {
|
|
@@ -146,7 +157,9 @@ export async function runGoalControl(ctx, sessionId, rawArgs = {}) {
|
|
|
146
157
|
throw new Error('Goal changed while editing; reopen the editor before saving');
|
|
147
158
|
}
|
|
148
159
|
const at = ctx.now();
|
|
149
|
-
if (goal.status === 'stopped'
|
|
160
|
+
if (goal.status === 'stopped' && action !== 'dismiss') {
|
|
161
|
+
throw new Error('a stopped Goal cannot be changed; create a new Goal');
|
|
162
|
+
}
|
|
150
163
|
const handler = GOAL_CONTROL_ACTIONS[action];
|
|
151
164
|
if (!handler) throw new Error(`unknown Goal action: ${action}`);
|
|
152
165
|
return handler(ctx, { id, goal, args, at, expectedGoalId, action });
|
|
@@ -6,6 +6,7 @@ import { clean, hasOwn } from './session-text.mjs';
|
|
|
6
6
|
import { modelSupportsServiceTier } from '../providers/model-service-tiers.mjs';
|
|
7
7
|
import { openAiDirectSupportsFast, openAiDirectSupportsUltrafast } from '../providers/openai-direct-request.mjs';
|
|
8
8
|
import { supportsAnthropicFastMode } from '../../../shared/llm/anthropic-betas.mjs';
|
|
9
|
+
import { normalizeContextTokens } from '../../../shared/llm/default-context-window.mjs';
|
|
9
10
|
|
|
10
11
|
const FAST_CAPABLE_PROVIDERS = new Set([
|
|
11
12
|
'anthropic',
|
|
@@ -123,6 +124,11 @@ export function saveModelSettings(cfgMod, route, { fastCapable = true, baseConfi
|
|
|
123
124
|
else delete nextSetting.effort;
|
|
124
125
|
if (fastCapable) nextSetting.fast = route.fast === true;
|
|
125
126
|
else nextSetting.fast = false;
|
|
127
|
+
// Auto effort is on unless turned off: only the off state is stored.
|
|
128
|
+
if (hasOwn(route, 'autoEffort')) {
|
|
129
|
+
if (route.autoEffort === false) nextSetting.autoEffort = false;
|
|
130
|
+
else delete nextSetting.autoEffort;
|
|
131
|
+
}
|
|
126
132
|
if (route.modelParameters && typeof route.modelParameters === 'object') {
|
|
127
133
|
nextSetting.modelParameters = Object.fromEntries(
|
|
128
134
|
Object.entries(route.modelParameters)
|
|
@@ -136,13 +142,22 @@ export function saveModelSettings(cfgMod, route, { fastCapable = true, baseConfi
|
|
|
136
142
|
// pickers send the default stop with every selection; storing it froze each
|
|
137
143
|
// model at whatever its default was that day, so a later default never
|
|
138
144
|
// reached anyone who had already selected the model.
|
|
145
|
+
// An exact window in tokens replaces the percentage, and a percentage
|
|
146
|
+
// replaces it. A token selection at the default window reaches here already
|
|
147
|
+
// dropped (resolveRouteContextState answers no contextTokens for it).
|
|
148
|
+
const contextTokens = normalizeContextTokens(route.contextTokens);
|
|
139
149
|
const requestedPercent = Number(route.contextPercent);
|
|
140
150
|
const contextPercent = Math.round(requestedPercent / 10) * 10;
|
|
141
151
|
const isDefault = contextPercent === Number(route.contextDefaultPercent);
|
|
142
|
-
if (
|
|
152
|
+
if (contextTokens) {
|
|
153
|
+
nextSetting.contextTokens = contextTokens;
|
|
154
|
+
delete nextSetting.contextPercent;
|
|
155
|
+
} else if (requestedPercent >= 10 && requestedPercent <= 100 && !isDefault) {
|
|
143
156
|
nextSetting.contextPercent = contextPercent;
|
|
157
|
+
delete nextSetting.contextTokens;
|
|
144
158
|
} else {
|
|
145
159
|
delete nextSetting.contextPercent;
|
|
160
|
+
delete nextSetting.contextTokens;
|
|
146
161
|
}
|
|
147
162
|
modelSettings[key] = nextSetting;
|
|
148
163
|
|