mixdog 0.9.50 → 0.9.52
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/package.json +5 -3
- package/scripts/abort-recovery-test.mjs +17 -1
- package/scripts/agent-model-liveness-test.mjs +79 -2
- package/scripts/anthropic-admission-retry-integration-test.mjs +119 -0
- package/scripts/anthropic-transport-policy-test.mjs +466 -0
- package/scripts/atomic-lock-tryonce-test.mjs +60 -1
- package/scripts/build-tui.mjs +13 -1
- package/scripts/channel-daemon-smoke.mjs +630 -10
- package/scripts/code-graph-aggregate-cwd-test.mjs +41 -37
- package/scripts/code-graph-disk-hit-test.mjs +11 -0
- package/scripts/code-graph-root-federation-test.mjs +273 -0
- package/scripts/compact-pressure-test.mjs +55 -1
- package/scripts/compact-smoke.mjs +80 -0
- package/scripts/context-mcp-metering-test.mjs +1350 -19
- package/scripts/deferred-tool-loading-test.mjs +17 -0
- package/scripts/gemini-provider-test.mjs +1053 -0
- package/scripts/hook-bus-test.mjs +23 -0
- package/scripts/internal-tools-normalization-test.mjs +10 -0
- package/scripts/interrupted-turn-history-test.mjs +371 -0
- package/scripts/lifecycle-api-test.mjs +76 -0
- package/scripts/max-output-recovery-test.mjs +55 -0
- package/scripts/mcp-grace-deferred-test.mjs +89 -13
- package/scripts/memory-pg-recovery-test.mjs +59 -0
- package/scripts/openai-oauth-ws-1006-retry-test.mjs +391 -4
- package/scripts/process-lifecycle-test.mjs +389 -0
- package/scripts/provider-admission-scheduler-test.mjs +582 -0
- package/scripts/provider-contract-test.mjs +268 -0
- package/scripts/provider-toolcall-test.mjs +520 -3
- package/scripts/reactive-compact-persist-smoke.mjs +59 -0
- package/scripts/resource-admission-test.mjs +789 -0
- package/scripts/session-bench-cache-break-test.mjs +102 -0
- package/scripts/session-bench.mjs +101 -42
- package/scripts/shell-failure-diagnostics-test.mjs +73 -4
- package/scripts/shell-jobs-windows-hide-test.mjs +1 -1
- package/scripts/smoke-loop-failure-summary-test.mjs +38 -0
- package/scripts/smoke-loop-failure-summary.mjs +16 -0
- package/scripts/smoke-loop.mjs +2 -7
- package/scripts/steering-drain-buckets-test.mjs +18 -0
- package/scripts/tool-failures.mjs +15 -1
- package/scripts/toolcall-args-test.mjs +14 -6
- package/scripts/tui-transcript-perf-test.mjs +43 -7
- package/scripts/web-fetch-routing-test.mjs +158 -0
- package/src/cli.mjs +15 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +26 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +12 -0
- package/src/runtime/agent/orchestrator/internal-tools.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +331 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +118 -26
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +29 -17
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +136 -38
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +24 -4
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +554 -42
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +67 -18
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +95 -46
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +12 -4
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +54 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +10 -80
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +89 -17
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +93 -26
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +144 -51
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +22 -8
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +74 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +111 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +13 -17
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +78 -12
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +44 -5
- package/src/runtime/agent/orchestrator/providers/registry.mjs +49 -8
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +224 -104
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +127 -55
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +99 -32
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +17 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +38 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +69 -37
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/manager/message-sanitize.mjs +8 -28
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +6 -7
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +42 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +220 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -4
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +17 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +89 -22
- package/src/runtime/agent/orchestrator/stall-policy.mjs +2 -12
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +42 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +74 -37
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +223 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +380 -37
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +176 -21
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +14 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +108 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +93 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +12 -3
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +124 -14
- package/src/runtime/memory/index.mjs +22 -4
- package/src/runtime/memory/lib/pg/adapter.mjs +84 -10
- package/src/runtime/memory/lib/pg/process.mjs +91 -47
- package/src/runtime/memory/lib/pg/supervisor.mjs +50 -13
- package/src/runtime/search/index.mjs +41 -0
- package/src/runtime/search/lib/http-fetch.mjs +154 -0
- package/src/runtime/search/tool-defs.mjs +23 -0
- package/src/runtime/shared/atomic-file.mjs +28 -150
- package/src/runtime/shared/process-lifecycle.mjs +363 -0
- package/src/runtime/shared/process-shutdown.mjs +27 -4
- package/src/runtime/shared/resource-admission.mjs +359 -0
- package/src/runtime/shared/staged-child-result.mjs +19 -0
- package/src/session-runtime/context-status.mjs +38 -27
- package/src/session-runtime/lifecycle-api.mjs +26 -6
- package/src/session-runtime/provider-request-tools.mjs +72 -0
- package/src/session-runtime/runtime-core.mjs +43 -18
- package/src/session-runtime/session-turn-api.mjs +5 -4
- package/src/session-runtime/tool-catalog.mjs +375 -15
- package/src/standalone/agent-tool.mjs +17 -38
- package/src/standalone/channel-daemon-client.mjs +200 -38
- package/src/standalone/channel-daemon-transport.mjs +136 -9
- package/src/standalone/channel-worker.mjs +79 -12
- package/src/standalone/hook-bus/handlers.mjs +4 -0
- package/src/standalone/hook-bus/rules.mjs +7 -1
- package/src/standalone/hook-bus.mjs +10 -2
- package/src/tui/App.jsx +17 -11
- package/src/tui/app/live-spinner-visibility.mjs +20 -0
- package/src/tui/dist/index.mjs +101 -281
- package/src/tui/engine/session-api-ext.mjs +13 -2
- package/src/tui/engine/session-api.mjs +1 -1
- package/src/tui/engine/turn.mjs +10 -6
- package/src/tui/engine.mjs +13 -4
- package/src/tui/index.jsx +4 -1
- package/src/tui/lib/voice-setup.mjs +16 -0
package/src/tui/engine/turn.mjs
CHANGED
|
@@ -148,7 +148,7 @@ export function createRunTurn(bag) {
|
|
|
148
148
|
const elapsed = Date.now() - startedAt;
|
|
149
149
|
tuiDebug(`runTurn WATCHDOG TRIP turn=${turnIndex} elapsedMs=${elapsed} idleMs=${idleMs} lastProgress=${lastProgressLabel} — aborting stuck turn`);
|
|
150
150
|
pushNotice(`Turn timed out after ${Math.round(idleMs / 1000)}s idle (last progress: ${lastProgressLabel}) — aborting stuck request. Input will be released shortly if abort does not unwind.`, 'warn', { transcript: true });
|
|
151
|
-
try { runtime.abort('
|
|
151
|
+
try { runtime.abort('watchdog'); } catch {}
|
|
152
152
|
// Belt-and-suspenders: if runtime.abort() did not reject runtime.ask()
|
|
153
153
|
// (unwind starved), hard-release the turn after a short grace so the
|
|
154
154
|
// React store is never left with busy=true and no drain in flight.
|
|
@@ -207,6 +207,7 @@ export function createRunTurn(bag) {
|
|
|
207
207
|
let thinkingSegmentStartedAt = 0;
|
|
208
208
|
let accumulatedThinkingMs = 0;
|
|
209
209
|
let cancelled = false;
|
|
210
|
+
let failed = false;
|
|
210
211
|
let askResult = null;
|
|
211
212
|
let turnFinishedNormally = false;
|
|
212
213
|
let transcriptCompactedThisTurn = false;
|
|
@@ -1187,8 +1188,9 @@ export function createRunTurn(bag) {
|
|
|
1187
1188
|
flushStreamBatch(); // ensure any batched text lands before the error notice
|
|
1188
1189
|
if (error?.name === 'SessionClosedError') {
|
|
1189
1190
|
cancelled = true;
|
|
1190
|
-
if (assistantText.trim()
|
|
1191
|
-
|
|
1191
|
+
if (assistantText.trim()) {
|
|
1192
|
+
const id = currentAssistantId || ensureAssistant(assistantText);
|
|
1193
|
+
settleStreamingTail(id, { text: currentAssistantText || assistantText });
|
|
1192
1194
|
}
|
|
1193
1195
|
// Finalize pending tool cards so they don't stay "Running..." forever
|
|
1194
1196
|
// after cancellation. Without this, the spinner vanishes and TurnDone
|
|
@@ -1198,6 +1200,7 @@ export function createRunTurn(bag) {
|
|
|
1198
1200
|
flushToolResults([], toolCards, cardByCallId, toolGroups, resultsDone, { finalize: true, cancelled: true });
|
|
1199
1201
|
finalizeToolHeaders();
|
|
1200
1202
|
} else {
|
|
1203
|
+
failed = true;
|
|
1201
1204
|
finalizeToolHeaders();
|
|
1202
1205
|
pushNotice(toolErrorDisplay(error, 'turn'), 'error');
|
|
1203
1206
|
}
|
|
@@ -1255,7 +1258,7 @@ export function createRunTurn(bag) {
|
|
|
1255
1258
|
const finalAssistantLen = Math.max(assistantText.length, currentAssistantText.length);
|
|
1256
1259
|
const finalResponseLength = finalAssistantLen + thinkingText.length;
|
|
1257
1260
|
const finalOutputTokens = Math.max(0, Number(getState().spinner?.outputTokens || 0), Math.round(finalResponseLength / 4));
|
|
1258
|
-
const turnStatus = cancelled ? 'cancelled' : 'done';
|
|
1261
|
+
const turnStatus = cancelled ? 'cancelled' : (failed ? 'failed' : 'done');
|
|
1259
1262
|
const resultContent = askResult?.content != null ? String(askResult.content).trim() : '';
|
|
1260
1263
|
const assistantOutput = (currentAssistantText || assistantText || '').trim();
|
|
1261
1264
|
// Suppress only true pending-resume no-ops: no transcript items added and no model output; cancelled/error turns and any visible turn stay marked.
|
|
@@ -1293,8 +1296,9 @@ export function createRunTurn(bag) {
|
|
|
1293
1296
|
// tool-summary line (same epoch rule as the shared-getState() block above).
|
|
1294
1297
|
if (flags.leadTurnEpoch === turnEpoch) clearActiveToolSummary();
|
|
1295
1298
|
_publishedThinkingActive = false; // turn teardown cleared getState().thinking
|
|
1296
|
-
|
|
1297
|
-
|
|
1299
|
+
const finalStatus = cancelled ? 'cancelled' : (failed ? 'failed' : 'done');
|
|
1300
|
+
tuiDebug(`runTurn end turn=${turnIndex} status=${finalStatus} elapsedMs=${Date.now() - startedAt}${watchdogTripped ? ' watchdogTripped=1' : ''} pending=${pending.length}`);
|
|
1301
|
+
return finalStatus;
|
|
1298
1302
|
}
|
|
1299
1303
|
|
|
1300
1304
|
return runTurn;
|
package/src/tui/engine.mjs
CHANGED
|
@@ -228,6 +228,8 @@ export async function createEngineSession({
|
|
|
228
228
|
model,
|
|
229
229
|
toolMode = 'full',
|
|
230
230
|
remote = false,
|
|
231
|
+
cwd,
|
|
232
|
+
desktopSession,
|
|
231
233
|
} = {}) {
|
|
232
234
|
const startedAt = performance.now();
|
|
233
235
|
bootProfile('engine:create:start', { provider: providerName, model, toolMode, remote });
|
|
@@ -242,9 +244,16 @@ export async function createEngineSession({
|
|
|
242
244
|
const importStartedAt = performance.now();
|
|
243
245
|
const { createMixdogSessionRuntime } = await import(SESSION_RUNTIME_MODULE);
|
|
244
246
|
bootProfile('session-runtime:imported', { ms: (performance.now() - importStartedAt).toFixed(1) });
|
|
245
|
-
const runtime = await createMixdogSessionRuntime({
|
|
247
|
+
const runtime = await createMixdogSessionRuntime({
|
|
248
|
+
provider: providerName,
|
|
249
|
+
model,
|
|
250
|
+
toolMode,
|
|
251
|
+
remote,
|
|
252
|
+
...(cwd ? { cwd } : {}),
|
|
253
|
+
...(desktopSession ? { desktopSession } : {}),
|
|
254
|
+
});
|
|
246
255
|
bootProfile('engine:create:runtime-ready', { ms: (performance.now() - startedAt).toFixed(1) });
|
|
247
|
-
const
|
|
256
|
+
const runtimeCwd = runtime.cwd || process.cwd();
|
|
248
257
|
const stateStartedAt = performance.now();
|
|
249
258
|
const flags = {
|
|
250
259
|
disposed: false,
|
|
@@ -308,14 +317,14 @@ export async function createEngineSession({
|
|
|
308
317
|
activeToolSummary: null,
|
|
309
318
|
// Seed from the persisted cwd-scoped store so up-arrow history is available
|
|
310
319
|
// on a fresh start, before any bulk swap / first submit republishes it.
|
|
311
|
-
promptHistoryList: buildMergedPromptHistory([], loadPromptHistory(
|
|
320
|
+
promptHistoryList: buildMergedPromptHistory([], loadPromptHistory(runtimeCwd)),
|
|
312
321
|
...baseRouteState(),
|
|
313
322
|
displayContextWindow: 0,
|
|
314
323
|
compactBoundaryTokens: 0,
|
|
315
324
|
autoCompactTokenLimit: 0,
|
|
316
325
|
...initialAgentState,
|
|
317
326
|
toolMode: runtime.toolMode,
|
|
318
|
-
cwd,
|
|
327
|
+
cwd: runtimeCwd,
|
|
319
328
|
themeEpoch: 0,
|
|
320
329
|
};
|
|
321
330
|
bootProfile('engine:route-state-ready', { ms: (performance.now() - stateStartedAt).toFixed(1) });
|
package/src/tui/index.jsx
CHANGED
|
@@ -15,6 +15,7 @@ import { App } from './App.jsx';
|
|
|
15
15
|
import { createEngineSession } from './engine.mjs';
|
|
16
16
|
import { scheduleRenderFrameAck } from './engine/render-timing.mjs';
|
|
17
17
|
import { installProcessSignalCleanup } from '../runtime/shared/process-shutdown.mjs';
|
|
18
|
+
import { finishProcessLifecycle } from '../runtime/shared/process-lifecycle.mjs';
|
|
18
19
|
import { rgbSgr } from '../ui/ansi.mjs';
|
|
19
20
|
import { emitTerminalBackground, loadThemeSettingFromConfig, theme } from './theme.mjs';
|
|
20
21
|
import { POP_KITTY, DISABLE_MODIFY_OTHER_KEYS } from './keyboard-protocol.mjs';
|
|
@@ -522,7 +523,8 @@ export async function runTui({ provider, model, toolMode, remote, forceOnboardin
|
|
|
522
523
|
const disposeStoreOnce = async (reason = 'cli-react-exit') => {
|
|
523
524
|
if (storeDisposed) return;
|
|
524
525
|
storeDisposed = true;
|
|
525
|
-
await waitWithTimeout(store.dispose?.(reason), EXIT_WAIT_TIMEOUT_MS);
|
|
526
|
+
const completed = await waitWithTimeout(store.dispose?.(reason), EXIT_WAIT_TIMEOUT_MS);
|
|
527
|
+
if (!completed) throw new Error(`mixdog-tui dispose timed out after ${EXIT_WAIT_TIMEOUT_MS}ms`);
|
|
526
528
|
};
|
|
527
529
|
const signalCleanup = installProcessSignalCleanup({
|
|
528
530
|
name: 'mixdog-tui',
|
|
@@ -627,6 +629,7 @@ export async function runTui({ provider, model, toolMode, remote, forceOnboardin
|
|
|
627
629
|
await disposeStoreOnce('cli-react-exit');
|
|
628
630
|
} catch (error) {
|
|
629
631
|
tuiExitDebug('store:dispose:failed', { error: error?.message || String(error) });
|
|
632
|
+
finishProcessLifecycle('forced-cleanup', 0);
|
|
630
633
|
}
|
|
631
634
|
restoreTerminal();
|
|
632
635
|
dumpActiveHandles('after-restore');
|
|
@@ -47,6 +47,22 @@ export function isVoiceEnabled() {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/** Read the managed runtime state without installing or mutating anything. */
|
|
51
|
+
export async function getVoiceStatus({ dataDir = resolvePluginData() } = {}) {
|
|
52
|
+
const fetcher = await loadVoiceRuntimeFetcher();
|
|
53
|
+
const runtime = fetcher.resolveVoiceRuntime(dataDir);
|
|
54
|
+
return {
|
|
55
|
+
enabled: isVoiceEnabled(),
|
|
56
|
+
busy: isVoiceInstallBusy(),
|
|
57
|
+
installed: runtime.installed === true,
|
|
58
|
+
components: {
|
|
59
|
+
whisper: Boolean(runtime.binary && runtime.serverCmd),
|
|
60
|
+
model: Boolean(runtime.model),
|
|
61
|
+
ffmpeg: Boolean(runtime.ffmpeg),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
50
66
|
// Coalesce ensure*'s onProgress ({ phase, downloaded, total } | { phase:'extra', ... })
|
|
51
67
|
// into a sticky, in-place input-hint-line progress bar (setProgressHint) so a
|
|
52
68
|
// multi-hundred-MB model download doesn't spam the notice toast on every
|