mixdog 0.9.95 → 0.9.96
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/LICENSES/Apache-2.0.txt +201 -0
- package/LICENSES/MIT.txt +56 -0
- package/LICENSES/codex-NOTICE.txt +6 -0
- package/NOTICE.md +46 -9
- package/package.json +12 -9
- package/scripts/.tmp-coverage-report.mjs +96 -0
- package/scripts/build-tui.mjs +17 -1
- package/scripts/fixtures/patch-replay-corpus.json +98 -0
- package/src/defaults/mixdog-config.template.json +5 -8
- package/src/rules/agent/30-explorer.md +7 -4
- package/src/rules/shared/01-tool.md +20 -29
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +31 -1
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +6 -17
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +12 -1
- package/src/runtime/agent/orchestrator/config.mjs +246 -67
- package/src/runtime/agent/orchestrator/mcp/client.mjs +26 -11
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +23 -0
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +113 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +32 -11
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +89 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +144 -39
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +22 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/openai-transport-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +3 -4
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +67 -7
- package/src/runtime/agent/orchestrator/providers/stream-json-pool.mjs +291 -0
- package/src/runtime/agent/orchestrator/providers/stream-json-worker.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -33
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +0 -24
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +1 -27
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +6 -10
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +142 -84
- package/src/runtime/agent/orchestrator/session/manager/runtime-loaders.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +31 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +29 -9
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +86 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +3 -33
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -5
- package/src/runtime/agent/orchestrator/stall-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +35 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +118 -18
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +8 -9
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +6 -15
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +10 -26
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -23
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +23 -9
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +7 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +17 -39
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +73 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +0 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +3 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +30 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +87 -15
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +6 -15
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/lib/pwsh-standby-pool.mjs +83 -13
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +39 -1
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +29 -1
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +16 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +108 -12
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +10 -10
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +56 -8
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +2 -2
- package/src/runtime/channels/lib/config.mjs +2 -2
- package/src/runtime/channels/lib/inbound-handler.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +2 -2
- package/src/runtime/memory/index.mjs +5 -38
- package/src/runtime/memory/lib/agent-ipc.mjs +145 -81
- package/src/runtime/memory/lib/compact-vector-cache.mjs +88 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +18 -1
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +12 -33
- package/src/runtime/memory/lib/embedding-provider.mjs +47 -26
- package/src/runtime/memory/lib/embedding-worker.mjs +30 -34
- package/src/runtime/memory/lib/http-router.mjs +8 -0
- package/src/runtime/memory/lib/ko-morph.mjs +3 -20
- package/src/runtime/memory/lib/memory-action-handlers.mjs +2 -1
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -0
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +4 -2
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +1 -0
- package/src/runtime/memory/lib/memory-cycle3.mjs +3 -1
- package/src/runtime/memory/lib/pg/process.mjs +32 -9
- package/src/runtime/memory/tool-defs.mjs +1 -5
- package/src/runtime/search/tool-defs.mjs +2 -2
- package/src/runtime/shared/agent-route-config.mjs +119 -0
- package/src/runtime/shared/atomic-file.mjs +80 -4
- package/src/runtime/shared/channel-notification-routing.mjs +2 -2
- package/src/runtime/shared/child-guardian.mjs +204 -108
- package/src/runtime/shared/child-spawn-gate.mjs +60 -31
- package/src/runtime/shared/config.mjs +130 -44
- package/src/runtime/shared/resource-admission.mjs +146 -97
- package/src/runtime/shared/stream-progress.mjs +6 -0
- package/src/runtime/shared/tool-surface.mjs +0 -5
- package/src/runtime/shared/turn-snapshot.mjs +31 -5
- package/src/runtime/shared/turn-worktree-snapshot.mjs +14 -2
- package/src/session-runtime/config-helpers.mjs +39 -37
- package/src/session-runtime/model-route-api.mjs +7 -5
- package/src/session-runtime/provider-auth-api.mjs +0 -7
- package/src/session-runtime/runtime-core.mjs +11 -11
- package/src/session-runtime/runtime-tunables.mjs +4 -4
- package/src/session-runtime/session-lifecycle.mjs +9 -2
- package/src/session-runtime/session-turn-api.mjs +41 -9
- package/src/session-runtime/settings-api.mjs +5 -17
- package/src/session-runtime/tool-defs.mjs +3 -3
- package/src/session-runtime/workflow-agents-api.mjs +55 -81
- package/src/session-runtime/workflow.mjs +14 -24
- package/src/standalone/agent-dispatch-broker.mjs +198 -0
- package/src/standalone/agent-tool/helpers.mjs +2 -2
- package/src/standalone/agent-tool/spawn-flow.mjs +2 -0
- package/src/standalone/agent-tool/spawn-preset.mjs +11 -21
- package/src/standalone/agent-tool/tool-def.mjs +0 -14
- package/src/standalone/backend-daemon.mjs +97 -36
- package/src/standalone/channel-admin.mjs +12 -12
- package/src/standalone/channel-daemon-client.mjs +17 -1
- package/src/standalone/channel-daemon-transport.mjs +90 -8
- package/src/standalone/engine-daemon-client.mjs +380 -205
- package/src/standalone/engine-daemon-protocol.mjs +3 -4
- package/src/standalone/engine-daemon-service.mjs +378 -134
- package/src/standalone/engine-daemon-transport.mjs +268 -77
- package/src/standalone/explore-tool.mjs +187 -70
- package/src/standalone/fair-call-scheduler.mjs +264 -0
- package/src/standalone/session-protocol.mjs +188 -0
- package/src/tui/App.jsx +30 -17
- package/src/tui/app/app-view.jsx +5 -2
- package/src/tui/app/core-memory-picker.mjs +19 -19
- package/src/tui/app/doctor.mjs +5 -11
- package/src/tui/app/message-selector.mjs +103 -0
- package/src/tui/app/onboarding-steps.mjs +1 -2
- package/src/tui/app/project-picker.mjs +80 -56
- package/src/tui/app/prompt-submit.mjs +46 -41
- package/src/tui/app/resume-picker.mjs +2 -2
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker.mjs +6 -8
- package/src/tui/app/transcript-window.mjs +38 -0
- package/src/tui/app/use-prompt-draft-flow.mjs +5 -7
- package/src/tui/app/use-prompt-handlers.mjs +86 -21
- package/src/tui/app/use-prompt-hint.mjs +3 -2
- package/src/tui/app/use-prompt-queue-history.mjs +10 -3
- package/src/tui/app/use-transcript-scroll.mjs +9 -2
- package/src/tui/app/use-transcript-window.mjs +50 -17
- package/src/tui/components/PromptInput.jsx +71 -38
- package/src/tui/components/Spinner.jsx +1 -1
- package/src/tui/components/prompt-input/edit-helpers.mjs +9 -11
- package/src/tui/components/prompt-input/escape-policy.mjs +42 -0
- package/src/tui/components/prompt-input/immediate-render.mjs +0 -10
- package/src/tui/components/prompt-input/interrupt-policy.mjs +10 -0
- package/src/tui/components/prompt-input/restore-policy.mjs +10 -0
- package/src/tui/dist/index.mjs +920 -1592
- package/src/tui/engine/live-share.mjs +34 -0
- package/src/tui/engine/session-api-ext.mjs +1 -4
- package/src/tui/engine/session-api.mjs +103 -33
- package/src/tui/engine/session-flow.mjs +7 -1
- package/src/tui/engine/tool-card-results.mjs +4 -2
- package/src/tui/engine/tool-result-text.mjs +10 -0
- package/src/tui/engine/turn.mjs +9 -69
- package/src/tui/engine-local-session.mjs +47 -31
- package/src/tui/index.jsx +1 -2
- package/src/tui/spinner-meta.mjs +4 -4
- package/src/tui/spinner-verbs.mjs +51 -3
- package/src/standalone/engine-daemon-local-bridge.mjs +0 -20
|
@@ -83,6 +83,8 @@ function createDiffTracker(meta = {}) {
|
|
|
83
83
|
return {
|
|
84
84
|
ownerSessionId: clean(meta.ownerSessionId) || null,
|
|
85
85
|
ownerGeneration: Number(meta.ownerGeneration) || 0,
|
|
86
|
+
worktreeRequest: clean(meta.worktreeRequest),
|
|
87
|
+
worktreeContended: false,
|
|
86
88
|
valid: true,
|
|
87
89
|
sealed: false,
|
|
88
90
|
revision: 0,
|
|
@@ -336,13 +338,31 @@ export async function beginTurnSnapshot(_worktree, sessionId) {
|
|
|
336
338
|
generation,
|
|
337
339
|
agents: new Map(),
|
|
338
340
|
});
|
|
339
|
-
const
|
|
341
|
+
const worktreeRequest = pathKey(_worktree);
|
|
342
|
+
const tracker = resetDiffTracker(ownerSessionId, { worktreeRequest });
|
|
340
343
|
trimTurnCache();
|
|
341
344
|
if (!tracker) return;
|
|
345
|
+
for (const [otherSessionId, other] of _diffTrackersBySession) {
|
|
346
|
+
if (otherSessionId === ownerSessionId || other.sealed) continue;
|
|
347
|
+
if (!worktreeRequest || other.worktreeRequest !== worktreeRequest) continue;
|
|
348
|
+
tracker.worktreeContended = true;
|
|
349
|
+
other.worktreeContended = true;
|
|
350
|
+
}
|
|
342
351
|
try {
|
|
343
352
|
const snapshot = await createTurnWorktreeSnapshot(_worktree);
|
|
344
353
|
if (_diffTrackersBySession.get(ownerSessionId) === tracker) {
|
|
345
354
|
tracker.worktreeSnapshot = snapshot;
|
|
355
|
+
if (snapshot?.root) {
|
|
356
|
+
for (const [otherSessionId, other] of _diffTrackersBySession) {
|
|
357
|
+
if (otherSessionId === ownerSessionId) continue;
|
|
358
|
+
if (other.worktreeSnapshot?.root !== snapshot.root) continue;
|
|
359
|
+
// A whole-worktree baseline cannot attribute concurrent mutations
|
|
360
|
+
// to either session. Mark both turns permanently contended and fall
|
|
361
|
+
// back to their exact session-owned mutation trackers.
|
|
362
|
+
tracker.worktreeContended = true;
|
|
363
|
+
other.worktreeContended = true;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
346
366
|
}
|
|
347
367
|
} catch {
|
|
348
368
|
// Git is optional. Exact apply_patch tracking remains the fallback.
|
|
@@ -421,7 +441,7 @@ export function completeAgentTurnReview(handle, patches = []) {
|
|
|
421
441
|
export async function completeTurnSnapshot(sessionId) {
|
|
422
442
|
const tracker = _diffTrackersBySession.get(clean(sessionId));
|
|
423
443
|
if (!tracker) return false;
|
|
424
|
-
if (tracker.worktreeSnapshot) {
|
|
444
|
+
if (tracker.worktreeSnapshot && !tracker.worktreeContended) {
|
|
425
445
|
try { await refreshTurnWorktreeSnapshot(tracker.worktreeSnapshot); } catch {}
|
|
426
446
|
}
|
|
427
447
|
tracker.sealed = true;
|
|
@@ -435,10 +455,13 @@ export async function getTurnReviewDiff(_worktree, sessionId) {
|
|
|
435
455
|
const ownerSessionId = clean(sessionId);
|
|
436
456
|
const turn = _turnsBySession.get(ownerSessionId);
|
|
437
457
|
const tracker = _diffTrackersBySession.get(ownerSessionId);
|
|
438
|
-
|
|
439
|
-
|
|
458
|
+
const isolatedWorktreeSnapshot = tracker?.worktreeContended
|
|
459
|
+
? null
|
|
460
|
+
: tracker?.worktreeSnapshot || null;
|
|
461
|
+
if (isolatedWorktreeSnapshot && !tracker.sealed) {
|
|
462
|
+
try { await refreshTurnWorktreeSnapshot(isolatedWorktreeSnapshot); } catch {}
|
|
440
463
|
}
|
|
441
|
-
const snapshot =
|
|
464
|
+
const snapshot = isolatedWorktreeSnapshot;
|
|
442
465
|
return {
|
|
443
466
|
supported: true,
|
|
444
467
|
files: snapshot?.files || [],
|
|
@@ -455,6 +478,9 @@ export async function getTurnReviewDiff(_worktree, sessionId) {
|
|
|
455
478
|
export async function revertTurnReviewFile(_worktree, sessionId, file) {
|
|
456
479
|
const ownerSessionId = clean(sessionId);
|
|
457
480
|
const tracker = _diffTrackersBySession.get(ownerSessionId);
|
|
481
|
+
if (tracker?.worktreeContended) {
|
|
482
|
+
throw new Error('turn review revert is unavailable while sessions share a worktree');
|
|
483
|
+
}
|
|
458
484
|
if (!tracker?.worktreeSnapshot) throw new Error('turn worktree snapshot is unavailable');
|
|
459
485
|
await revertTurnWorktreeFile(tracker.worktreeSnapshot, file);
|
|
460
486
|
return await getTurnReviewDiff(_worktree, ownerSessionId);
|
|
@@ -43,15 +43,17 @@ function runGit(args, {
|
|
|
43
43
|
allowFailure = false,
|
|
44
44
|
} = {}) {
|
|
45
45
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
46
|
+
const hasInput = (typeof input === 'string' || Buffer.isBuffer(input)) && input.length > 0;
|
|
46
47
|
const child = spawn('git', args, {
|
|
47
48
|
cwd,
|
|
48
49
|
windowsHide: true,
|
|
49
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
50
|
+
stdio: [hasInput ? 'pipe' : 'ignore', 'pipe', 'pipe'],
|
|
50
51
|
});
|
|
51
52
|
const stdout = [];
|
|
52
53
|
const stderr = [];
|
|
53
54
|
let stdoutBytes = 0;
|
|
54
55
|
let stderrBytes = 0;
|
|
56
|
+
let stdinError = null;
|
|
55
57
|
let settled = false;
|
|
56
58
|
const finish = (error, result) => {
|
|
57
59
|
if (settled) return;
|
|
@@ -93,9 +95,19 @@ function runGit(args, {
|
|
|
93
95
|
finish(commandError(args, result.stderr, result.code));
|
|
94
96
|
return;
|
|
95
97
|
}
|
|
98
|
+
if (stdinError && result.code === 0) {
|
|
99
|
+
finish(stdinError);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
96
102
|
finish(null, result);
|
|
97
103
|
});
|
|
98
|
-
child.stdin
|
|
104
|
+
if (child.stdin) {
|
|
105
|
+
// A short-lived git command can close before Node flushes stdin. Keep
|
|
106
|
+
// that transport race inside this promise instead of emitting an
|
|
107
|
+
// unhandled EPIPE that terminates the entire release validator.
|
|
108
|
+
child.stdin.on('error', (error) => { stdinError = error; });
|
|
109
|
+
child.stdin.end(input);
|
|
110
|
+
}
|
|
99
111
|
});
|
|
100
112
|
}
|
|
101
113
|
|
|
@@ -7,11 +7,13 @@ import { routeFastKey, fastPreferenceFor } from './model-capabilities.mjs';
|
|
|
7
7
|
export const DEFAULT_PROVIDER = 'anthropic-oauth';
|
|
8
8
|
export const DEFAULT_MODEL = '';
|
|
9
9
|
|
|
10
|
-
// Resolve
|
|
11
|
-
//
|
|
10
|
+
// Resolve a provider-less MAIN selector against the selected Main preset.
|
|
11
|
+
// DEFAULT_PROVIDER is only the unconfigured bootstrap fallback (model remains
|
|
12
|
+
// empty); agent/search override resolution never calls this to synthesize one.
|
|
12
13
|
export function makeResolveDefaultProvider(isKnownProvider) {
|
|
13
14
|
return function resolveDefaultProvider(config) {
|
|
14
|
-
const
|
|
15
|
+
const selectedMain = findPreset(config, config?.default);
|
|
16
|
+
const configured = clean(selectedMain?.provider);
|
|
15
17
|
if (configured && isKnownProvider(configured)) return configured;
|
|
16
18
|
return DEFAULT_PROVIDER;
|
|
17
19
|
};
|
|
@@ -46,16 +48,18 @@ export function makeResolveRoute(resolveDefaultProvider) {
|
|
|
46
48
|
if (explicitModel && !explicitProvider) {
|
|
47
49
|
const preset = findPreset(config, explicitModel);
|
|
48
50
|
if (preset) {
|
|
49
|
-
const p = clean(preset.provider)
|
|
51
|
+
const p = clean(preset.provider);
|
|
50
52
|
const m = clean(preset.model) || DEFAULT_MODEL;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
if (p && m) {
|
|
54
|
+
const saved = modelSettingsFor(config, p, m);
|
|
55
|
+
return {
|
|
56
|
+
provider: p,
|
|
57
|
+
model: m,
|
|
58
|
+
preset,
|
|
59
|
+
effort: hasExplicitEffort ? explicitEffort : normalizeSavedEffort(saved.effort ?? preset.effort),
|
|
60
|
+
fast: hasExplicitFast ? explicitFast : (hasOwn(saved, 'fast') ? saved.fast === true : (preset.fast === true || fastPreferenceFor(config, p, m))),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
|
|
@@ -63,16 +67,18 @@ export function makeResolveRoute(resolveDefaultProvider) {
|
|
|
63
67
|
const defaultKey = config?.default;
|
|
64
68
|
const preset = findPreset(config, defaultKey);
|
|
65
69
|
if (preset) {
|
|
66
|
-
const p = clean(preset.provider)
|
|
70
|
+
const p = clean(preset.provider);
|
|
67
71
|
const m = clean(preset.model) || DEFAULT_MODEL;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
if (p && m) {
|
|
73
|
+
const saved = modelSettingsFor(config, p, m);
|
|
74
|
+
return {
|
|
75
|
+
provider: p,
|
|
76
|
+
model: m,
|
|
77
|
+
preset,
|
|
78
|
+
effort: hasExplicitEffort ? explicitEffort : normalizeSavedEffort(saved.effort ?? preset.effort),
|
|
79
|
+
fast: hasExplicitFast ? explicitFast : (hasOwn(saved, 'fast') ? saved.fast === true : (preset.fast === true || fastPreferenceFor(config, p, m))),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
|
|
@@ -197,14 +203,14 @@ export function resolveAgentTerminalReapMs(config, provider) {
|
|
|
197
203
|
// fall back to the provider's default; else the global 1h default.
|
|
198
204
|
export function resolveAutoClearIdleMs(config, provider) {
|
|
199
205
|
const raw = config?.autoClear && typeof config.autoClear === 'object' ? config.autoClear : {};
|
|
200
|
-
const idleMs = Number(raw.idleMs
|
|
206
|
+
const idleMs = Number(raw.idleMs);
|
|
201
207
|
if (Number.isFinite(idleMs) && idleMs > 0) return Math.max(60_000, Math.round(idleMs));
|
|
202
|
-
return autoClearIdleMsForProvider(provider, raw.providerIdleMs
|
|
208
|
+
return autoClearIdleMsForProvider(provider, raw.providerIdleMs);
|
|
203
209
|
}
|
|
204
210
|
|
|
205
211
|
export function normalizeSystemShellConfig(value = {}) {
|
|
206
212
|
const raw = value && typeof value === 'object' ? value : {};
|
|
207
|
-
const command = clean(raw.command
|
|
213
|
+
const command = clean(raw.command);
|
|
208
214
|
const envCommand = clean(process.env.MIXDOG_SHELL);
|
|
209
215
|
return {
|
|
210
216
|
command,
|
|
@@ -227,7 +233,7 @@ export function normalizeSystemShellCommand(value) {
|
|
|
227
233
|
|
|
228
234
|
export function normalizeAutoClearConfig(value = {}) {
|
|
229
235
|
const raw = value && typeof value === 'object' ? value : {};
|
|
230
|
-
const idleMs = Number(raw.idleMs
|
|
236
|
+
const idleMs = Number(raw.idleMs);
|
|
231
237
|
const hasExplicitIdle = Number.isFinite(idleMs) && idleMs > 0;
|
|
232
238
|
const rawMinPct = Number(raw.minContextPercent);
|
|
233
239
|
const minContextPercent = Number.isFinite(rawMinPct)
|
|
@@ -241,7 +247,7 @@ export function normalizeAutoClearConfig(value = {}) {
|
|
|
241
247
|
enabled: raw.enabled !== false,
|
|
242
248
|
idleMs: hasExplicitIdle ? Math.max(60_000, Math.round(idleMs)) : null,
|
|
243
249
|
custom: hasExplicitIdle,
|
|
244
|
-
providerIdleMs: normalizeAutoClearProviderIdleMs(raw.providerIdleMs
|
|
250
|
+
providerIdleMs: normalizeAutoClearProviderIdleMs(raw.providerIdleMs),
|
|
245
251
|
minContextPercent,
|
|
246
252
|
};
|
|
247
253
|
}
|
|
@@ -254,16 +260,15 @@ export function normalizeCompactTypeSetting(value, fallback = 'recall-fasttrack'
|
|
|
254
260
|
return fallback;
|
|
255
261
|
}
|
|
256
262
|
|
|
257
|
-
export function normalizeCompactionConfig(value = {}
|
|
263
|
+
export function normalizeCompactionConfig(value = {}) {
|
|
258
264
|
const raw = value && typeof value === 'object' ? value : {};
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
void memoryEnabled;
|
|
265
|
+
const compactType = normalizeCompactTypeSetting(raw.type, 'recall-fasttrack');
|
|
266
|
+
const next = { ...raw };
|
|
267
|
+
delete next.compactType;
|
|
268
|
+
delete next.compact_type;
|
|
269
|
+
delete next.enabled;
|
|
265
270
|
return {
|
|
266
|
-
...
|
|
271
|
+
...next,
|
|
267
272
|
auto: raw.auto !== false && raw.enabled !== false,
|
|
268
273
|
type: compactType,
|
|
269
274
|
compactType,
|
|
@@ -284,9 +289,6 @@ export function moduleEnabled(configLike, name, fallback = true) {
|
|
|
284
289
|
export function recapEnabled(configLike, fallback = true) {
|
|
285
290
|
const entry = configLike?.recap;
|
|
286
291
|
if (entry && typeof entry === 'object' && entry.enabled === false) return false;
|
|
287
|
-
// Legacy fallback: pre-migration configs may still carry modules.memory=false.
|
|
288
|
-
if (configLike?.modules?.memory === false) return false;
|
|
289
|
-
if (moduleEnabled(configLike, 'memory', true) === false) return false;
|
|
290
292
|
return fallback !== false;
|
|
291
293
|
}
|
|
292
294
|
|
|
@@ -64,11 +64,13 @@ export function createModelRouteApi(deps) {
|
|
|
64
64
|
return await collectSearchProviderModels({ force: options.force === true || options.refresh === true });
|
|
65
65
|
},
|
|
66
66
|
async setSearchRoute(next) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
let selectedRoute = clean(next?.provider)
|
|
68
|
+
? normalizeSearchRouteConfig(next)
|
|
69
|
+
: normalizeSearchRouteConfig({
|
|
70
|
+
provider: SEARCH_DEFAULT_PROVIDER,
|
|
71
|
+
model: SEARCH_DEFAULT_MODEL,
|
|
72
|
+
...(next?.toolType ? { toolType: next.toolType } : {}),
|
|
73
|
+
});
|
|
72
74
|
if (!selectedRoute) throw new Error('search route requires provider and model');
|
|
73
75
|
if (isDefaultSearchRouteConfig(selectedRoute)) {
|
|
74
76
|
await awaitKeychainPrewarm();
|
|
@@ -193,12 +193,5 @@ export function createProviderAuthApi({
|
|
|
193
193
|
quick: options.quick === true,
|
|
194
194
|
});
|
|
195
195
|
},
|
|
196
|
-
async setDefaultProvider(provider) {
|
|
197
|
-
const requested = clean(provider);
|
|
198
|
-
if (!requested) throw new Error('provider is required');
|
|
199
|
-
if (!isKnownProvider(requested)) throw new Error(`unknown provider "${provider}"`);
|
|
200
|
-
saveConfigAndAdopt({ ...getConfig(), defaultProvider: requested });
|
|
201
|
-
return requested;
|
|
202
|
-
},
|
|
203
196
|
};
|
|
204
197
|
}
|
|
@@ -428,11 +428,8 @@ export async function createMixdogSessionRuntime({
|
|
|
428
428
|
rt.searchModPromise = null;
|
|
429
429
|
rt.codeGraphModPromise = null;
|
|
430
430
|
|
|
431
|
-
// Memory
|
|
432
|
-
//
|
|
433
|
-
// the user-facing toggle is `recap` (background cycles only), read via
|
|
434
|
-
// recapEnabled(config).
|
|
435
|
-
const memoryEnabled = () => true;
|
|
431
|
+
// Memory is always-on. The user-facing toggle is `recap` (background cycles
|
|
432
|
+
// only), read via recapEnabled(config).
|
|
436
433
|
const recapEnabledFn = () => recapEnabled(rt.config, true);
|
|
437
434
|
const channelsEnabled = () => moduleEnabled(rt.config, 'channels', true);
|
|
438
435
|
|
|
@@ -469,10 +466,6 @@ export async function createMixdogSessionRuntime({
|
|
|
469
466
|
|
|
470
467
|
const nextConfig = { ...(rt.config || {}) };
|
|
471
468
|
nextConfig.presets = upsertWorkflowPreset(nextConfig.presets, 'lead', leadRoute);
|
|
472
|
-
nextConfig.workflowRoutes = {
|
|
473
|
-
...(nextConfig.workflowRoutes || {}),
|
|
474
|
-
lead: leadRoute,
|
|
475
|
-
};
|
|
476
469
|
nextConfig.default = workflowPresetId('lead');
|
|
477
470
|
|
|
478
471
|
saveConfigAndAdopt(nextConfig);
|
|
@@ -1198,7 +1191,6 @@ export async function createMixdogSessionRuntime({
|
|
|
1198
1191
|
reg,
|
|
1199
1192
|
cfgMod,
|
|
1200
1193
|
activeWorkflowContext,
|
|
1201
|
-
memoryEnabled,
|
|
1202
1194
|
hooks,
|
|
1203
1195
|
hookCommonPayload,
|
|
1204
1196
|
mcpClient,
|
|
@@ -1368,7 +1360,6 @@ export async function createMixdogSessionRuntime({
|
|
|
1368
1360
|
parseDurationMs,
|
|
1369
1361
|
formatDurationMs,
|
|
1370
1362
|
localPackageVersion,
|
|
1371
|
-
memoryEnabled,
|
|
1372
1363
|
recapEnabledFn,
|
|
1373
1364
|
channelsEnabled,
|
|
1374
1365
|
autoUpdateEnabled,
|
|
@@ -1651,6 +1642,15 @@ export async function createMixdogSessionRuntime({
|
|
|
1651
1642
|
throw new Error(`session ${rt.session.id} is already materialized`);
|
|
1652
1643
|
}
|
|
1653
1644
|
rt.reservedSessionId = id;
|
|
1645
|
+
// Reservation is the earliest safe point to prepare keychain, memory,
|
|
1646
|
+
// provider metadata, hooks, and the provider transport. This starts no
|
|
1647
|
+
// model response and therefore incurs no inference/token usage. The first
|
|
1648
|
+
// submit joins this single-flight promise instead of paying cold setup.
|
|
1649
|
+
void createCurrentSession('reservation').catch((error) => {
|
|
1650
|
+
bootProfile('session:reservation-prewarm-failed', {
|
|
1651
|
+
error: error?.message || String(error),
|
|
1652
|
+
});
|
|
1653
|
+
});
|
|
1654
1654
|
return id;
|
|
1655
1655
|
},
|
|
1656
1656
|
get provider() {
|
|
@@ -24,10 +24,10 @@ export function readRuntimeTunables() {
|
|
|
24
24
|
statuslineUsageRefreshDelayMs: envDelayMs('MIXDOG_STATUSLINE_USAGE_REFRESH_MS', 240_000, { min: 30_000, max: 540_000 }),
|
|
25
25
|
channelStartDelayMs: envDelayMs('MIXDOG_CHANNEL_START_DELAY_MS', 10_000, { min: 0, max: 120_000 }),
|
|
26
26
|
backgroundBusyRetryMs: envDelayMs('MIXDOG_BACKGROUND_BUSY_RETRY_MS', 1_000, { min: 50, max: 10_000 }),
|
|
27
|
-
// MCP startup
|
|
28
|
-
//
|
|
29
|
-
// late-tool announcement path
|
|
30
|
-
mcpTurnGraceMs: envDelayMs('MIXDOG_MCP_TURN_GRACE_MS',
|
|
27
|
+
// MCP startup never owns the first-token critical path by default. Already
|
|
28
|
+
// connected tools fold synchronously; in-flight servers join through the
|
|
29
|
+
// late-tool announcement path. Operators may opt back into a grace window.
|
|
30
|
+
mcpTurnGraceMs: envDelayMs('MIXDOG_MCP_TURN_GRACE_MS', 0, { min: 0, max: 2_000 }),
|
|
31
31
|
// Boot-time remote start is deferred past the first frame; see the caller.
|
|
32
32
|
remoteAutoStartDelayMs: envDelayMs('MIXDOG_REMOTE_AUTOSTART_DELAY_MS', 1_500, { min: 0, max: 60_000 }),
|
|
33
33
|
providerWarmupEnabled: !envFlag('MIXDOG_DISABLE_PROVIDER_WARMUP')
|
|
@@ -30,7 +30,6 @@ export function createSessionLifecycle({
|
|
|
30
30
|
reg,
|
|
31
31
|
cfgMod,
|
|
32
32
|
activeWorkflowContext,
|
|
33
|
-
memoryEnabled,
|
|
34
33
|
hooks,
|
|
35
34
|
hookCommonPayload,
|
|
36
35
|
mcpClient,
|
|
@@ -140,6 +139,14 @@ export function createSessionLifecycle({
|
|
|
140
139
|
|
|
141
140
|
const startedAt = performance.now();
|
|
142
141
|
bootProfile('session:create:start', { mode: rt.mode, reason });
|
|
142
|
+
// A daemon reservation is deliberate user-think-time prewarm. Start the
|
|
143
|
+
// one-time agent-loop module load now so the first real prompt does not pay
|
|
144
|
+
// its ~100ms dynamic-import graph immediately before provider.send.
|
|
145
|
+
if (reason === 'reservation' && typeof mgr.prewarmAgentLoop === 'function') {
|
|
146
|
+
void mgr.prewarmAgentLoop().catch((error) => {
|
|
147
|
+
bootProfile('agent-loop:prewarm-failed', { error: error?.message || String(error) });
|
|
148
|
+
});
|
|
149
|
+
}
|
|
143
150
|
const promise = (async () => {
|
|
144
151
|
// Demand-only: this starts only after the user submits (unless an
|
|
145
152
|
// explicitly enabled prewarm caller asks for a session). Core-memory
|
|
@@ -187,7 +194,7 @@ export function createSessionLifecycle({
|
|
|
187
194
|
workflowContext,
|
|
188
195
|
fast: rt.route.fast === true,
|
|
189
196
|
compaction: rt.config.compaction && typeof rt.config.compaction === 'object'
|
|
190
|
-
? normalizeCompactionConfig(rt.config.compaction
|
|
197
|
+
? normalizeCompactionConfig(rt.config.compaction)
|
|
191
198
|
: undefined,
|
|
192
199
|
};
|
|
193
200
|
if (hasOwn(rt.route, 'effort') || rt.route.effectiveEffort) {
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { getMcpTools } from '../runtime/agent/orchestrator/mcp/client.mjs';
|
|
13
13
|
import { traceTurnTiming } from '../runtime/agent/orchestrator/agent-trace.mjs';
|
|
14
14
|
import { beginTurnSnapshot, completeTurnSnapshot } from '../runtime/shared/turn-snapshot.mjs';
|
|
15
|
+
import { isVisibleStreamProgress } from '../runtime/shared/stream-progress.mjs';
|
|
15
16
|
|
|
16
17
|
export function splitToolStatusCounts(rows) {
|
|
17
18
|
const list = Array.isArray(rows) ? rows : [];
|
|
@@ -44,7 +45,7 @@ export function createSessionTurnApi(deps) {
|
|
|
44
45
|
scheduleProviderWarmup, scheduleProviderModelWarmup, invalidateContextStatusCache,
|
|
45
46
|
agentTool, recreateCurrentSessionIfReady, invalidatePreSessionToolSurface,
|
|
46
47
|
activeToolSurface, applyResolvedCwd, resolveCwdPath, agentStatusState, notificationListeners,
|
|
47
|
-
awaitInitialMcpConnect, mcpTurnGraceMs =
|
|
48
|
+
awaitInitialMcpConnect, mcpTurnGraceMs = 0, awaitRoutePreparation,
|
|
48
49
|
getReservedSessionId, sessionTitles,
|
|
49
50
|
} = deps;
|
|
50
51
|
const enqueueRemoteAttachedPrompt = (prompt) => {
|
|
@@ -79,7 +80,14 @@ export function createSessionTurnApi(deps) {
|
|
|
79
80
|
// a normal user turn and this surface refreshes from disk.
|
|
80
81
|
const attachedSession = getSession();
|
|
81
82
|
if (attachedSession?.remoteAttached) {
|
|
82
|
-
|
|
83
|
+
// Carry the submission id into the spool: the owner reuses it for the
|
|
84
|
+
// queue entry and the settled user row, so the submitting surface's
|
|
85
|
+
// optimistic bubble is released instead of standing beside the
|
|
86
|
+
// mirrored twin (user: 같은 세션에서 메세지가 두 개로 보인다).
|
|
87
|
+
const submissionId = String(options.id || '').trim();
|
|
88
|
+
const delivered = enqueueRemoteAttachedPrompt(
|
|
89
|
+
submissionId ? { content: prompt, id: submissionId } : prompt,
|
|
90
|
+
);
|
|
83
91
|
return {
|
|
84
92
|
// This branch is only a race-safe fallback for callers that reached
|
|
85
93
|
// ask() before the live pipe was ready. Never manufacture an
|
|
@@ -117,9 +125,10 @@ export function createSessionTurnApi(deps) {
|
|
|
117
125
|
let turnTimingEmitted = false;
|
|
118
126
|
// Heavy runtime warmup is one-shot and demand-driven: idle desktop panes
|
|
119
127
|
// never spawn shell/token/shard helpers or a code-graph worker. More
|
|
120
|
-
// importantly, do not start them until the provider has produced
|
|
121
|
-
//
|
|
122
|
-
//
|
|
128
|
+
// importantly, do not start them until the provider has produced visible
|
|
129
|
+
// text/reasoning/tool progress: transport headers and response-created
|
|
130
|
+
// acknowledgements arrive earlier and would make PowerShell + graph
|
|
131
|
+
// workers compete with the actual first-token critical path.
|
|
123
132
|
const heavyRuntimeWarmupPending = typeof getCodeGraphFirstTurnPrewarmDone === 'function'
|
|
124
133
|
&& !getCodeGraphFirstTurnPrewarmDone();
|
|
125
134
|
if (heavyRuntimeWarmupPending) {
|
|
@@ -264,7 +273,6 @@ export function createSessionTurnApi(deps) {
|
|
|
264
273
|
.map((part) => String(part || '').trim())
|
|
265
274
|
.filter(Boolean)
|
|
266
275
|
.join('\n\n');
|
|
267
|
-
providerStartedAt = performance.now();
|
|
268
276
|
const result = await mgr.askSession(
|
|
269
277
|
session0.id,
|
|
270
278
|
prompt,
|
|
@@ -322,14 +330,26 @@ export function createSessionTurnApi(deps) {
|
|
|
322
330
|
onToolApproval: options.onToolApproval,
|
|
323
331
|
onCompactEvent: options.onCompactEvent,
|
|
324
332
|
onStageChange: options.onStageChange,
|
|
333
|
+
onProviderSendStarted: (...args) => {
|
|
334
|
+
// This callback is emitted immediately before provider.send,
|
|
335
|
+
// after session locking, history shaping and pre-send compact.
|
|
336
|
+
// The old timestamp above mgr.askSession mislabeled all of that
|
|
337
|
+
// Mixdog work as provider latency.
|
|
338
|
+
if (!providerStartedAt) providerStartedAt = performance.now();
|
|
339
|
+
return options.onProviderSendStarted?.(...args);
|
|
340
|
+
},
|
|
341
|
+
onToolPhaseStarted: options.onToolPhaseStarted,
|
|
342
|
+
onToolPhaseCompleted: options.onToolPhaseCompleted,
|
|
325
343
|
onStreamDelta: (...args) => {
|
|
326
344
|
let value;
|
|
327
345
|
try {
|
|
328
346
|
value = options.onStreamDelta?.(...args);
|
|
329
347
|
} finally {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
348
|
+
if (isVisibleStreamProgress(args[0])) {
|
|
349
|
+
turnTimingStatus = 'first-visible';
|
|
350
|
+
emitTurnTiming(turnTimingStatus);
|
|
351
|
+
armHeavyRuntimeWarmup('first-visible');
|
|
352
|
+
}
|
|
333
353
|
}
|
|
334
354
|
return value;
|
|
335
355
|
},
|
|
@@ -399,6 +419,18 @@ export function createSessionTurnApi(deps) {
|
|
|
399
419
|
pushTranscriptRebind?.();
|
|
400
420
|
return true;
|
|
401
421
|
},
|
|
422
|
+
// Message-selector rewind: drop the chosen user prompt and everything
|
|
423
|
+
// after it from the model history. Unlike clear() the session object is
|
|
424
|
+
// kept (same id, same provider/model/cwd) — only the tail is undone.
|
|
425
|
+
async rewindMessages(options = {}) {
|
|
426
|
+
const session = getSession();
|
|
427
|
+
if (!session?.id) return null;
|
|
428
|
+
const result = await mgr.rewindSessionMessagesTo?.(session.id, options);
|
|
429
|
+
if (!result) return null;
|
|
430
|
+
setSession(mgr.getSession(session.id) || session);
|
|
431
|
+
invalidateContextStatusCache();
|
|
432
|
+
return result;
|
|
433
|
+
},
|
|
402
434
|
// session_manage tool handoff: the engine polls this at turn end and, if
|
|
403
435
|
// set, runs the same clear path the idle auto-clear uses. One-shot read.
|
|
404
436
|
consumePendingSessionReset() {
|
|
@@ -35,7 +35,6 @@ export function createSettingsApi({
|
|
|
35
35
|
formatDurationMs,
|
|
36
36
|
localPackageVersion,
|
|
37
37
|
// state getters / feature flags
|
|
38
|
-
memoryEnabled,
|
|
39
38
|
recapEnabledFn,
|
|
40
39
|
channelsEnabled,
|
|
41
40
|
autoUpdateEnabled,
|
|
@@ -173,11 +172,11 @@ export function createSettingsApi({
|
|
|
173
172
|
},
|
|
174
173
|
getCompactionSettings() {
|
|
175
174
|
const config = getConfig();
|
|
176
|
-
return normalizeCompactionConfig(config.compaction
|
|
175
|
+
return normalizeCompactionConfig(config.compaction);
|
|
177
176
|
},
|
|
178
177
|
setCompactionSettings(input = {}) {
|
|
179
178
|
const config = getConfig();
|
|
180
|
-
const current = normalizeCompactionConfig(config.compaction
|
|
179
|
+
const current = normalizeCompactionConfig(config.compaction);
|
|
181
180
|
const next = { ...current };
|
|
182
181
|
if (hasOwn(input, 'auto')) next.auto = input.auto !== false;
|
|
183
182
|
if (hasOwn(input, 'enabled')) next.auto = input.enabled !== false;
|
|
@@ -193,18 +192,18 @@ export function createSettingsApi({
|
|
|
193
192
|
if (hasOwn(input, key)) next[key] = input[key];
|
|
194
193
|
}
|
|
195
194
|
const nextConfig = { ...config };
|
|
196
|
-
nextConfig.compaction = normalizeCompactionConfig(next
|
|
195
|
+
nextConfig.compaction = normalizeCompactionConfig(next);
|
|
197
196
|
saveConfigAndAdopt(nextConfig);
|
|
198
197
|
const config2 = getConfig();
|
|
199
198
|
const session = getSession();
|
|
200
199
|
if (session) {
|
|
201
200
|
session.compaction = {
|
|
202
201
|
...(session.compaction || {}),
|
|
203
|
-
...normalizeCompactionConfig(config2.compaction
|
|
202
|
+
...normalizeCompactionConfig(config2.compaction),
|
|
204
203
|
};
|
|
205
204
|
}
|
|
206
205
|
invalidateContextStatusCache();
|
|
207
|
-
return normalizeCompactionConfig(config2.compaction
|
|
206
|
+
return normalizeCompactionConfig(config2.compaction);
|
|
208
207
|
},
|
|
209
208
|
// Recap toggle: user-facing switch that gates ONLY the background memory
|
|
210
209
|
// cycles (1/2/3). The memory module (transcript watcher/ingest, on-demand
|
|
@@ -223,17 +222,6 @@ export function createSettingsApi({
|
|
|
223
222
|
invalidateContextStatusCache();
|
|
224
223
|
return this.getRecapSettings();
|
|
225
224
|
},
|
|
226
|
-
// Thin aliases kept for the current TUI callsites (updated separately).
|
|
227
|
-
// enabled here reflects the recap toggle; memory itself is always-on.
|
|
228
|
-
getMemorySettings() {
|
|
229
|
-
return {
|
|
230
|
-
enabled: recapEnabledFn(),
|
|
231
|
-
compactFastTrackAvailable: true,
|
|
232
|
-
};
|
|
233
|
-
},
|
|
234
|
-
async setMemoryEnabled(enabled) {
|
|
235
|
-
return this.setRecapEnabled(enabled);
|
|
236
|
-
},
|
|
237
225
|
getChannelSettings(options = {}) {
|
|
238
226
|
return {
|
|
239
227
|
enabled: channelsEnabled(),
|
|
@@ -13,7 +13,7 @@ export const TOOL_SEARCH_TOOL = {
|
|
|
13
13
|
openWorldHint: false,
|
|
14
14
|
agentHidden: true,
|
|
15
15
|
},
|
|
16
|
-
description: '
|
|
16
|
+
description: 'Deferred-tool activation status; direct calls auto-load.',
|
|
17
17
|
inputSchema: {
|
|
18
18
|
type: 'object',
|
|
19
19
|
properties: {
|
|
@@ -34,7 +34,7 @@ export const CWD_TOOL = {
|
|
|
34
34
|
openWorldHint: false,
|
|
35
35
|
agentHidden: true,
|
|
36
36
|
},
|
|
37
|
-
description: 'Show or set the session work project for tool execution.
|
|
37
|
+
description: 'Show or set the session work project for tool execution.',
|
|
38
38
|
inputSchema: {
|
|
39
39
|
type: 'object',
|
|
40
40
|
properties: {
|
|
@@ -84,7 +84,7 @@ export const SESSION_MANAGE_TOOL = {
|
|
|
84
84
|
openWorldHint: false,
|
|
85
85
|
agentHidden: true,
|
|
86
86
|
},
|
|
87
|
-
description: '
|
|
87
|
+
description: 'Schedule conversation reset at current-turn end.',
|
|
88
88
|
inputSchema: {
|
|
89
89
|
type: 'object',
|
|
90
90
|
properties: {
|