mixdog 0.9.131 → 0.9.133
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 -2
- package/scripts/fixtures/patch-replay-corpus.json +9 -9
- package/scripts/reduction-trace-report.mjs +29 -0
- package/scripts/tool-failures.mjs +36 -0
- package/scripts/tool-stress.mjs +2 -2
- package/src/lib/rules-builder.cjs +0 -3
- package/src/rules/lead/01-general.md +1 -9
- package/src/rules/shared/01-tool.md +71 -39
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -10
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +72 -9
- package/src/runtime/agent/orchestrator/agent-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +212 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +2100 -0
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +615 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +65 -35
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +35 -6
- package/src/runtime/agent/orchestrator/providers/media-parity.test.mjs +142 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +16 -5
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +69 -53
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +12 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +30 -5
- package/src/runtime/agent/orchestrator/session/eager-dispatch.test.mjs +55 -0
- package/src/runtime/agent/orchestrator/session/evidence-union.mjs +548 -0
- package/src/runtime/agent/orchestrator/session/evidence-union.test.mjs +211 -0
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +68 -11
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.test.mjs +122 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +31 -3
- package/src/runtime/agent/orchestrator/session/lossless-tool-output.test.mjs +124 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +17 -14
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/provider-cache-key.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +3 -6
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -6
- package/src/runtime/agent/orchestrator/session/reduction-metrics.mjs +120 -0
- package/src/runtime/agent/orchestrator/session/reduction-metrics.test.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +13 -4
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +55 -37
- package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +93 -2
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +142 -23
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +111 -71
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +23 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +51 -46
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +63 -24
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +57 -23
- package/src/runtime/agent/orchestrator/tools/builtin/edit-sequential-occupation.test.mjs +56 -0
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +134 -30
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +107 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.test.mjs +27 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +600 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +140 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +96 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.test.mjs +83 -0
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +8 -5
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool-integrity.test.mjs +132 -0
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +90 -10
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +167 -25
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-health.test.mjs +21 -0
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-runner.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +24 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +33 -8
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +17 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +9 -15
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +40 -51
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +115 -56
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +18 -63
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +6 -47
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +5 -85
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +8 -15
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.test.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +23 -18
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +92 -116
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +5 -45
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +0 -17
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +15 -16
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/tool-batch-trace.mjs +7 -0
- package/src/runtime/channels/lib/session-discovery.mjs +66 -1
- package/src/runtime/channels/lib/session-discovery.test.mjs +32 -0
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -1
- package/src/runtime/shared/agent-route-config.mjs +3 -0
- package/src/runtime/shared/child-guardian.mjs +14 -0
- package/src/runtime/shared/edit-tool-dialect.mjs +30 -0
- package/src/runtime/shared/pristine-execution-contract.json +1 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -5
- package/src/runtime/shared/schedule-session-run.mjs +2 -0
- package/src/runtime/shared/session-shard-health.mjs +89 -0
- package/src/runtime/shared/session-shard-health.test.mjs +30 -0
- package/src/runtime/shared/tool-execution-contract.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +5 -0
- package/src/runtime/shared/webhook-session-run.mjs +8 -1
- package/src/session-runtime/config-helpers.mjs +18 -1
- package/src/session-runtime/lifecycle-api.mjs +13 -2
- package/src/session-runtime/model-capabilities.mjs +24 -2
- package/src/session-runtime/model-recency.mjs +11 -0
- package/src/session-runtime/model-route-api.mjs +37 -6
- package/src/session-runtime/model-settings-persist.test.mjs +6 -1
- package/src/session-runtime/native-search.mjs +1 -0
- package/src/session-runtime/provider-auth-api.mjs +13 -11
- package/src/session-runtime/provider-models.mjs +8 -4
- package/src/session-runtime/runtime-core.mjs +6 -31
- package/src/session-runtime/session-lifecycle.mjs +13 -1
- package/src/session-runtime/session-turn-api.mjs +1 -13
- package/src/session-runtime/tool-catalog-data.mjs +8 -5
- package/src/session-runtime/tool-catalog-schema.mjs +2 -3
- package/src/session-runtime/tool-catalog.mjs +6 -1
- package/src/session-runtime/tool-defs.mjs +0 -28
- package/src/session-runtime/tool-policy-surface.test.mjs +32 -0
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/workflow-agents-api.mjs +9 -1
- package/src/session-runtime/workflow.mjs +5 -0
- package/src/standalone/agent-tool/lead-worker-index.mjs +144 -0
- package/src/standalone/agent-tool/notify.mjs +6 -2
- package/src/standalone/agent-tool/tag-registry.mjs +7 -1
- package/src/standalone/agent-tool/tool-def.mjs +1 -0
- package/src/standalone/agent-tool/worker-index.mjs +2 -12
- package/src/standalone/channel-client.mjs +18 -6
- package/src/standalone/channel-restart.test.mjs +163 -0
- package/src/standalone/channel-transport.mjs +54 -15
- package/src/standalone/channel-worker.mjs +6 -2
- package/src/standalone/provider-admin.mjs +14 -4
- package/src/standalone/session-runtime-pool-health.test.mjs +85 -0
- package/src/standalone/session-runtime-pool.mjs +22 -3
- package/src/standalone/session-runtime-worker.mjs +35 -0
- package/src/standalone/usage-dashboard.mjs +11 -1
- package/src/tui/app/model-options.mjs +2 -0
- package/src/tui/app/model-picker.mjs +64 -11
- package/src/tui/app/provider-setup-picker.mjs +32 -28
- package/src/tui/dist/index.mjs +111 -40
- package/src/tui/session/agent-envelope.mjs +1 -1
- package/src/tui/session/context-state.mjs +1 -0
- package/src/tui/session/session-api-ext.mjs +2 -0
- package/src/tui/session/session-api.mjs +1 -1
- package/src/tui/session/session-flow.mjs +32 -19
- package/src/workflows/default/WORKFLOW.md +3 -0
- package/src/workflows/solo/WORKFLOW.md +3 -1
- package/src/rules/lead/lead-tool.md +0 -3
- package/src/runtime/agent/orchestrator/session/loop/stop-hooks.mjs +0 -98
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +0 -279
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixdog",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.133",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Standalone mixdog coding-agent CLI/TUI workspace.",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"test:tool-contracts": "npm run build:spawn:test && node scripts/tool-smoke.mjs",
|
|
60
60
|
"smoke:patch": "node scripts/apply-patch-edit-smoke.mjs",
|
|
61
61
|
"test:shellhardening": "npm run build:spawn:test && node --test scripts/suite-shellhardening-test.mjs scripts/suite-shell-direct-exe-test.mjs",
|
|
62
|
-
"test:providers": "node --test scripts/provider-toolcall-test.mjs scripts/provider-contract-test.mjs scripts/provider-stream-outcome-test.mjs",
|
|
62
|
+
"test:providers": "node --test scripts/provider-toolcall-test.mjs scripts/provider-contract-test.mjs scripts/provider-stream-outcome-test.mjs scripts/cursor-provider-test.mjs",
|
|
63
63
|
"test:embedding-runtime:warmup": "node scripts/verify-embedding-runtime.mjs --warmup",
|
|
64
64
|
"test:release-assets": "node --check scripts/verify-release-assets.mjs && node --check scripts/release-gate-test.mjs && node --check scripts/prepare-native-assets.mjs && node --test scripts/release-gate-test.mjs scripts/prepare-native-assets-test.mjs",
|
|
65
65
|
"test:native-edit-wire": "node scripts/native-edit-wire-test.mjs",
|
|
@@ -169,9 +169,9 @@
|
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
"id": "add-overwrite-crlf",
|
|
172
|
-
"note": "Add File
|
|
173
|
-
"expect": "
|
|
174
|
-
"
|
|
172
|
+
"note": "Add File must reject an existing file without changing its CRLF content",
|
|
173
|
+
"expect": "rejected",
|
|
174
|
+
"expect_error": "Add File target already exists",
|
|
175
175
|
"file_snapshots": { "a.txt": "old\r\n" },
|
|
176
176
|
"args": { "patch": "*** Begin Patch\n*** Add File: a.txt\n+NEW\n*** End Patch\n" }
|
|
177
177
|
},
|
|
@@ -194,24 +194,24 @@
|
|
|
194
194
|
{
|
|
195
195
|
"id": "already-applied-insert",
|
|
196
196
|
"note": "observed: re-sent insertion whose unique new-side is already on disk",
|
|
197
|
-
"expect": "
|
|
198
|
-
"
|
|
197
|
+
"expect": "rejected",
|
|
198
|
+
"expect_error": "context not found",
|
|
199
199
|
"file_snapshots": { "a.js": "const STATUS = {\n pending: 1,\n archived: 2,\n}\n" },
|
|
200
200
|
"args": { "patch": "*** Begin Patch\n*** Update File: a.js\n@@\n const STATUS = {\n pending: 1,\n+ archived: 2,\n }\n*** End Patch\n" }
|
|
201
201
|
},
|
|
202
202
|
{
|
|
203
203
|
"id": "already-applied-replace",
|
|
204
204
|
"note": "observed: re-sent replacement whose unique new-side is already on disk",
|
|
205
|
-
"expect": "
|
|
206
|
-
"
|
|
205
|
+
"expect": "rejected",
|
|
206
|
+
"expect_error": "context not found",
|
|
207
207
|
"file_snapshots": { "a.js": "head\nreturn ALL.has(v) || v === 'core' || v === 'lineage'\ntail\n" },
|
|
208
208
|
"args": { "patch": "*** Begin Patch\n*** Update File: a.js\n@@\n head\n-return ALL.has(v) || v === 'core'\n+return ALL.has(v) || v === 'core' || v === 'lineage'\n tail\n*** End Patch\n" }
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
211
|
"id": "already-applied-mixed-remaining",
|
|
212
212
|
"note": "already-applied hunks skip; a later unique old-side hunk still applies",
|
|
213
|
-
"expect": "
|
|
214
|
-
"
|
|
213
|
+
"expect": "rejected",
|
|
214
|
+
"expect_error": "context not found",
|
|
215
215
|
"file_snapshots": { "a.js": "const STATUS = {\n pending: 1,\n archived: 2,\n}\n// pending/active only\n" },
|
|
216
216
|
"args": { "patch": "*** Begin Patch\n*** Update File: a.js\n@@\n const STATUS = {\n pending: 1,\n+ archived: 2,\n }\n@@\n-// pending/active only\n+// lineage backfill\n*** End Patch\n" }
|
|
217
217
|
},
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { summarizeReductionTraceRows } from '../src/runtime/agent/orchestrator/session/reduction-metrics.mjs';
|
|
6
|
+
|
|
7
|
+
export function parseTraceJsonl(text) {
|
|
8
|
+
const rows = [];
|
|
9
|
+
for (const line of String(text || '').split(/\r?\n/)) {
|
|
10
|
+
if (!line.trim()) continue;
|
|
11
|
+
try { rows.push(JSON.parse(line)); } catch { /* retain valid rows */ }
|
|
12
|
+
}
|
|
13
|
+
return rows;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function main(argv) {
|
|
17
|
+
const tracePath = argv[2];
|
|
18
|
+
if (!tracePath) {
|
|
19
|
+
process.stderr.write('Usage: node scripts/reduction-trace-report.mjs <agent-trace.jsonl>\n');
|
|
20
|
+
return 2;
|
|
21
|
+
}
|
|
22
|
+
const rows = parseTraceJsonl(readFileSync(resolve(tracePath), 'utf8'));
|
|
23
|
+
process.stdout.write(`${JSON.stringify(summarizeReductionTraceRows(rows), null, 2)}\n`);
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (resolve(process.argv[1] || '') === fileURLToPath(import.meta.url)) {
|
|
28
|
+
process.exitCode = main(process.argv);
|
|
29
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { resolve } from 'node:path';
|
|
5
|
+
import { classifyToolFailure } from '../src/runtime/agent/orchestrator/agent-trace-format.mjs';
|
|
5
6
|
|
|
6
7
|
function argValue(name, fallback = null) {
|
|
7
8
|
const idx = process.argv.indexOf(name);
|
|
@@ -87,9 +88,40 @@ function rowCategory(row) {
|
|
|
87
88
|
return row.category || row.result_kind || row.resultKind || '(uncategorized)';
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
function rowErrorText(row) {
|
|
92
|
+
return row.error_preview || row.result || row.error || row.message || row.error_first_line || '';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isKnownTestFixture(row) {
|
|
96
|
+
if (row.session_id !== 'no-session' || row.agent != null || row.model != null) return false;
|
|
97
|
+
const tool = rowTool(row);
|
|
98
|
+
if (tool === 'unknown_test_tool') return true;
|
|
99
|
+
return tool === 'apply_patch' && /^Error:\s*patch failed\s*$/i.test(String(rowErrorText(row)).trim());
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function normalizeRowCategory(row) {
|
|
103
|
+
const storedCategory = rowCategory(row);
|
|
104
|
+
let category = storedCategory;
|
|
105
|
+
if (isKnownTestFixture(row)) {
|
|
106
|
+
category = 'expected-test';
|
|
107
|
+
} else if (rowTool(row) === 'apply_patch') {
|
|
108
|
+
const derived = classifyToolFailure(rowErrorText(row), 'apply_patch');
|
|
109
|
+
// Failure previews are bounded and may end before the nested cause. Never
|
|
110
|
+
// downgrade a stored specific category to the generic fallback merely
|
|
111
|
+
// because the historical preview lacks that tail.
|
|
112
|
+
if (derived !== 'runtime/failure' || storedCategory === 'runtime/failure') {
|
|
113
|
+
category = derived;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return category === storedCategory
|
|
117
|
+
? row
|
|
118
|
+
: { ...row, stored_category: storedCategory, category };
|
|
119
|
+
}
|
|
120
|
+
|
|
90
121
|
const sinceTs = parseSince(sinceArg);
|
|
91
122
|
const onlyArg = String(argValue('--only', 'all') || 'all').toLowerCase();
|
|
92
123
|
const rows = files.flatMap(readRows)
|
|
124
|
+
.map(normalizeRowCategory)
|
|
93
125
|
.filter((row) => sinceTs == null || Number(row.ts || 0) >= sinceTs)
|
|
94
126
|
.filter((row) => !toolFilter || rowTool(row) === toolFilter)
|
|
95
127
|
.filter((row) => !agentFilter || String(row.agent || '-') === agentFilter)
|
|
@@ -150,6 +182,8 @@ const actionableByFamily = tally(actionableRows, categoryFamily);
|
|
|
150
182
|
const commandExitByTool = tally(commandExitRows, rowTool);
|
|
151
183
|
const expectedByCategory = tally(expectedRows, rowCategory);
|
|
152
184
|
const patchByCategory = tally(patchRows, rowCategory);
|
|
185
|
+
const reclassifiedRows = rows.filter((row) => row.stored_category && row.stored_category !== rowCategory(row));
|
|
186
|
+
const reclassifiedByCategory = tally(reclassifiedRows, (row) => `${row.stored_category} -> ${rowCategory(row)}`);
|
|
153
187
|
|
|
154
188
|
if (jsonMode) {
|
|
155
189
|
console.log(JSON.stringify({
|
|
@@ -160,6 +194,7 @@ if (jsonMode) {
|
|
|
160
194
|
expected_absorbed: { shown: expectedRecent.length, matched: expectedRows.length },
|
|
161
195
|
session_cancellations: { shown: 0, matched: cancellationRows.length },
|
|
162
196
|
patch_failures: { matched: patchRows.length, categories: asObject(patchByCategory) },
|
|
197
|
+
reclassified: { matched: reclassifiedRows.length, categories: asObject(reclassifiedByCategory) },
|
|
163
198
|
since: sinceTs ? new Date(sinceTs).toISOString() : null,
|
|
164
199
|
filters: {
|
|
165
200
|
tool: toolFilter,
|
|
@@ -200,6 +235,7 @@ console.log(`actionable families (matched): ${asText(actionableByFamily)}`);
|
|
|
200
235
|
console.log(`patch failures (matched): ${patchRows.length} — ${asText(patchByCategory)}`);
|
|
201
236
|
console.log(`command-exit tools (matched): ${asText(commandExitByTool)}`);
|
|
202
237
|
console.log(`expected/absorbed categories (matched): ${asText(expectedByCategory)}`);
|
|
238
|
+
console.log(`reclassified rows (matched): ${reclassifiedRows.length} — ${asText(reclassifiedByCategory)}`);
|
|
203
239
|
console.log(`shown categories: ${asText(byCategory)}`);
|
|
204
240
|
for (const row of recent) {
|
|
205
241
|
const tool = rowTool(row);
|
package/scripts/tool-stress.mjs
CHANGED
|
@@ -129,13 +129,13 @@ try {
|
|
|
129
129
|
|
|
130
130
|
// ── Phase D: cancellation under load ─────────────────────────────────────
|
|
131
131
|
const bg = await timed('shell-async', /task_id/, () => executeBuiltinTool('shell', {
|
|
132
|
-
command: 'node -e "setTimeout(()=>{}, 30000)"',
|
|
132
|
+
command: 'node -e "setTimeout(()=>{}, 30000)"',
|
|
133
133
|
}, root, { sessionId: 'stress-cancel' }));
|
|
134
134
|
const bgId = (/task_id:\s*(\S+)/.exec(String(bg)) || [])[1];
|
|
135
135
|
if (!bgId) failures.push('async shell did not return task_id');
|
|
136
136
|
else {
|
|
137
137
|
await timed('task-cancel', /cancelled/, () => executeBuiltinTool('task', { action: 'cancel', task_id: bgId }, root, { sessionId: 'stress-cancel' }));
|
|
138
|
-
const st = await timed('task-status', /cancelled|failed/, () => executeBuiltinTool('task', { action: '
|
|
138
|
+
const st = await timed('task-status', /cancelled|failed/, () => executeBuiltinTool('task', { action: 'read', task_id: bgId }, root, { sessionId: 'stress-cancel' }));
|
|
139
139
|
if (!/cancelled/.test(String(st))) failures.push(`cancelled task not reported cancelled: ${String(st).slice(0, 120)}`);
|
|
140
140
|
}
|
|
141
141
|
} finally {
|
|
@@ -211,9 +211,6 @@ function buildLeadRoleContent({ PLUGIN_ROOT, DATA_DIR, includeLeadBrief = true }
|
|
|
211
211
|
const general = readOptional(path.join(LEAD_DIR, '01-general.md'));
|
|
212
212
|
const parts = [];
|
|
213
213
|
|
|
214
|
-
const toolLead = readOptional(path.join(LEAD_DIR, 'lead-tool.md'));
|
|
215
|
-
if (toolLead) parts.push(toolLead);
|
|
216
|
-
|
|
217
214
|
if (includeLeadBrief) {
|
|
218
215
|
const briefLead = readOptional(path.join(LEAD_DIR, 'lead-brief.md'));
|
|
219
216
|
if (briefLead) parts.push(briefLead);
|
|
@@ -7,17 +7,9 @@
|
|
|
7
7
|
- Confirm destructive/hard-to-reverse actions against explicit validated paths;
|
|
8
8
|
never `~`, a root, or unresolved variables/globs; report material deletion
|
|
9
9
|
recoverability.
|
|
10
|
-
- Ask only for decisions.
|
|
11
|
-
- Investigate, build, and verify only what the requested outcome requires;
|
|
12
|
-
trust internal and framework guarantees.
|
|
13
|
-
- Blocking tests cover only essential integrity, security, compatibility, and
|
|
14
|
-
buildability invariants. Treat mutable behavior, UX, exact text, snapshots,
|
|
15
|
-
and implementation shape as advisory specifications; update them when the
|
|
16
|
-
requested behavior changes instead of preserving obsolete behavior.
|
|
17
10
|
- After required work, run final verification only when the outcome needs
|
|
18
11
|
evidence the successful tool result does not already give, and run only
|
|
19
|
-
affected blocking invariants.
|
|
20
|
-
reopening already obtained content. Combine commands when dependency or
|
|
12
|
+
affected blocking invariants. Combine commands when dependency or
|
|
21
13
|
atomicity requires it.
|
|
22
14
|
- Mid-task: replacement supersedes; addition folds in; status gets a brief
|
|
23
15
|
answer while work continues. After compaction, resume the summary.
|
|
@@ -5,15 +5,18 @@
|
|
|
5
5
|
path/name only→`find`; wildcard/recursive paths→`glob` (including known-root
|
|
6
6
|
unknown descendants); exact directory entries→`list`;
|
|
7
7
|
file-content search→`grep`; known-file content→`read`;
|
|
8
|
-
exact symbol, body, or relation→`code_graph
|
|
8
|
+
exact symbol, body, or relation→`code_graph`
|
|
9
|
+
(identifier declarations/usages→`code_graph`; literal values/strings→`grep`);
|
|
10
|
+
local Git repository inspection and mutation→`git`;
|
|
9
11
|
program execution, calculations, data transformation, file generation, or
|
|
10
12
|
unsupported formats→`shell`;
|
|
11
13
|
web/current→`search`; returned URL body→`web_fetch`;
|
|
12
14
|
prior work→`recall` (history only, never current local state);
|
|
13
15
|
durable compact English memory→`memory`;
|
|
14
16
|
explicit Project change→`cwd`
|
|
15
|
-
(a shell-local `cd` never changes the Project)
|
|
16
|
-
|
|
17
|
+
(a shell-local `cd` never changes the Project).
|
|
18
|
+
Paths reachable by expanding an environment variable or the home directory
|
|
19
|
+
are resolved locations, not unknowns.
|
|
17
20
|
Use only named tools present in the current tool surface.
|
|
18
21
|
- Requirements define what must be true; evidence establishes what is true.
|
|
19
22
|
Never use one as the other. Treat supplied target locations as resolved;
|
|
@@ -22,30 +25,56 @@
|
|
|
22
25
|
inspect the original content itself. Within the current project, pass project-relative
|
|
23
26
|
paths and omit optional scopes equal to its root; explicit paths may be
|
|
24
27
|
outside cwd only for targets outside the project.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
For a required new file, Add File itself is the atomic absence check: call
|
|
29
|
+
it directly, and inspect only if it reports that the target already exists.
|
|
30
|
+
- Evidence economy: investigate, build, and verify only what the requested
|
|
31
|
+
outcome requires; trust internal and framework guarantees. After
|
|
32
|
+
identifying all result-critical evidence needs, plan the fewest
|
|
33
|
+
evidence-complete dependent rounds, then the fewest calls.
|
|
34
|
+
Known state — system/framework guarantees, supplied facts, exact lines or
|
|
35
|
+
values already visible here, tool returns, applied patches, and proved
|
|
36
|
+
checks — is never re-found, re-derived, or re-verified at any granularity:
|
|
37
|
+
no re-query call, no confirmation subcommand inside a shell command, no
|
|
38
|
+
availability probe for what the operation itself would report, no reopening
|
|
39
|
+
a file to rebuild context or confirm an edit, no rerun of a passed check.
|
|
30
40
|
A hole (needed content absent and not reconstructable) is fetched once;
|
|
31
|
-
a change re-opens only that hole.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
a change re-opens only that hole. Returned output is fully mined before the
|
|
42
|
+
next round. `code_graph references` supplies the declaration and scoped
|
|
43
|
+
usages and ends that facet; values/locations end at the context grep
|
|
44
|
+
returns; `read` covers only what returned spans cannot, as an anchored
|
|
45
|
+
offset/limit window. Already obtained hunk text is any visible span —
|
|
46
|
+
`grep`, `code_graph`, `shell`, system/reminder text, or `read` — not only
|
|
47
|
+
`read`. Each follow-up may address only facts left unresolved or changed by
|
|
48
|
+
prior results. Evidence that determines the answer, edit, or deliverable
|
|
49
|
+
ends retrieval — patch if needed.
|
|
50
|
+
- Parallel batching: independent calls share one batch by default — one
|
|
51
|
+
best-routed call per facet. Cost is counted in rounds, not calls: a batch
|
|
52
|
+
of N calls in one message is one round, so a call-count saving never
|
|
53
|
+
justifies folding work into a single worse-routed call.
|
|
54
|
+
The opening round is a one-shot sweep: every facet knowable from the
|
|
55
|
+
request alone — enumeration, content probes, file samples — launches in
|
|
56
|
+
that single first batch. Each later round exists only for facets the
|
|
57
|
+
previous round's results created; a facet no result produced belonged in
|
|
58
|
+
the round before it.
|
|
59
|
+
Opening-round batching never licenses a guessed path. `glob.path` must be
|
|
60
|
+
an established existing directory; omit it for the current Project. When
|
|
61
|
+
the location itself is unknown, use `find` first and call `glob` only if
|
|
62
|
+
wildcard descendants are still needed.
|
|
63
|
+
Serialize two calls only when the later call's
|
|
64
|
+
inputs are actually produced by the earlier result; the mere possibility
|
|
65
|
+
that a result could reshape later work never defers an independent call.
|
|
66
|
+
Before each batch, deduplicate the remaining necessary facets and route
|
|
67
|
+
each once to the cheapest sufficient tool — never split or duplicate a
|
|
68
|
+
facet across tools, mutate merely to widen retrieval, reserve known work,
|
|
69
|
+
or cap fanout. Applying one analysis to many targets is a single
|
|
70
|
+
parameterized call over all targets, not one call per target.
|
|
71
|
+
Enumerating sibling directories or same-kind files is one wildcard call
|
|
72
|
+
(`glob`, or `read` with a glob for content sampling), never a
|
|
73
|
+
directory-by-directory `list` walk or one `read` per file.
|
|
74
|
+
- Blocking checks cover only essential integrity, security, compatibility,
|
|
75
|
+
and buildability invariants. Treat mutable behavior, UX, exact text,
|
|
76
|
+
snapshots, and implementation shape as advisory specifications; update them
|
|
77
|
+
when the requested behavior changes instead of preserving obsolete behavior.
|
|
49
78
|
- A successful verification closes the task unless later changes affect it.
|
|
50
79
|
Rerun a failed action only after its inputs or subject changes; otherwise
|
|
51
80
|
report it unresolved.
|
|
@@ -53,17 +82,19 @@
|
|
|
53
82
|
mutate only when the deliverable requires it, first preserving evidence
|
|
54
83
|
at risk. Never mutate merely to clear an obstacle or unexpected state;
|
|
55
84
|
unrecoverably lost evidence ends its search — report best effort.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Hand-authored text is edited only with
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
- Before the exposed file-editing tool, use only already obtained exact source
|
|
86
|
+
text. Never infer edit context from another file, a sample, or expected text.
|
|
87
|
+
For context patches, include exact unchanged lines around each change and use
|
|
88
|
+
a class/function locator when that context is not unique.
|
|
89
|
+
- Apply all determined changes in the fewest safe calls the active tool
|
|
90
|
+
supports. Hand-authored text is edited only with the exposed file-editing
|
|
91
|
+
tool.
|
|
92
|
+
- Avoid Shell for file operations covered by dedicated tools unless explicitly
|
|
93
|
+
instructed or after verifying that a dedicated tool cannot do the job.
|
|
94
|
+
Shell otherwise joins investigation only for facts requiring execution or
|
|
95
|
+
unsupported decoding; an already-open shell is never a routing reason.
|
|
96
|
+
- Shell commands start in the foreground. If still running after 15 seconds,
|
|
97
|
+
the command continues as a tracked `task_id`; completion arrives by notification.
|
|
67
98
|
Only when the request explicitly requires
|
|
68
99
|
a service to survive after the run exits, detach it at shell level (for
|
|
69
100
|
example, `nohup ... &`); never detach ordinary jobs merely to avoid tracking.
|
|
@@ -73,5 +104,6 @@
|
|
|
73
104
|
to return the current status and output snapshot. If it is still running,
|
|
74
105
|
await the completion notification; do not
|
|
75
106
|
call `task` again unless the user explicitly asks for another snapshot.
|
|
76
|
-
Omit
|
|
77
|
-
deadline
|
|
107
|
+
Omit `timeout_ms` by default, including for long jobs. A positive value is a
|
|
108
|
+
hard total deadline that kills the command even after task promotion; `0`
|
|
109
|
+
means no deadline.
|
|
@@ -173,6 +173,9 @@ function maintenanceRouteToPreset(routeOrName, agent) {
|
|
|
173
173
|
const effort = String(routeOrName.effort || '').trim();
|
|
174
174
|
if (effort) out.effort = effort;
|
|
175
175
|
if (routeOrName.fast === true) out.fast = true;
|
|
176
|
+
if (routeOrName.modelParameters && typeof routeOrName.modelParameters === 'object') {
|
|
177
|
+
out.modelParameters = { ...routeOrName.modelParameters };
|
|
178
|
+
}
|
|
176
179
|
return out;
|
|
177
180
|
}
|
|
178
181
|
|
|
@@ -49,8 +49,9 @@ function isAgentProgressWatchdogAbortError(err) {
|
|
|
49
49
|
return typeof msg === 'string' && WATCHDOG_ABORT_RE.test(msg);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
// Tools that enforce their own execution deadline:
|
|
53
|
-
//
|
|
52
|
+
// Tools that enforce their own execution deadline: shell kills the process
|
|
53
|
+
// only when the caller supplied a positive timeout_ms. These are NOT
|
|
54
|
+
// blanket-exempted from the
|
|
54
55
|
// tool-running watchdog — if their own
|
|
55
56
|
// deadline timer dies the session would otherwise hang forever. Instead the
|
|
56
57
|
// watchdog raises the tool-running ceiling to their self-deadline + a grace
|
|
@@ -60,10 +61,6 @@ const SELF_DEADLINE_TOOLS = new Set(['shell']);
|
|
|
60
61
|
// Grace added on top of a tool's own deadline before the watchdog steps in, so
|
|
61
62
|
// the tool's in-process kill always fires first under normal operation.
|
|
62
63
|
const TOOL_SELF_DEADLINE_GRACE_MS = 60_000;
|
|
63
|
-
// Fallback deadline matching the shell implementation's 120s foreground
|
|
64
|
-
// timeout.
|
|
65
|
-
const SHELL_DEFAULT_TIMEOUT_MS = 120_000;
|
|
66
|
-
|
|
67
64
|
function bareToolName(toolName) {
|
|
68
65
|
if (typeof toolName !== 'string' || !toolName) return '';
|
|
69
66
|
// Strip any MCP/server prefix (e.g. 'server__shell' or 'server.shell').
|
|
@@ -80,17 +77,16 @@ function isSelfDeadlineTool(toolName) {
|
|
|
80
77
|
* recorded into the progress snapshot at dispatch time. Returns a positive
|
|
81
78
|
* number when the tool enforces its own deadline, or null when unknown/missing
|
|
82
79
|
* (caller then falls back to the plain toolRunningMs ceiling).
|
|
83
|
-
* - shell: explicit `
|
|
80
|
+
* - shell: explicit positive `timeout_ms`; omitted/0 has no self-deadline.
|
|
84
81
|
*/
|
|
85
82
|
export function resolveToolSelfDeadlineMs(toolName, args) {
|
|
86
83
|
if (!isSelfDeadlineTool(toolName)) return null;
|
|
87
84
|
const bare = bareToolName(toolName);
|
|
88
85
|
const a = (args && typeof args === 'object') ? args : {};
|
|
89
86
|
if (bare === 'shell') {
|
|
90
|
-
const t = Number(a.
|
|
87
|
+
const t = Number(a.timeout_ms);
|
|
91
88
|
if (Number.isFinite(t) && t > 0) return t;
|
|
92
|
-
|
|
93
|
-
return envDefault > 0 ? envDefault : SHELL_DEFAULT_TIMEOUT_MS;
|
|
89
|
+
return null;
|
|
94
90
|
}
|
|
95
91
|
return null;
|
|
96
92
|
}
|
|
@@ -130,7 +130,7 @@ function traceAgentCompact({
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
const TOOL_ARG_KEYS = {
|
|
133
|
-
read: ['path', 'offset', 'limit', 'line', 'context'
|
|
133
|
+
read: ['path', 'offset', 'limit', 'line', 'context'],
|
|
134
134
|
grep: ['pattern', 'path', 'glob', 'output_mode', 'head_limit', 'offset'],
|
|
135
135
|
glob: ['pattern', 'path', 'head_limit', 'offset', 'sort'],
|
|
136
136
|
find: ['query', 'path', 'head_limit'],
|
|
@@ -140,7 +140,7 @@ const TOOL_ARG_KEYS = {
|
|
|
140
140
|
code_graph: ['mode', 'file', 'files', 'symbol', 'symbols', 'body', 'language', 'limit', 'depth', 'page', 'cwd'],
|
|
141
141
|
shell: ['command', 'timeout_ms'],
|
|
142
142
|
task: ['action', 'task_id'],
|
|
143
|
-
edit: ['
|
|
143
|
+
edit: ['file_path', 'replace_all'],
|
|
144
144
|
edit_many: ['edits'],
|
|
145
145
|
write: ['path'],
|
|
146
146
|
apply_patch: ['base_path', 'dry_run'],
|
|
@@ -305,11 +305,10 @@ function classifyPatchFailure(text) {
|
|
|
305
305
|
if (PATCH_COMMITTED_WRITES_RE.test(text)) return 'patch/partial-apply';
|
|
306
306
|
// Resource guards (byte cap) are deliberate rejections, not tool defects.
|
|
307
307
|
if (/patch too large|byte cap/.test(text)) return 'patch/limit';
|
|
308
|
-
if (/
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|| /contained no file sections|contains an empty file path/.test(text)) return 'patch/parse';
|
|
308
|
+
if (/(?:multiple|conflicting) operations target/.test(text)) return 'patch/duplicate-target';
|
|
309
|
+
// Inspect the nested cause before the outer `V4A parse failed` wrapper.
|
|
310
|
+
// Conversion-time context misses are edit-evidence failures, not malformed
|
|
311
|
+
// patch envelopes.
|
|
313
312
|
if (/hunk rejected|context not found|context mismatch|anchor not found|expected first old(?:\/context| line)/.test(text)) {
|
|
314
313
|
// Stale context requires REAL evidence that the region exists but has
|
|
315
314
|
// moved/changed (nearest line, divergent line, rejected hunk). The
|
|
@@ -319,10 +318,16 @@ function classifyPatchFailure(text) {
|
|
|
319
318
|
? 'patch/stale-context'
|
|
320
319
|
: 'patch/context';
|
|
321
320
|
}
|
|
321
|
+
if (/parse failed|invalid patch|malformed patch|missing \*\*\* (?:begin|end) patch|patch body is empty|unsupported patch format/.test(text)
|
|
322
|
+
// `patch contained no file sections` / `contains an empty file path`:
|
|
323
|
+
// the envelope parsed but produced nothing applicable — a patch-text
|
|
324
|
+
// defect, not a context miss.
|
|
325
|
+
|| /contained no file sections|contains an empty file path/.test(text)) return 'patch/parse';
|
|
326
|
+
if (/target\(s\) fall outside the write root/.test(text)) return 'path/outside-root';
|
|
322
327
|
// Missing/unreadable targets are path problems even when a preflight
|
|
323
328
|
// wrapper reports them; fall through to the generic path rules.
|
|
324
329
|
if (/enoent|no such file|target unreadable|source (?:missing or )?unreadable|destination unreadable|cannot find/.test(text)) return null;
|
|
325
|
-
if (/preflight rejected|does not support|cannot be combined|only one v4a rename|missing parsed entry|internal js dispatch|rollback snapshot target/.test(text)) return 'patch/verification';
|
|
330
|
+
if (/preflight rejected|does not support|cannot be combined|only one v4a rename|missing parsed entry|internal js dispatch|rollback snapshot target|refusing hunkless delete/.test(text)) return 'patch/verification';
|
|
326
331
|
return null;
|
|
327
332
|
}
|
|
328
333
|
|
|
@@ -368,6 +373,7 @@ function classifyToolFailure(resultText, toolName) {
|
|
|
368
373
|
|| /must be|schema|required|old_string is .*>?=/.test(text)) return 'schema/args';
|
|
369
374
|
if (/not in allow-list|not allowed/.test(text)) return 'permission';
|
|
370
375
|
if (String(toolName || '') === 'shell' || /^\s*\[exit code:\s*\d+\]/i.test(raw)) return 'command-exit';
|
|
376
|
+
if (String(toolName || '') === 'glob' && /enoent|path does not exist|directory does not exist/.test(text)) return 'navigation/miss';
|
|
371
377
|
if (/enoent|cannot find|not found at this path|path does not exist|no such file|file not found in graph|unreadable/.test(text)) return 'path/enoent';
|
|
372
378
|
if (/timed out|timeout|interrupted|aborted/.test(text)) return 'timeout/abort';
|
|
373
379
|
if (/unknown tool|tool.*not.*available|missing.*tool/.test(text)) return 'tool-surface';
|
|
@@ -414,7 +420,7 @@ function traceAgentToolFailure({ sessionId, iteration, toolName, toolKind, toolM
|
|
|
414
420
|
}
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
function traceAgentTool({ sessionId, iteration, toolName, toolKind, toolMs, toolArgs, agent, resultKind, model, resultText, localSearchTelemetry = null, cwd }) {
|
|
423
|
+
function traceAgentTool({ sessionId, iteration, toolName, toolKind, toolMs, toolArgs, agent, resultKind, model, resultText, localSearchTelemetry = null, resultTelemetry = null, cwd }) {
|
|
418
424
|
const nextCallCount = countJsonNextCalls(resultText);
|
|
419
425
|
const resultBytesEst = typeof resultText === 'string' ? Buffer.byteLength(resultText, 'utf8') : 0;
|
|
420
426
|
const resultLinesEst = typeof resultText === 'string' && resultText.length > 0 ? resultText.split('\n').length : 0;
|
|
@@ -465,6 +471,9 @@ function traceAgentTool({ sessionId, iteration, toolName, toolKind, toolMs, tool
|
|
|
465
471
|
local_search: localSearchTelemetry && Object.keys(localSearchTelemetry).length > 0
|
|
466
472
|
? { ...localSearchTelemetry }
|
|
467
473
|
: null,
|
|
474
|
+
payload: resultTelemetry?.integrity
|
|
475
|
+
? { integrity: { ...resultTelemetry.integrity } }
|
|
476
|
+
: {},
|
|
468
477
|
cwd: cwd || null,
|
|
469
478
|
});
|
|
470
479
|
if (
|
|
@@ -586,6 +595,60 @@ export function traceAgentShellOutput({
|
|
|
586
595
|
});
|
|
587
596
|
}
|
|
588
597
|
|
|
598
|
+
export function buildToolOutputTelemetryPayload({
|
|
599
|
+
toolCallId,
|
|
600
|
+
preOffloadBytes,
|
|
601
|
+
postOffloadBytes,
|
|
602
|
+
modelVisibleBytes,
|
|
603
|
+
offloaded,
|
|
604
|
+
resultKind,
|
|
605
|
+
}) {
|
|
606
|
+
const before = Number(preOffloadBytes);
|
|
607
|
+
const after = Number(postOffloadBytes);
|
|
608
|
+
if (!Number.isFinite(before) || before < 0 || !Number.isFinite(after) || after < 0) return null;
|
|
609
|
+
const visible = Math.max(0, Math.trunc(Number(modelVisibleBytes) || 0));
|
|
610
|
+
const saved = Math.max(0, Math.trunc(before) - visible);
|
|
611
|
+
return {
|
|
612
|
+
tool_call_id: toolCallId || null,
|
|
613
|
+
result_kind: resultKind || null,
|
|
614
|
+
pre_offload_bytes: Math.trunc(before),
|
|
615
|
+
post_offload_bytes: Math.trunc(after),
|
|
616
|
+
model_visible_bytes: visible,
|
|
617
|
+
saved_bytes: saved,
|
|
618
|
+
reduction_pct: before > 0
|
|
619
|
+
? Math.round((1 - visible / before) * 100)
|
|
620
|
+
: null,
|
|
621
|
+
offloaded: offloaded === true,
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export function traceAgentToolOutput({
|
|
626
|
+
sessionId,
|
|
627
|
+
toolName,
|
|
628
|
+
toolCallId,
|
|
629
|
+
preOffloadBytes,
|
|
630
|
+
postOffloadBytes,
|
|
631
|
+
modelVisibleBytes,
|
|
632
|
+
offloaded,
|
|
633
|
+
resultKind,
|
|
634
|
+
}) {
|
|
635
|
+
const payload = buildToolOutputTelemetryPayload({
|
|
636
|
+
toolCallId,
|
|
637
|
+
preOffloadBytes,
|
|
638
|
+
postOffloadBytes,
|
|
639
|
+
modelVisibleBytes,
|
|
640
|
+
offloaded,
|
|
641
|
+
resultKind,
|
|
642
|
+
});
|
|
643
|
+
if (!sessionId || !payload || payload.offloaded !== true) return;
|
|
644
|
+
appendAgentTrace({
|
|
645
|
+
sessionId,
|
|
646
|
+
kind: 'tool_output',
|
|
647
|
+
tool_name: toolName || null,
|
|
648
|
+
payload,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
|
|
589
652
|
// Per-turn batch shape — one row per assistant turn with the number of
|
|
590
653
|
// tool calls observed. Lets a consumer compute Lead-side multi-tool
|
|
591
654
|
// adoption ratio (calls > 1 / total turns) directly from trace rows
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
traceAgentToolFailure,
|
|
14
14
|
traceAgentCompress,
|
|
15
15
|
traceAgentShellOutput,
|
|
16
|
+
traceAgentToolOutput,
|
|
16
17
|
traceAgentBatch,
|
|
17
18
|
} from './agent-trace-format.mjs';
|
|
18
19
|
|
|
@@ -342,6 +343,7 @@ export {
|
|
|
342
343
|
grokCacheChainTraceFields,
|
|
343
344
|
traceAgentCompress,
|
|
344
345
|
traceAgentShellOutput,
|
|
346
|
+
traceAgentToolOutput,
|
|
345
347
|
traceAgentBatch,
|
|
346
348
|
traceStreamAborted,
|
|
347
349
|
traceStreamStalled,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
hasAnthropicOAuthCredentials,
|
|
10
10
|
hasOpenAIOAuthCredentials,
|
|
11
11
|
hasGrokOAuthCredentials,
|
|
12
|
+
hasCursorOAuthCredentials,
|
|
12
13
|
} from './providers/oauth-credential-probes.mjs';
|
|
13
14
|
|
|
14
15
|
// Thin wrapper around resolvePluginData so callers in this orchestrator tree
|
|
@@ -155,6 +156,9 @@ function buildDefaultConfig(options = {}) {
|
|
|
155
156
|
// stored in mixdog-config.json — enabled at runtime from the presence of
|
|
156
157
|
// Mixdog-owned credentials.
|
|
157
158
|
providers['grok-oauth'] = { enabled: detectCredentials ? hasGrokOAuthCredentials() : false };
|
|
159
|
+
// Experimental direct Cursor wire provider. It remains disabled unless a
|
|
160
|
+
// Mixdog-owned login or CURSOR_ACCESS_TOKEN is present.
|
|
161
|
+
providers['cursor-oauth'] = { enabled: detectCredentials ? hasCursorOAuthCredentials() : false };
|
|
158
162
|
// Local providers — opt-in via setup UI after HTTP ping confirms server is running
|
|
159
163
|
providers.ollama = { enabled: false, baseURL: 'http://localhost:11434/v1' };
|
|
160
164
|
providers.lmstudio = { enabled: false, baseURL: 'http://localhost:1234/v1' };
|
|
@@ -479,6 +483,9 @@ export function loadConfig(options = {}) {
|
|
|
479
483
|
if (kc) mergedProviders[name] = { ...(mergedProviders[name] || {}), apiKey: kc, enabled: true };
|
|
480
484
|
}
|
|
481
485
|
}
|
|
486
|
+
// Cursor account access is OAuth-only. The dashboard's "API"
|
|
487
|
+
// meter is a quota bucket on that account, not a separate provider.
|
|
488
|
+
delete mergedProviders['cursor-api'];
|
|
482
489
|
// Drop unknown maintenance keys (e.g. truly legacy slot names from
|
|
483
490
|
// pre-removal installs). Every valid fallback slot lives in
|
|
484
491
|
// DEFAULT_MAINTENANCE, so the allow-list below is the single
|
|
@@ -799,6 +806,8 @@ const FAST_CAPABLE_PRESET_PROVIDERS = new Set([
|
|
|
799
806
|
'anthropic-oauth',
|
|
800
807
|
'openai',
|
|
801
808
|
'openai-oauth',
|
|
809
|
+
'cursor-oauth',
|
|
810
|
+
'cursor-api',
|
|
802
811
|
]);
|
|
803
812
|
function normalizeAgentProviderId(provider) {
|
|
804
813
|
const id = String(provider || '').trim();
|