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
|
@@ -12,10 +12,14 @@ import {
|
|
|
12
12
|
unlinkSync,
|
|
13
13
|
writeFileSync,
|
|
14
14
|
} from 'node:fs';
|
|
15
|
-
import {
|
|
15
|
+
import { join, relative, sep } from 'node:path';
|
|
16
16
|
import { clean } from './session-text.mjs';
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import {
|
|
18
|
+
PLUGIN_MANIFEST_FILES,
|
|
19
|
+
pluginManifest,
|
|
20
|
+
pluginSkillsRoots,
|
|
21
|
+
resolveContainedPluginPath,
|
|
22
|
+
} from '../../../shared/plugin-manifest.mjs';
|
|
19
23
|
import { isPlainObject } from '../../../shared/object.mjs';
|
|
20
24
|
|
|
21
25
|
const MCP_TRANSPORT_FIELDS = new Set([
|
|
@@ -33,9 +37,20 @@ const MCP_TRANSPORT_FIELDS = new Set([
|
|
|
33
37
|
'autoDetect',
|
|
34
38
|
]);
|
|
35
39
|
|
|
40
|
+
// Every spelling resolveMcpStartupTimeoutMs / resolveMcpCallTimeoutMs reads.
|
|
41
|
+
// A newly supplied value must replace the whole group, or a stale alias that
|
|
42
|
+
// the resolver prefers would keep winning.
|
|
43
|
+
export const MCP_TIMEOUT_FIELD_GROUPS = [
|
|
44
|
+
['startupTimeoutMs', 'startup_timeout_ms', 'startupTimeoutSec', 'startup_timeout_sec'],
|
|
45
|
+
['timeoutMs', 'timeout_ms', 'callTimeoutMs', 'call_timeout_ms'],
|
|
46
|
+
];
|
|
47
|
+
|
|
36
48
|
export function mergeMcpServerConfig(existing, next) {
|
|
37
49
|
const merged = isPlainObject(existing) ? { ...existing } : {};
|
|
38
50
|
for (const field of MCP_TRANSPORT_FIELDS) delete merged[field];
|
|
51
|
+
for (const group of MCP_TIMEOUT_FIELD_GROUPS) {
|
|
52
|
+
if (group.some((field) => Object.hasOwn(next, field))) for (const field of group) delete merged[field];
|
|
53
|
+
}
|
|
39
54
|
return { ...merged, ...next };
|
|
40
55
|
}
|
|
41
56
|
|
|
@@ -127,17 +142,15 @@ export function saveProjectMcpServer(cwd, { originalName = '', name, config }) {
|
|
|
127
142
|
// discovery and this status surface read the same roots.
|
|
128
143
|
export { pluginManifest, resolveContainedPluginPath };
|
|
129
144
|
|
|
130
|
-
function mcpServersMapFromJson(raw) {
|
|
131
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;
|
|
132
|
-
if (isPlainObject(raw.mcpServers)) return raw.mcpServers;
|
|
133
|
-
return raw;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
145
|
function isSkillMdFile(name) {
|
|
137
146
|
return /^(SKILL|skill)\.md$/i.test(name);
|
|
138
147
|
}
|
|
139
148
|
|
|
140
|
-
const
|
|
149
|
+
const PLUGIN_MANIFEST_FORMATS = {
|
|
150
|
+
'.codex-plugin/plugin.json': 'codex',
|
|
151
|
+
'plugin.json': 'mixdog',
|
|
152
|
+
'.claude-plugin/plugin.json': 'claude',
|
|
153
|
+
};
|
|
141
154
|
|
|
142
155
|
export function countSkillFiles(root) {
|
|
143
156
|
let count = 0;
|
|
@@ -166,102 +179,283 @@ export function countSkillFiles(root) {
|
|
|
166
179
|
return count;
|
|
167
180
|
}
|
|
168
181
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
176
|
-
} else if (isPlainObject(mcp)) {
|
|
177
|
-
const keys = Object.keys(mcp).filter((k) => isPlainObject(mcp[k]));
|
|
178
|
-
if (keys.length) return { mcpScript: null, mcpInline: true };
|
|
182
|
+
const MCP_STDIO_TYPES = new Set(['stdio']);
|
|
183
|
+
const MCP_URL_TYPES = new Set(['http', 'streamable-http', 'sse', 'ws']);
|
|
184
|
+
|
|
185
|
+
function manifestFormat(root) {
|
|
186
|
+
for (const rel of PLUGIN_MANIFEST_FILES) {
|
|
187
|
+
const path = join(root, ...rel.split('/'));
|
|
188
|
+
if (existsSync(path)) return { path, format: PLUGIN_MANIFEST_FORMATS[rel] };
|
|
179
189
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Transport a declared server asks for, inferred the way the MCP client does
|
|
194
|
+
* when `type` is absent: `transport: "http"` or a `url` -> http, else stdio.
|
|
195
|
+
* Null for an unrecognized explicit type. */
|
|
196
|
+
export function declaredMcpTransport(config) {
|
|
197
|
+
if (config?.type !== undefined && config?.type !== null && config?.type !== '') {
|
|
198
|
+
if (typeof config.type !== 'string') return null;
|
|
199
|
+
const type = config.type.toLowerCase();
|
|
200
|
+
if (type === 'streamablehttp') return 'streamable-http';
|
|
201
|
+
return MCP_STDIO_TYPES.has(type) || MCP_URL_TYPES.has(type) ? type : null;
|
|
184
202
|
}
|
|
185
|
-
|
|
203
|
+
if (config?.transport === 'http') return 'http';
|
|
204
|
+
if (config?.command !== undefined) return 'stdio';
|
|
205
|
+
if (config?.url !== undefined) return 'http';
|
|
206
|
+
return 'stdio';
|
|
186
207
|
}
|
|
187
208
|
|
|
188
|
-
|
|
189
|
-
|
|
209
|
+
// One server entry -> a message when it cannot be launched, else null. Messages
|
|
210
|
+
// name fields and expected types only, never a configured value.
|
|
211
|
+
function mcpServerProblem(config) {
|
|
212
|
+
if (!isPlainObject(config)) return 'server entry must be an object';
|
|
213
|
+
const type = declaredMcpTransport(config);
|
|
214
|
+
if (!type) return '"type" must be one of stdio, http, streamable-http, sse, ws';
|
|
215
|
+
if (MCP_STDIO_TYPES.has(type)) {
|
|
216
|
+
return typeof config.command === 'string' && config.command.trim() ? null : 'stdio server requires "command"';
|
|
217
|
+
}
|
|
218
|
+
return typeof config.url === 'string' && config.url.trim() ? null : `${type} server requires "url"`;
|
|
190
219
|
}
|
|
191
220
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
if (
|
|
198
|
-
|
|
221
|
+
// A JSON parse failure as a location only: engines may quote the offending
|
|
222
|
+
// source text, which can hold credentials.
|
|
223
|
+
function jsonErrorMessage(error) {
|
|
224
|
+
const text = String(error?.message || '');
|
|
225
|
+
const lineColumn = /line (\d+) column (\d+)/.exec(text);
|
|
226
|
+
if (lineColumn) return `invalid JSON at line ${lineColumn[1]} column ${lineColumn[2]}`;
|
|
227
|
+
const position = /position (\d+)/.exec(text);
|
|
228
|
+
if (position) return `invalid JSON at position ${position[1]}`;
|
|
229
|
+
return /end of (JSON|data) input/i.test(text) ? 'invalid JSON: unexpected end of input' : 'invalid JSON';
|
|
199
230
|
}
|
|
200
231
|
|
|
201
|
-
function
|
|
202
|
-
|
|
203
|
-
|
|
232
|
+
function readJsonFile(path, errors) {
|
|
233
|
+
let text;
|
|
234
|
+
try {
|
|
235
|
+
text = readFileSync(path, 'utf8');
|
|
236
|
+
} catch (error) {
|
|
237
|
+
errors.push({ source: path, message: `cannot read file${error?.code ? ` (${error.code})` : ''}` });
|
|
238
|
+
return { ok: false };
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
return { ok: true, value: JSON.parse(text) };
|
|
242
|
+
} catch (error) {
|
|
243
|
+
errors.push({ source: path, message: jsonErrorMessage(error) });
|
|
244
|
+
return { ok: false };
|
|
245
|
+
}
|
|
204
246
|
}
|
|
205
247
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
248
|
+
// A `{ mcpServers: {...} }` wrapper or a bare server map -> the server map.
|
|
249
|
+
function mcpServerMap(doc, source, errors, where = '') {
|
|
250
|
+
if (!isPlainObject(doc)) {
|
|
251
|
+
errors.push({ source, message: `${where}MCP declaration must be an object` });
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
if (!Object.hasOwn(doc, 'mcpServers')) return doc;
|
|
255
|
+
if (!isPlainObject(doc.mcpServers)) {
|
|
256
|
+
errors.push({ source, message: `${where}"mcpServers" must be an object` });
|
|
257
|
+
return null;
|
|
213
258
|
}
|
|
214
|
-
return
|
|
259
|
+
return doc.mcpServers;
|
|
215
260
|
}
|
|
216
261
|
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
} else {
|
|
223
|
-
out.cwd = root;
|
|
262
|
+
function collectMcpServers(map, source, into, errors) {
|
|
263
|
+
for (const [key, config] of Object.entries(map)) {
|
|
264
|
+
const problem = mcpServerProblem(config);
|
|
265
|
+
if (problem) errors.push({ source, key, message: problem });
|
|
266
|
+
else into.set(key, { key, config, source });
|
|
224
267
|
}
|
|
225
|
-
return out;
|
|
226
268
|
}
|
|
227
269
|
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
if (!
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
270
|
+
function loadMcpJsonFile(path, into, errors) {
|
|
271
|
+
const read = readJsonFile(path, errors);
|
|
272
|
+
if (!read.ok) return;
|
|
273
|
+
const map = mcpServerMap(read.value, path, errors);
|
|
274
|
+
if (map) collectMcpServers(map, path, into, errors);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// `where` locates the manifest field (e.g. `mcpServers[1]: `); the declared
|
|
278
|
+
// path itself is never echoed.
|
|
279
|
+
function loadDeclaredPath(root, rel, manifestPath, into, errors, touched, where) {
|
|
280
|
+
if (typeof rel !== 'string' || !rel.trim()) {
|
|
281
|
+
errors.push({ source: manifestPath, message: `${where}MCP path must be a non-empty string` });
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const abs = resolveContainedPluginPath(root, rel);
|
|
285
|
+
if (!abs || rel.split(/[\\/]/).includes('..')) {
|
|
286
|
+
errors.push({ source: manifestPath, message: `${where}MCP path must be relative and stay inside the plugin root` });
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
touched.add(abs);
|
|
290
|
+
if (!existsSync(abs)) {
|
|
291
|
+
errors.push({ source: manifestPath, message: `${where}MCP file not found` });
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
loadMcpJsonFile(abs, into, errors);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function readPluginMcpDeclarations(root, touched) {
|
|
298
|
+
const errors = [];
|
|
299
|
+
const into = new Map();
|
|
300
|
+
for (const rel of PLUGIN_MANIFEST_FILES) touched.add(join(root, ...rel.split('/')));
|
|
301
|
+
const found = manifestFormat(root);
|
|
302
|
+
const mcpJson = join(root, '.mcp.json');
|
|
303
|
+
touched.add(mcpJson);
|
|
304
|
+
const hasMcpJson = existsSync(mcpJson);
|
|
305
|
+
let format = 'none';
|
|
306
|
+
if (found) format = found.format;
|
|
307
|
+
else if (hasMcpJson) format = 'claude';
|
|
308
|
+
|
|
309
|
+
if (hasMcpJson) loadMcpJsonFile(mcpJson, into, errors);
|
|
310
|
+
|
|
311
|
+
let declaredRef;
|
|
312
|
+
if (found) {
|
|
313
|
+
const read = readJsonFile(found.path, errors);
|
|
314
|
+
const declared = read.ok && isPlainObject(read.value) ? read.value.mcpServers : undefined;
|
|
315
|
+
declaredRef = declared;
|
|
316
|
+
if (declared === undefined) {
|
|
317
|
+
/* nothing declared */
|
|
318
|
+
} else if (typeof declared === 'string') {
|
|
319
|
+
loadDeclaredPath(root, declared, found.path, into, errors, touched, '"mcpServers": ');
|
|
320
|
+
} else if (Array.isArray(declared)) {
|
|
321
|
+
// Members merge in order: a path to a JSON file, or an inline server
|
|
322
|
+
// map (bare or `{ mcpServers }`-wrapped).
|
|
323
|
+
declared.forEach((entry, index) => {
|
|
324
|
+
const where = `"mcpServers"[${index}]: `;
|
|
325
|
+
if (isPlainObject(entry)) {
|
|
326
|
+
const map = mcpServerMap(entry, found.path, errors, where);
|
|
327
|
+
if (map) collectMcpServers(map, found.path, into, errors);
|
|
328
|
+
} else {
|
|
329
|
+
loadDeclaredPath(root, entry, found.path, into, errors, touched, where);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
} else if (isPlainObject(declared)) {
|
|
333
|
+
const map = mcpServerMap(declared, found.path, errors);
|
|
334
|
+
if (map) collectMcpServers(map, found.path, into, errors);
|
|
335
|
+
} else {
|
|
336
|
+
errors.push({ source: found.path, message: '"mcpServers" must be a path, a list, or an object' });
|
|
236
337
|
}
|
|
237
|
-
const keys = Object.keys(rawServers).filter((k) => isPlainObject(rawServers[k]));
|
|
238
|
-
if (!keys.length) throw new Error('plugin.json has no mcpServers');
|
|
239
|
-
return { rawServers, mcpRoot: root };
|
|
240
338
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
339
|
+
const declaredPath = typeof declaredRef === 'string' ? declaredRef : null;
|
|
340
|
+
return { format, servers: [...into.values()], errors, declaredPath };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Parsed declarations per plugin root, valid while every file the parse looked
|
|
344
|
+
// at (present or absent) still has the same identity, size and timestamps.
|
|
345
|
+
const DECLARATION_CACHE_MAX = 256;
|
|
346
|
+
const declarationCache = new Map();
|
|
347
|
+
const declarationCacheStats = { hits: 0, misses: 0 };
|
|
348
|
+
|
|
349
|
+
function fileStamp(path) {
|
|
350
|
+
try {
|
|
351
|
+
const st = statSync(path, { bigint: true });
|
|
352
|
+
return `${st.ino}:${st.size}:${st.mtimeNs}:${st.ctimeNs}`;
|
|
353
|
+
} catch {
|
|
354
|
+
return '-';
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function copyDeclarations(result) {
|
|
359
|
+
return {
|
|
360
|
+
format: result.format,
|
|
361
|
+
servers: result.servers.map((server) => ({ ...server, config: structuredClone(server.config) })),
|
|
362
|
+
errors: result.errors.map((error) => ({ ...error })),
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/** What a plugin declares for MCP, read raw: `<root>/.mcp.json` first, then the
|
|
367
|
+
* manifest `mcpServers` (a path, an inline object, or a list mixing both).
|
|
368
|
+
* Later sources override earlier ones by key. Never throws for plugin
|
|
369
|
+
* content; errors carry locations and field names, never values. Unchanged
|
|
370
|
+
* declaration files are not parsed again. */
|
|
371
|
+
export function loadPluginMcpDeclarations(root) {
|
|
372
|
+
return copyDeclarations(cachedDeclarations(root));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function cachedDeclarations(root) {
|
|
376
|
+
const key = String(root || '');
|
|
377
|
+
const cached = declarationCache.get(key);
|
|
378
|
+
if (cached?.signature.every(([path, stamp]) => fileStamp(path) === stamp)) {
|
|
379
|
+
declarationCacheStats.hits += 1;
|
|
380
|
+
return cached.result;
|
|
245
381
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
382
|
+
declarationCacheStats.misses += 1;
|
|
383
|
+
// Stamps are taken before reading, so a write racing the parse invalidates.
|
|
384
|
+
const before = new Map();
|
|
385
|
+
const result = readPluginMcpDeclarations(root, {
|
|
386
|
+
add(path) {
|
|
387
|
+
if (!before.has(path)) before.set(path, fileStamp(path));
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
declarationCache.delete(key);
|
|
391
|
+
declarationCache.set(key, { signature: [...before], result });
|
|
392
|
+
if (declarationCache.size > DECLARATION_CACHE_MAX) declarationCache.delete(declarationCache.keys().next().value);
|
|
393
|
+
return result;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Test seam: cache hit/miss counters. */
|
|
397
|
+
export function pluginMcpDeclarationCacheStats() {
|
|
398
|
+
return { ...declarationCacheStats };
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Adapter: where the declarations live, in the shape older callers expect.
|
|
402
|
+
export function discoverPluginMcp(root) {
|
|
403
|
+
const { servers, declaredPath } = cachedDeclarations(root);
|
|
404
|
+
if (!servers.length) return { mcpScript: null, mcpInline: false };
|
|
405
|
+
const inline = servers.some((s) => PLUGIN_MANIFEST_FILES.some((rel) => s.source === join(root, ...rel.split('/'))));
|
|
406
|
+
if (inline) return { mcpScript: null, mcpInline: true };
|
|
407
|
+
if (declaredPath?.trim()) {
|
|
408
|
+
const abs = resolveContainedPluginPath(root, declaredPath);
|
|
409
|
+
if (servers.some((s) => s.source === abs)) return { mcpScript: declaredPath.trim(), mcpInline: false };
|
|
249
410
|
}
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
return {
|
|
411
|
+
const mcpJson = join(root, '.mcp.json');
|
|
412
|
+
const declaredFile = servers.find((s) => s.source !== mcpJson) || servers[0];
|
|
413
|
+
return { mcpScript: relative(root, declaredFile.source).split(sep).join('/'), mcpInline: false };
|
|
253
414
|
}
|
|
254
415
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
416
|
+
// User intent for plugin-declared servers, stored apart from the declarations
|
|
417
|
+
// as `pluginMcp[pluginId][declaredKey]`: `enabled: false`, a kept `alias`
|
|
418
|
+
// name, and connection overrides layered over the declaration.
|
|
419
|
+
export const PLUGIN_MCP_OVERRIDE_MAP_FIELDS = Object.freeze(['env', 'headers', 'env_http_headers']);
|
|
420
|
+
export const PLUGIN_MCP_OVERRIDE_VALUE_FIELDS = Object.freeze([
|
|
421
|
+
'command',
|
|
422
|
+
'args',
|
|
423
|
+
'url',
|
|
424
|
+
'bearer_token_env_var',
|
|
425
|
+
'env_vars',
|
|
426
|
+
...MCP_TIMEOUT_FIELD_GROUPS.flat(),
|
|
427
|
+
]);
|
|
428
|
+
|
|
429
|
+
function normalizePluginMcpIntent(value) {
|
|
430
|
+
if (!isPlainObject(value)) return null;
|
|
431
|
+
const out = {};
|
|
432
|
+
// `enabled: true` is kept too: it turns on a server declared `enabled: false`.
|
|
433
|
+
if (typeof value.enabled === 'boolean') out.enabled = value.enabled;
|
|
434
|
+
if (typeof value.alias === 'string' && value.alias.trim()) out.alias = value.alias.trim();
|
|
435
|
+
for (const field of PLUGIN_MCP_OVERRIDE_MAP_FIELDS) {
|
|
436
|
+
if (!isPlainObject(value[field])) continue;
|
|
437
|
+
const map = Object.fromEntries(Object.entries(value[field]).filter(([, v]) => v !== null && v !== undefined));
|
|
438
|
+
if (Object.keys(map).length) out[field] = map;
|
|
439
|
+
}
|
|
440
|
+
for (const field of PLUGIN_MCP_OVERRIDE_VALUE_FIELDS) {
|
|
441
|
+
if (value[field] !== undefined && value[field] !== null) out[field] = value[field];
|
|
442
|
+
}
|
|
443
|
+
return Object.keys(out).length ? out : null;
|
|
259
444
|
}
|
|
260
445
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
446
|
+
/** `{ [pluginId]: { [declaredKey]: intent } }` with empty records dropped. */
|
|
447
|
+
export function normalizePluginMcpIntents(value) {
|
|
448
|
+
const out = {};
|
|
449
|
+
if (!isPlainObject(value)) return out;
|
|
450
|
+
for (const [pluginId, servers] of Object.entries(value)) {
|
|
451
|
+
const id = clean(pluginId);
|
|
452
|
+
if (!id || !isPlainObject(servers)) continue;
|
|
453
|
+
const kept = {};
|
|
454
|
+
for (const [key, intent] of Object.entries(servers)) {
|
|
455
|
+
const normalized = normalizePluginMcpIntent(intent);
|
|
456
|
+
if (key && normalized) kept[key] = normalized;
|
|
457
|
+
}
|
|
458
|
+
if (Object.keys(kept).length) out[id] = kept;
|
|
459
|
+
}
|
|
460
|
+
return out;
|
|
267
461
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// definitions out of the eager prefix; selection never changes permission policy.
|
|
3
3
|
import { deferredCatalogUnion, selectDeferredTools, toolSearchNativePayload } from './tool-catalog.mjs';
|
|
4
4
|
import { preDispatchDenyForSession } from '../session/loop/pre-dispatch-deny.mjs';
|
|
5
|
+
import { parseMcpToolName } from '../../../shared/tool-primitives.mjs';
|
|
5
6
|
|
|
6
7
|
export function loadSkillToolDependencies(envelope, session, mode) {
|
|
7
8
|
if (!envelope?.__toolEnvelope) return envelope;
|
|
@@ -15,7 +16,9 @@ export function loadSkillToolDependencies(envelope, session, mode) {
|
|
|
15
16
|
for (const { type, value } of dependencies) {
|
|
16
17
|
if (type === 'tool') names.add(value);
|
|
17
18
|
else if (type === 'mcp') {
|
|
18
|
-
const matches = [...catalog.
|
|
19
|
+
const matches = [...catalog.values()]
|
|
20
|
+
.filter((tool) => parseMcpToolName(tool)?.server === value)
|
|
21
|
+
.map((tool) => tool.name);
|
|
19
22
|
if (matches.length)
|
|
20
23
|
matches.forEach((name) => {
|
|
21
24
|
names.add(name);
|
|
@@ -145,11 +145,32 @@ export function sortedCatalogByMeasuredUsage(catalog) {
|
|
|
145
145
|
.map((entry) => entry.tool);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
const IMMUTABLE_SURFACE_TOOLS = new WeakSet();
|
|
149
|
+
|
|
150
|
+
function deepFreeze(value) {
|
|
151
|
+
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
|
|
152
|
+
Object.freeze(value);
|
|
153
|
+
for (const key of Object.keys(value)) deepFreeze(value[key]);
|
|
154
|
+
}
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
|
|
148
158
|
export function activeToolForSurface(tool) {
|
|
149
159
|
if (!tool || typeof tool !== 'object') return tool;
|
|
160
|
+
if (IMMUTABLE_SURFACE_TOOLS.has(tool)) return tool;
|
|
150
161
|
return JSON.parse(JSON.stringify(tool));
|
|
151
162
|
}
|
|
152
163
|
|
|
164
|
+
// Clone once into a deep-frozen definition that activeToolForSurface passes
|
|
165
|
+
// through without re-cloning. Safe to share: it can never be mutated in place.
|
|
166
|
+
export function immutableToolForSurface(tool) {
|
|
167
|
+
if (!tool || typeof tool !== 'object') return tool;
|
|
168
|
+
if (IMMUTABLE_SURFACE_TOOLS.has(tool)) return tool;
|
|
169
|
+
const frozen = deepFreeze(JSON.parse(JSON.stringify(tool)));
|
|
170
|
+
IMMUTABLE_SURFACE_TOOLS.add(frozen);
|
|
171
|
+
return frozen;
|
|
172
|
+
}
|
|
173
|
+
|
|
153
174
|
export function deferredProviderMode(provider) {
|
|
154
175
|
const p = clean(provider).toLowerCase();
|
|
155
176
|
if (p === 'gemini') return 'manifest';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { clean } from './session-text.mjs';
|
|
5
5
|
import { mergePendingDeferredToolDelta } from './deferred-tool-delta.mjs';
|
|
6
6
|
import { applyInitialDeferredToolManifestToBp2, stripDeferredToolManifestBlock } from '../context/collect.mjs';
|
|
7
|
-
import { getMcpServerInstructionsMap, getMcpTools } from '../mcp/client.mjs';
|
|
7
|
+
import { getMcpServerInstructionsMap, getMcpTools, getMcpToolGeneration } from '../mcp/client.mjs';
|
|
8
8
|
import { filterMcpToolsForSession } from './extension-scopes.mjs';
|
|
9
9
|
import { isDeferredToolAvailable } from './deferred-tool-availability.mjs';
|
|
10
10
|
import { isResponsesFreeformTool, toResponsesCustomTool } from '../providers/custom-tool-wire.mjs';
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
routeToolRank,
|
|
24
24
|
sortedCatalogByMeasuredUsage,
|
|
25
25
|
activeToolForSurface,
|
|
26
|
+
immutableToolForSurface,
|
|
26
27
|
deferredProviderMode,
|
|
27
28
|
nativeProviderFamily,
|
|
28
29
|
} from './tool-catalog-schema.mjs';
|
|
@@ -464,6 +465,56 @@ export function refreshInitialDeferredMcpSurface(session, liveMcpTools) {
|
|
|
464
465
|
*/
|
|
465
466
|
export function reconcileDeferredMcpToolCatalog(session, liveMcpTools) {
|
|
466
467
|
if (!session || !Array.isArray(session.tools)) return null;
|
|
468
|
+
const cached = RECONCILE_STATE.get(session);
|
|
469
|
+
if (cached && reconcileStateMatches(cached, reconcileStateOf(session, liveMcpTools))) return null;
|
|
470
|
+
const result = reconcileDeferredMcpToolCatalogUncached(session, liveMcpTools);
|
|
471
|
+
RECONCILE_STATE.set(session, reconcileStateOf(session, liveMcpTools));
|
|
472
|
+
return result;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Last reconciled inputs per session. A matching state means the surface that
|
|
476
|
+
// reconciliation would rebuild is identical, so it is skipped outright.
|
|
477
|
+
const RECONCILE_STATE = new WeakMap();
|
|
478
|
+
const LIVE_CLONES = new WeakMap();
|
|
479
|
+
|
|
480
|
+
function liveToolClone(tool) {
|
|
481
|
+
if (!tool || typeof tool !== 'object') return tool;
|
|
482
|
+
const generation = getMcpToolGeneration();
|
|
483
|
+
const hit = LIVE_CLONES.get(tool);
|
|
484
|
+
if (hit && hit.generation === generation) return hit.clone;
|
|
485
|
+
const clone = immutableToolForSurface(tool);
|
|
486
|
+
LIVE_CLONES.set(tool, { generation, clone });
|
|
487
|
+
return clone;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function reconcileStateOf(session, liveMcpTools) {
|
|
491
|
+
return {
|
|
492
|
+
generation: getMcpToolGeneration(),
|
|
493
|
+
live: Array.isArray(liveMcpTools) ? liveMcpTools.slice() : [],
|
|
494
|
+
tools: session.tools.slice(),
|
|
495
|
+
lateCatalog: session.deferredLateToolCatalog,
|
|
496
|
+
scope: clean(session.mcpScopeId),
|
|
497
|
+
cwd: clean(session.cwd),
|
|
498
|
+
mode: clean(session.deferredSurfaceMode),
|
|
499
|
+
providerMode: clean(session.deferredProviderMode),
|
|
500
|
+
provider: clean(session.provider),
|
|
501
|
+
model: clean(session.model),
|
|
502
|
+
disallowed: JSON.stringify(session.disallowedTools || []),
|
|
503
|
+
callable: JSON.stringify(parseToolSelection(session.deferredCallableTools)),
|
|
504
|
+
discovered: JSON.stringify(parseToolSelection(session.deferredDiscoveredTools)),
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function reconcileStateMatches(a, b) {
|
|
509
|
+
for (const key of Object.keys(a)) {
|
|
510
|
+
if (key === 'live' || key === 'tools') {
|
|
511
|
+
if (a[key].length !== b[key].length || a[key].some((tool, i) => tool !== b[key][i])) return false;
|
|
512
|
+
} else if (a[key] !== b[key]) return false;
|
|
513
|
+
}
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function reconcileDeferredMcpToolCatalogUncached(session, liveMcpTools) {
|
|
467
518
|
const live = filterDisallowedTools(Array.isArray(liveMcpTools) ? liveMcpTools : [], session.disallowedTools);
|
|
468
519
|
const hadSnapshot = Array.isArray(session.deferredMcpToolNames);
|
|
469
520
|
const previousNames = new Set(
|
|
@@ -482,7 +533,7 @@ export function reconcileDeferredMcpToolCatalog(session, liveMcpTools) {
|
|
|
482
533
|
}
|
|
483
534
|
for (const tool of live) {
|
|
484
535
|
const name = clean(tool?.name);
|
|
485
|
-
if (name && isMcpToolName(name)) byName.set(name,
|
|
536
|
+
if (name && isMcpToolName(name)) byName.set(name, liveToolClone(tool));
|
|
486
537
|
}
|
|
487
538
|
const catalog = sortedCatalogByMeasuredUsage([...byName.values()]);
|
|
488
539
|
const next = catalog.filter((tool) => session.deferredSurfaceMode !== 'readonly' || isReadonlySelectable(tool));
|
|
@@ -505,7 +556,7 @@ export function reconcileDeferredMcpToolCatalog(session, liveMcpTools) {
|
|
|
505
556
|
for (const tool of live) {
|
|
506
557
|
const name = clean(tool?.name);
|
|
507
558
|
if (!name || !isMcpToolName(name) || liveMcpByName.has(name)) continue;
|
|
508
|
-
liveMcpByName.set(name,
|
|
559
|
+
liveMcpByName.set(name, liveToolClone(tool));
|
|
509
560
|
}
|
|
510
561
|
|
|
511
562
|
// Rebuild the LATE pool only (boot catalog stays frozen). It holds live MCP
|
|
@@ -40,17 +40,21 @@ export const CWD_TOOL = {
|
|
|
40
40
|
},
|
|
41
41
|
trigger: 'Show or switch the active Project; not a shell-local cd.',
|
|
42
42
|
description:
|
|
43
|
-
'Show or switch the active Project. list returns the registered projects (name, path); a project name instead of a path → list first, then set the matching path, ask only if several match. path must be an existing directory. A shell-local cd does not change the Project.',
|
|
43
|
+
'Show or switch the active Project. list returns the registered projects (name, path); a project name instead of a path → list first, then set the matching path, ask only if several match. path must be an existing directory. A shell-local cd does not change the Project. merge-worktree / remove-worktree act on this session’s git worktree only when the user explicitly asks.',
|
|
44
44
|
inputSchema: {
|
|
45
45
|
type: 'object',
|
|
46
46
|
properties: {
|
|
47
47
|
action: {
|
|
48
48
|
type: 'string',
|
|
49
|
-
enum: ['get', 'set', 'list'],
|
|
49
|
+
enum: ['get', 'set', 'list', 'merge-worktree', 'remove-worktree', 'list-worktrees', 'prune-worktrees'],
|
|
50
50
|
description:
|
|
51
|
-
'get shows the active Project (default without path), set switches to path, list returns registered projects.',
|
|
51
|
+
'get shows the active Project (default without path), set switches to path, list returns registered projects; merge-worktree merges this session’s worktree into the project folder’s checked-out branch, remove-worktree deletes it (returning to the project folder; call again if it reports WORKTREE_REMOVAL_INCOMPLETE); list-worktrees lists every managed worktree and who retains it; prune-worktrees removes clean, merged ones no session retains.',
|
|
52
52
|
},
|
|
53
53
|
path: { type: 'string', description: 'Existing directory to switch to (implies action=set).' },
|
|
54
|
+
force: {
|
|
55
|
+
type: 'boolean',
|
|
56
|
+
description: 'remove-worktree: delete even with uncommitted or unmerged work (only when the user says so).',
|
|
57
|
+
},
|
|
54
58
|
},
|
|
55
59
|
additionalProperties: false,
|
|
56
60
|
},
|
|
@@ -93,6 +97,7 @@ const TERMINAL_RUNTIME_TOOLS = ['terminal'];
|
|
|
93
97
|
const OFFICE_RUNTIME_TOOLS = ['office'];
|
|
94
98
|
const MEDIA_RUNTIME_TOOLS = ['media'];
|
|
95
99
|
const TIDY_RUNTIME_TOOLS = ['tidy'];
|
|
100
|
+
const VISUALIZE_RUNTIME_TOOLS = ['visualize'];
|
|
96
101
|
|
|
97
102
|
const admitted = (tools, names) => (tools || []).filter((tool) => names.includes(tool?.name));
|
|
98
103
|
|
|
@@ -114,6 +119,7 @@ export function collectStandaloneToolDefs({
|
|
|
114
119
|
officeToolDefs = [],
|
|
115
120
|
mediaToolDefs = [],
|
|
116
121
|
tidyToolDefs = [],
|
|
122
|
+
visualizeToolDefs = [],
|
|
117
123
|
setupToolDefs = [],
|
|
118
124
|
goalTools = [],
|
|
119
125
|
agentTools = [],
|
|
@@ -133,6 +139,7 @@ export function collectStandaloneToolDefs({
|
|
|
133
139
|
...admitted(officeToolDefs, OFFICE_RUNTIME_TOOLS),
|
|
134
140
|
...admitted(mediaToolDefs, MEDIA_RUNTIME_TOOLS),
|
|
135
141
|
...admitted(tidyToolDefs, TIDY_RUNTIME_TOOLS),
|
|
142
|
+
...admitted(visualizeToolDefs, VISUALIZE_RUNTIME_TOOLS),
|
|
136
143
|
...setupToolDefs,
|
|
137
144
|
...goalTools,
|
|
138
145
|
...agentTools,
|
|
@@ -6,6 +6,7 @@ import { clean } from './session-text.mjs';
|
|
|
6
6
|
import { normalizeEffortInput } from './effort.mjs';
|
|
7
7
|
import { isLikelyRawModelId } from './config-helpers.mjs';
|
|
8
8
|
import { configuredAgentRouteCandidates } from '../../../shared/agent-route-config.mjs';
|
|
9
|
+
import { normalizeContextTokens } from '../../../shared/llm/default-context-window.mjs';
|
|
9
10
|
import { normalizeAgentId, normalizeWorkflowId } from './workflow-ids.mjs';
|
|
10
11
|
import { createWorkflowPacks } from './workflow/packs.mjs';
|
|
11
12
|
import { createWorkflowAgents } from './workflow/agents.mjs';
|
|
@@ -186,19 +187,27 @@ export function normalizeWorkflowRoute(routeLike, fallback = {}) {
|
|
|
186
187
|
if (!isLikelyRawModelId(model)) return null;
|
|
187
188
|
const effort = normalizeEffortInput(routeLike?.effort ?? fallback.effort);
|
|
188
189
|
const fast = routeLike?.fast ?? fallback.fast;
|
|
190
|
+
// Absent means Auto effort is on; only the off state is carried.
|
|
191
|
+
const autoEffort = routeLike?.autoEffort ?? fallback.autoEffort;
|
|
189
192
|
const modelParameters = routeLike?.modelParameters ?? fallback.modelParameters;
|
|
190
193
|
const requestedPercent = Number(routeLike?.contextPercent ?? fallback.contextPercent);
|
|
191
194
|
const contextPercent =
|
|
192
195
|
Number.isFinite(requestedPercent) && requestedPercent >= 10 && requestedPercent <= 100
|
|
193
196
|
? Math.round(requestedPercent / 10) * 10
|
|
194
197
|
: null;
|
|
198
|
+
// A percent on the route replaces the fallback's exact window.
|
|
199
|
+
const contextTokens = normalizeContextTokens(
|
|
200
|
+
routeLike?.contextTokens ?? (routeLike?.contextPercent == null ? fallback.contextTokens : undefined)
|
|
201
|
+
);
|
|
195
202
|
return {
|
|
196
203
|
provider,
|
|
197
204
|
model,
|
|
198
205
|
...(effort ? { effort } : {}),
|
|
199
206
|
...(typeof fast === 'boolean' ? { fast } : {}),
|
|
207
|
+
...(autoEffort === false ? { autoEffort: false } : {}),
|
|
200
208
|
...(modelParameters && typeof modelParameters === 'object' ? { modelParameters: { ...modelParameters } } : {}),
|
|
201
209
|
...(contextPercent ? { contextPercent } : {}),
|
|
210
|
+
...(contextTokens ? { contextTokens } : {}),
|
|
202
211
|
};
|
|
203
212
|
}
|
|
204
213
|
|
|
@@ -214,6 +223,7 @@ export function upsertWorkflowPreset(presets, slot, routeLike) {
|
|
|
214
223
|
model: route.model,
|
|
215
224
|
...(route.effort ? { effort: route.effort } : {}),
|
|
216
225
|
...(route.fast === true ? { fast: true } : {}),
|
|
226
|
+
...(route.autoEffort === false ? { autoEffort: false } : {}),
|
|
217
227
|
...(route.modelParameters ? { modelParameters: route.modelParameters } : {}),
|
|
218
228
|
tools: 'full',
|
|
219
229
|
};
|