mixdog 1.1.2 → 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 -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 +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/help.mjs +2 -0
- 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 +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/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/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/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/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/attachments/store.mjs +38 -0
- 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/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 +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 +161 -11
- 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/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 +4 -0
- 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 +20 -7
- 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/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/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-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/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/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-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 +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 +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 +16 -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/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 +2 -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 +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
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// progress, filtered by default to workers that can still do work.
|
|
4
4
|
import { ACTIVE_STAGES } from '../tool-def.mjs';
|
|
5
5
|
import { isTerminalWorkerStatus } from '../worker-rows.mjs';
|
|
6
|
+
import { sessionUsageTotals } from '../../../../runtime/shared/session-usage-totals.mjs';
|
|
6
7
|
|
|
7
8
|
// Idle, closed, errored and reaped/unknown rows are history and stay reachable
|
|
8
9
|
// through the task section (status/read keep their terminal result).
|
|
@@ -36,6 +37,7 @@ function agentRow({ tag, session, runtime, progress, now, indexRow = null }) {
|
|
|
36
37
|
preset: session.presetName || null,
|
|
37
38
|
effort: session.effort || null,
|
|
38
39
|
fast: session.fast === true,
|
|
40
|
+
...(session.autoEffort === false ? { autoEffort: false } : {}),
|
|
39
41
|
// Additive: route model parameters (e.g. Daybreak Blue) when the route has any.
|
|
40
42
|
...(session.modelParameters && Object.keys(session.modelParameters).length
|
|
41
43
|
? { modelParameters: { ...session.modelParameters } }
|
|
@@ -51,6 +53,7 @@ function agentRow({ tag, session, runtime, progress, now, indexRow = null }) {
|
|
|
51
53
|
clientHostPid: session.clientHostPid || null,
|
|
52
54
|
lastStreamDeltaAt: runtime?.lastStreamDeltaAt ? new Date(runtime.lastStreamDeltaAt).toISOString() : null,
|
|
53
55
|
staleSeconds: runtime?.lastStreamDeltaAt ? Math.floor((now - runtime.lastStreamDeltaAt) / 1000) : null,
|
|
56
|
+
...sessionUsageTotals(session),
|
|
54
57
|
windowTokens: Number(session.lastContextTokens ?? session.lastInputTokens) || 0,
|
|
55
58
|
windowCap: Number(session.contextWindow) || null,
|
|
56
59
|
permission: session.permission || null,
|
|
@@ -16,6 +16,7 @@ export function preparedSpawnMeta(prepared, extras = {}) {
|
|
|
16
16
|
model: prepared.preset.model,
|
|
17
17
|
effort: prepared.preset.effort || null,
|
|
18
18
|
fast: prepared.preset.fast === true,
|
|
19
|
+
...(prepared.preset.autoEffort === false ? { autoEffort: false } : {}),
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -72,6 +72,20 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
|
|
|
72
72
|
return true;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/** A workspace transition moved the Lead: its existing row follows (status,
|
|
76
|
+
* reap deadline and liveness stamps unchanged). No row: nothing to write. */
|
|
77
|
+
function updateLeadWorkerCwd(sessionId, cwd) {
|
|
78
|
+
const id = clean(sessionId);
|
|
79
|
+
const next = clean(cwd);
|
|
80
|
+
if (!id || !next) return false;
|
|
81
|
+
index.write((byKey) => {
|
|
82
|
+
const current = byKey.get(id);
|
|
83
|
+
if (!current || current.cwd === next) return;
|
|
84
|
+
byKey.set(id, { ...current, cwd: next });
|
|
85
|
+
});
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
/** Graceful-exit settlement: every turn this process still claims goes idle
|
|
76
90
|
* before the runtime disappears. */
|
|
77
91
|
function flushActiveLeadRows() {
|
|
@@ -147,6 +161,7 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
|
|
|
147
161
|
/** Resolves once every queued Lead index write is on disk. */
|
|
148
162
|
flushLeadWorkerIndexWrites: index.flush,
|
|
149
163
|
upsertLeadSession,
|
|
164
|
+
updateLeadWorkerCwd,
|
|
150
165
|
removeLeadWorkerRow,
|
|
151
166
|
flushActiveLeadRows,
|
|
152
167
|
recoverStaleLeadRows,
|
|
@@ -180,6 +180,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
180
180
|
preset: session.presetName || null,
|
|
181
181
|
effort: session.effort || null,
|
|
182
182
|
fast: session.fast === true,
|
|
183
|
+
...(session.autoEffort === false ? { autoEffort: false } : {}),
|
|
183
184
|
},
|
|
184
185
|
(job, ownerNotifyContext) => runSend(prepared, ownerNotifyContext, job),
|
|
185
186
|
notifyContext
|
|
@@ -17,6 +17,7 @@ import { isAgentDisabled } from '../../../../runtime/shared/agent-route-config.m
|
|
|
17
17
|
import { normalizeAgentPermission } from '../../../../runtime/shared/markdown-frontmatter.mjs';
|
|
18
18
|
import { resolveAgentSpawnPreset } from '../spawn-preset.mjs';
|
|
19
19
|
import { AGENT_OWNER } from '../../../../runtime/agent/orchestrator/agent-owner.mjs';
|
|
20
|
+
import { workspaceCwdLock } from '../../../workspace/admission-gate.mjs';
|
|
20
21
|
|
|
21
22
|
export function createSpawnPlanner({
|
|
22
23
|
cfgMod,
|
|
@@ -52,8 +53,15 @@ export function createSpawnPlanner({
|
|
|
52
53
|
if (resolveTag(tag, context, { scanSessions: wantsSessionScan(args) })) {
|
|
53
54
|
throw new Error(`agent spawn: tag "${tag}" already exists`);
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
// Workers share their Lead's execution root. While the Lead runs in its
|
|
57
|
+
// worktree, that root is locked: neither args.cwd nor an inherited
|
|
58
|
+
// (pre-transition) cwd can send a worker elsewhere.
|
|
59
|
+
const lockedCwd = workspaceCwdLock([
|
|
60
|
+
context?.ownerSessionId,
|
|
61
|
+
context?.callerSessionId || context?.sessionId,
|
|
62
|
+
]);
|
|
63
|
+
const baseCwd = resolve(lockedCwd || callerCwd || defaultCwd || process.cwd());
|
|
64
|
+
const workerCwd = !lockedCwd && clean(args.cwd) ? resolve(baseCwd, args.cwd) : baseCwd;
|
|
57
65
|
const prompt = await resolvePrompt(args, workerCwd);
|
|
58
66
|
if (prepState?.timedOut) {
|
|
59
67
|
throw new Error('agent spawn prep timed out before session bind');
|
|
@@ -10,6 +10,7 @@ import { prepareAgentSession } from '../../../../runtime/agent/orchestrator/agen
|
|
|
10
10
|
import { getProvider } from '../../../../runtime/agent/orchestrator/providers/registry.mjs';
|
|
11
11
|
import { resolveRouteContextState } from '../../../route-state.mjs';
|
|
12
12
|
import { createSpawnPlanner } from './spawn-plan.mjs';
|
|
13
|
+
import { enterWorkerSpawn } from '../../../workspace/admission-gate.mjs';
|
|
13
14
|
|
|
14
15
|
/** The route fields every worker-row and tag record carries. */
|
|
15
16
|
export function presetDescriptor(agent, preset, presetName) {
|
|
@@ -20,6 +21,7 @@ export function presetDescriptor(agent, preset, presetName) {
|
|
|
20
21
|
model: preset.model,
|
|
21
22
|
effort: preset.effort || null,
|
|
22
23
|
fast: preset.fast === true,
|
|
24
|
+
...(preset.autoEffort === false ? { autoEffort: false } : {}),
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -84,9 +86,9 @@ export function createSpawnPreparer({
|
|
|
84
86
|
// A sub-100 context share needs the window it selects; a percent alone
|
|
85
87
|
// keeps the full served window.
|
|
86
88
|
const sessionSpec = { ...spec };
|
|
87
|
-
if (plan.preset.contextPercent) {
|
|
88
|
-
const { contextPercent, selectedContextWindow } = resolveRouteContextState(plan.preset, null);
|
|
89
|
-
Object.assign(sessionSpec, { contextPercent, selectedContextWindow });
|
|
89
|
+
if (plan.preset.contextPercent || plan.preset.contextTokens) {
|
|
90
|
+
const { contextPercent, selectedContextWindow, contextTokens } = resolveRouteContextState(plan.preset, null);
|
|
91
|
+
Object.assign(sessionSpec, { contextPercent, selectedContextWindow }, contextTokens ? { contextTokens } : {});
|
|
90
92
|
}
|
|
91
93
|
if (sessionSurface?.canonical === true && typeof sessionSurface.createChild === 'function') {
|
|
92
94
|
return sessionSurface.createChild({ spec: sessionSpec, prompt: plan.prompt, tag: plan.tag });
|
|
@@ -99,10 +101,20 @@ export function createSpawnPreparer({
|
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
async function prepareSpawnInProcess(args, callerCwd = null, context = {}, prepState = null) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
104
|
+
// Shared admission with Lead workspace transitions: no spawn is prepared
|
|
105
|
+
// while the Lead's workspace changes, no transition starts mid-spawn.
|
|
106
|
+
const leaveSpawn = enterWorkerSpawn([context?.ownerSessionId, context?.callerSessionId || context?.sessionId]);
|
|
107
|
+
let plan;
|
|
108
|
+
let session;
|
|
109
|
+
let effectiveCwd;
|
|
110
|
+
try {
|
|
111
|
+
plan = await resolveSpawnPlan(args, callerCwd, context, prepState);
|
|
112
|
+
const spec = spawnSessionSpec(plan, args, context);
|
|
113
|
+
({ session, effectiveCwd } = await createSpawnedSession(plan, spec, prepState));
|
|
114
|
+
bindSpawnedSession(session, plan);
|
|
115
|
+
} finally {
|
|
116
|
+
leaveSpawn();
|
|
117
|
+
}
|
|
106
118
|
if (sessionSurface?.canonical !== true) {
|
|
107
119
|
maybePrewarmSpawnTransport(plan, session);
|
|
108
120
|
}
|
|
@@ -20,6 +20,7 @@ export function resolveAgentSpawnPreset(config, args = {}) {
|
|
|
20
20
|
model: clean(args.model),
|
|
21
21
|
effort: clean(args.effort) || undefined,
|
|
22
22
|
fast: args.fast === true,
|
|
23
|
+
...(args.autoEffort === false ? { autoEffort: false } : {}),
|
|
23
24
|
tools: 'full',
|
|
24
25
|
},
|
|
25
26
|
};
|
|
@@ -42,8 +43,10 @@ export function resolveAgentSpawnPreset(config, args = {}) {
|
|
|
42
43
|
model: agentRoute.model,
|
|
43
44
|
effort: agentRoute.effort,
|
|
44
45
|
fast: agentRoute.fast === true,
|
|
46
|
+
...(agentRoute.autoEffort === false ? { autoEffort: false } : {}),
|
|
45
47
|
...(agentRoute.modelParameters ? { modelParameters: agentRoute.modelParameters } : {}),
|
|
46
48
|
...(agentRoute.contextPercent ? { contextPercent: agentRoute.contextPercent } : {}),
|
|
49
|
+
...(agentRoute.contextTokens ? { contextTokens: agentRoute.contextTokens } : {}),
|
|
47
50
|
tools: 'full',
|
|
48
51
|
},
|
|
49
52
|
};
|
|
@@ -29,7 +29,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
29
29
|
workerRowFromSession: index.workerRowFromSession,
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
const { upsertLeadSession } = leadIndex;
|
|
32
|
+
const { upsertLeadSession, updateLeadWorkerCwd } = leadIndex;
|
|
33
33
|
|
|
34
34
|
function dispose(options) {
|
|
35
35
|
try {
|
|
@@ -103,6 +103,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
103
103
|
upsertWorkerSession: index.upsertWorkerSession,
|
|
104
104
|
upsertWorkerSessionDeferred,
|
|
105
105
|
upsertLeadSession,
|
|
106
|
+
updateLeadWorkerCwd,
|
|
106
107
|
removeWorkerRow,
|
|
107
108
|
refreshTagsFromIndex,
|
|
108
109
|
tags,
|
|
@@ -38,6 +38,7 @@ export function normalizeWorkerRows(value) {
|
|
|
38
38
|
preset: clean(row.preset) || null,
|
|
39
39
|
effort: clean(row.effort) || null,
|
|
40
40
|
fast: typeof row.fast === 'boolean' ? row.fast : null,
|
|
41
|
+
...(row.autoEffort === false ? { autoEffort: false } : {}),
|
|
41
42
|
status: clean(row.status) || 'idle',
|
|
42
43
|
stage: clean(row.stage) || clean(row.status) || 'idle',
|
|
43
44
|
createdAt: clean(row.createdAt) || null,
|
|
@@ -87,6 +88,10 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
|
|
|
87
88
|
preset: clean(extra.preset) || clean(session?.presetName) || null,
|
|
88
89
|
effort: clean(extra.effort) || clean(session?.effort) || null,
|
|
89
90
|
fast: fastFlag(extra.fast, session?.fast),
|
|
91
|
+
// Absent means Auto effort is on; an explicit boolean wins over the session's.
|
|
92
|
+
...((typeof extra.autoEffort === 'boolean' ? extra.autoEffort : session?.autoEffort) === false
|
|
93
|
+
? { autoEffort: false }
|
|
94
|
+
: {}),
|
|
90
95
|
status,
|
|
91
96
|
stage,
|
|
92
97
|
createdAt: clean(session?.createdAt) || clean(extra.createdAt) || nowIso,
|
|
@@ -133,6 +133,7 @@ export function workerRowToSession(row = {}) {
|
|
|
133
133
|
presetName: row.preset || null,
|
|
134
134
|
effort: row.effort || null,
|
|
135
135
|
fast: row.fast === true,
|
|
136
|
+
...(row.autoEffort === false ? { autoEffort: false } : {}),
|
|
136
137
|
status: row.status || 'idle',
|
|
137
138
|
stage: row.stage || row.status || 'idle',
|
|
138
139
|
createdAt: row.createdAt || null,
|
|
@@ -146,6 +146,7 @@ export function createStandaloneAgent({
|
|
|
146
146
|
getStatus,
|
|
147
147
|
recoverWorkers,
|
|
148
148
|
upsertLeadSession: registry.upsertLeadSession,
|
|
149
|
+
updateLeadWorkerCwd: registry.updateLeadWorkerCwd,
|
|
149
150
|
closeAll: closeFlow.closeAll,
|
|
150
151
|
dispose: (options) => registry.dispose(options),
|
|
151
152
|
};
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
// ready handoff so the daemon's code/signal is recorded against its pid, boot
|
|
6
6
|
// time and ready state. Resolves once the candidate reported ready, exited,
|
|
7
7
|
// failed to spawn, or the timeout elapsed; the caller then re-reads discovery
|
|
8
|
-
// and attaches to whoever won.
|
|
8
|
+
// and attaches to whoever won. The resolved `summary()` describes this boot as
|
|
9
|
+
// observed when called, for a caller that has to give up.
|
|
9
10
|
import { fork } from 'node:child_process';
|
|
10
11
|
import { beginDaemonSpawnCapture } from './daemon-crash-capture.mjs';
|
|
11
12
|
|
|
@@ -34,7 +35,7 @@ export function forkDaemonCandidate({
|
|
|
34
35
|
// Boot diagnostics written to fd 2 reach this log exactly once, even when
|
|
35
36
|
// the candidate never reached ready.
|
|
36
37
|
capture.mirror();
|
|
37
|
-
resolve();
|
|
38
|
+
resolve({ summary: capture.summary });
|
|
38
39
|
};
|
|
39
40
|
let child;
|
|
40
41
|
try {
|
|
@@ -20,6 +20,11 @@ const CAPTURE_ID_ATTEMPTS = 8;
|
|
|
20
20
|
const MIRROR_MAX_BYTES = 16 * 1024;
|
|
21
21
|
const MESSAGE_MAX_CHARS = 512;
|
|
22
22
|
const HEAP_FLAG_RE = /^--max-(?:old-space|semi-space|heap)-size=/;
|
|
23
|
+
// Bytes of fd 2 a failure summary scans (the newest ones when larger).
|
|
24
|
+
const SUMMARY_SCAN_MAX_BYTES = 256 * 1024;
|
|
25
|
+
// Node's uncaught-error report (`TypeError: …`, `Error [ERR_…]: …`), V8's
|
|
26
|
+
// fatal abort and the daemon's own `fatal boot error` log line.
|
|
27
|
+
const STDERR_ERROR_LINE_RE = /\b[A-Z][A-Za-z]*Error\b(?: \[[A-Z0-9_]+\])?:|^Error\b|FATAL ERROR|(?<!non-)\bfatal\b/;
|
|
23
28
|
|
|
24
29
|
function stamp(ms) {
|
|
25
30
|
const iso = new Date(ms).toISOString();
|
|
@@ -256,6 +261,8 @@ function noteSpawnError(capture, error) {
|
|
|
256
261
|
// this stream, so nothing here extends its lifetime.
|
|
257
262
|
function drainStderrPipe(capture, stream) {
|
|
258
263
|
const onData = (chunk) => {
|
|
264
|
+
// No capture file to read back: keep the newest bytes for summary().
|
|
265
|
+
capture.pipeText = `${capture.pipeText}${chunk}`.slice(-SUMMARY_SCAN_MAX_BYTES);
|
|
259
266
|
mirrorText(capture.log, chunk);
|
|
260
267
|
};
|
|
261
268
|
stream.on('data', onData);
|
|
@@ -272,6 +279,52 @@ function drainStderrPipe(capture, stream) {
|
|
|
272
279
|
});
|
|
273
280
|
}
|
|
274
281
|
|
|
282
|
+
/** The candidate's fd 2 as text: the capture file (its newest bytes when
|
|
283
|
+
* large) or, when fd 2 fell back to a pipe, what that pipe delivered. */
|
|
284
|
+
function stderrText(capture) {
|
|
285
|
+
if (!capture.capturePath || capture.removed) return capture.pipeText;
|
|
286
|
+
try {
|
|
287
|
+
const handle = fs.openSync(capture.capturePath, 'r');
|
|
288
|
+
try {
|
|
289
|
+
const size = fs.fstatSync(handle).size;
|
|
290
|
+
const length = Math.min(size, SUMMARY_SCAN_MAX_BYTES);
|
|
291
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
292
|
+
const bytesRead = fs.readSync(handle, buffer, 0, length, size - length);
|
|
293
|
+
return buffer.subarray(0, bytesRead).toString('utf8');
|
|
294
|
+
} finally {
|
|
295
|
+
fs.closeSync(handle);
|
|
296
|
+
}
|
|
297
|
+
} catch {
|
|
298
|
+
return capture.pipeText;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** What a launcher that gave up on this boot needs to name its cause: the
|
|
303
|
+
* lifecycle as far as observed, the first error line on fd 2 (else its last
|
|
304
|
+
* line, where a stalled boot stopped) and where the full text is. */
|
|
305
|
+
function summarize(capture) {
|
|
306
|
+
const { record } = capture;
|
|
307
|
+
const lines = stderrText(capture)
|
|
308
|
+
.split(/\r?\n/)
|
|
309
|
+
.map((line) => line.trim())
|
|
310
|
+
.filter(Boolean);
|
|
311
|
+
const errorLine = lines.find((line) => STDERR_ERROR_LINE_RE.test(line));
|
|
312
|
+
return {
|
|
313
|
+
pid: record.pid,
|
|
314
|
+
ready: record.ready,
|
|
315
|
+
spawnedAt: record.spawnedAt,
|
|
316
|
+
exitedAt: record.exitedAt,
|
|
317
|
+
exitCode: record.exitCode,
|
|
318
|
+
exitSignal: record.exitSignal,
|
|
319
|
+
exitReason: record.exitReason ?? null,
|
|
320
|
+
uptimeMs: record.uptimeMs,
|
|
321
|
+
error: record.error,
|
|
322
|
+
stderrErrorLine: errorLine ? boundedMessage(errorLine) : null,
|
|
323
|
+
stderrLastLine: lines.length > 0 ? boundedMessage(lines.at(-1)) : null,
|
|
324
|
+
stderrPath: capture.removed ? null : capture.capturePath,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
275
328
|
/** Attach to the forked child: record its identity and keep a lifetime
|
|
276
329
|
* listener that survives the ready handoff, so a later exit is still
|
|
277
330
|
* correlated to this pid, boot time and ready state. */
|
|
@@ -347,6 +400,7 @@ export function beginDaemonSpawnCapture({
|
|
|
347
400
|
readOffset: 0,
|
|
348
401
|
removed: false,
|
|
349
402
|
pipeDrained: null,
|
|
403
|
+
pipeText: '',
|
|
350
404
|
stderrStdio: 'pipe',
|
|
351
405
|
};
|
|
352
406
|
openCapture(capture, { captureDir, prune, launcherPid, nonce });
|
|
@@ -377,5 +431,6 @@ export function beginDaemonSpawnCapture({
|
|
|
377
431
|
* recording anything — the child, if any, keeps its duplicate. */
|
|
378
432
|
release: () => closeWriteFd(capture),
|
|
379
433
|
snapshot: () => ({ ...capture.record }),
|
|
434
|
+
summary: () => summarize(capture),
|
|
380
435
|
};
|
|
381
436
|
}
|
|
@@ -6,6 +6,7 @@ import { hasOwn } from '../../runtime/agent/orchestrator/runtime-core/session-te
|
|
|
6
6
|
import { toolSpecForMode } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
|
|
7
7
|
import { pluginDataDir } from '../runtime-paths.mjs';
|
|
8
8
|
import { LEAD_DISALLOWED_TOOLS } from '../../runtime/agent/orchestrator/runtime-core/tool-defs.mjs';
|
|
9
|
+
import { HEADLESS_TOOL_PROFILE } from '../../runtime/agent/orchestrator/runtime-core/tool-profile.mjs';
|
|
9
10
|
|
|
10
11
|
// Ownership and permission fields an agent-owned session inherits from its profile.
|
|
11
12
|
function agentOwnedSessionFields(sessionProfile) {
|
|
@@ -47,7 +48,13 @@ export function sessionOptions(deps, coreMemoryContext) {
|
|
|
47
48
|
owner: agentOwned ? 'agent' : 'cli',
|
|
48
49
|
agent: agentOwned ? sessionProfile?.agent || 'worker' : 'lead',
|
|
49
50
|
lane: agentOwned ? 'agent' : 'cli',
|
|
50
|
-
|
|
51
|
+
// One-shot `mixdog exec` runs carry their own source so session catalogs
|
|
52
|
+
// can keep them out of the user's resumable list.
|
|
53
|
+
sourceType: agentOwned
|
|
54
|
+
? sessionProfile?.sourceType || 'agent'
|
|
55
|
+
: rt.toolProfile === HEADLESS_TOOL_PROFILE
|
|
56
|
+
? 'exec'
|
|
57
|
+
: 'lead',
|
|
51
58
|
sourceName: agentOwned ? sessionProfile?.sourceName || sessionProfile?.agent || 'agent' : 'main',
|
|
52
59
|
...(rt.approvalMode ? { approvalMode: rt.approvalMode } : {}),
|
|
53
60
|
clientHostPid: sessionProfile?.clientHostPid || process.pid,
|
|
@@ -64,8 +71,10 @@ export function sessionOptions(deps, coreMemoryContext) {
|
|
|
64
71
|
workflowContext,
|
|
65
72
|
orchestrationMode,
|
|
66
73
|
fast: rt.route.fast === true,
|
|
74
|
+
autoEffort: rt.route.autoEffort !== false,
|
|
67
75
|
modelParameters: rt.route.modelParameters || {},
|
|
68
76
|
contextPercent: rt.route.contextPercent,
|
|
77
|
+
contextTokens: rt.route.contextTokens || null,
|
|
69
78
|
selectedContextWindow: rt.route.selectedContextWindow || null,
|
|
70
79
|
compaction:
|
|
71
80
|
rt.config.compaction && typeof rt.config.compaction === 'object'
|
|
@@ -34,6 +34,7 @@ export function createSessionTurnApi(deps) {
|
|
|
34
34
|
sessionOwnerGone: share.sessionOwnerGone,
|
|
35
35
|
agentControl: agent.agentControl,
|
|
36
36
|
taskControl: agent.taskControl,
|
|
37
|
+
stopShellJob: agent.stopShellJob,
|
|
37
38
|
onNotification: agent.onNotification,
|
|
38
39
|
toolsStatus: agent.toolsStatus,
|
|
39
40
|
selectTools: agent.selectTools,
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// `this.*` resolve against the spread target, so cross-member calls (e.g.
|
|
6
6
|
// setProfile -> this.getProfile) keep working when spread into the facade.
|
|
7
7
|
//
|
|
8
|
-
// The members live in
|
|
8
|
+
// The members live in six topic modules: profile/onboarding/skills,
|
|
9
9
|
// compaction/auto-clear, built-in tool modules, system (channels, shell,
|
|
10
|
-
// updates) and
|
|
10
|
+
// updates), developer options and worktree defaults; the local provider's own methods come from
|
|
11
11
|
// local-provider-settings.mjs.
|
|
12
12
|
import { createLocalProviderSettings } from './local-provider-settings.mjs';
|
|
13
13
|
import { createProfileSettings } from './settings-profile-api.mjs';
|
|
@@ -15,6 +15,7 @@ import { createCompactionSettings } from './settings-compaction-api.mjs';
|
|
|
15
15
|
import { createBuiltinToolSettings } from './settings-builtin-tools-api.mjs';
|
|
16
16
|
import { createSystemSettings } from './settings-system-api.mjs';
|
|
17
17
|
import { createDeveloperSettings } from './settings-developer-api.mjs';
|
|
18
|
+
import { createWorktreeSettings } from './settings-worktree-api.mjs';
|
|
18
19
|
|
|
19
20
|
export function createSettingsApi(deps) {
|
|
20
21
|
// Optional: callers without a live local provider / gate fall back to the
|
|
@@ -38,5 +39,6 @@ export function createSettingsApi(deps) {
|
|
|
38
39
|
...createBuiltinToolSettings(shared, localSettings),
|
|
39
40
|
...createSystemSettings(shared),
|
|
40
41
|
...createDeveloperSettings(shared),
|
|
42
|
+
...createWorktreeSettings(shared),
|
|
41
43
|
};
|
|
42
44
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
builtinInstalled,
|
|
8
8
|
setBuiltinInstalledInConfig,
|
|
9
9
|
} from '../runtime/agent/orchestrator/runtime-core/builtin-features.mjs';
|
|
10
|
+
import { featureEnvOverride, moduleEnabled } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
10
11
|
import { LOCAL_PROVIDER_ID } from '../runtime/local-provider/managed-runtime.mjs';
|
|
11
12
|
import {
|
|
12
13
|
INSTRUCTION_FILES_MODES,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
shutdownEffortJudge,
|
|
24
25
|
} from '../runtime/effort-judge/judge-client.mjs';
|
|
25
26
|
|
|
26
|
-
const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort'];
|
|
27
|
+
const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort', 'visualize'];
|
|
27
28
|
|
|
28
29
|
function setLocalProviderEnabledInConfig(configLike, enabled) {
|
|
29
30
|
const next = { ...(configLike || {}) };
|
|
@@ -97,6 +98,12 @@ export function createBuiltinToolSettings(
|
|
|
97
98
|
enabled: tidyToolEnabledFn ? tidyToolEnabledFn() : builtinFeatureActive(config, 'tidy'),
|
|
98
99
|
installed: builtinInstalled(config, 'tidy'),
|
|
99
100
|
},
|
|
101
|
+
// Ships with the runtime and needs no install; the toggle reflects the
|
|
102
|
+
// module flag, not live bridge presence.
|
|
103
|
+
visualize: {
|
|
104
|
+
enabled: featureEnvOverride('MIXDOG_FEATURE_VISUALIZE') ?? moduleEnabled(config, 'visualize', true),
|
|
105
|
+
installed: true,
|
|
106
|
+
},
|
|
100
107
|
localProvider: {
|
|
101
108
|
...localProvider,
|
|
102
109
|
...localSettings.status(),
|
|
@@ -152,7 +159,7 @@ export function createBuiltinToolSettings(
|
|
|
152
159
|
},
|
|
153
160
|
async setBuiltinToolEnabled(name, enabled) {
|
|
154
161
|
if (!TOGGLEABLE_BUILTINS.includes(name)) {
|
|
155
|
-
throw new TypeError('Built-in tool must be git, office, tidy, localProvider, or
|
|
162
|
+
throw new TypeError('Built-in tool must be git, office, tidy, localProvider, autoEffort, or visualize.');
|
|
156
163
|
}
|
|
157
164
|
if (name === 'autoEffort' && enabled !== false && !onnxRuntimeSupported()) {
|
|
158
165
|
throw new Error(EFFORT_JUDGE_UNSUPPORTED);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Settings → Worktrees: defaults for Lead-session git worktrees
|
|
2
|
+
// (runtime/shared/worktrees/settings.mjs). Values persist at agent config
|
|
3
|
+
// `worktree.<key>`; defaults are not stored.
|
|
4
|
+
import { applyWorktreeSettingsPatch, normalizeWorktreeSettings } from '../runtime/shared/worktrees/settings.mjs';
|
|
5
|
+
|
|
6
|
+
export function createWorktreeSettings({ getConfig, saveConfigAndAdopt }) {
|
|
7
|
+
return {
|
|
8
|
+
getWorktreeSettings() {
|
|
9
|
+
return normalizeWorktreeSettings(getConfig()?.worktree);
|
|
10
|
+
},
|
|
11
|
+
setWorktreeSettings(patch) {
|
|
12
|
+
const config = getConfig() || {};
|
|
13
|
+
saveConfigAndAdopt({ ...config, worktree: applyWorktreeSettingsPatch(config.worktree, patch) });
|
|
14
|
+
return this.getWorktreeSettings();
|
|
15
|
+
},
|
|
16
|
+
};
|
|
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,
|