mixdog 0.9.94 → 0.9.95
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/NOTICE.md +72 -0
- package/package.json +16 -6
- package/scripts/lib/isolated-root-cleanup.mjs +19 -0
- package/scripts/run-suite.mjs +100 -0
- package/src/lib/rules-builder.cjs +4 -3
- package/src/output-styles/detailed.md +13 -15
- package/src/output-styles/extreme-minimal.md +7 -11
- package/src/output-styles/minimal.md +4 -7
- package/src/output-styles/simple.md +11 -13
- package/src/rules/lead/01-general.md +1 -2
- package/src/rules/lead/lead-brief.md +4 -5
- package/src/rules/lead/lead-tool.md +3 -2
- package/src/rules/shared/01-tool.md +28 -34
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +4 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +29 -0
- package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +97 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/lib/stream-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +8 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +14 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-headers.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +10 -10
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/registry.mjs +51 -4
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +15 -15
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +12 -32
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +10 -11
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +0 -14
- package/src/runtime/agent/orchestrator/session/loop/stop-hooks.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +40 -13
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +5 -9
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +3 -6
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +1 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +2 -3
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +22 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +14 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +35 -5
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +98 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +53 -12
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/env-scrub.mjs +9 -2
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +57 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +148 -15
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +109 -13
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +10 -10
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +4 -0
- package/src/runtime/channels/backends/discord.mjs +5 -14
- package/src/runtime/channels/backends/telegram.mjs +0 -5
- package/src/runtime/channels/lib/inbound-handler.mjs +0 -1
- package/src/runtime/channels/lib/output-forwarder.mjs +24 -5
- package/src/runtime/channels/lib/scheduler.mjs +1 -1
- package/src/runtime/channels/lib/worker-main.mjs +1 -1
- package/src/runtime/media/renditions.mjs +21 -2
- package/src/runtime/memory/tool-defs.mjs +6 -6
- package/src/runtime/shared/atomic-file.mjs +53 -0
- package/src/runtime/shared/background-tasks.mjs +6 -3
- package/src/runtime/shared/resource-admission.mjs +40 -1
- package/src/runtime/shared/tool-status.mjs +10 -1
- package/src/runtime/shared/tool-surface.mjs +7 -7
- package/src/runtime/shared/turn-snapshot.mjs +385 -21
- package/src/runtime/shared/turn-worktree-snapshot.mjs +540 -0
- package/src/session-runtime/context-status.mjs +9 -3
- package/src/session-runtime/lifecycle-api.mjs +35 -5
- package/src/session-runtime/mcp-glue.mjs +11 -6
- package/src/session-runtime/provider-models.mjs +94 -43
- package/src/session-runtime/runtime-core.mjs +46 -8
- package/src/session-runtime/runtime-tunables.mjs +4 -0
- package/src/session-runtime/self-update.mjs +33 -4
- package/src/session-runtime/session-lifecycle.mjs +2 -0
- package/src/session-runtime/session-text.mjs +2 -1
- package/src/session-runtime/session-turn-api.mjs +106 -22
- package/src/session-runtime/workflow.mjs +11 -4
- package/src/standalone/agent-tool.mjs +4 -4
- package/src/standalone/backend-daemon.mjs +570 -0
- package/src/standalone/channel-daemon-transport.mjs +141 -1
- package/src/standalone/channel-worker.mjs +3 -2
- package/src/standalone/engine-daemon-client.mjs +894 -0
- package/src/standalone/engine-daemon-local-bridge.mjs +20 -0
- package/src/standalone/engine-daemon-protocol.mjs +33 -0
- package/src/standalone/engine-daemon-service.mjs +864 -0
- package/src/standalone/engine-daemon-transport.mjs +603 -0
- package/src/tui/App.jsx +62 -47
- package/src/tui/app/app-format.mjs +4 -2
- package/src/tui/app/app-view.jsx +5 -0
- package/src/tui/app/channel-pickers.mjs +7 -6
- package/src/tui/app/core-memory-picker.mjs +4 -4
- package/src/tui/app/extension-pickers.mjs +20 -18
- package/src/tui/app/maintenance-pickers.mjs +27 -27
- package/src/tui/app/onboarding-steps.mjs +23 -18
- package/src/tui/app/prompt-submit.mjs +13 -2
- package/src/tui/app/route-pickers.mjs +13 -8
- package/src/tui/app/settings-picker.mjs +55 -58
- package/src/tui/app/slash-dispatch.mjs +32 -28
- package/src/tui/app/transcript-window.mjs +19 -0
- package/src/tui/app/usage-context-panels.mjs +22 -7
- package/src/tui/app/use-mouse-input.mjs +25 -3
- package/src/tui/app/use-prompt-queue-history.mjs +31 -16
- package/src/tui/app/use-transcript-scroll.mjs +30 -8
- package/src/tui/app/use-transcript-window.mjs +15 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +2 -2
- package/src/tui/components/PromptInput.jsx +10 -0
- package/src/tui/components/Spinner.jsx +89 -95
- package/src/tui/components/TextEntryPanel.jsx +14 -0
- package/src/tui/components/ToolExecution.jsx +2 -2
- package/src/tui/dist/index.mjs +1534 -9801
- package/src/tui/engine/agent-job-feed.mjs +2 -2
- package/src/tui/engine/live-share.mjs +76 -3
- package/src/tui/engine/session-api-ext.mjs +23 -1
- package/src/tui/engine/session-api.mjs +81 -41
- package/src/tui/engine/session-flow.mjs +43 -4
- package/src/tui/engine/tool-card-results.mjs +6 -0
- package/src/tui/engine/turn.mjs +8 -1
- package/src/tui/engine-local-session.mjs +1108 -0
- package/src/tui/engine.mjs +16 -1065
- package/src/tui/index.jsx +40 -2
- package/src/tui/markdown/stream-fence.mjs +1 -1
- package/src/tui/spinner-meta.mjs +80 -0
- package/src/tui/spinner-verbs.mjs +35 -0
- package/src/ui/statusline-segments.mjs +43 -10
- package/src/ui/statusline.mjs +10 -1
- package/scripts/tmp-cdp-errors.mjs +0 -41
- package/scripts/tmp-cdp-inspect.mjs +0 -41
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +0 -176
- package/src/standalone/channel-daemon.mjs +0 -226
package/NOTICE.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# NOTICE
|
|
2
|
+
|
|
3
|
+
Mixdog itself is MIT-licensed (see `LICENSE`). Parts of it were written
|
|
4
|
+
against the public source of the projects listed below. Their terms are
|
|
5
|
+
preserved here in one place so the individual source files can stay free of
|
|
6
|
+
scattered attribution comments.
|
|
7
|
+
|
|
8
|
+
## MIT
|
|
9
|
+
|
|
10
|
+
### Visual Studio Code — Copyright (c) Microsoft Corporation
|
|
11
|
+
|
|
12
|
+
<https://github.com/microsoft/vscode>
|
|
13
|
+
|
|
14
|
+
Explorer name-validation and sort grammar, editor/terminal defaults, the Seti
|
|
15
|
+
icon-theme resolution rules, shell-profile detection, and the built-in
|
|
16
|
+
language contributions used to generate the Monaco pane languages.
|
|
17
|
+
|
|
18
|
+
- `apps/desktop/src/renderer/explorer-logic.ts`, `ExplorerTree.tsx`,
|
|
19
|
+
`editor-ansi.ts`, `file-icons.tsx`, `seti-icons.ts`
|
|
20
|
+
- `apps/desktop/src/shared/editor-languages.ts`
|
|
21
|
+
- `apps/desktop/src/main/shell-profiles.ts`
|
|
22
|
+
- `apps/desktop/scripts/generate-seti-icons.mjs`,
|
|
23
|
+
`apps/desktop/scripts/generate-editor-languages.mjs`
|
|
24
|
+
|
|
25
|
+
### Seti UI — Copyright (c) 2014 Jesse Weed
|
|
26
|
+
|
|
27
|
+
Bundled glyphs and colour tables. Full license text in
|
|
28
|
+
`apps/desktop/THIRD-PARTY-NOTICES.txt`.
|
|
29
|
+
|
|
30
|
+
### Files — Copyright (c) Files Community
|
|
31
|
+
|
|
32
|
+
<https://github.com/files-community/Files>
|
|
33
|
+
|
|
34
|
+
Folder-pane grouping keys, date-span labels, size buckets and the discrete
|
|
35
|
+
layout size ladder in `apps/desktop/src/renderer/FolderPane.lazy.tsx`.
|
|
36
|
+
|
|
37
|
+
### OpenCode — Copyright (c) Anomaly / SST
|
|
38
|
+
|
|
39
|
+
<https://github.com/anomalyco/opencode>
|
|
40
|
+
|
|
41
|
+
Transcript auto-scroll gesture grammar, virtual-timeline anchoring and the
|
|
42
|
+
streaming-markdown projection model.
|
|
43
|
+
|
|
44
|
+
- `apps/desktop/src/renderer/use-transcript-follow.ts`, `TranscriptList.tsx`,
|
|
45
|
+
`transcript-measure.ts`, `transcript-rows.ts`, `transcript-virtual-cache.ts`,
|
|
46
|
+
`StreamingMarkdownBody.tsx`, `streaming-markdown.ts`, `Conversation.tsx`
|
|
47
|
+
|
|
48
|
+
### Ink — Copyright (c) Vadim Demedes
|
|
49
|
+
|
|
50
|
+
Vendored under `vendor/ink` together with its own license file.
|
|
51
|
+
|
|
52
|
+
## Apache License 2.0
|
|
53
|
+
|
|
54
|
+
### OpenAI Codex CLI — Copyright (c) OpenAI
|
|
55
|
+
|
|
56
|
+
<https://github.com/openai/codex>
|
|
57
|
+
|
|
58
|
+
The V4A `apply_patch` grammar with its seek/replacement semantics.
|
|
59
|
+
|
|
60
|
+
- `src/runtime/agent/orchestrator/tools/patch/`
|
|
61
|
+
- `native/mixdog-patch/`
|
|
62
|
+
|
|
63
|
+
### AiderDesk — Copyright (c) Hotovo
|
|
64
|
+
|
|
65
|
+
<https://github.com/hotovo/aider-desk>
|
|
66
|
+
|
|
67
|
+
electron-vite configuration structure in
|
|
68
|
+
`apps/desktop/electron.vite.config.ts`.
|
|
69
|
+
|
|
70
|
+
The Apache-2.0 terms require this notice to travel with any redistribution of
|
|
71
|
+
the derived files. Full license text:
|
|
72
|
+
<https://www.apache.org/licenses/LICENSE-2.0>.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixdog",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.95",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Standalone mixdog coding-agent CLI/TUI workspace.",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"README.md",
|
|
28
|
+
"NOTICE.md",
|
|
28
29
|
"scripts/",
|
|
29
30
|
"!scripts/bench/",
|
|
30
31
|
"!scripts/recall-bench-*.txt",
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"prepublishOnly": "node -e \"if(!process.env.CI){console.error('local npm publish is disabled — run npm run release:patch');process.exit(1)}\"",
|
|
47
48
|
"start": "node src/cli.mjs",
|
|
48
49
|
"smoke": "node scripts/smoke.mjs",
|
|
50
|
+
"test:contract": "node scripts/run-suite.mjs contract",
|
|
49
51
|
"smoke:all": "npm run smoke && npm run smoke:boot && npm run smoke:patch && npm run smoke:output && npm run smoke:tui && npm run smoke:live-worker",
|
|
50
52
|
"smoke:boot": "node scripts/boot-smoke.mjs",
|
|
51
53
|
"smoke:compact": "node scripts/compact-smoke.mjs",
|
|
@@ -68,7 +70,7 @@
|
|
|
68
70
|
"test:toolcall": "node --test scripts/toolcall-args-test.mjs",
|
|
69
71
|
"test:tool-batching": "node --test scripts/eager-patch-shell-order-test.mjs scripts/session-bench-batching-test.mjs",
|
|
70
72
|
"test:shipmode": "node --test scripts/ship-mode-test.mjs",
|
|
71
|
-
"test:shellhardening": "node --test scripts/shell-hardening-test.mjs scripts/shell-failure-diagnostics-test.mjs scripts/windows-hide-spawn-options-test.mjs",
|
|
73
|
+
"test:shellhardening": "node --test scripts/shell-hardening-test.mjs scripts/shell-failure-diagnostics-test.mjs scripts/windows-hide-spawn-options-test.mjs scripts/shell-job-session-scope-test.mjs",
|
|
72
74
|
"test:placeholder": "node --test scripts/compacted-placeholder-scrub-test.mjs",
|
|
73
75
|
"test:providers": "node --test scripts/provider-toolcall-test.mjs scripts/provider-contract-test.mjs scripts/provider-stream-stall-test.mjs scripts/provider-stream-outcome-test.mjs scripts/stream-frame-fault-matrix-test.mjs scripts/gemini-provider-test.mjs scripts/anthropic-transport-policy-test.mjs scripts/anthropic-native-block-replay-test.mjs scripts/openai-oauth-ws-1006-retry-test.mjs scripts/openai-end-turn-signal-test.mjs",
|
|
74
76
|
"test:provider-admission": "node --test scripts/provider-admission-scheduler-test.mjs",
|
|
@@ -83,7 +85,6 @@
|
|
|
83
85
|
"test:embedding-runtime:core": "node --test scripts/embedding-runtime-prune-test.mjs scripts/memory-pg-recovery-test.mjs && node scripts/verify-embedding-runtime.mjs --core",
|
|
84
86
|
"test:embedding-runtime:warmup": "node scripts/verify-embedding-runtime.mjs --warmup",
|
|
85
87
|
"test:code-graph-dispatch": "node --test scripts/code-graph-dispatch-test.mjs",
|
|
86
|
-
"test:code-graph-clean-cache": "node --test scripts/code-graph-dispatch-test.mjs",
|
|
87
88
|
"test:tui-queue": "node --test scripts/submit-commandbusy-race-test.mjs scripts/steering-drain-buckets-test.mjs scripts/abort-recovery-test.mjs scripts/execution-pending-resume-kick-test.mjs scripts/execution-resume-esc-integration-test.mjs scripts/pending-stale-injection-test.mjs",
|
|
88
89
|
"test:tui-input-render": "node --test scripts/prompt-immediate-render-test.mjs",
|
|
89
90
|
"test:tui-streaming-window": "node --test scripts/streaming-tail-window-test.mjs scripts/tui-store-frame-batch-test.mjs && node scripts/tui-transcript-jitter-harness.mjs",
|
|
@@ -92,11 +93,13 @@
|
|
|
92
93
|
"test:release-focused": "npm run test:release-assets && npm run test:tool-contracts && npm run test:tool-batching && npm run test:placeholder && npm run smoke:patch && npm run test:patch-binary-cache && npm run test:providers && npm run test:deferred-tools && npm run smoke:compact && npm run test:compact && npm run test:context && node --test scripts/code-graph-root-federation-test.mjs scripts/code-graph-aggregate-cwd-test.mjs && npm run test:code-graph-dispatch && node --test scripts/code-graph-disk-hit-test.mjs && npm run test:shellhardening && npm run test:project-registry && npm run test:session && npm run test:workflow-editor && npm run test:embedding-runtime && node --test scripts/tui-transcript-perf-test.mjs",
|
|
93
94
|
"test:native-edit-wire": "node --test scripts/native-edit-wire-test.mjs",
|
|
94
95
|
"test:patch-binary-cache": "node --test scripts/patch-binary-cache-test.mjs",
|
|
95
|
-
"test:patch-parity": "node --test scripts/v4a-
|
|
96
|
+
"test:patch-parity": "node --test scripts/v4a-parity-test.mjs",
|
|
96
97
|
"test:project-registry": "node --test scripts/project-registry-isolation-test.mjs",
|
|
98
|
+
"test:engine-daemon": "node --test scripts/engine-daemon-test.mjs scripts/engine-daemon-local-bridge-test.mjs scripts/engine-daemon-tui-parity-test.mjs scripts/engine-daemon-recovery-test.mjs scripts/engine-daemon-submit-delivery-test.mjs scripts/engine-daemon-process-lifetime-test.mjs scripts/engine-daemon-multipane-stress-test.mjs",
|
|
99
|
+
"smoke:engine-daemon": "node scripts/engine-daemon-smoke.mjs",
|
|
97
100
|
"test:session": "node --test scripts/session-orphan-sweep-test.mjs scripts/interrupted-turn-history-test.mjs scripts/turn-checkpoint-crash-test.mjs scripts/turn-outcome-fault-matrix-test.mjs scripts/session-save-fault-store-test.mjs scripts/session-disk-authority-test.mjs scripts/session-load-cache-race-test.mjs scripts/agent-loop-complete-turn-test.mjs scripts/session-heartbeat-lifecycle-test.mjs scripts/remote-transition-order-test.mjs scripts/session-new-reset-test.mjs",
|
|
98
101
|
"test:live-canary": "node --test scripts/live-canary-test.mjs",
|
|
99
|
-
"test:rebindtail": "node --test scripts/forwarder-rebind-tail-test.mjs",
|
|
102
|
+
"test:rebindtail": "node --test scripts/forwarder-rebind-tail-test.mjs scripts/channel-remote-format-test.mjs",
|
|
100
103
|
"test:workflow-editor": "node --test scripts/workflow-id-test.mjs scripts/workflow-pack-editor-test.mjs",
|
|
101
104
|
"test:route-scope": "node --test scripts/route-scope-isolation-test.mjs",
|
|
102
105
|
"test:schedule-reload": "node --test scripts/schedule-reload-arm-test.mjs",
|
|
@@ -105,13 +108,20 @@
|
|
|
105
108
|
"failures": "node scripts/tool-failures.mjs",
|
|
106
109
|
"trace:llm": "node scripts/llm-trace-summary.mjs",
|
|
107
110
|
"diag:sessions": "node scripts/session-diag.mjs",
|
|
108
|
-
"diag:
|
|
111
|
+
"diag:tools": "node scripts/tool-efficiency-diag.mjs",
|
|
112
|
+
"diag:sweep": "node scripts/session-sweep.mjs",
|
|
109
113
|
"bench:session": "node scripts/session-bench.mjs",
|
|
110
114
|
"bench:task": "node scripts/task-bench.mjs",
|
|
111
115
|
"bench:corpus": "node scripts/routing-corpus.mjs",
|
|
112
116
|
"bench:run": "node scripts/bench-run.mjs",
|
|
113
117
|
"bench:recall": "node scripts/recall-bench.mjs",
|
|
114
118
|
"bench:tui-load": "node scripts/tui-runtime-load-bench.mjs",
|
|
119
|
+
"bench:explore": "node scripts/explore-bench.mjs",
|
|
120
|
+
"bench:output-style": "node scripts/output-style-bench.mjs",
|
|
121
|
+
"bench:session-context": "node scripts/session-context-bench.mjs",
|
|
122
|
+
"bench:engine-daemon": "node scripts/engine-daemon-bench.mjs",
|
|
123
|
+
"bench:tool-overhead": "node scripts/tool-overhead-microbench.mjs",
|
|
124
|
+
"bench:internal-comms": "node scripts/internal-comms-bench.mjs",
|
|
115
125
|
"audit:models": "node scripts/model-catalog-audit.mjs",
|
|
116
126
|
"patch:replay": "node scripts/patch-replay.mjs",
|
|
117
127
|
"build:tui": "node scripts/build-tui.mjs",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Isolated-root test hygiene. A session engine spawns its OWN memory runtime
|
|
2
|
+
// (Postgres + embeddings) under the root it was given, and a hard-killed daemon
|
|
3
|
+
// cannot reap it. Tests that use a throwaway root call this so a run can never
|
|
4
|
+
// leave a live cluster behind pointing at a deleted directory.
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
|
|
7
|
+
export function killProcessesUnder(root) {
|
|
8
|
+
if (!root) return;
|
|
9
|
+
if (process.platform === 'win32') {
|
|
10
|
+
const escaped = String(root).replace(/'/g, "''");
|
|
11
|
+
spawnSync('powershell', [
|
|
12
|
+
'-NoProfile', '-NonInteractive', '-Command',
|
|
13
|
+
`Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -like '${escaped}*' } `
|
|
14
|
+
+ '| ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }',
|
|
15
|
+
], { stdio: 'ignore' });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
spawnSync('bash', ['-lc', `pkill -f ${JSON.stringify(root)} || true`], { stdio: 'ignore' });
|
|
19
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Named test suites, so package.json keeps one entry per suite instead of a
|
|
3
|
+
// 2KB command line. Files listed here are RUN; anything under scripts/ that is
|
|
4
|
+
// not in a suite (or another npm script) is dead weight by definition.
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { dirname, join } from 'node:path';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
|
|
9
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
// contract: the cheap, always-true invariants (tool args, session/steering
|
|
12
|
+
// persistence, memory rules, routing sanitizers). Live-model, UI-frame and
|
|
13
|
+
// bench suites deliberately stay out — they belong to smoke:*/bench:*.
|
|
14
|
+
export const SUITES = {
|
|
15
|
+
contract: [
|
|
16
|
+
'abort-queued-drain-kick-test.mjs',
|
|
17
|
+
'agent-dispatch-abort-compose-test.mjs',
|
|
18
|
+
'agent-loop-policy-test.mjs',
|
|
19
|
+
'agent-trace-io-test.mjs',
|
|
20
|
+
'anthropic-admission-retry-integration-test.mjs',
|
|
21
|
+
'anthropic-maxtokens-test.mjs',
|
|
22
|
+
'arg-guard-test.mjs',
|
|
23
|
+
'async-notify-settlement-test.mjs',
|
|
24
|
+
'background-task-meta-smoke.mjs',
|
|
25
|
+
'dead-owner-attach-test.mjs',
|
|
26
|
+
'debounced-skills-async-save-test.mjs',
|
|
27
|
+
'dispatch-persist-recovery-test.mjs',
|
|
28
|
+
'explore-prompt-policy-test.mjs',
|
|
29
|
+
'find-fuzzy-hidden-test.mjs',
|
|
30
|
+
'ingest-pure-conversation-smoke.mjs',
|
|
31
|
+
'internal-tools-normalization-test.mjs',
|
|
32
|
+
'legacy-config-cleanup-test.mjs',
|
|
33
|
+
'lifecycle-api-test.mjs',
|
|
34
|
+
'live-share-test.mjs',
|
|
35
|
+
'max-output-recovery-persist-test.mjs',
|
|
36
|
+
'mcp-client-normalization-test.mjs',
|
|
37
|
+
'mcp-grace-deferred-test.mjs',
|
|
38
|
+
'memory-core-input-test.mjs',
|
|
39
|
+
'memory-meta-concurrency-test.mjs',
|
|
40
|
+
'memory-retention-test.mjs',
|
|
41
|
+
'memory-rule-contract-test.mjs',
|
|
42
|
+
'memory-worker-stability-test.mjs',
|
|
43
|
+
'model-list-sanitize-test.mjs',
|
|
44
|
+
'notify-completion-mirror-test.mjs',
|
|
45
|
+
'openai-oauth-refresh-race-test.mjs',
|
|
46
|
+
'openai-ws-early-settle-test.mjs',
|
|
47
|
+
'parent-abort-link-test.mjs',
|
|
48
|
+
'path-suffix-test.mjs',
|
|
49
|
+
'pending-completion-drop-test.mjs',
|
|
50
|
+
'pending-messages-lock-nonblocking-test.mjs',
|
|
51
|
+
'pretool-ask-runtime-test.mjs',
|
|
52
|
+
'prompt-input-parity-test.mjs',
|
|
53
|
+
'reactive-compact-persist-smoke.mjs',
|
|
54
|
+
'repl-stream-finalize-test.mjs',
|
|
55
|
+
'result-classification-test.mjs',
|
|
56
|
+
'rg-runner-test.mjs',
|
|
57
|
+
'sanitize-tool-pairs-test.mjs',
|
|
58
|
+
'save-worker-delta-test.mjs',
|
|
59
|
+
'session-ingest-smoke.mjs',
|
|
60
|
+
'session-title-controller-test.mjs',
|
|
61
|
+
'set-effort-config-test.mjs',
|
|
62
|
+
'shell-jobs-windows-hide-test.mjs',
|
|
63
|
+
'spinner-meta-test.mjs',
|
|
64
|
+
'statusline-agents-test.mjs',
|
|
65
|
+
'statusline-quota-hysteresis-test.mjs',
|
|
66
|
+
'steering-fold-provenance-test.mjs',
|
|
67
|
+
'steering-persist-orphan-prune-test.mjs',
|
|
68
|
+
'stop-hook-informational-exit1-test.mjs',
|
|
69
|
+
'stream-stall-budget-test.mjs',
|
|
70
|
+
'title-completion-test.mjs',
|
|
71
|
+
'tool-output-budget-test.mjs',
|
|
72
|
+
'tool-result-hook-test.mjs',
|
|
73
|
+
'turn-snapshot-test.mjs',
|
|
74
|
+
'usage-metrics-epoch-smoke.mjs',
|
|
75
|
+
'web-fetch-routing-test.mjs',
|
|
76
|
+
'webhook-smoke.mjs',
|
|
77
|
+
'worker-notify-rejection-test.mjs',
|
|
78
|
+
'write-backpressure-test.mjs',
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const name = process.argv[2];
|
|
83
|
+
const files = SUITES[name];
|
|
84
|
+
if (!files) {
|
|
85
|
+
process.stderr.write(`unknown suite: ${name}. known: ${Object.keys(SUITES).join(', ')}
|
|
86
|
+
`);
|
|
87
|
+
process.exit(2);
|
|
88
|
+
}
|
|
89
|
+
// Bounded concurrency: the default (one worker per core) ran ~60 node processes
|
|
90
|
+
// at once, which spiked memory and made lock-contending suites (OAuth keychain,
|
|
91
|
+
// config RMW) fail from load rather than from a real regression.
|
|
92
|
+
const concurrency = Number(process.env.MIXDOG_SUITE_CONCURRENCY) > 0
|
|
93
|
+
? Math.floor(Number(process.env.MIXDOG_SUITE_CONCURRENCY))
|
|
94
|
+
: 4;
|
|
95
|
+
const result = spawnSync(
|
|
96
|
+
process.execPath,
|
|
97
|
+
['--test', `--test-concurrency=${concurrency}`, ...files.map((f) => join(here, f))],
|
|
98
|
+
{ stdio: 'inherit' },
|
|
99
|
+
);
|
|
100
|
+
process.exit(result.status ?? 1);
|
|
@@ -132,8 +132,9 @@ function buildProfilePreferencesContent(dataDir) {
|
|
|
132
132
|
lines.push(`- User title: ${profile.title}.`);
|
|
133
133
|
lines.push(`- Use "${profile.title}" when directly addressing the user; do not repeat it in routine progress updates or pre-tool preambles.`);
|
|
134
134
|
}
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
// Host shell syntax is NOT repeated here: the `shell` tool schema already
|
|
136
|
+
// carries the PowerShell/bash cheat next to its command argument, and a
|
|
137
|
+
// standing prompt line only primed shell use the tool policy discourages.
|
|
137
138
|
return lines.length ? `# Profile Preferences\n\n${lines.join('\n')}` : '';
|
|
138
139
|
}
|
|
139
140
|
|
|
@@ -145,7 +146,7 @@ function buildLanguageSection(dataDir) {
|
|
|
145
146
|
? ` from system locale ${language.locale}`
|
|
146
147
|
: '';
|
|
147
148
|
const lines = [
|
|
148
|
-
`- Default user-facing response language${source}: ${language.prompt}.
|
|
149
|
+
`- Default user-facing response language${source}: ${language.prompt}. Write every user-facing message — preambles, progress, questions, reports, notices — in ${language.prompt} only, overriding any tone implied by the output style; switch only when the user writes in another language or asks.`,
|
|
149
150
|
`- Code identifiers, paths, commands, symbols, API names, and exact errors should remain in their original form.`,
|
|
150
151
|
];
|
|
151
152
|
return `# Language\n\n${lines.join('\n')}`;
|
|
@@ -8,20 +8,18 @@ keep-coding-instructions: true
|
|
|
8
8
|
|
|
9
9
|
# Output Style
|
|
10
10
|
|
|
11
|
-
Detailed — the fullest style,
|
|
12
|
-
|
|
11
|
+
Detailed — the fullest style, still summary-form: depth comes from picking the
|
|
12
|
+
right facts, not from explaining more.
|
|
13
13
|
|
|
14
14
|
- Lead with the outcome in one short sentence, then only the detail that
|
|
15
|
-
matters: what changed
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
sub-level at most.
|
|
27
|
-
- Never name this style unless asked.
|
|
15
|
+
matters: what changed, paths, commands, errors. Conclusions, not reasoning;
|
|
16
|
+
cite a symbol/path only as an anchor.
|
|
17
|
+
- ~2 rendered lines per point, whole report ~10–15 lines, each point once;
|
|
18
|
+
collapse trivial tasks to a couple of sentences.
|
|
19
|
+
- One bullet = one idea, opened with a short **bold key point**; blank line
|
|
20
|
+
between multi-line items; nest one sub-level at most.
|
|
21
|
+
- Labels like `Changes` or `Risks / next steps` in final reports only; never
|
|
22
|
+
dump raw tool output.
|
|
23
|
+
- State blockers and failures in one short clause each.
|
|
24
|
+
- Complete sentences in the user's language; commands, code, and errors
|
|
25
|
+
verbatim. Never name this style unless asked.
|
|
@@ -8,15 +8,11 @@ keep-coding-instructions: true
|
|
|
8
8
|
|
|
9
9
|
# Output Style
|
|
10
10
|
|
|
11
|
-
Extreme minimal —
|
|
12
|
-
characters.
|
|
11
|
+
Extreme minimal — exactly one sentence, under 100 characters.
|
|
13
12
|
|
|
14
|
-
- A SINGLE sentence
|
|
15
|
-
|
|
16
|
-
- Net result only:
|
|
17
|
-
the
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
- Preferred pattern: `<target> changed.`
|
|
21
|
-
- Preserve one decisive path, command, symbol, or error verbatim, only if it
|
|
22
|
-
fits the limit.
|
|
13
|
+
- A SINGLE sentence — never a second one or a run-on that smuggles in extra
|
|
14
|
+
facts.
|
|
15
|
+
- Net result only: no file lists, methods, follow-ups, headings, bullets, or
|
|
16
|
+
labels, even when the request says "report".
|
|
17
|
+
- Preferred pattern: `<target> changed.` Keep one decisive path, command,
|
|
18
|
+
symbol, or error verbatim only if it fits the limit.
|
|
@@ -7,14 +7,11 @@ keep-coding-instructions: true
|
|
|
7
7
|
|
|
8
8
|
# Output Style
|
|
9
9
|
|
|
10
|
-
Minimal —
|
|
10
|
+
Minimal — one or two sentences, nothing more.
|
|
11
11
|
|
|
12
12
|
- One short sentence with the net result; a second only for a fact that
|
|
13
|
-
genuinely needs it
|
|
14
|
-
- Roughly HALF Simple: 1–2 plain sentences (~2–3 rendered lines) however
|
|
15
|
-
large the task, concept-level only.
|
|
13
|
+
genuinely needs it, never a run-on. Concept level whatever the task size.
|
|
16
14
|
- Never itemize: no headings, bullets, labels, sections, or file-by-file
|
|
17
15
|
detail — even when the request says "report".
|
|
18
|
-
- Preferred pattern: `<target> changed.`
|
|
19
|
-
|
|
20
|
-
error verbatim.
|
|
16
|
+
- Preferred pattern: `<target> changed.` Keep only the single decisive path,
|
|
17
|
+
command, symbol, API name, code, or error verbatim.
|
|
@@ -8,18 +8,16 @@ keep-coding-instructions: true
|
|
|
8
8
|
|
|
9
9
|
# Output Style
|
|
10
10
|
|
|
11
|
-
Practical concise — outcome
|
|
12
|
-
narrate the work.
|
|
11
|
+
Practical concise — outcome first, never a narration of the work.
|
|
13
12
|
|
|
14
13
|
- Open with the outcome in one sentence: done, blocked, or awaiting a decision.
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- Never name this style unless asked.
|
|
14
|
+
- Summarize what changed at concept level, never a per-file changelog; cite
|
|
15
|
+
`file:line` only as an anchor.
|
|
16
|
+
- 1–3 bullets or 2–3 sentences, ~5–7 lines total, each point once.
|
|
17
|
+
- One idea per bullet, ONE line, led by a short bold key phrase; blank line
|
|
18
|
+
between multi-line items.
|
|
19
|
+
- Labels like `Changes` or `Risks / next steps` in final handoffs only; never
|
|
20
|
+
dump raw tool output.
|
|
21
|
+
- State blockers and failures in one short clause each.
|
|
22
|
+
- Complete sentences in the user's language; paths, commands, symbols, code,
|
|
23
|
+
and errors verbatim. Never name this style unless asked.
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
into it, a status question gets a brief answer while work continues; after
|
|
14
14
|
context compaction continue from the summary — never restart or redo
|
|
15
15
|
finished work.
|
|
16
|
-
- When blocked, exhaust safe in-scope checks once and report the blocker
|
|
17
|
-
never spend turns without a tool call or new evidence.
|
|
16
|
+
- When blocked, exhaust safe in-scope checks once and report the blocker.
|
|
18
17
|
- Your final message ends the turn: answer only when the work is done. After a
|
|
19
18
|
failed tool call, fix and re-run it, or state plainly that it is unresolved.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# Lead Brief
|
|
2
2
|
|
|
3
|
-
- Minimum chars, maximum info: one-line fragments. `Task:` is
|
|
4
|
-
lossless
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
completion/stop boundary, user-supplied exact targets, and exact
|
|
3
|
+
- Minimum chars, maximum info: one-line fragments. Every role's `Task:` is
|
|
4
|
+
mandatory and lossless — build it from the original request and the official
|
|
5
|
+
spec/test acceptance criteria, preserving intent, required and forbidden
|
|
6
|
+
outcomes, completion/stop boundary, user-supplied exact targets, and exact
|
|
8
7
|
replacements/outputs. Never infer exactness from task name, file count, or
|
|
9
8
|
difficulty.
|
|
10
9
|
- Omit role-known rules, repeated context/facts, and padding; split scope
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Lead Tools
|
|
2
2
|
|
|
3
|
-
- Write-role agents self-verify with `shell`. Lead uses `shell` for
|
|
4
|
-
|
|
3
|
+
- Write-role agents self-verify with `shell`. Lead uses `shell` only for git,
|
|
4
|
+
benches, and cross-scope verification no retrieval tool can produce;
|
|
5
|
+
inspection stays on `read`/`grep`/`glob`/`list`/`find`/`code_graph`.
|
|
5
6
|
- Use the current project/workspace unless the request or tool requires another.
|
|
@@ -1,37 +1,31 @@
|
|
|
1
1
|
# Tool Use
|
|
2
2
|
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
verified directory→`list`; known
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Distinct facets only — never two routes per facet. The archetype is two
|
|
16
|
-
turns — one message observes through the dedicated tools (`shell` beside
|
|
17
|
-
them, not instead of them), one chain produces and proves itself; a new
|
|
18
|
-
turn exists only at a true data dependency.
|
|
3
|
+
- Gather every known facet — environment, capability, artifact, failure — in
|
|
4
|
+
one bounded first message, one shortest route each: unknown coordinates→
|
|
5
|
+
`explore` first and alone, its anchors routing the next batch (roles without
|
|
6
|
+
it: `find`); a known path or anchor skips it; partial path/name→`find`;
|
|
7
|
+
verified root+wildcard→`glob`; text/code→`grep`; symbol/relation→`code_graph`;
|
|
8
|
+
known file/span→`read`, not `grep`; verified directory→`list`; known
|
|
9
|
+
edit→`apply_patch`; web/current→`search`; only what none of them reach
|
|
10
|
+
(process/env, git, build/run/test)→`shell`, never to cat/ls/find/grep.
|
|
11
|
+
- Fewest turns, not fewest calls: always send independent calls together in
|
|
12
|
+
one message, merged per tool — one `shell` chain (`&&`/`;`), one `read`
|
|
13
|
+
region array, one `apply_patch` with every determined edit proved by its
|
|
14
|
+
`post_shell` in the same turn; a later turn only for unseen output.
|
|
19
15
|
- Verified paths: project root, session cwd, user-provided, tool-returned.
|
|
20
|
-
`find` first for guessed
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
explicit wait only for a result the current turn cannot proceed without.
|
|
37
|
-
Long commands whose output the next step does not need go async.
|
|
16
|
+
`find` first for guessed fragments; on ENOENT find the basename; retry
|
|
17
|
+
`EXPLORATION_FAILED` once with changed tokens.
|
|
18
|
+
- Never re-fetch what a tool already returned: every span this session emitted —
|
|
19
|
+
`path:line` hits, read regions, an `apply_patch` post-patch body — is final for
|
|
20
|
+
its range, so read only uncovered lines and stop once evidence covers the
|
|
21
|
+
deliverable; only zero/error justifies new scope, each call narrow
|
|
22
|
+
(`head_limit`, regions).
|
|
23
|
+
- Verify in proportion to risk: one decisive probe rides the edit call. A pass
|
|
24
|
+
is final; on failure fix and rerun what failed. Diagnostics non-fatal; report
|
|
25
|
+
verified vs assumed.
|
|
26
|
+
- `apply_patch` is the primary edit tool: once path and content are known it
|
|
27
|
+
joins the current batch — all files and hunks in one call, never one turn per
|
|
28
|
+
file (the format contract lives in its tool description).
|
|
29
|
+
- After a background task starts or reports, end the turn — its notification
|
|
30
|
+
resumes the work. Never poll or block; wait only for what the turn cannot
|
|
31
|
+
proceed without. Long commands whose output the next step ignores go async.
|
|
@@ -282,7 +282,7 @@ function summarizePromptCacheTools(tools) {
|
|
|
282
282
|
|
|
283
283
|
/**
|
|
284
284
|
* Build a stable, prefix-scoped prompt_cache_key for OpenAI-style key-prefix
|
|
285
|
-
* providers. OpenAI OAuth
|
|
285
|
+
* providers. OpenAI OAuth uses a thread-scoped key by default:
|
|
286
286
|
* prompt_cache_key is the session/thread identity, clamped to the backend's
|
|
287
287
|
* 64-character limit. Other OpenAI-style providers keep the older
|
|
288
288
|
* namespace+prefix-hash key shape, but no longer get a shard suffix unless an
|
|
@@ -400,7 +400,7 @@ function assignPromptCacheLaneSlot(provider, opts, shards, seed, { auto = false
|
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
402
|
* Resolve an optional cache-lane slot for OpenAI-style prompt cache sharding.
|
|
403
|
-
*
|
|
403
|
+
* prompt_cache_key is not sharded by default, so every provider now gets
|
|
404
404
|
* one un-suffixed key unless an env/config override opts into shards.
|
|
405
405
|
*/
|
|
406
406
|
export function resolveProviderPromptCacheLane(provider, opts = {}, config = {}) {
|
|
@@ -278,7 +278,7 @@ export function parseGrepCoverage(resultText, toolName, toolArgs, resultKind) {
|
|
|
278
278
|
return out.length ? out : null;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
//
|
|
281
|
+
// Patch failures all arrive as "apply_patch … failed" prose, but
|
|
282
282
|
// a malformed envelope, a rejected hunk, a preflight veto and a size/lock
|
|
283
283
|
// guard need different operator responses. Returning null means "nothing
|
|
284
284
|
// patch-specific here" and lets the generic rules (path/enoent, schema/args,
|
|
@@ -368,6 +368,10 @@ function _resolveToolFailurePath() {
|
|
|
368
368
|
if (process.env.MIXDOG_TOOL_FAILURE_LOG_DISABLE === '1') return null;
|
|
369
369
|
if (_toolFailurePath) return _toolFailurePath;
|
|
370
370
|
const explicit = process.env.MIXDOG_TOOL_FAILURE_LOG_PATH;
|
|
371
|
+
// The repo's own `node --test` suites drive intentional tool failures
|
|
372
|
+
// (patch ordering, arg guards, ...). Without an explicit path those rows
|
|
373
|
+
// land in the user's real failure log and read as production incidents.
|
|
374
|
+
if (!explicit && process.env.NODE_TEST_CONTEXT) return null;
|
|
371
375
|
// Ship-mode default: skip diagnostic tool-failure log file IO unless
|
|
372
376
|
// dev/debug, MIXDOG_DIAGNOSTICS, or an explicit path opts back in.
|
|
373
377
|
if (!explicit && !isDiagnosticIOEnabled()) return null;
|
|
@@ -158,6 +158,34 @@ function traceAgentSse({ sessionId, sseParseMs, ttftMs, provider, model, transpo
|
|
|
158
158
|
});
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
// Per-turn preflight timing (submit → provider request). The runtime also
|
|
162
|
+
// emits this as a `mixdog:turn-timing` process event for the daemon log, but
|
|
163
|
+
// that sink is process-local and invisible to trace tooling — the row below is
|
|
164
|
+
// what session-bench reads, so TTFT stage regressions stay measurable offline.
|
|
165
|
+
function traceTurnTiming({
|
|
166
|
+
sessionId, status, requestId, ttftMs, endToEndTtftMs,
|
|
167
|
+
queueMs, routeMs, preflightMs, mcpMs, providerMs,
|
|
168
|
+
}) {
|
|
169
|
+
const ms = (value) => (Number.isFinite(Number(value)) ? Math.round(Number(value)) : null);
|
|
170
|
+
const payload = {
|
|
171
|
+
status: status || 'unknown',
|
|
172
|
+
request_id: requestId || null,
|
|
173
|
+
ttft_ms: ms(ttftMs),
|
|
174
|
+
end_to_end_ttft_ms: ms(endToEndTtftMs),
|
|
175
|
+
queue_ms: ms(queueMs),
|
|
176
|
+
route_ms: ms(routeMs),
|
|
177
|
+
preflight_ms: ms(preflightMs),
|
|
178
|
+
mcp_ms: ms(mcpMs),
|
|
179
|
+
provider_ms: ms(providerMs),
|
|
180
|
+
};
|
|
181
|
+
appendAgentTrace({
|
|
182
|
+
sessionId,
|
|
183
|
+
kind: 'turn_timing',
|
|
184
|
+
...payload,
|
|
185
|
+
payload,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
161
189
|
function extractThinkingTokens(rawUsage) {
|
|
162
190
|
if (!rawUsage || typeof rawUsage !== 'object') return null;
|
|
163
191
|
const direct = Number(rawUsage.thinking_tokens ?? rawUsage.thinkingTokens);
|
|
@@ -294,6 +322,7 @@ export {
|
|
|
294
322
|
traceAgentToolFailure,
|
|
295
323
|
traceAgentCompact,
|
|
296
324
|
traceAgentUsage,
|
|
325
|
+
traceTurnTiming,
|
|
297
326
|
resolveTraceUsageInput,
|
|
298
327
|
grokCacheChainTraceFields,
|
|
299
328
|
traceAgentCompress,
|
|
@@ -19,7 +19,7 @@ const AUTO_DETECT_PORTS = {
|
|
|
19
19
|
'mixdog-memory': { discovery: 'memory', dir: 'mixdog', file: 'active-instance.json', portField: 'memory_port', endpoint: '/mcp' },
|
|
20
20
|
};
|
|
21
21
|
const DEFAULT_MCP_CALL_TIMEOUT_MS = 120000;
|
|
22
|
-
// Per-server STARTUP handshake budget (connect + listTools)
|
|
22
|
+
// Per-server STARTUP handshake budget (connect + listTools): 10s.
|
|
23
23
|
const DEFAULT_MCP_STARTUP_TIMEOUT_MS = 10000;
|
|
24
24
|
// --- State ---
|
|
25
25
|
const servers = new Map();
|
|
@@ -264,8 +264,8 @@ function isMcpToolCallTimeoutError(err) {
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
// MCP per-server STARTUP timeout: bounds the connect + listTools handshake so a
|
|
267
|
-
// slow or hung server can't stall boot or the first turn. Default 10s
|
|
268
|
-
//
|
|
267
|
+
// slow or hung server can't stall boot or the first turn. Default 10s.
|
|
268
|
+
// Per-server override: startupTimeoutMs / startupTimeoutSec. Global
|
|
269
269
|
// env: MIXDOG_MCP_STARTUP_TIMEOUT_MS. A value of 0/off/none/false disables it.
|
|
270
270
|
export function resolveMcpStartupTimeoutMs(cfg = {}, env = process.env) {
|
|
271
271
|
const rawMs = cfg?.startupTimeoutMs ?? cfg?.startup_timeout_ms;
|