mixdog 1.1.1 → 1.2.0
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 +1 -0
- package/package.json +2 -2
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/release-paths.mjs +39 -2
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +6 -0
- package/src/defaults/skills/setup/references/actions.md +5 -2
- package/src/defaults/skills/visualize/SKILL.md +157 -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/headless-role.mjs +2 -2
- package/src/help.mjs +2 -0
- package/src/lib/rules-builder.cjs +0 -23
- package/src/rules/lead/LEAD.md +2 -2
- package/src/rules/shared/70-delivery.md +2 -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/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 +9 -1
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +47 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +51 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +25 -5
- package/src/runtime/agent/orchestrator/mcp/client.mjs +348 -122
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- 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 +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +12 -4
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- 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/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-channel.d.mts +67 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +521 -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 +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
- 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/registry.mjs +15 -1
- 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 +12 -11
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +11 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +11 -8
- 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/compact/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +18 -11
- 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/context-utils.mjs +12 -14
- 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 +2 -1
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +17 -7
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +5 -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/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 +1 -5
- 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 +29 -19
- package/src/runtime/agent/orchestrator/session/read-dedup.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -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-fields.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +28 -8
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +140 -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/read-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +31 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- 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 +80 -66
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +5 -1
- 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/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/trusted-roots.mjs +25 -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-command.mjs +0 -10
- package/src/runtime/attachments/store.mjs +38 -0
- package/src/runtime/channels/index.mjs +1 -5
- package/src/runtime/channels/lib/runtime-paths.mjs +8 -23
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -13
- package/src/runtime/channels/lib/worker-ipc.mjs +2 -2
- package/src/runtime/channels/lib/worker-main.mjs +4 -34
- package/src/runtime/shared/atomic-file.mjs +8 -2
- 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/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- 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 -118
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +156 -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/provider-accounts.mjs +2 -2
- package/src/runtime/shared/provider-api-key.mjs +21 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/semver.d.mts +1 -0
- package/src/runtime/shared/semver.mjs +57 -0
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
- package/src/runtime/shared/tool-surface.mjs +9 -2
- 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 +161 -11
- package/src/runtime/shared/update-checker.mjs +2 -31
- 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/boot/apis.mjs +35 -0
- package/src/session-runtime/boot/begin.mjs +0 -2
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +20 -0
- package/src/session-runtime/boot/infrastructure.mjs +1 -0
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +9 -4
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +11 -1
- 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 +11 -6
- package/src/session-runtime/mcp-glue/server-catalog.mjs +7 -3
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- 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/notification-bus.mjs +9 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- package/src/session-runtime/resource-extension-sync.mjs +30 -7
- package/src/session-runtime/resource-mcp-api.mjs +27 -10
- package/src/session-runtime/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-bootstrap.mjs +0 -4
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-paths.mjs +0 -1
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- 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-worker.mjs +1 -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/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-profile-api.mjs +27 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +11 -4
- package/src/session-runtime/setup-tool/settings-contract.mjs +3 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +31 -3
- package/src/session-runtime/starter-guide-state.mjs +62 -0
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +13 -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/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -2
- 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/standalone/channel-binding.mjs +1 -2
- package/src/standalone/channel-transport/call-dispatch.mjs +4 -10
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-channels-loader.mjs +2 -3
- 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 +4 -1
- package/src/standalone/daemon.mjs +139 -5
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +13 -78
- 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 +17 -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 +11 -3
- 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/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +35 -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/dist/index.mjs +332 -36
- 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/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 +12 -8
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +18 -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 +2 -0
- package/src/tui/session/session-api/shared.mjs +10 -6
- 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 +15 -1
- 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/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +39 -10
- package/src/runtime/channels/tool-defs.mjs +0 -17
|
@@ -30,6 +30,7 @@ const PROFILE_VALUE_IDS = Object.freeze({
|
|
|
30
30
|
const ACTION_APPLIES_TO = {
|
|
31
31
|
set_recap_enabled: 'background Memory cycles; no restart required',
|
|
32
32
|
set_auto_update: 'subsequent automatic update checks',
|
|
33
|
+
set_worktree_settings: 'new tasks and worktrees created afterwards; existing worktrees are unchanged',
|
|
33
34
|
set_system_shell: 'subsequent shell calls',
|
|
34
35
|
save_automation: 'the automation worker; scheduled runs follow the saved timing',
|
|
35
36
|
delete_automation: 'future automation runs',
|
|
@@ -93,6 +94,7 @@ function routeInput(source) {
|
|
|
93
94
|
if (typeof source.fast === 'boolean') next.fast = source.fast;
|
|
94
95
|
if (Object.hasOwn(source, 'modelParameters')) next.modelParameters = { ...source.modelParameters };
|
|
95
96
|
if (Object.hasOwn(source, 'contextPercent')) next.contextPercent = source.contextPercent;
|
|
97
|
+
if (Object.hasOwn(source, 'contextTokens')) next.contextTokens = source.contextTokens;
|
|
96
98
|
if (Object.hasOwn(source, 'disabled')) next.disabled = source.disabled;
|
|
97
99
|
return next;
|
|
98
100
|
}
|
|
@@ -178,6 +180,7 @@ const mainRoute = (rt) => ({
|
|
|
178
180
|
fastCapable: rt.fastCapable === true,
|
|
179
181
|
modelParameters: rt.modelParameters || {},
|
|
180
182
|
contextPercent: rt.contextPercent ?? null,
|
|
183
|
+
contextTokens: rt.contextTokens ?? null,
|
|
181
184
|
});
|
|
182
185
|
|
|
183
186
|
async function automationStatus(rt, { domain }) {
|
|
@@ -303,6 +306,7 @@ const SETUP_STATUS_READERS = {
|
|
|
303
306
|
plugins: (rt) => rt.pluginsStatus?.() || {},
|
|
304
307
|
update: (rt) => rt.getUpdateSettings?.() || {},
|
|
305
308
|
onboarding: (rt) => rt.getOnboardingStatus?.() || {},
|
|
309
|
+
worktree: (rt) => rt.getWorktreeSettings(),
|
|
306
310
|
schedules: automationStatus,
|
|
307
311
|
webhooks: automationStatus,
|
|
308
312
|
hooks: hookStatus,
|
|
@@ -328,11 +332,13 @@ function validateSetupInput(args) {
|
|
|
328
332
|
if (action !== 'set_agent_route' && Object.hasOwn(args.route, 'disabled')) {
|
|
329
333
|
throw new Error('route.disabled is only accepted by set_agent_route');
|
|
330
334
|
}
|
|
331
|
-
|
|
332
|
-
|
|
335
|
+
for (const field of ['contextPercent', 'contextTokens']) {
|
|
336
|
+
if (action !== 'set_route' && action !== 'set_agent_route' && Object.hasOwn(args.route, field)) {
|
|
337
|
+
throw new Error(`route.${field} is only accepted by set_route and set_agent_route`);
|
|
338
|
+
}
|
|
333
339
|
}
|
|
334
340
|
}
|
|
335
|
-
for (const field of ['desktop', 'appearance', 'webhook', 'compaction', 'providerAccount']) {
|
|
341
|
+
for (const field of ['desktop', 'appearance', 'webhook', 'compaction', 'providerAccount', 'worktree']) {
|
|
336
342
|
if (args[field] && !Object.keys(args[field]).length) throw new Error(`${field} requires at least one setting`);
|
|
337
343
|
}
|
|
338
344
|
return action;
|
|
@@ -507,6 +513,7 @@ const SETUP_ACTION_HANDLERS = {
|
|
|
507
513
|
rt.deleteLocalProviderModel(requireText(args.confirmationToken, 'confirmationToken')),
|
|
508
514
|
set_system_shell: (rt, args) => rt.setSystemShell({ command: clean(args.command) }),
|
|
509
515
|
set_auto_update: (rt, args) => rt.setAutoUpdate(requireBoolean(args.enabled)),
|
|
516
|
+
set_worktree_settings: (rt, args) => rt.setWorktreeSettings(args.worktree),
|
|
510
517
|
forget_provider_auth: async (rt, args) => {
|
|
511
518
|
const name = requireText(args.name, 'name');
|
|
512
519
|
const setup = await rt.getProviderSetup({});
|
|
@@ -541,7 +548,7 @@ const SETUP_ACTION_HANDLERS = {
|
|
|
541
548
|
set_mcp_enabled: async (rt, args) => ({
|
|
542
549
|
mcp: mcpRows(await rt.setMcpServerEnabled(requireText(args.name, 'name'), requireBoolean(args.enabled))),
|
|
543
550
|
}),
|
|
544
|
-
reconnect_mcp: async (rt) => ({ mcp: mcpRows(await rt.reconnectMcp()) }),
|
|
551
|
+
reconnect_mcp: async (rt, args) => ({ mcp: mcpRows(await rt.reconnectMcp(clean(args.name) || undefined)) }),
|
|
545
552
|
set_disabled_skills: (rt, args) => {
|
|
546
553
|
if (!Array.isArray(args.skills)) throw new Error('skills (array of names) is required');
|
|
547
554
|
return rt.setDisabledSkills(args.skills.map(clean).filter(Boolean));
|
|
@@ -108,6 +108,8 @@ export const SETUP_MCP_SCHEMA = object({
|
|
|
108
108
|
additionalProperties: removableText,
|
|
109
109
|
description: 'HTTP header names mapped to existing environment variable names.',
|
|
110
110
|
},
|
|
111
|
+
startupTimeoutSec: { type: 'number', description: 'Connect/handshake timeout in seconds (>0, default 30).' },
|
|
112
|
+
toolTimeoutSec: { type: 'number', description: 'Per tool-call timeout in seconds (>0, default 120).' },
|
|
111
113
|
});
|
|
112
114
|
|
|
113
115
|
export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
@@ -158,7 +160,7 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
158
160
|
model: {
|
|
159
161
|
...text,
|
|
160
162
|
description:
|
|
161
|
-
'Required for new schedules; no default-model fallback. Use provider/model[@effort][+fast][?parameter=value] or an existing preset name. On overwrite, omission preserves the saved model, which must be non-empty.',
|
|
163
|
+
'Required for new schedules; no default-model fallback. Use provider/model[@effort][+fast][+noauto][?parameter=value] (+noauto: Auto reasoning off; absent = on) or an existing preset name. On overwrite, omission preserves the saved model, which must be non-empty.',
|
|
162
164
|
},
|
|
163
165
|
cwd: text,
|
|
164
166
|
workflow: text,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from './settings-contract.mjs';
|
|
7
7
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
8
8
|
import { INSTRUCTION_FILES_MODES } from '../../runtime/shared/instruction-files-mode.mjs';
|
|
9
|
+
import { WORKTREE_NEW_TASK_DEFAULTS } from '../../runtime/shared/worktrees/settings.mjs';
|
|
9
10
|
|
|
10
11
|
/** Built-in `setup` tool: the model's handle on a Mixdog user's persisted
|
|
11
12
|
* configuration. The description is a contract only; how to use each action
|
|
@@ -31,6 +32,7 @@ export const SETUP_STATUS_DOMAINS = Object.freeze([
|
|
|
31
32
|
'plugins',
|
|
32
33
|
'update',
|
|
33
34
|
'onboarding',
|
|
35
|
+
'worktree',
|
|
34
36
|
...SETUP_EXTENDED_DOMAINS,
|
|
35
37
|
]);
|
|
36
38
|
|
|
@@ -100,7 +102,7 @@ export const SETUP_ACTION_FIELDS = Object.freeze({
|
|
|
100
102
|
save_mcp_server: 'server',
|
|
101
103
|
remove_mcp_server: 'name',
|
|
102
104
|
set_mcp_enabled: 'name enabled',
|
|
103
|
-
reconnect_mcp: '',
|
|
105
|
+
reconnect_mcp: 'name?',
|
|
104
106
|
set_disabled_skills: 'skills',
|
|
105
107
|
set_extension_scope: 'kind name projects',
|
|
106
108
|
add_plugin: 'source',
|
|
@@ -108,6 +110,7 @@ export const SETUP_ACTION_FIELDS = Object.freeze({
|
|
|
108
110
|
set_plugin_enabled: 'name enabled',
|
|
109
111
|
remove_plugin: 'name',
|
|
110
112
|
enable_plugin_mcp: 'name',
|
|
113
|
+
set_worktree_settings: 'worktree',
|
|
111
114
|
...SETUP_EXTENDED_ACTION_FIELDS,
|
|
112
115
|
});
|
|
113
116
|
|
|
@@ -122,6 +125,7 @@ export const SETUP_BUILTIN_TOGGLE_FEATURES = Object.freeze([
|
|
|
122
125
|
'browser',
|
|
123
126
|
'computer',
|
|
124
127
|
'voice',
|
|
128
|
+
'visualize',
|
|
125
129
|
]);
|
|
126
130
|
|
|
127
131
|
const ROUTE_SCHEMA = {
|
|
@@ -136,6 +140,11 @@ const ROUTE_SCHEMA = {
|
|
|
136
140
|
// A typed enum is unrepresentable on Gemini; the bounds project everywhere
|
|
137
141
|
// and the executor rejects values that are not a multiple of 10.
|
|
138
142
|
contextPercent: { type: 'integer', minimum: 10, maximum: 100, description: 'A multiple of 10.' },
|
|
143
|
+
contextTokens: {
|
|
144
|
+
type: 'integer',
|
|
145
|
+
minimum: 1,
|
|
146
|
+
description: 'Exact context window in tokens; overrides contextPercent, clamped to 10%-100% of the model window.',
|
|
147
|
+
},
|
|
139
148
|
disabled: {
|
|
140
149
|
type: 'boolean',
|
|
141
150
|
description: 'Agent routes only: true disables without losing the route; false re-enables.',
|
|
@@ -176,7 +185,7 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
176
185
|
route: {
|
|
177
186
|
...ROUTE_SCHEMA,
|
|
178
187
|
description:
|
|
179
|
-
'Partial route update; omitted fields are preserved. Agent or Web Search provider "" restores Main inheritance. contextPercent
|
|
188
|
+
'Partial route update; omitted fields are preserved. Agent or Web Search provider "" restores Main inheritance. contextPercent and contextTokens apply to Main and agent routes only.',
|
|
180
189
|
},
|
|
181
190
|
agent: { type: 'string', description: 'set_agent_route: agent id.' },
|
|
182
191
|
workflow: { type: 'string', description: 'set_workflow: pack id.' },
|
|
@@ -222,7 +231,7 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
222
231
|
},
|
|
223
232
|
name: {
|
|
224
233
|
type: 'string',
|
|
225
|
-
description: `set_builtin_enabled: ${SETUP_BUILTIN_TOGGLE_FEATURES.join('|')}; install_builtin also accepts memory. Memory toggles use set_memory_enabled. revoke_linked_device: client id from status connection, not its display name; set_developer_option: option id from status developer; read_definition/delete_definition: the definition id; else MCP/plugin/provider id.`,
|
|
234
|
+
description: `set_builtin_enabled: ${SETUP_BUILTIN_TOGGLE_FEATURES.join('|')}; install_builtin also accepts memory. Memory toggles use set_memory_enabled. revoke_linked_device: client id from status connection, not its display name; set_developer_option: option id from status developer; read_definition/delete_definition: the definition id; reconnect_mcp: optional MCP server name (omit for all); else MCP/plugin/provider id.`,
|
|
226
235
|
},
|
|
227
236
|
accountId: {
|
|
228
237
|
type: 'string',
|
|
@@ -320,6 +329,25 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
320
329
|
items: { type: 'string', minLength: 1, pattern: '\\S' },
|
|
321
330
|
description: 'set_extension_scope: required project roots; [] = every project.',
|
|
322
331
|
},
|
|
332
|
+
worktree: {
|
|
333
|
+
type: 'object',
|
|
334
|
+
additionalProperties: false,
|
|
335
|
+
properties: {
|
|
336
|
+
newTaskDefault: {
|
|
337
|
+
type: 'string',
|
|
338
|
+
enum: [...WORKTREE_NEW_TASK_DEFAULTS],
|
|
339
|
+
description: 'branch = new tasks use the current branch (default); worktree = a new worktree.',
|
|
340
|
+
},
|
|
341
|
+
branchPrefix: { type: 'string', description: 'Ref prefix ending with "/"; default "mixdog/".' },
|
|
342
|
+
sizeWarnBytes: {
|
|
343
|
+
type: 'integer',
|
|
344
|
+
minimum: 0,
|
|
345
|
+
description: 'Repository size that asks for confirmation first; 0 never asks.',
|
|
346
|
+
},
|
|
347
|
+
autoCleanup: { type: 'boolean', description: 'Remove clean, merged worktrees when their task ends.' },
|
|
348
|
+
},
|
|
349
|
+
description: 'set_worktree_settings: only the given fields change.',
|
|
350
|
+
},
|
|
323
351
|
...SETUP_EXTENDED_PROPERTIES,
|
|
324
352
|
},
|
|
325
353
|
},
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// The desktop "Getting started" guide state, kept in the config beside the
|
|
2
|
+
// onboarding flags (`onboarding.starterGuide`) so it outlives the renderer's
|
|
3
|
+
// localStorage. The desktop IPC gate (ipc-validation.ts) mirrors the schema.
|
|
4
|
+
export const STARTER_GUIDE_STEPS = Object.freeze(['provider', 'project', 'workflow', 'extensions', 'remote']);
|
|
5
|
+
const STARTER_GUIDE_KEYS = new Set(['closed', 'welcomed', 'visited']);
|
|
6
|
+
|
|
7
|
+
const plainObject = (value) => Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
8
|
+
|
|
9
|
+
/** The guide state of a user who has not answered it yet. */
|
|
10
|
+
export function freshStarterGuide() {
|
|
11
|
+
return { closed: false, welcomed: false, visited: [] };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** The stored copy, read tolerantly; null when there is none. */
|
|
15
|
+
export function storedStarterGuide(value) {
|
|
16
|
+
if (!plainObject(value)) return null;
|
|
17
|
+
const visited = Array.isArray(value.visited) ? value.visited : [];
|
|
18
|
+
return {
|
|
19
|
+
closed: value.closed === true,
|
|
20
|
+
welcomed: value.welcomed === true,
|
|
21
|
+
visited: STARTER_GUIDE_STEPS.filter((step) => visited.includes(step)),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** A save request, read strictly: anything off-schema is rejected, never coerced. */
|
|
26
|
+
export function requiredStarterGuideState(value) {
|
|
27
|
+
if (!plainObject(value)) throw new TypeError('starter guide state must be an object.');
|
|
28
|
+
for (const key of Object.keys(value)) {
|
|
29
|
+
if (!STARTER_GUIDE_KEYS.has(key)) throw new TypeError(`starter guide state has an unknown field: ${key}.`);
|
|
30
|
+
}
|
|
31
|
+
if (typeof value.closed !== 'boolean' || typeof value.welcomed !== 'boolean') {
|
|
32
|
+
throw new TypeError('starter guide closed and welcomed must be booleans.');
|
|
33
|
+
}
|
|
34
|
+
if (
|
|
35
|
+
!Array.isArray(value.visited) ||
|
|
36
|
+
value.visited.length > STARTER_GUIDE_STEPS.length * 2 ||
|
|
37
|
+
value.visited.some((step) => !STARTER_GUIDE_STEPS.includes(step))
|
|
38
|
+
) {
|
|
39
|
+
throw new TypeError('starter guide visited must list known steps.');
|
|
40
|
+
}
|
|
41
|
+
return storedStarterGuide(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Every field only moves forward: a stale save can add, never undo. */
|
|
45
|
+
export function mergeStarterGuide(stored, next) {
|
|
46
|
+
const base = stored || freshStarterGuide();
|
|
47
|
+
return {
|
|
48
|
+
closed: base.closed || next.closed,
|
|
49
|
+
welcomed: base.welcomed || next.welcomed,
|
|
50
|
+
visited: STARTER_GUIDE_STEPS.filter((step) => base.visited.includes(step) || next.visited.includes(step)),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The onboarding section after a completion: a first completion starts the
|
|
56
|
+
* guide fresh, so an absent copy afterwards means a profile onboarded before
|
|
57
|
+
* the guide was persisted here.
|
|
58
|
+
*/
|
|
59
|
+
export function withStarterGuideOnCompletion(previous, onboarding) {
|
|
60
|
+
if (previous?.completed === true || storedStarterGuide(previous?.starterGuide)) return onboarding;
|
|
61
|
+
return { ...onboarding, starterGuide: freshStarterGuide() };
|
|
62
|
+
}
|
|
@@ -56,6 +56,17 @@ export function createAgentOps(deps) {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// Stop one background shell job of THIS session through the task tool's
|
|
60
|
+
// cancel path; the answer is structured so a surface never parses text.
|
|
61
|
+
async function stopShellJob(taskId) {
|
|
62
|
+
const session = getSession();
|
|
63
|
+
const { stopBackgroundShellJob } = await import('../../runtime/agent/orchestrator/tools/builtin/task-tool.mjs');
|
|
64
|
+
return stopBackgroundShellJob(taskId, {
|
|
65
|
+
callerSessionId: session?.id || null,
|
|
66
|
+
clientHostPid: session?.clientHostPid || process.pid,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
function onNotification(listener) {
|
|
60
71
|
if (typeof listener !== 'function') return () => {};
|
|
61
72
|
const sessionId = getSession()?.id || getReservedSessionId?.() || '';
|
|
@@ -94,5 +105,5 @@ export function createAgentOps(deps) {
|
|
|
94
105
|
return { ...result, status: toolsStatus() };
|
|
95
106
|
}
|
|
96
107
|
|
|
97
|
-
return { agentControl, taskControl, onNotification, toolsStatus, selectTools };
|
|
108
|
+
return { agentControl, taskControl, stopShellJob, onNotification, toolsStatus, selectTools };
|
|
98
109
|
}
|
|
@@ -55,18 +55,28 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
|
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// The turn's change-record key rides the caller's transcript metadata (in
|
|
59
|
+
// place: the stream stamps assistantAt on this same object), so the
|
|
60
|
+
// persisted user row and completion carry it across restore.
|
|
61
|
+
function stampCheckpoint(options) {
|
|
62
|
+
const meta = options.transcriptMeta;
|
|
63
|
+
const checkpointId = String(options.id || '').trim();
|
|
64
|
+
if (checkpointId && meta && typeof meta === 'object') meta.checkpointId = checkpointId;
|
|
65
|
+
return meta;
|
|
66
|
+
}
|
|
67
|
+
|
|
58
68
|
function askCallbacks(turn, session0, options) {
|
|
59
69
|
return {
|
|
60
70
|
beforeToolExecution: () => turn.snapshot.promise || Promise.resolve(),
|
|
61
|
-
transcriptMeta: options
|
|
71
|
+
transcriptMeta: stampCheckpoint(options),
|
|
62
72
|
promptSource: options.promptSource,
|
|
63
73
|
retryFailedTurn: options.retryFailedTurn === true,
|
|
64
74
|
onTextDelta: options.onTextDelta,
|
|
65
75
|
onTextReset: options.onTextReset,
|
|
66
76
|
onReasoningDelta: options.onReasoningDelta,
|
|
67
|
-
onAssistantText: (text) => {
|
|
77
|
+
onAssistantText: (text, detail) => {
|
|
68
78
|
transcript.appendAssistantText(text);
|
|
69
|
-
return options.onAssistantText?.(text);
|
|
79
|
+
return options.onAssistantText?.(text, detail);
|
|
70
80
|
},
|
|
71
81
|
onUsageDelta: options.onUsageDelta,
|
|
72
82
|
onAssistantToolCallObserved: options.onAssistantToolCallObserved,
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import { settleWithin } from '../../../runtime/shared/abort-race.mjs';
|
|
2
2
|
|
|
3
|
-
// Worktree snapshot for the turn review. Captured
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Worktree snapshot for the turn review. Captured as soon as the turn's
|
|
4
|
+
// workspace is final (after any lazy worktree provisioning, so the baseline is
|
|
5
|
+
// taken in the root the turn runs in), but never on the first-token critical
|
|
6
|
+
// path: every actual tool execution joins the same promise, so
|
|
7
|
+
// shell/apply_patch cannot mutate the worktree before the baseline.
|
|
6
8
|
export function createSnapshotTrackerFactory({
|
|
7
9
|
getCurrentCwd,
|
|
8
10
|
beginTurnSnapshotForTurn,
|
|
9
|
-
cancelTurnSnapshotForTurn,
|
|
10
11
|
completeTurnSnapshotForTurn,
|
|
11
12
|
turnCleanupSettleMs,
|
|
12
13
|
}) {
|
|
13
14
|
return function createSnapshotTracker(options) {
|
|
15
|
+
// `promise` resolves to the turn token beginTurnSnapshot returns
|
|
16
|
+
// (`{ generation, checkpointId }`), or undefined when nothing began.
|
|
14
17
|
const tracker = { sessionId: null, promise: null };
|
|
15
|
-
// A completion wake continues the user turn whose review already exists;
|
|
16
|
-
// aborting the wake seals that review instead of discarding it.
|
|
17
18
|
const continueTurn = options.continueTurn === true;
|
|
18
|
-
const cancel = () => {
|
|
19
|
-
try {
|
|
20
|
-
cancelTurnSnapshotForTurn(tracker.sessionId);
|
|
21
|
-
} catch {}
|
|
22
|
-
};
|
|
23
19
|
tracker.start = (sessionId) => {
|
|
24
20
|
const id = typeof sessionId === 'string' ? sessionId.trim() : '';
|
|
25
21
|
if (!id || (tracker.promise && tracker.sessionId === id)) return;
|
|
@@ -36,19 +32,28 @@ export function createSnapshotTrackerFactory({
|
|
|
36
32
|
.catch(() => undefined);
|
|
37
33
|
};
|
|
38
34
|
tracker.finish = async (signal, awaitTurn) => {
|
|
35
|
+
// A turn refused before its workspace was final never began a review.
|
|
36
|
+
if (!tracker.promise) return;
|
|
37
|
+
// Captured now: a later start (or the next turn) cannot redirect this seal.
|
|
38
|
+
const sessionId = tracker.sessionId;
|
|
39
|
+
const started = Promise.resolve(tracker.promise);
|
|
39
40
|
if (signal.aborted && !continueTurn) {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
// A cancelled turn keeps its edits as a change record. Sealing waits
|
|
42
|
+
// for the snapshot start, never for the abort's settlement, and only
|
|
43
|
+
// seals the generation this turn began: delayed cleanup cannot seal
|
|
44
|
+
// a newer turn.
|
|
45
|
+
void started
|
|
46
|
+
.then((token) => (token ? completeTurnSnapshotForTurn(sessionId, token) : undefined))
|
|
47
|
+
.catch(() => {});
|
|
42
48
|
return;
|
|
43
49
|
}
|
|
44
|
-
const cleanup =
|
|
50
|
+
const cleanup = started.then((token) => completeTurnSnapshotForTurn(sessionId, token));
|
|
45
51
|
cleanup.catch(() => {});
|
|
46
52
|
try {
|
|
47
53
|
await awaitTurn(() => settleWithin(cleanup, turnCleanupSettleMs));
|
|
48
54
|
} catch {
|
|
49
55
|
/* optional review cleanup never overrides turn settlement */
|
|
50
56
|
}
|
|
51
|
-
if (signal.aborted && !continueTurn) cancel();
|
|
52
57
|
};
|
|
53
58
|
return tracker;
|
|
54
59
|
};
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { runAbortable } from '../../../runtime/shared/abort-race.mjs';
|
|
2
2
|
|
|
3
3
|
// Opens one turn: abort controller registration, timing, the worktree
|
|
4
|
-
// snapshot tracker
|
|
5
|
-
// warmup arm.
|
|
4
|
+
// snapshot tracker (started by session preparation once the turn's workspace
|
|
5
|
+
// is final), the active-turn count and the one-shot heavy-runtime warmup arm.
|
|
6
6
|
export function createTurnOpener({
|
|
7
7
|
createTiming,
|
|
8
8
|
createSnapshot,
|
|
9
|
-
getSession,
|
|
10
|
-
getReservedSessionId,
|
|
11
9
|
registerActiveTurnController,
|
|
12
10
|
getActiveTurnCount,
|
|
13
11
|
setActiveTurnCount,
|
|
@@ -41,7 +39,6 @@ export function createTurnOpener({
|
|
|
41
39
|
const signal = controller.signal;
|
|
42
40
|
const snapshot = createSnapshot(options);
|
|
43
41
|
const routeStartedAt = performance.now();
|
|
44
|
-
snapshot.start(getSession()?.id || getReservedSessionId?.());
|
|
45
42
|
setActiveTurnCount(getActiveTurnCount() + 1);
|
|
46
43
|
return {
|
|
47
44
|
signal,
|
|
@@ -54,6 +51,8 @@ export function createTurnOpener({
|
|
|
54
51
|
armHeavyRuntimeWarmup: heavyRuntimeWarmupArm(),
|
|
55
52
|
session0: null,
|
|
56
53
|
releaseFirstTitle: null,
|
|
54
|
+
/** Set by turn admission (admitTurnWorkspace); released by settleTurn. */
|
|
55
|
+
releaseWorkspace: null,
|
|
57
56
|
startedAt: Date.now(),
|
|
58
57
|
};
|
|
59
58
|
};
|
|
@@ -21,6 +21,8 @@ export function createTurnPreparation({
|
|
|
21
21
|
agentTool,
|
|
22
22
|
getConfig,
|
|
23
23
|
assertSessionAdmission,
|
|
24
|
+
prepareTurnWorkspace,
|
|
25
|
+
admitTurnWorkspace,
|
|
24
26
|
}) {
|
|
25
27
|
const scopedMcpTools = (session) => scopedMcpToolsFor(session, getConfig());
|
|
26
28
|
|
|
@@ -84,7 +86,7 @@ export function createTurnPreparation({
|
|
|
84
86
|
// Historical-session resume publishes its transcript immediately while
|
|
85
87
|
// provider/model metadata initializes in the background. Only the next
|
|
86
88
|
// actual turn waits, guaranteeing that it cannot run on a stale route.
|
|
87
|
-
async function prepareSession(turn, prompt) {
|
|
89
|
+
async function prepareSession(turn, prompt, options = {}) {
|
|
88
90
|
// A closing/closed addressed runtime admits no turn (checked again after
|
|
89
91
|
// every await that could have outlived a close).
|
|
90
92
|
assertSessionAdmission?.();
|
|
@@ -96,6 +98,32 @@ export function createTurnPreparation({
|
|
|
96
98
|
}
|
|
97
99
|
throwIfAborted(turn.signal);
|
|
98
100
|
assertSessionAdmission?.();
|
|
101
|
+
// Turn admission: waits while this session's workspace transitions or
|
|
102
|
+
// another session changes the checkout this session works in, then holds
|
|
103
|
+
// the turn registered (released by settleTurn) so no checkout changes
|
|
104
|
+
// under it.
|
|
105
|
+
if (typeof admitTurnWorkspace === 'function') {
|
|
106
|
+
turn.releaseWorkspace = await admitTurnWorkspace({ signal: turn.signal });
|
|
107
|
+
throwIfAborted(turn.signal);
|
|
108
|
+
assertSessionAdmission?.();
|
|
109
|
+
}
|
|
110
|
+
// Workspace gate: a session in recovery refuses the turn, and a pending
|
|
111
|
+
// worktree intent is provisioned and applied (cwd, record, prompt context)
|
|
112
|
+
// BEFORE the user row, the review snapshot, hooks, the provider and any
|
|
113
|
+
// worker spawn. The submission id is the provisioning transaction id, so a
|
|
114
|
+
// retried or duplicate send reuses the same worktree.
|
|
115
|
+
if (typeof prepareTurnWorkspace === 'function') {
|
|
116
|
+
await turn.awaitTurn(() =>
|
|
117
|
+
prepareTurnWorkspace({
|
|
118
|
+
submissionId: String(options.id || '').trim(),
|
|
119
|
+
prompt,
|
|
120
|
+
signal: turn.signal,
|
|
121
|
+
confirmLarge: options.confirmLarge === true,
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
throwIfAborted(turn.signal);
|
|
125
|
+
assertSessionAdmission?.();
|
|
126
|
+
}
|
|
99
127
|
ensureSessionTranscriptWriter?.();
|
|
100
128
|
transcript.appendUser(prompt);
|
|
101
129
|
const session0 = getSession();
|
|
@@ -84,7 +84,12 @@ export function createTurnSettlement({
|
|
|
84
84
|
turn.releaseFirstTitle?.();
|
|
85
85
|
turn.emitTiming(turn.timing.status);
|
|
86
86
|
turn.armHeavyRuntimeWarmup('turn-settled');
|
|
87
|
-
|
|
87
|
+
try {
|
|
88
|
+
await turn.snapshot.finish(turn.signal, turn.awaitTurn);
|
|
89
|
+
} finally {
|
|
90
|
+
// The turn no longer works in its checkout: transitions may proceed.
|
|
91
|
+
turn.releaseWorkspace?.();
|
|
92
|
+
}
|
|
88
93
|
try {
|
|
89
94
|
turn.unregister?.();
|
|
90
95
|
} catch {}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/session-runtime/turn/turn-run.mjs - one user turn end to end: viewer
|
|
3
|
-
* forwarding, turn open (abort controller, timing,
|
|
4
|
-
*
|
|
5
|
-
* settlement that always runs. The phases
|
|
3
|
+
* forwarding, turn open (abort controller, timing, warmup arming), session
|
|
4
|
+
* preparation (workspace provisioning, then the worktree review snapshot), the
|
|
5
|
+
* askSession callback bridge, and the settlement that always runs. The phases
|
|
6
|
+
* live under turn-run/.
|
|
6
7
|
*/
|
|
7
|
-
import { beginTurnSnapshot,
|
|
8
|
+
import { beginTurnSnapshot, completeTurnSnapshot } from '../../runtime/shared/turn-snapshot.mjs';
|
|
8
9
|
import { runWithCwdOverride } from '../../runtime/shared/user-cwd.mjs';
|
|
9
10
|
import { createTurnTranscript } from './turn-run/transcript.mjs';
|
|
10
11
|
import { createTurnTimingFactory } from './turn-run/turn-timing.mjs';
|
|
@@ -23,7 +24,6 @@ export function createTurnRunner(deps) {
|
|
|
23
24
|
endComputerExecution = async () => false,
|
|
24
25
|
deferComputerSessionRelease = () => false,
|
|
25
26
|
beginTurnSnapshotForTurn = beginTurnSnapshot,
|
|
26
|
-
cancelTurnSnapshotForTurn = cancelTurnSnapshot,
|
|
27
27
|
completeTurnSnapshotForTurn = completeTurnSnapshot,
|
|
28
28
|
turnCleanupSettleMs = 2_000,
|
|
29
29
|
getConfig = () => null,
|
|
@@ -35,7 +35,6 @@ export function createTurnRunner(deps) {
|
|
|
35
35
|
createSnapshot: createSnapshotTrackerFactory({
|
|
36
36
|
getCurrentCwd,
|
|
37
37
|
beginTurnSnapshotForTurn,
|
|
38
|
-
cancelTurnSnapshotForTurn,
|
|
39
38
|
completeTurnSnapshotForTurn,
|
|
40
39
|
turnCleanupSettleMs,
|
|
41
40
|
}),
|
|
@@ -93,7 +92,7 @@ export function createTurnRunner(deps) {
|
|
|
93
92
|
if (attachedSession?.remoteAttached) return forwardAttachedPrompt(attachedSession, prompt, options);
|
|
94
93
|
const turn = openTurn(options);
|
|
95
94
|
try {
|
|
96
|
-
const session0 = await prepareSession(turn, prompt);
|
|
95
|
+
const session0 = await prepareSession(turn, prompt, options);
|
|
97
96
|
const turnContext = await dispatchPromptSubmit(turn, session0, prompt, options);
|
|
98
97
|
const result = await mgr.askSession(
|
|
99
98
|
session0.id,
|
|
@@ -3,7 +3,7 @@ import { hasOwn } from '../../runtime/shared/object.mjs';
|
|
|
3
3
|
import { isHiddenAgent } from '../../runtime/agent/orchestrator/internal-agents.mjs';
|
|
4
4
|
import { normalizeWorkflowRoute } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
5
5
|
import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
6
|
-
import { selectionFastCapable } from '../route-state.mjs';
|
|
6
|
+
import { resolveRouteContextState, selectionFastCapable } from '../route-state.mjs';
|
|
7
7
|
import { canonicalizeAgentRouteStorage, withAgentDisabled } from '../../runtime/shared/agent-route-config.mjs';
|
|
8
8
|
import { agentEditorId } from './shared.mjs';
|
|
9
9
|
|
|
@@ -43,19 +43,31 @@ export function createAgentRouteApi(deps) {
|
|
|
43
43
|
clean(selectedRoute.provider) === clean(stored.provider) && clean(selectedRoute.model) === clean(stored.model);
|
|
44
44
|
const inheritedEffort = sameModel ? stored.effort || null : null;
|
|
45
45
|
const inheritedModelParameters = sameModel ? stored.modelParameters || {} : {};
|
|
46
|
-
|
|
46
|
+
// A requested percent replaces the stored exact window and requested
|
|
47
|
+
// tokens replace the stored percent.
|
|
48
|
+
const requestsPercent = requested.contextPercent !== undefined;
|
|
49
|
+
const requestsTokens = requested.contextTokens !== undefined;
|
|
50
|
+
const inheritedContextPercent = sameModel && !requestsTokens ? stored.contextPercent : undefined;
|
|
51
|
+
const inheritedContextTokens = sameModel && !requestsPercent ? stored.contextTokens : undefined;
|
|
47
52
|
selectedRoute = {
|
|
48
53
|
...selectedRoute,
|
|
49
54
|
effort: requested.effort !== undefined ? selectedRoute.effort : inheritedEffort,
|
|
50
55
|
fast: requested.fast !== undefined ? selectedRoute.fast === true : sameModel && stored.fast === true,
|
|
56
|
+
// Main's modelSettings bucket must not decide an agent's Auto effort.
|
|
57
|
+
autoEffort:
|
|
58
|
+
requested.autoEffort !== undefined ? requested.autoEffort !== false : !sameModel || stored.autoEffort !== false,
|
|
51
59
|
modelParameters:
|
|
52
60
|
requested.modelParameters !== undefined ? selectedRoute.modelParameters : inheritedModelParameters,
|
|
53
61
|
// resolveRoute reads contextPercent from Main's modelSettings bucket;
|
|
54
62
|
// an agent route owns its own.
|
|
55
|
-
contextPercent:
|
|
63
|
+
contextPercent: requestsPercent ? requested.contextPercent : inheritedContextPercent,
|
|
64
|
+
contextTokens: requestsTokens ? requested.contextTokens : inheritedContextTokens,
|
|
56
65
|
};
|
|
57
66
|
await ensureProvidersReady(ensureProviderEnabled(getConfig(), selectedRoute.provider));
|
|
58
67
|
const modelMeta = await lookupModelMeta(selectedRoute.provider, selectedRoute.model);
|
|
68
|
+
// Stored clamped, and not at all at the default window, as for Main.
|
|
69
|
+
const contextState = resolveRouteContextState(selectedRoute, modelMeta);
|
|
70
|
+
if (contextState.contextDefaultPercent !== undefined) selectedRoute.contextTokens = contextState.contextTokens;
|
|
59
71
|
const fastCapable = selectionFastCapable(
|
|
60
72
|
selectedRoute.provider,
|
|
61
73
|
modelMeta,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
13
13
|
import { ONBOARDING_VERSION } from '../quick-web-search-models.mjs';
|
|
14
14
|
import { canonicalizeAgentRouteStorage } from '../../runtime/shared/agent-route-config.mjs';
|
|
15
|
+
import { withStarterGuideOnCompletion } from '../starter-guide-state.mjs';
|
|
15
16
|
import { resolveDataDir } from './shared.mjs';
|
|
16
17
|
|
|
17
18
|
// Onboarding slot picks: lead → default preset, agent → worker route,
|
|
@@ -91,12 +92,12 @@ export function createOnboardingApi(deps) {
|
|
|
91
92
|
]);
|
|
92
93
|
nextConfig.agents = applyAgentRouteInput(agentInput, draft.agentRoutes, configurableIds);
|
|
93
94
|
}
|
|
94
|
-
nextConfig.onboarding = {
|
|
95
|
+
nextConfig.onboarding = withStarterGuideOnCompletion(config.onboarding, {
|
|
95
96
|
...(nextConfig.onboarding || {}),
|
|
96
97
|
completed: true,
|
|
97
98
|
version: ONBOARDING_VERSION,
|
|
98
99
|
completedAt: new Date().toISOString(),
|
|
99
|
-
};
|
|
100
|
+
});
|
|
100
101
|
if (payload.webSearchRoute) {
|
|
101
102
|
const webSearchToSave = webSearchRouteToSave(payload.webSearchRoute);
|
|
102
103
|
if (webSearchToSave) nextConfig.webSearchRoute = webSearchToSave;
|