mixdog 0.9.2 → 0.9.3
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 +2 -1
- package/scripts/anthropic-maxtokens-test.mjs +119 -0
- package/scripts/build-tui.mjs +13 -1
- package/scripts/explore-bench.mjs +124 -0
- package/scripts/hook-bus-test.mjs +191 -0
- package/scripts/path-suffix-test.mjs +57 -0
- package/scripts/recall-bench.mjs +207 -0
- package/scripts/tool-smoke.mjs +7 -4
- package/src/agents/debugger/AGENT.md +2 -2
- package/src/agents/heavy-worker/AGENT.md +20 -11
- package/src/agents/reviewer/AGENT.md +2 -2
- package/src/agents/worker/AGENT.md +17 -11
- package/src/mixdog-session-runtime.mjs +424 -1812
- package/src/repl.mjs +5 -5
- package/src/rules/agent/30-explorer.md +8 -11
- package/src/rules/lead/lead-tool.md +9 -5
- package/src/rules/shared/01-tool.md +11 -5
- package/src/runtime/agent/orchestrator/context/collect.mjs +51 -0
- package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +22 -68
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +1 -13
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +54 -20
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +19 -12
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +7 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +33 -23
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +31 -14
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +7 -8
- package/src/runtime/agent/orchestrator/session/loop/compact-debug.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +262 -0
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
- package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +63 -0
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
- package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +169 -918
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +227 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +137 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +303 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +65 -1032
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +162 -0
- package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +5 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +50 -39
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +11 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +497 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1192 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +36 -4277
- package/src/runtime/agent/orchestrator/tools/patch.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
- package/src/runtime/channels/index.mjs +14 -233
- package/src/runtime/channels/lib/boot-profile.mjs +23 -0
- package/src/runtime/channels/lib/crash-log.mjs +106 -0
- package/src/runtime/channels/lib/index-drop-trace.mjs +72 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +8 -0
- package/src/runtime/channels/lib/telegram-format.mjs +19 -22
- package/src/runtime/channels/lib/whisper-language.mjs +42 -0
- package/src/runtime/memory/index.mjs +314 -359
- package/src/runtime/memory/lib/core-memory-store.mjs +351 -1
- package/src/runtime/memory/lib/cycle-signatures.mjs +34 -0
- package/src/runtime/memory/lib/http-wire.mjs +57 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +56 -3
- package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +24 -0
- package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
- package/src/runtime/memory/lib/memory.mjs +20 -0
- package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
- package/src/runtime/memory/lib/recall-format.mjs +183 -0
- package/src/runtime/memory/tool-defs.mjs +4 -4
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/background-tasks.mjs +2 -3
- package/src/runtime/shared/buffered-appender.mjs +149 -0
- package/src/runtime/shared/task-notification-envelope.mjs +98 -0
- package/src/runtime/shared/task-notification-envelope.test.mjs +107 -0
- package/src/runtime/shared/tool-execution-contract.mjs +2 -2
- package/src/runtime/shared/transcript-writer.mjs +29 -2
- package/src/session-runtime/config-helpers.mjs +209 -0
- package/src/session-runtime/effort.mjs +128 -0
- package/src/session-runtime/fs-utils.mjs +10 -0
- package/src/session-runtime/model-capabilities.mjs +130 -0
- package/src/session-runtime/output-styles.mjs +124 -0
- package/src/session-runtime/plugin-mcp.mjs +114 -0
- package/src/session-runtime/session-text.mjs +100 -0
- package/src/session-runtime/statusline-route.mjs +35 -0
- package/src/session-runtime/tool-catalog.mjs +720 -0
- package/src/session-runtime/workflow.mjs +358 -0
- package/src/standalone/agent-tool.mjs +49 -10
- package/src/standalone/channel-worker.mjs +3 -2
- package/src/standalone/explore-tool.mjs +10 -3
- package/src/standalone/hook-bus.mjs +165 -8
- package/src/standalone/opencode-go-login.mjs +121 -0
- package/src/standalone/provider-admin.mjs +14 -3
- package/src/tui/App.jsx +884 -143
- package/src/tui/components/PromptInput.jsx +272 -15
- package/src/tui/components/ToolExecution.jsx +20 -10
- package/src/tui/components/tool-output-format.mjs +2 -2
- package/src/tui/dist/index.mjs +1771 -1947
- package/src/tui/engine/agent-envelope.mjs +296 -0
- package/src/tui/engine/boot-profile.mjs +21 -0
- package/src/tui/engine/labels.mjs +67 -0
- package/src/tui/engine/notice-text.mjs +112 -0
- package/src/tui/engine/queue-helpers.mjs +161 -0
- package/src/tui/engine/session-stats.mjs +46 -0
- package/src/tui/engine/tool-call-fields.mjs +23 -0
- package/src/tui/engine/tool-result-text.mjs +126 -0
- package/src/tui/engine.mjs +311 -851
- package/src/tui/input-editing.mjs +58 -8
- package/src/tui/input-editing.selection.test.mjs +75 -0
- package/src/tui/keyboard-protocol.mjs +2 -2
- package/src/tui/lib/voice-recorder.mjs +35 -19
- package/src/tui/markdown/format-token.mjs +7 -8
- package/src/tui/markdown/format-token.test.mjs +3 -3
- package/src/tui/paste-attachments.mjs +38 -0
- package/src/tui/paste-fix.test.mjs +119 -0
- package/src/tui/themes/base.mjs +2 -2
- package/src/tui/themes/kanagawa.mjs +4 -4
- package/src/tui/themes/teal.mjs +4 -5
- package/src/tui/themes/utils.mjs +1 -1
- package/src/ui/statusline.mjs +49 -0
- package/src/workflows/default/WORKFLOW.md +16 -9
- package/src/workflows/sequential/WORKFLOW.md +16 -11
- package/src/workflows/solo/WORKFLOW.md +5 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// recall-bench.mjs — case-based recall quality bench against the LIVE memory
|
|
3
|
+
// DB. READ-ONLY: every case goes through handleToolCall('search_memories')
|
|
4
|
+
// which only performs SELECTs (handleSearch path). No mutation actions
|
|
5
|
+
// ('memory' tool / cycle1 / cycle2 / prune / purge / etc.) are ever invoked
|
|
6
|
+
// here — do not add any.
|
|
7
|
+
//
|
|
8
|
+
// node scripts/recall-bench.mjs [--cases scripts/recall-bench-cases.json] [--json]
|
|
9
|
+
//
|
|
10
|
+
// Loads src/runtime/memory/index.mjs in-process (same module the daemon
|
|
11
|
+
// uses), calls init() once, runs each bench case through handleToolCall,
|
|
12
|
+
// prints params/result-count/top-3/latency/PASS-WARN per case, then a
|
|
13
|
+
// summary table, then calls stop().
|
|
14
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
15
|
+
import { resolve, dirname } from 'node:path';
|
|
16
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
17
|
+
|
|
18
|
+
const __dir = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const ROOT = resolve(__dir, '..');
|
|
20
|
+
const DEFAULT_CASES_PATH = resolve(__dir, 'recall-bench-cases.json');
|
|
21
|
+
|
|
22
|
+
function argValue(name, fallback = null) {
|
|
23
|
+
const idx = process.argv.indexOf(`--${name}`);
|
|
24
|
+
if (idx >= 0 && idx + 1 < process.argv.length) return process.argv[idx + 1];
|
|
25
|
+
const pref = `--${name}=`;
|
|
26
|
+
const hit = process.argv.find((a) => a.startsWith(pref));
|
|
27
|
+
return hit ? hit.slice(pref.length) : fallback;
|
|
28
|
+
}
|
|
29
|
+
function hasFlag(name) { return process.argv.includes(`--${name}`); }
|
|
30
|
+
|
|
31
|
+
const WARN_LATENCY_MS = 3000;
|
|
32
|
+
|
|
33
|
+
const DEFAULT_CASES = [
|
|
34
|
+
{ id: 'kw-ko', label: 'keyword query (ko)', args: { query: '메모리 재현' }, expect: 'results' },
|
|
35
|
+
{ id: 'kw-en', label: 'keyword query (en)', args: { query: 'memory recall pipeline' }, expect: 'results' },
|
|
36
|
+
{ id: 'short-1tok', label: 'short 1-token query', args: { query: 'recall' }, expect: 'results' },
|
|
37
|
+
{ id: 'short-2tok', label: 'short 2-token query', args: { query: 'cycle1 drain' }, expect: 'results' },
|
|
38
|
+
{ id: 'browse-last', label: 'query-less recent browse (period=last)', args: { period: 'last', limit: 10 }, expect: 'browse' },
|
|
39
|
+
{ id: 'period-24h', label: 'period window 24h', args: { period: '24h', limit: 10 }, expect: 'browse' },
|
|
40
|
+
{ id: 'period-7d', label: 'period window 7d', args: { period: '7d', limit: 10 }, expect: 'browse' },
|
|
41
|
+
{ id: 'category-filter', label: 'category filter (decision)', args: { period: '30d', category: 'decision', limit: 10 }, expect: 'browse' },
|
|
42
|
+
{ id: 'id-lookup', label: 'id lookup', args: { id: 1 }, expect: 'idlookup' },
|
|
43
|
+
{ id: 'scope-project', label: 'project-scoped query', args: { query: 'recall', cwd: ROOT, limit: 10 }, expect: 'results' },
|
|
44
|
+
{ id: 'scope-all', label: 'all-scope query', args: { query: 'recall', projectScope: 'all', limit: 10 }, expect: 'results' },
|
|
45
|
+
{ id: 'raw-on', label: 'includeRaw on', args: { query: 'recall', includeRaw: true, limit: 10 }, expect: 'results' },
|
|
46
|
+
{ id: 'raw-off', label: 'includeRaw off', args: { query: 'recall', includeRaw: false, limit: 10 }, expect: 'results' },
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
function loadCases(path) {
|
|
50
|
+
if (path && existsSync(resolve(path))) {
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(readFileSync(resolve(path), 'utf8'));
|
|
53
|
+
if (Array.isArray(parsed) && parsed.length) return parsed;
|
|
54
|
+
} catch (e) {
|
|
55
|
+
process.stderr.write(`[recall-bench] failed to parse cases file ${path}: ${e.message}; using built-in cases\n`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return DEFAULT_CASES;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function textOfResult(result) {
|
|
62
|
+
if (result && typeof result === 'object' && Array.isArray(result.content)) {
|
|
63
|
+
return result.content.map((p) => (p?.type === 'text' ? p.text || '' : JSON.stringify(p))).join('\n');
|
|
64
|
+
}
|
|
65
|
+
if (result && typeof result === 'object' && typeof result.text === 'string') return result.text;
|
|
66
|
+
if (typeof result === 'string') return result;
|
|
67
|
+
return JSON.stringify(result ?? '');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function countEntryLines(text) {
|
|
71
|
+
const t = String(text || '').trim();
|
|
72
|
+
if (!t || t === '(no results)' || t === '(no valid ids)') return 0;
|
|
73
|
+
return t.split('\n').filter((line) => line.trim() && !line.startsWith('[recall truncated') && !line.startsWith('note:')).length;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function topN(text, n = 3, maxLen = 140) {
|
|
77
|
+
const t = String(text || '').trim();
|
|
78
|
+
if (!t || t === '(no results)') return [];
|
|
79
|
+
return t.split('\n')
|
|
80
|
+
.filter((line) => line.trim() && !line.startsWith('[recall truncated') && !line.startsWith('note:'))
|
|
81
|
+
.slice(0, n)
|
|
82
|
+
.map((line) => (line.length > maxLen ? `${line.slice(0, maxLen - 1)}…` : line));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function evaluateCase(kase, { count, ms, isError }) {
|
|
86
|
+
const warnings = [];
|
|
87
|
+
if (isError) warnings.push('error result');
|
|
88
|
+
if (ms > WARN_LATENCY_MS) warnings.push(`latency ${ms}ms > ${WARN_LATENCY_MS}ms`);
|
|
89
|
+
if ((kase.expect === 'browse' || kase.expect === 'idlookup') && count === 0) {
|
|
90
|
+
warnings.push('0 results for a browse/id-lookup case (expected data present)');
|
|
91
|
+
}
|
|
92
|
+
const status = warnings.length ? 'WARN' : 'PASS';
|
|
93
|
+
return { status, warnings };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function runCase(memoryModule, kase) {
|
|
97
|
+
const started = Date.now();
|
|
98
|
+
let result;
|
|
99
|
+
let isError = false;
|
|
100
|
+
let errMsg = null;
|
|
101
|
+
try {
|
|
102
|
+
result = await memoryModule.handleToolCall('search_memories', kase.args || {});
|
|
103
|
+
isError = Boolean(result?.isError);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
isError = true;
|
|
106
|
+
errMsg = e?.message || String(e);
|
|
107
|
+
result = { text: `(error: ${errMsg})` };
|
|
108
|
+
}
|
|
109
|
+
const ms = Date.now() - started;
|
|
110
|
+
const text = textOfResult(result);
|
|
111
|
+
const count = countEntryLines(text);
|
|
112
|
+
const evalResult = evaluateCase(kase, { count, ms, isError });
|
|
113
|
+
return {
|
|
114
|
+
id: kase.id,
|
|
115
|
+
label: kase.label,
|
|
116
|
+
args: kase.args,
|
|
117
|
+
count,
|
|
118
|
+
ms,
|
|
119
|
+
isError,
|
|
120
|
+
errMsg,
|
|
121
|
+
top3: topN(text, 3),
|
|
122
|
+
status: evalResult.status,
|
|
123
|
+
warnings: evalResult.warnings,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function printCase(row) {
|
|
128
|
+
process.stdout.write(`\n[${row.status}] ${row.id} — ${row.label}\n`);
|
|
129
|
+
process.stdout.write(` params: ${JSON.stringify(row.args)}\n`);
|
|
130
|
+
process.stdout.write(` results: ${row.count} latency: ${row.ms}ms${row.isError ? ` ERROR: ${row.errMsg}` : ''}\n`);
|
|
131
|
+
if (row.top3.length) {
|
|
132
|
+
for (const line of row.top3) process.stdout.write(` - ${line}\n`);
|
|
133
|
+
} else {
|
|
134
|
+
process.stdout.write(' (no results)\n');
|
|
135
|
+
}
|
|
136
|
+
for (const w of row.warnings) process.stdout.write(` WARN: ${w}\n`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function printSummary(rows) {
|
|
140
|
+
process.stdout.write('\n=== recall-bench summary ===\n');
|
|
141
|
+
const widths = { id: 18, results: 8, ms: 8, status: 6 };
|
|
142
|
+
process.stdout.write(
|
|
143
|
+
`${'case'.padEnd(widths.id)}${'results'.padEnd(widths.results)}${'ms'.padEnd(widths.ms)}${'status'.padEnd(widths.status)}notes\n`,
|
|
144
|
+
);
|
|
145
|
+
for (const r of rows) {
|
|
146
|
+
process.stdout.write(
|
|
147
|
+
`${String(r.id).padEnd(widths.id)}${String(r.count).padEnd(widths.results)}${String(r.ms).padEnd(widths.ms)}${String(r.status).padEnd(widths.status)}${r.warnings.join('; ')}\n`,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
const warnCount = rows.filter((r) => r.status === 'WARN').length;
|
|
151
|
+
const totalMs = rows.reduce((s, r) => s + r.ms, 0);
|
|
152
|
+
process.stdout.write(`\ncases=${rows.length} pass=${rows.length - warnCount} warn=${warnCount} total_latency=${totalMs}ms\n`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function main() {
|
|
156
|
+
const casesPath = argValue('cases', DEFAULT_CASES_PATH);
|
|
157
|
+
const jsonMode = hasFlag('json');
|
|
158
|
+
const cases = loadCases(casesPath);
|
|
159
|
+
|
|
160
|
+
let memoryModule;
|
|
161
|
+
try {
|
|
162
|
+
memoryModule = await import(pathToFileURL(resolve(ROOT, 'src/runtime/memory/index.mjs')).href);
|
|
163
|
+
} catch (e) {
|
|
164
|
+
process.stderr.write(`[recall-bench] failed to load memory module: ${e?.stack || e?.message || e}\n`);
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
await memoryModule.init();
|
|
171
|
+
} catch (e) {
|
|
172
|
+
process.stdout.write(`recall-bench: DB unreachable / init failed — reporting clearly, no fabricated results.\n`);
|
|
173
|
+
process.stdout.write(`error: ${e?.stack || e?.message || e}\n`);
|
|
174
|
+
process.exitCode = 1;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const rows = [];
|
|
179
|
+
try {
|
|
180
|
+
for (const kase of cases) {
|
|
181
|
+
const row = await runCase(memoryModule, kase);
|
|
182
|
+
rows.push(row);
|
|
183
|
+
if (!jsonMode) printCase(row);
|
|
184
|
+
}
|
|
185
|
+
} finally {
|
|
186
|
+
try { await memoryModule.stop?.(); } catch {}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const allZero = rows.length > 0 && rows.every((r) => r.count === 0 && !r.isError);
|
|
190
|
+
if (allZero) {
|
|
191
|
+
process.stdout.write('\nNOTE: every case returned 0 results — DB is likely empty (or unreachable pool). Treat WARNs below as expected-empty, not a recall bug, until data is present.\n');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (jsonMode) {
|
|
195
|
+
process.stdout.write(JSON.stringify({ cases: rows }, null, 2) + '\n');
|
|
196
|
+
} else {
|
|
197
|
+
printSummary(rows);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const hardErrors = rows.filter((r) => r.isError);
|
|
201
|
+
if (hardErrors.length) process.exitCode = 1;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
main().catch((e) => {
|
|
205
|
+
process.stderr.write(`${e?.stack || e?.message || e}\n`);
|
|
206
|
+
process.exitCode = 1;
|
|
207
|
+
});
|
package/scripts/tool-smoke.mjs
CHANGED
|
@@ -747,7 +747,7 @@ if (agentProps.mode || agentProps.wait) throw new Error('agent schema should not
|
|
|
747
747
|
agentRules: '# Tool Use',
|
|
748
748
|
skillManifest: '',
|
|
749
749
|
});
|
|
750
|
-
if (!heavyPrompt.stableSystemContext.includes('## heavy-worker')
|
|
750
|
+
if (!heavyPrompt.stableSystemContext.includes('## heavy-worker')) {
|
|
751
751
|
throw new Error(`heavy-worker AGENT.md must be included in scoped role instructions: ${heavyPrompt.stableSystemContext}`);
|
|
752
752
|
}
|
|
753
753
|
const workerPrompt = composeSystemPrompt({
|
|
@@ -756,7 +756,7 @@ if (agentProps.mode || agentProps.wait) throw new Error('agent schema should not
|
|
|
756
756
|
agentRules: '# Tool Use',
|
|
757
757
|
skillManifest: '',
|
|
758
758
|
});
|
|
759
|
-
if (!workerPrompt.stableSystemContext.includes('## worker')
|
|
759
|
+
if (!workerPrompt.stableSystemContext.includes('## worker')) {
|
|
760
760
|
throw new Error(`worker AGENT.md must be included in scoped role instructions: ${workerPrompt.stableSystemContext}`);
|
|
761
761
|
}
|
|
762
762
|
}
|
|
@@ -1091,7 +1091,7 @@ setInternalToolsProvider({
|
|
|
1091
1091
|
if (!/Read-only retrieval role/i.test(visible) || /# environment/i.test(visible) || /git operations deferred to Lead/i.test(visible)) {
|
|
1092
1092
|
throw new Error(`explorer hidden retrieval context should stay slim: ${visible.slice(0, 1200)}`);
|
|
1093
1093
|
}
|
|
1094
|
-
if (!/# Role: explorer/i.test(systemVisible) || /# Role: explorer/i.test(userReminderVisible) || !/
|
|
1094
|
+
if (!/# Role: explorer/i.test(systemVisible) || /# Role: explorer/i.test(userReminderVisible) || !/one-shot locator/i.test(systemVisible)) {
|
|
1095
1095
|
throw new Error(`explorer role md must ride BP2 system, not BP3 user reminder: system=${systemVisible.slice(0, 600)} user=${userReminderVisible.slice(0, 600)}`);
|
|
1096
1096
|
}
|
|
1097
1097
|
const visibleBytes = Buffer.byteLength(visible, 'utf8');
|
|
@@ -1434,9 +1434,12 @@ for (const requiredGrammarLine of [
|
|
|
1434
1434
|
}
|
|
1435
1435
|
const readPathSchema = BUILTIN_TOOLS.find((tool) => tool.name === 'read')?.inputSchema?.properties?.path || {};
|
|
1436
1436
|
const readPathDescription = readPathSchema.description || '';
|
|
1437
|
-
if (!/File path/i.test(readPathDescription) || !/\{path,offset,limit\}\[\]/i.test(readPathDescription) || !/Pass arrays directly/i.test(readPathDescription) || !/legacy recovery only/i.test(readPathDescription)
|
|
1437
|
+
if (!/File path/i.test(readPathDescription) || !/\{path,offset,limit\}\[\]/i.test(readPathDescription) || !/Pass arrays directly/i.test(readPathDescription) || !/legacy recovery only/i.test(readPathDescription)) {
|
|
1438
1438
|
throw new Error('read schema must keep directory-vs-file guidance');
|
|
1439
1439
|
}
|
|
1440
|
+
if (!/Dirs use list/i.test((BUILTIN_TOOLS.find((tool) => tool.name === 'read')?.description) || '')) {
|
|
1441
|
+
throw new Error('read description must keep directory-vs-file guidance');
|
|
1442
|
+
}
|
|
1440
1443
|
const readTool = BUILTIN_TOOLS.find((tool) => tool.name === 'read');
|
|
1441
1444
|
const readDescription = readTool?.description || '';
|
|
1442
1445
|
const readProps = readTool?.inputSchema?.properties || {};
|
|
@@ -7,5 +7,5 @@ permission: read
|
|
|
7
7
|
Root-cause analysis agent.
|
|
8
8
|
|
|
9
9
|
Smallest confirmed cause chain before fixes. Return likely cause, evidence
|
|
10
|
-
(`file:line`), smallest next check/fix.
|
|
11
|
-
|
|
10
|
+
(`file:line`), smallest next check/fix. Mark confirmed facts vs inferences;
|
|
11
|
+
avoid broad speculation.
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
---
|
|
2
|
-
permission: read-write
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Heavy Worker
|
|
6
|
-
Broad implementation agent.
|
|
7
|
-
|
|
8
|
-
Bounded slices; smallest coherent change, not rewrite. Stop: unclear scope,
|
|
9
|
-
growing blast radius, or Lead-only verification.
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
---
|
|
2
|
+
permission: read-write
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Heavy Worker
|
|
6
|
+
Broad implementation agent.
|
|
7
|
+
|
|
8
|
+
Bounded slices; smallest coherent change, not rewrite. Stop: unclear scope,
|
|
9
|
+
growing blast radius, or Lead-only verification.
|
|
10
|
+
|
|
11
|
+
EDIT-FIRST DISCIPLINE. Survey the slice with ONE batched read/grep round,
|
|
12
|
+
then start patching the first bounded piece — broad scope means edit
|
|
13
|
+
incrementally, not read exhaustively. NEVER "one more confirming read": if
|
|
14
|
+
an anchor is plausible, the next call is `apply_patch`. 3+ consecutive
|
|
15
|
+
read-only calls without an edit = stalling — patch the piece you understand
|
|
16
|
+
or stop and report blocked. Self-check comes AFTER edits; deep verification
|
|
17
|
+
is Lead's.
|
|
18
|
+
|
|
19
|
+
Minimal checks + how-to-verify.
|
|
20
|
+
|
|
@@ -7,5 +7,5 @@ permission: read
|
|
|
7
7
|
Regression/risk review agent.
|
|
8
8
|
|
|
9
9
|
Find actionable correctness/regression/security/verification risks. Findings
|
|
10
|
-
first, severity-ordered, one line with `file:line`; skip non-risky nits.
|
|
11
|
-
|
|
10
|
+
first, severity-ordered, one line with `file:line`; skip non-risky nits. If
|
|
11
|
+
clean, one line + only material residual risk.
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
---
|
|
2
|
-
permission: read-write
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Worker
|
|
6
|
-
Scoped implementation agent.
|
|
7
|
-
|
|
8
|
-
Smallest scoped change; no drive-by cleanup. Stop when done/blocked.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
---
|
|
2
|
+
permission: read-write
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Worker
|
|
6
|
+
Scoped implementation agent.
|
|
7
|
+
|
|
8
|
+
Smallest scoped change; no drive-by cleanup. Stop when done/blocked.
|
|
9
|
+
|
|
10
|
+
EDIT-FIRST DISCIPLINE. Brief anchors (`file:line`) are pre-verified — trust
|
|
11
|
+
them and patch. No anchor: locate with AT MOST 1-2 reads, then edit. NEVER
|
|
12
|
+
"one more confirming read": if you know the file and the change, the next
|
|
13
|
+
call is `apply_patch`. 3+ read-only calls without an edit = you are stalling
|
|
14
|
+
— either patch now or return blocked with what's missing. Confidence
|
|
15
|
+
threshold is "plausible", not "proven"; self-check comes AFTER the edit, and
|
|
16
|
+
Lead/Reviewer own final verification.
|
|
17
|
+
|