mixdog 0.9.0 → 0.9.2
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 +10 -3
- package/scripts/_bench-cwc.json +20 -0
- package/scripts/agent-loop-policy-test.mjs +37 -0
- package/scripts/agent-parallel-smoke.mjs +54 -10
- package/scripts/background-task-meta-smoke.mjs +1 -1
- package/scripts/bench-run.mjs +262 -0
- package/scripts/compact-smoke.mjs +12 -0
- package/scripts/compact-trigger-migration-smoke.mjs +67 -1
- package/scripts/ingest-pure-conversation-smoke.mjs +148 -0
- package/scripts/internal-comms-bench.mjs +727 -0
- package/scripts/internal-comms-smoke.mjs +75 -0
- package/scripts/lead-workflow-smoke.mjs +4 -4
- package/scripts/live-worker-smoke.mjs +9 -9
- package/scripts/output-style-bench.mjs +285 -0
- package/scripts/output-style-smoke.mjs +13 -10
- package/scripts/patch-replay.mjs +90 -0
- package/scripts/provider-stream-stall-test.mjs +276 -0
- package/scripts/provider-toolcall-test.mjs +599 -1
- package/scripts/routing-corpus.mjs +281 -0
- package/scripts/session-bench.mjs +1526 -0
- package/scripts/session-diag.mjs +595 -0
- package/scripts/session-ingest-smoke.mjs +2 -2
- package/scripts/task-bench.mjs +207 -0
- package/scripts/tool-failures.mjs +6 -6
- package/scripts/tool-smoke.mjs +306 -66
- package/scripts/toolcall-args-test.mjs +81 -0
- package/src/agents/debugger/AGENT.md +4 -4
- package/src/agents/heavy-worker/AGENT.md +4 -2
- package/src/agents/reviewer/AGENT.md +4 -4
- package/src/agents/worker/AGENT.md +4 -2
- package/src/app.mjs +10 -6
- package/src/defaults/{hidden-roles.json → agents.json} +7 -7
- package/src/examples/schedules/SCHEDULE.example.md +32 -0
- package/src/examples/webhooks/WEBHOOK.example.md +40 -0
- package/src/headless-role.mjs +14 -14
- package/src/help.mjs +1 -0
- package/src/lib/mixdog-debug.cjs +0 -22
- package/src/lib/plugin-paths.cjs +1 -7
- package/src/lib/rules-builder.cjs +34 -56
- package/src/mixdog-session-runtime.mjs +710 -319
- package/src/output-styles/default.md +12 -7
- package/src/output-styles/minimal.md +25 -0
- package/src/output-styles/oneline.md +21 -0
- package/src/output-styles/simple.md +10 -9
- package/src/repl.mjs +12 -4
- package/src/rules/agent/00-common.md +7 -5
- package/src/rules/agent/30-explorer.md +7 -8
- package/src/rules/lead/01-general.md +3 -1
- package/src/rules/lead/lead-tool.md +7 -0
- package/src/rules/shared/01-tool.md +17 -12
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +90 -32
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +32 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +18 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +23 -20
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +48 -14
- package/src/runtime/agent/orchestrator/agent-trace.mjs +87 -12
- package/src/runtime/agent/orchestrator/config.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +131 -67
- package/src/runtime/agent/orchestrator/{internal-roles.mjs → internal-agents.mjs} +72 -72
- package/src/runtime/agent/orchestrator/internal-tools.mjs +13 -26
- package/src/runtime/agent/orchestrator/mcp/client.mjs +94 -16
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +188 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +444 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +359 -106
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +63 -51
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +27 -20
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +184 -17
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +8 -1
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +18 -8
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +210 -21
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +86 -30
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +254 -280
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +191 -50
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +11 -5
- package/src/runtime/agent/orchestrator/providers/registry.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +265 -1
- package/src/runtime/agent/orchestrator/session/compact.mjs +560 -51
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +250 -3
- package/src/runtime/agent/orchestrator/session/loop.mjs +394 -132
- package/src/runtime/agent/orchestrator/session/manager.mjs +217 -170
- package/src/runtime/agent/orchestrator/session/store.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +5 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +63 -15
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +194 -32
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +143 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +1 -44
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +34 -18
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +0 -0
- package/src/runtime/agent/orchestrator/tools/builtin/list-formatting.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +15 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +9 -44
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +13 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +10 -17
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +18 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/builtin/tool-output-limit.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4076 -3985
- package/src/runtime/agent/orchestrator/tools/patch.mjs +116 -2
- package/src/runtime/channels/backends/discord.mjs +99 -9
- package/src/runtime/channels/backends/telegram.mjs +501 -0
- package/src/runtime/channels/index.mjs +441 -1254
- package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
- package/src/runtime/channels/lib/config.mjs +54 -3
- package/src/runtime/channels/lib/drop-trace.mjs +1 -1
- package/src/runtime/channels/lib/executor.mjs +0 -3
- package/src/runtime/channels/lib/format.mjs +4 -2
- package/src/runtime/channels/lib/memory-client.mjs +0 -38
- package/src/runtime/channels/lib/output-forwarder.mjs +77 -71
- package/src/runtime/channels/lib/runtime-paths.mjs +29 -6
- package/src/runtime/channels/lib/scheduler.mjs +1 -1
- package/src/runtime/channels/lib/session-discovery.mjs +0 -4
- package/src/runtime/channels/lib/telegram-format.mjs +283 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -2
- package/src/runtime/channels/lib/transcript-discovery.mjs +20 -11
- package/src/runtime/channels/lib/webhook.mjs +59 -31
- package/src/runtime/channels/tool-defs.mjs +1 -1
- package/src/runtime/lib/keychain-cjs.cjs +0 -1
- package/src/runtime/memory/data/runtime-manifest.json +6 -7
- package/src/runtime/memory/index.mjs +187 -43
- package/src/runtime/memory/lib/agent-ipc.mjs +2 -2
- package/src/runtime/memory/lib/core-memory-store.mjs +1 -1
- package/src/runtime/memory/lib/llm-worker-host.mjs +0 -4
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2.mjs +9 -6
- package/src/runtime/memory/lib/memory-cycle3.mjs +1 -1
- package/src/runtime/memory/lib/memory-ops-policy.mjs +0 -1
- package/src/runtime/memory/lib/memory.mjs +101 -4
- package/src/runtime/memory/lib/pg/adapter.mjs +139 -15
- package/src/runtime/memory/lib/runtime-fetcher.mjs +43 -18
- package/src/runtime/memory/lib/session-ingest.mjs +116 -7
- package/src/runtime/memory/lib/trace-store.mjs +69 -22
- package/src/runtime/memory/tool-defs.mjs +6 -3
- package/src/runtime/search/index.mjs +2 -7
- package/src/runtime/search/lib/config.mjs +0 -4
- package/src/runtime/search/lib/state.mjs +1 -15
- package/src/runtime/search/lib/web-tools.mjs +0 -1
- package/src/runtime/shared/channel-notification-routing.mjs +12 -0
- package/src/runtime/shared/channel-notification-routing.test.mjs +45 -0
- package/src/runtime/shared/child-spawn-gate.mjs +0 -6
- package/src/runtime/shared/config.mjs +9 -0
- package/src/runtime/shared/llm/http-agent.mjs +12 -5
- package/src/runtime/shared/schedules-store.mjs +21 -19
- package/src/runtime/shared/tool-surface.mjs +98 -13
- package/src/runtime/shared/transcript-writer.mjs +129 -0
- package/src/runtime/shared/update-checker.mjs +214 -0
- package/src/standalone/agent-tool.mjs +255 -109
- package/src/standalone/channel-admin.mjs +133 -40
- package/src/standalone/channel-worker.mjs +8 -291
- package/src/standalone/explore-tool.mjs +2 -2
- package/src/standalone/memory-runtime-proxy.mjs +3 -1
- package/src/standalone/provider-admin.mjs +11 -0
- package/src/standalone/seeds.mjs +1 -11
- package/src/standalone/usage-dashboard.mjs +1 -1
- package/src/tui/App.jsx +2137 -750
- package/src/tui/components/ConfirmBar.jsx +47 -0
- package/src/tui/components/ContextPanel.jsx +5 -3
- package/src/tui/components/ItemRightHintOverprint.jsx +54 -0
- package/src/tui/components/Markdown.jsx +22 -98
- package/src/tui/components/Message.jsx +14 -35
- package/src/tui/components/Picker.jsx +87 -12
- package/src/tui/components/PromptInput.jsx +146 -9
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +8 -5
- package/src/tui/components/Spinner.jsx +7 -7
- package/src/tui/components/StatusLine.jsx +40 -21
- package/src/tui/components/TextEntryPanel.jsx +51 -7
- package/src/tui/components/ToolExecution.jsx +177 -100
- package/src/tui/components/TurnDone.jsx +4 -4
- package/src/tui/components/UsagePanel.jsx +1 -1
- package/src/tui/components/tool-output-format.mjs +312 -40
- package/src/tui/components/tool-output-format.test.mjs +180 -1
- package/src/tui/display-width.mjs +69 -0
- package/src/tui/display-width.test.mjs +35 -0
- package/src/tui/dist/index.mjs +7324 -2393
- package/src/tui/engine.mjs +287 -126
- package/src/tui/index.jsx +117 -7
- package/src/tui/keyboard-protocol.mjs +42 -0
- package/src/tui/lib/voice-recorder.mjs +453 -0
- package/src/tui/markdown/format-token.mjs +354 -142
- package/src/tui/markdown/format-token.test.mjs +155 -17
- package/src/tui/markdown/measure-rendered-rows.mjs +85 -0
- package/src/tui/markdown/render-ansi.test.mjs +1 -1
- package/src/tui/markdown/streaming-markdown.mjs +167 -0
- package/src/tui/markdown/streaming-markdown.test.mjs +70 -0
- package/src/tui/markdown/table-layout.mjs +9 -9
- package/src/tui/paste-attachments.mjs +0 -11
- package/src/tui/prompt-history-store.mjs +129 -0
- package/src/tui/prompt-history-store.test.mjs +52 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +3 -3
- package/src/tui/theme.mjs +41 -647
- package/src/tui/themes/base.mjs +86 -0
- package/src/tui/themes/basic.mjs +85 -0
- package/src/tui/themes/catppuccin.mjs +72 -0
- package/src/tui/themes/dracula.mjs +70 -0
- package/src/tui/themes/everforest.mjs +71 -0
- package/src/tui/themes/gruvbox.mjs +71 -0
- package/src/tui/themes/index.mjs +71 -0
- package/src/tui/themes/indigo.mjs +78 -0
- package/src/tui/themes/kanagawa.mjs +80 -0
- package/src/tui/themes/light.mjs +81 -0
- package/src/tui/themes/nord.mjs +72 -0
- package/src/tui/themes/onedark.mjs +16 -0
- package/src/tui/themes/rosepine.mjs +70 -0
- package/src/tui/themes/teal.mjs +81 -0
- package/src/tui/themes/tokyonight.mjs +79 -0
- package/src/tui/themes/utils.mjs +106 -0
- package/src/tui/themes/warm.mjs +79 -0
- package/src/tui/transcript-tool-failures.mjs +13 -2
- package/src/ui/markdown.mjs +1 -1
- package/src/ui/model-display.mjs +2 -2
- package/src/ui/statusline.mjs +26 -27
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -623
- package/src/vendor/statusline/bin/statusline-route.mjs +5 -12
- package/src/vendor/statusline/src/gateway/claude-current.mjs +3 -3
- package/src/vendor/statusline/src/gateway/route-meta.mjs +30 -16
- package/src/workflows/default/WORKFLOW.md +39 -12
- package/src/workflows/sequential/WORKFLOW.md +46 -0
- package/src/workflows/solo/WORKFLOW.md +7 -0
- package/vendor/ink/build/display-width.js +62 -0
- package/vendor/ink/build/ink.js +154 -20
- package/vendor/ink/build/measure-text.js +4 -1
- package/vendor/ink/build/output.js +115 -9
- package/vendor/ink/build/render-node-to-output.js +4 -1
- package/vendor/ink/build/render.js +4 -0
- package/src/hooks/lib/permission-rules.cjs +0 -170
- package/src/hooks/lib/settings-loader.cjs +0 -112
- package/src/lib/hook-pipe-path.cjs +0 -10
- package/src/output-styles/extreme-simple.md +0 -20
- package/src/rules/lead/04-workflow.md +0 -51
- package/src/runtime/channels/lib/hook-pipe-server.mjs +0 -671
- package/src/workflows/default/workflow.json +0 -13
- package/src/workflows/solo/workflow.json +0 -7
|
@@ -36,6 +36,11 @@ import {
|
|
|
36
36
|
import { recordReadSnapshot } from './read-snapshot-runtime.mjs';
|
|
37
37
|
import { applyGrepContextLeadPolicy, GREP_CONTEXT_MAX } from './arg-guard.mjs';
|
|
38
38
|
|
|
39
|
+
// Default surrounding-lines window applied by output_mode:'content_with_context'
|
|
40
|
+
// when the caller does not pass an explicit -A/-B/-C/context. Sized to cover a
|
|
41
|
+
// typical function/block so a match arrives readable without a follow-up read.
|
|
42
|
+
const GREP_AUTO_CONTEXT_LINES = 25;
|
|
43
|
+
|
|
39
44
|
const MIXDOG_GREP_CASE_HINT_PROBE = /^(1|true|yes|on)$/i.test(String(process.env.MIXDOG_GREP_CASE_HINT_PROBE || ''));
|
|
40
45
|
|
|
41
46
|
function expandLegacyEscapedAlternationPattern(rawPattern) {
|
|
@@ -353,18 +358,23 @@ export async function executeGrepTool(args, workDir, executeChildBuiltinTool, re
|
|
|
353
358
|
.map(canonicalizeGlobSlashes)
|
|
354
359
|
.filter((g) => !isRedundantAllFilesGlob(g)));
|
|
355
360
|
|
|
356
|
-
const ALLOWED_OUTPUT_MODES = new Set(['files_with_matches', 'content', 'count']);
|
|
361
|
+
const ALLOWED_OUTPUT_MODES = new Set(['files_with_matches', 'content', 'content_with_context', 'count']);
|
|
357
362
|
const rawOutputMode = typeof args.output_mode === 'string' ? args.output_mode.trim() : '';
|
|
358
363
|
if (rawOutputMode && !ALLOWED_OUTPUT_MODES.has(rawOutputMode)) {
|
|
359
364
|
return `Error: invalid output_mode ${JSON.stringify(args.output_mode)}; expected one of ${[...ALLOWED_OUTPUT_MODES].join(', ')}`;
|
|
360
365
|
}
|
|
366
|
+
// `content_with_context` is a convenience alias for `content` that auto-applies
|
|
367
|
+
// a generous surrounding-lines window, so the model can read a match in place
|
|
368
|
+
// without following up with `read`. It maps to content mode; the default
|
|
369
|
+
// context is applied below unless the caller passed an explicit -A/-B/-C/context.
|
|
370
|
+
const wantAutoContext = rawOutputMode === 'content_with_context';
|
|
361
371
|
// Default to `content` when output_mode is omitted. A pattern is always
|
|
362
372
|
// present here (the no-pattern case returned above), so this is a content
|
|
363
373
|
// search — it should return the matching lines WITH line numbers, not just
|
|
364
374
|
// filenames. Filename-only was forcing callers to re-grep for the actual
|
|
365
375
|
// coordinates (the explorer over-iteration root cause). `files_with_matches`
|
|
366
376
|
// is now opt-in; pure filename discovery belongs to `glob`.
|
|
367
|
-
const outputMode = rawOutputMode || 'content';
|
|
377
|
+
const outputMode = (rawOutputMode === 'content_with_context') ? 'content' : (rawOutputMode || 'content');
|
|
368
378
|
const headLimitRaw = args.head_limit;
|
|
369
379
|
const headLimitCoerced = coerceNonNegInt(headLimitRaw);
|
|
370
380
|
if (Number.isNaN(headLimitCoerced)) {
|
|
@@ -391,6 +401,12 @@ export async function executeGrepTool(args, workDir, executeChildBuiltinTool, re
|
|
|
391
401
|
let contextN = args['-C'] !== undefined && args['-C'] !== null && args['-C'] !== ''
|
|
392
402
|
? coerceContext(args['-C'])
|
|
393
403
|
: coerceContext(args.context);
|
|
404
|
+
// content_with_context: if no explicit context flag was supplied, apply a
|
|
405
|
+
// generous default so the match arrives with enough surrounding code to
|
|
406
|
+
// understand it (function-sized) without a separate read.
|
|
407
|
+
if (wantAutoContext && afterN === null && beforeN === null && contextN === null) {
|
|
408
|
+
contextN = GREP_AUTO_CONTEXT_LINES;
|
|
409
|
+
}
|
|
394
410
|
if (contextN !== null && contextN > 0) {
|
|
395
411
|
if (afterN === 0) afterN = null;
|
|
396
412
|
if (beforeN === 0) beforeN = null;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { countSplitLines } from './path-utils.mjs';
|
|
2
|
+
import { TOOL_OUTPUT_MAX_BYTES } from './tool-output-limit.mjs';
|
|
2
3
|
|
|
3
|
-
export const SHELL_OUTPUT_MAX_CHARS =
|
|
4
|
+
export const SHELL_OUTPUT_MAX_CHARS = TOOL_OUTPUT_MAX_BYTES;
|
|
4
5
|
|
|
5
6
|
export const SMART_BASH_MAX_LINES = 400;
|
|
6
|
-
export const SMART_BASH_MAX_BYTES =
|
|
7
|
+
export const SMART_BASH_MAX_BYTES = TOOL_OUTPUT_MAX_BYTES;
|
|
7
8
|
export const SMART_BASH_HEAD_LINES = 80;
|
|
8
9
|
export const SMART_BASH_TAIL_LINES = 80;
|
|
9
10
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Single source of truth for the model-facing tool-output byte budget.
|
|
2
|
+
// read / shell / list-tree all truncate their output to this cap so the
|
|
3
|
+
// context cost of any one tool call is bounded and consistent. Override with
|
|
4
|
+
// MIXDOG_TOOL_OUTPUT_MAX_BYTES. Line-based sub-caps (e.g. bash max lines) stay
|
|
5
|
+
// per-tool; this governs only the byte budget.
|
|
6
|
+
function _envInt(name, fallback) {
|
|
7
|
+
const v = parseInt(process.env[name], 10);
|
|
8
|
+
return Number.isFinite(v) && v > 0 ? v : fallback;
|
|
9
|
+
}
|
|
10
|
+
export const TOOL_OUTPUT_MAX_BYTES = _envInt('MIXDOG_TOOL_OUTPUT_MAX_BYTES', 50 * 1024);
|
|
@@ -277,6 +277,8 @@ const EXTERNAL_TOOL_REDIRECTS = new Map([
|
|
|
277
277
|
['strreplace', 'use `apply_patch` with a `*** Update File:` V4A section'],
|
|
278
278
|
['str_replace', 'use `apply_patch` with a `*** Update File:` V4A section'],
|
|
279
279
|
['str_replace_editor', 'use `apply_patch` with a `*** Update File:` V4A section'],
|
|
280
|
+
['search_replace', 'use `apply_patch` with a `*** Update File:` V4A section'],
|
|
281
|
+
['applypatch', 'call the `apply_patch` tool (snake_case) with a V4A patch'],
|
|
280
282
|
['createfile', 'use `apply_patch` with an `*** Add File:` V4A section'],
|
|
281
283
|
['create_file', 'use `apply_patch` with an `*** Add File:` V4A section'],
|
|
282
284
|
['deletefile', 'use `apply_patch` with a `*** Delete File:` V4A section'],
|
|
@@ -287,9 +289,15 @@ const EXTERNAL_TOOL_REDIRECTS = new Map([
|
|
|
287
289
|
['terminal', 'use the `shell` tool'],
|
|
288
290
|
['view', 'use the `read` tool'],
|
|
289
291
|
['cat', 'use the `read` tool'],
|
|
292
|
+
['read_file', 'use the `read` tool'],
|
|
290
293
|
['ls', 'use the `list` tool'],
|
|
294
|
+
['list_dir', 'use the `list` tool'],
|
|
291
295
|
['searchfiles', 'use the `grep` tool'],
|
|
296
|
+
['file_search', 'use the `find` or `glob` tool'],
|
|
297
|
+
['grep_search', 'use the `grep` tool'],
|
|
292
298
|
['codebase_search', 'use the `grep` or `code_graph` tool'],
|
|
299
|
+
['semanticsearch', 'use the `grep` or `code_graph` tool'],
|
|
300
|
+
['semantic_search', 'use the `grep` or `code_graph` tool'],
|
|
293
301
|
]);
|
|
294
302
|
|
|
295
303
|
export function canonicalizeBuiltinToolName(name) {
|
|
@@ -401,6 +409,55 @@ function capToolOutput(result, options = {}) {
|
|
|
401
409
|
return `${head}\n... [tool-output truncated: ${Math.round(bytes / 1024)} KB -> ${Math.round(cap / 1024)} KB cap (tool_output_token_limit)] ...\n${tail}`;
|
|
402
410
|
}
|
|
403
411
|
|
|
412
|
+
const _GREP_SWEEP_NUDGE_ENABLED = /^(1|true|yes|on)$/i.test(String(process.env.MIXDOG_ENABLE_GREP_SWEEP_NUDGE || ''));
|
|
413
|
+
const _GREP_SWEEP_MIN_CALLS = 20;
|
|
414
|
+
const _GREP_SWEEP_MIN_UNIQUE = 16;
|
|
415
|
+
const _grepSweepState = new Map();
|
|
416
|
+
|
|
417
|
+
function _grepSweepTerms(pattern) {
|
|
418
|
+
const raw = Array.isArray(pattern) ? pattern.join('|') : String(pattern || '');
|
|
419
|
+
return [...new Set(raw
|
|
420
|
+
.split(/[|,\s()"'`[\]{}.*+?^$\\:-]+/g)
|
|
421
|
+
.map((s) => s.trim().toLowerCase())
|
|
422
|
+
.filter((s) => s.length >= 4))];
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function _normalizeSweepPath(value) {
|
|
426
|
+
return String(value || '.')
|
|
427
|
+
.replace(/\\/g, '/')
|
|
428
|
+
.replace(/^([A-Za-z]):/, (_, d) => d.toLowerCase() + ':')
|
|
429
|
+
.replace(/\/+/g, '/')
|
|
430
|
+
.replace(/\/$/, '') || '.';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function _grepSweepKey(args = {}) {
|
|
434
|
+
const path = _normalizeSweepPath(args.path || '.');
|
|
435
|
+
const glob = Array.isArray(args.glob) ? args.glob.join(',') : String(args.glob || '');
|
|
436
|
+
const terms = _grepSweepTerms(args.pattern).slice(0, 3).join('|');
|
|
437
|
+
return `${path}::${glob}::${terms}`;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function _maybeAppendGrepSweepNudge(toolName, args, result, scope) {
|
|
441
|
+
if (!_GREP_SWEEP_NUDGE_ENABLED || toolName !== 'grep' || typeof result !== 'string') return result;
|
|
442
|
+
const key = scope || 'global';
|
|
443
|
+
const now = Date.now();
|
|
444
|
+
let state = _grepSweepState.get(key);
|
|
445
|
+
if (!state || now - state.lastTs > 10 * 60_000) {
|
|
446
|
+
state = { count: 0, unique: new Set(), lastTs: 0, nudged: false };
|
|
447
|
+
_grepSweepState.set(key, state);
|
|
448
|
+
}
|
|
449
|
+
state.count += 1;
|
|
450
|
+
state.unique.add(_grepSweepKey(args));
|
|
451
|
+
state.lastTs = now;
|
|
452
|
+
if (_grepSweepState.size > 256) {
|
|
453
|
+
const oldest = [..._grepSweepState.entries()].sort((a, b) => (a[1].lastTs || 0) - (b[1].lastTs || 0)).slice(0, 32);
|
|
454
|
+
for (const [oldKey] of oldest) _grepSweepState.delete(oldKey);
|
|
455
|
+
}
|
|
456
|
+
if (state.nudged || state.count < _GREP_SWEEP_MIN_CALLS || state.unique.size < _GREP_SWEEP_MIN_UNIQUE) return result;
|
|
457
|
+
state.nudged = true;
|
|
458
|
+
return `${result}\n\n[grep_sweep_hint] Many distinct grep searches were used in this session. Stop rewording search terms; synthesize from existing anchors or switch tools once (code_graph/find/read known regions).`;
|
|
459
|
+
}
|
|
460
|
+
|
|
404
461
|
export async function executeBuiltinTool(name, args, cwd, options = {}) {
|
|
405
462
|
if (options.abortSignal && !options.signal) {
|
|
406
463
|
options = { ...options, signal: options.abortSignal };
|
|
@@ -463,7 +520,8 @@ export async function executeBuiltinTool(name, args, cwd, options = {}) {
|
|
|
463
520
|
return formatUnknownBuiltinToolMessage(name, args);
|
|
464
521
|
}
|
|
465
522
|
})();
|
|
466
|
-
|
|
523
|
+
const _withNudge = _maybeAppendGrepSweepNudge(toolName, args, _toolResult, readStateScope);
|
|
524
|
+
return capToolOutput(_withNudge, options);
|
|
467
525
|
}
|
|
468
526
|
/**
|
|
469
527
|
* Check if a tool name is a builtin tool.
|
|
@@ -3,14 +3,14 @@ export const CODE_GRAPH_TOOL_DEFS = [
|
|
|
3
3
|
name: 'code_graph',
|
|
4
4
|
title: 'Code Graph',
|
|
5
5
|
annotations: { title: 'Code Graph', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, compressible: false, compressibleLossless: true },
|
|
6
|
-
description: '
|
|
6
|
+
description: 'Repo-local code structure/flow lookup, not web: symbols/references/calls/deps before text grep. Batch symbols[].',
|
|
7
7
|
inputSchema: {
|
|
8
8
|
type: 'object',
|
|
9
9
|
properties: {
|
|
10
|
-
mode: { type: 'string', enum: ['overview', 'imports', 'dependents', 'related', 'impact', 'symbols', 'find_symbol', 'search', 'references', 'callers', 'callees', 'prewarm'], description: '
|
|
11
|
-
file: { type: 'string', description: '
|
|
12
|
-
symbol: { type: 'string', description: 'Identifier
|
|
13
|
-
symbols: { type: 'array', items: { type: 'string' }, description: 'Batch identifiers.' },
|
|
10
|
+
mode: { type: 'string', enum: ['overview', 'imports', 'dependents', 'related', 'impact', 'symbols', 'find_symbol', 'symbol_search', 'search', 'references', 'callers', 'callees', 'prewarm'], description: 'Repo-local operation; code flow before text search.' },
|
|
11
|
+
file: { type: 'string', description: 'Known source file.' },
|
|
12
|
+
symbol: { type: 'string', description: 'Identifier/keyword; one anchor is enough.' },
|
|
13
|
+
symbols: { type: 'array', items: { type: 'string' }, description: 'Batch identifiers in one call.' },
|
|
14
14
|
body: { type: 'boolean', description: 'Include body.' },
|
|
15
15
|
language: { type: 'string', description: 'Language hint.' },
|
|
16
16
|
limit: { type: 'number', minimum: 1, description: 'Max results.' },
|