micro-models-agent 0.43.1 → 0.43.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/dist/main.js +366 -270
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2358,7 +2358,9 @@ var init_en = __esm(() => {
|
|
|
2358
2358
|
"file.is_directory": "Is a directory, use rmdir: {path}",
|
|
2359
2359
|
"file.replaced_in": "Replaced in {path}",
|
|
2360
2360
|
"file.string_not_found": `String not found in file:
|
|
2361
|
-
{str}
|
|
2361
|
+
{str}
|
|
2362
|
+
|
|
2363
|
+
Use read_file on {path} to see the current content before editing — the target may differ (whitespace, line endings) or was already replaced.`,
|
|
2362
2364
|
"file.moved": "Moved {from} → {to}",
|
|
2363
2365
|
"file.not_found_short": "Not found: {path}",
|
|
2364
2366
|
"file.notfound_resolved": "File not found: {path} (resolved to {resolved})",
|
|
@@ -2540,6 +2542,9 @@ Command: {command}`,
|
|
|
2540
2542
|
"plan.kinds_invalid": 'Invalid step kind(s): {kinds}. Use "create" or "delete".',
|
|
2541
2543
|
"plan.kinds_not_array": 'kinds must be an array of "create" or "delete"',
|
|
2542
2544
|
"plan.deliverables_remain": "Cannot mark step {step} done: the files it names still exist: {files}. This step is kind=delete — delete these files first (or set status=skipped if they should stay).",
|
|
2545
|
+
"plan.typecheck_failed": `Cannot mark step {step} done: the last check still reports a compile error:
|
|
2546
|
+
{error}
|
|
2547
|
+
Fix the error and re-edit the file (a clean write clears the failure), or mark the step status=skipped if it is not needed.`,
|
|
2543
2548
|
"plan.show_header": "Plan status:",
|
|
2544
2549
|
"plan.show_empty": "(plan has no steps)",
|
|
2545
2550
|
"plan.list_header": "Plans:",
|
|
@@ -2575,6 +2580,7 @@ Command: {command}`,
|
|
|
2575
2580
|
"verify.script_passed": "Script '{script}' passed",
|
|
2576
2581
|
"verify.script_failed": "Script '{script}' failed: {message}",
|
|
2577
2582
|
"verify.syntax_error": "Syntax error in: {path}",
|
|
2583
|
+
"verify.file_still_exists": "File should be deleted but still exists: {path}",
|
|
2578
2584
|
"verify.no_files": "Step {step} has no named files to verify — run a real check instead (bash: bun run build / bun test / lsp_check) and confirm the result.",
|
|
2579
2585
|
"lsp.unavailable": "static checks are unavailable (server not found). Verify via the project's own build/test instead.",
|
|
2580
2586
|
"lsp.check_disabled": "LSP checks are disabled in the config.",
|
|
@@ -3012,7 +3018,9 @@ var init_ru = __esm(() => {
|
|
|
3012
3018
|
"file.is_directory": "Это каталог, используйте rmdir: {path}",
|
|
3013
3019
|
"file.replaced_in": "Заменено в {path}",
|
|
3014
3020
|
"file.string_not_found": `Строка не найдена в файле:
|
|
3015
|
-
{str}
|
|
3021
|
+
{str}
|
|
3022
|
+
|
|
3023
|
+
Используй read_file для {path}, чтобы увидеть текущее содержимое файла перед редактированием — искомая строка может отличаться (пробелы, переводы строк) или уже была заменена.`,
|
|
3016
3024
|
"file.moved": "Перемещён {from} → {to}",
|
|
3017
3025
|
"file.not_found_short": "Не найдено: {path}",
|
|
3018
3026
|
"file.empty": "(пусто)",
|
|
@@ -3192,6 +3200,9 @@ var init_ru = __esm(() => {
|
|
|
3192
3200
|
"plan.kinds_invalid": 'Недопустимый kind шага: {kinds}. Используй "create" или "delete".',
|
|
3193
3201
|
"plan.kinds_not_array": 'kinds должен быть массивом значений "create" или "delete"',
|
|
3194
3202
|
"plan.deliverables_remain": "Нельзя пометить шаг {step} как выполненный: указанные файлы всё ещё существуют: {files}. Шаг имеет kind=delete — сначала удали их (или поставь status=skipped, если они должны остаться).",
|
|
3203
|
+
"plan.typecheck_failed": `Нельзя отметить шаг {step} выполненным: последняя проверка всё ещё сообщает об ошибке компиляции:
|
|
3204
|
+
{error}
|
|
3205
|
+
Исправь ошибку и снова отредактируй файл (чистая запись снимает блокировку), либо отметь шаг status=skipped, если он не нужен.`,
|
|
3195
3206
|
"plan.show_header": "Статус плана:",
|
|
3196
3207
|
"plan.show_empty": "(в плане нет шагов)",
|
|
3197
3208
|
"plan.list_header": "Планы:",
|
|
@@ -3227,6 +3238,7 @@ var init_ru = __esm(() => {
|
|
|
3227
3238
|
"verify.script_passed": "Скрипт '{script}' пройден",
|
|
3228
3239
|
"verify.script_failed": "Скрипт '{script}' не пройден: {message}",
|
|
3229
3240
|
"verify.syntax_error": "Синтаксическая ошибка в: {path}",
|
|
3241
|
+
"verify.file_still_exists": "Файл должен быть удалён, но всё ещё существует: {path}",
|
|
3230
3242
|
"verify.no_files": "Шаг {step} не содержит именованных файлов для проверки — выполни реальную проверку (bun run build / bun test / lsp_check) и подтверди результат.",
|
|
3231
3243
|
"lsp.unavailable": "статические проверки недоступны (сервер не найден). Проверяйте через собственный build/test проекта.",
|
|
3232
3244
|
"lsp.check_disabled": "LSP-проверки отключены в конфигурации.",
|
|
@@ -6764,7 +6776,7 @@ var init_edit_file = __esm(() => {
|
|
|
6764
6776
|
if (!content.includes(oldStr)) {
|
|
6765
6777
|
return {
|
|
6766
6778
|
success: false,
|
|
6767
|
-
output: t("file.string_not_found", { str: oldStr })
|
|
6779
|
+
output: t("file.string_not_found", { str: oldStr, path })
|
|
6768
6780
|
};
|
|
6769
6781
|
}
|
|
6770
6782
|
const updated = content.replace(oldStr, newStr);
|
|
@@ -9660,6 +9672,9 @@ class StuckDetector {
|
|
|
9660
9672
|
this.consecutiveFailures = 0;
|
|
9661
9673
|
this.lastFailedTool = "";
|
|
9662
9674
|
this.escalationCount = 0;
|
|
9675
|
+
if (this.iterationsOnCurrentStep > 0) {
|
|
9676
|
+
this.iterationsOnCurrentStep = Math.max(0, this.iterationsOnCurrentStep - 1);
|
|
9677
|
+
}
|
|
9663
9678
|
}
|
|
9664
9679
|
setCurrentStep(stepId, description) {
|
|
9665
9680
|
if (stepId !== this.currentStepId) {
|
|
@@ -11051,7 +11066,7 @@ class StepVerifier {
|
|
|
11051
11066
|
details
|
|
11052
11067
|
};
|
|
11053
11068
|
}
|
|
11054
|
-
async verifyStep(stepDescription) {
|
|
11069
|
+
async verifyStep(stepDescription, kind) {
|
|
11055
11070
|
const fileMatches = extractFileLikeTokens(stripUrls(stepDescription));
|
|
11056
11071
|
if (fileMatches.length === 0) {
|
|
11057
11072
|
return { passed: false, syntaxValid: true, failed: [], noFiles: true };
|
|
@@ -11060,7 +11075,15 @@ class StepVerifier {
|
|
|
11060
11075
|
let syntaxValid = true;
|
|
11061
11076
|
for (const filePath of fileMatches) {
|
|
11062
11077
|
const resolved = findExistingFile(this.baseDir, filePath);
|
|
11063
|
-
|
|
11078
|
+
const exists = !!resolved;
|
|
11079
|
+
if (kind === "delete") {
|
|
11080
|
+
results.push({
|
|
11081
|
+
passed: !exists,
|
|
11082
|
+
message: exists ? t("verify.file_still_exists", { path: filePath }) : t("verify.file_not_found", { path: filePath })
|
|
11083
|
+
});
|
|
11084
|
+
continue;
|
|
11085
|
+
}
|
|
11086
|
+
if (!exists) {
|
|
11064
11087
|
results.push({ passed: false, message: t("verify.file_not_found", { path: filePath }) });
|
|
11065
11088
|
continue;
|
|
11066
11089
|
}
|
|
@@ -17402,6 +17425,317 @@ var init_plan_coverage = __esm(() => {
|
|
|
17402
17425
|
]);
|
|
17403
17426
|
});
|
|
17404
17427
|
|
|
17428
|
+
// src/modules/execution/windows-commands.ts
|
|
17429
|
+
function firstWord(command) {
|
|
17430
|
+
const segs = command.trim().split(/[\s;|&]+/);
|
|
17431
|
+
return (segs[0] || "").replace(/[^\w-]/g, "").toLowerCase();
|
|
17432
|
+
}
|
|
17433
|
+
function forbiddenWindowsCommand(command) {
|
|
17434
|
+
const m = command.match(/^\s*cd\s+\S+\s*&&\s*(\S+)/);
|
|
17435
|
+
if (m)
|
|
17436
|
+
return forbiddenWindowsCommand(m[1]);
|
|
17437
|
+
const word = firstWord(command);
|
|
17438
|
+
if (word && FORBIDDEN_COMMANDS.has(word))
|
|
17439
|
+
return word;
|
|
17440
|
+
return null;
|
|
17441
|
+
}
|
|
17442
|
+
var FORBIDDEN_COMMANDS;
|
|
17443
|
+
var init_windows_commands = __esm(() => {
|
|
17444
|
+
FORBIDDEN_COMMANDS = new Set([
|
|
17445
|
+
"grep",
|
|
17446
|
+
"sed",
|
|
17447
|
+
"ls",
|
|
17448
|
+
"find",
|
|
17449
|
+
"rm",
|
|
17450
|
+
"touch",
|
|
17451
|
+
"which",
|
|
17452
|
+
"diff",
|
|
17453
|
+
"cp",
|
|
17454
|
+
"mv"
|
|
17455
|
+
]);
|
|
17456
|
+
});
|
|
17457
|
+
|
|
17458
|
+
// src/modules/execution/execution-plugin.ts
|
|
17459
|
+
import { platform as platform6 } from "os";
|
|
17460
|
+
function normalizeBrokenPath(p) {
|
|
17461
|
+
return p.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
17462
|
+
}
|
|
17463
|
+
function parseBrokenFile(line) {
|
|
17464
|
+
const trimmed = line.trim();
|
|
17465
|
+
const tsc = /^(.+?)\s*\(\d+,\d+\)\s*:\s*error TS\d+/.exec(trimmed);
|
|
17466
|
+
if (tsc)
|
|
17467
|
+
return normalizeBrokenPath(tsc[1]);
|
|
17468
|
+
const bn = /^(.+?):\d+:\d+\s*:\s*(?:error|SyntaxError)/.exec(trimmed);
|
|
17469
|
+
if (bn)
|
|
17470
|
+
return normalizeBrokenPath(bn[1]);
|
|
17471
|
+
return null;
|
|
17472
|
+
}
|
|
17473
|
+
function extractBrokenFiles(output) {
|
|
17474
|
+
const out = [];
|
|
17475
|
+
for (const line of output.split(`
|
|
17476
|
+
`)) {
|
|
17477
|
+
const marker = /\[(?:Project typecheck failed|Syntax check failed)\]:\s*(.+)$/.exec(line);
|
|
17478
|
+
if (!marker)
|
|
17479
|
+
continue;
|
|
17480
|
+
const errLine = marker[1].trim();
|
|
17481
|
+
out.push({ file: parseBrokenFile(errLine) ?? "", error: errLine.slice(0, 300) });
|
|
17482
|
+
}
|
|
17483
|
+
return out;
|
|
17484
|
+
}
|
|
17485
|
+
function stepTypecheckGate(failures, stepDescription) {
|
|
17486
|
+
if (failures.size === 0)
|
|
17487
|
+
return null;
|
|
17488
|
+
const projectError = failures.get("");
|
|
17489
|
+
if (projectError)
|
|
17490
|
+
return projectError;
|
|
17491
|
+
const stepTokens = extractFileLikeTokens(stripUrls(stepDescription)).map((p) => normalizeBrokenPath(p).toLowerCase());
|
|
17492
|
+
if (stepTokens.length === 0)
|
|
17493
|
+
return null;
|
|
17494
|
+
for (const [file, err] of failures) {
|
|
17495
|
+
const f = normalizeBrokenPath(file).toLowerCase();
|
|
17496
|
+
if (stepTokens.some((tok) => f.endsWith(tok) || tok.endsWith(f)))
|
|
17497
|
+
return err;
|
|
17498
|
+
}
|
|
17499
|
+
return null;
|
|
17500
|
+
}
|
|
17501
|
+
function createExecutionPlugin(deps) {
|
|
17502
|
+
return {
|
|
17503
|
+
name: "execution",
|
|
17504
|
+
onBeforeThink: (ctx) => {
|
|
17505
|
+
if (ctx.contextManager && deps.pendingMessages.length > 0) {
|
|
17506
|
+
for (const m of deps.pendingMessages.splice(0)) {
|
|
17507
|
+
ctx.contextManager.addMessage(m);
|
|
17508
|
+
}
|
|
17509
|
+
}
|
|
17510
|
+
if (deps.trackerRef.current?.isComplete()) {
|
|
17511
|
+
deps.stuckDetector.resetStepProgress();
|
|
17512
|
+
deps.state.consecutivePlanWarnings = 0;
|
|
17513
|
+
deps.state.lastStepId = -1;
|
|
17514
|
+
deps.state.stuckNotified = false;
|
|
17515
|
+
deps.state.mutationsWithoutPlan = 0;
|
|
17516
|
+
deps.state.planNudgeSent = false;
|
|
17517
|
+
} else {
|
|
17518
|
+
const step = deps.trackerRef.current?.getCurrentStep();
|
|
17519
|
+
if (deps.trackerRef.current && step) {
|
|
17520
|
+
if (step.id !== deps.state.lastStepId) {
|
|
17521
|
+
deps.state.consecutivePlanWarnings = 0;
|
|
17522
|
+
deps.state.lastStepId = step.id;
|
|
17523
|
+
deps.state.stuckNotified = false;
|
|
17524
|
+
}
|
|
17525
|
+
deps.stuckDetector.setCurrentStep(step.id, step.description);
|
|
17526
|
+
deps.stuckDetector.recordIteration(step.id);
|
|
17527
|
+
deps.state.mutationsWithoutPlan = 0;
|
|
17528
|
+
deps.state.planNudgeSent = false;
|
|
17529
|
+
} else {
|
|
17530
|
+
deps.stuckDetector.reset();
|
|
17531
|
+
deps.state.consecutivePlanWarnings = 0;
|
|
17532
|
+
deps.state.lastStepId = -1;
|
|
17533
|
+
deps.state.stuckNotified = false;
|
|
17534
|
+
const mutations = deps.state.mutationsWithoutPlan;
|
|
17535
|
+
if (mutations >= PLAN_NUDGE_THRESHOLD && !deps.state.planNudgeSent && ctx.contextManager) {
|
|
17536
|
+
deps.state.planNudgeSent = true;
|
|
17537
|
+
ctx.contextManager.addMessage({
|
|
17538
|
+
role: "user",
|
|
17539
|
+
content: `<system-summary>${t("exec.plan_nudge", {
|
|
17540
|
+
count: String(mutations)
|
|
17541
|
+
})}</system-summary>`
|
|
17542
|
+
});
|
|
17543
|
+
}
|
|
17544
|
+
}
|
|
17545
|
+
}
|
|
17546
|
+
const stuckReason = deps.stuckDetector.getStuckReason();
|
|
17547
|
+
if (stuckReason) {
|
|
17548
|
+
const logIt = deps.stuckDetector.isStuck() ? !deps.state.stuckNotified : true;
|
|
17549
|
+
if (logIt) {
|
|
17550
|
+
ctx.logger?.warn(stuckReason);
|
|
17551
|
+
ctx.sessionLog?.plan("stuck-warning", stuckReason, typeof ctx.iteration === "number" ? ctx.iteration : undefined);
|
|
17552
|
+
if (deps.stuckDetector.isStuck())
|
|
17553
|
+
deps.state.stuckNotified = true;
|
|
17554
|
+
}
|
|
17555
|
+
}
|
|
17556
|
+
if (deps.stuckDetector.isStuck() || deps.stuckDetector.hasRepetitiveToolCalls() || deps.stuckDetector.hasReadOnlyLoop()) {
|
|
17557
|
+
const currentIter = typeof ctx.iteration === "number" ? ctx.iteration : 0;
|
|
17558
|
+
if (currentIter - deps.state.lastRecoveryIteration >= STUCK_RECOVERY_COOLDOWN) {
|
|
17559
|
+
const recovery = deps.stuckDetector.getRecoveryMessage();
|
|
17560
|
+
if (recovery && ctx.contextManager) {
|
|
17561
|
+
let tscContext = "";
|
|
17562
|
+
if (deps.state.typecheckFailures.size > 0) {
|
|
17563
|
+
const currentStep = deps.trackerRef.current?.getCurrentStep();
|
|
17564
|
+
if (currentStep) {
|
|
17565
|
+
const stepFiles = extractFileLikeTokens(stripUrls(currentStep.description));
|
|
17566
|
+
for (const [file, error] of deps.state.typecheckFailures) {
|
|
17567
|
+
if (!file || stepFiles.some((f) => file.endsWith(f) || f.endsWith(file))) {
|
|
17568
|
+
tscContext = `
|
|
17569
|
+
Last compile error: ${error}`;
|
|
17570
|
+
break;
|
|
17571
|
+
}
|
|
17572
|
+
}
|
|
17573
|
+
if (!tscContext) {
|
|
17574
|
+
const first = deps.state.typecheckFailures.entries().next().value;
|
|
17575
|
+
if (first)
|
|
17576
|
+
tscContext = `
|
|
17577
|
+
Last compile error: ${first[1]}`;
|
|
17578
|
+
}
|
|
17579
|
+
}
|
|
17580
|
+
}
|
|
17581
|
+
ctx.contextManager.addMessage({
|
|
17582
|
+
role: "user",
|
|
17583
|
+
content: `<system-summary>${recovery}${tscContext}</system-summary>`
|
|
17584
|
+
});
|
|
17585
|
+
}
|
|
17586
|
+
deps.stuckDetector.recordEscalation();
|
|
17587
|
+
deps.state.lastRecoveryIteration = currentIter;
|
|
17588
|
+
if (deps.stuckDetector.shouldEscalate() && ctx.onMeta) {
|
|
17589
|
+
const escalation = t("exec.escalation", {
|
|
17590
|
+
stepId: String(deps.trackerRef.current?.getCurrentStep()?.id ?? "?"),
|
|
17591
|
+
description: deps.trackerRef.current?.getCurrentStep()?.description ?? ""
|
|
17592
|
+
});
|
|
17593
|
+
ctx.onMeta(escalation);
|
|
17594
|
+
}
|
|
17595
|
+
if (deps.stuckDetector.getIterationsOnCurrentStep() >= FORCE_SKIP_THRESHOLD && ctx.contextManager) {
|
|
17596
|
+
const step = deps.trackerRef.current?.getCurrentStep();
|
|
17597
|
+
ctx.contextManager.addMessage({
|
|
17598
|
+
role: "user",
|
|
17599
|
+
content: `<system-summary>STOP. Step ${step?.id ?? "?"} ("${step?.description ?? ""}") took ${deps.stuckDetector.getIterationsOnCurrentStep()} iterations with no progress. DO NOT continue this step. Immediately call: plan update step=${step?.id ?? "?"} status=done (if code works despite warnings) OR plan update step=${step?.id ?? "?"} status=skipped note="reason". Do NOT make any other tool calls before updating the plan.</system-summary>`
|
|
17600
|
+
});
|
|
17601
|
+
}
|
|
17602
|
+
}
|
|
17603
|
+
}
|
|
17604
|
+
},
|
|
17605
|
+
onBeforeTool: (_ctx, call) => {
|
|
17606
|
+
const warning = deps.checkPlanAlignment(call);
|
|
17607
|
+
if (warning) {
|
|
17608
|
+
deps.pendingMessages.push({
|
|
17609
|
+
role: "user",
|
|
17610
|
+
content: `<system-summary>${warning}</system-summary>`
|
|
17611
|
+
});
|
|
17612
|
+
deps.state.consecutivePlanWarnings++;
|
|
17613
|
+
if (deps.state.consecutivePlanWarnings >= MAX_PLAN_WARNINGS_BEFORE_BLOCK) {
|
|
17614
|
+
deps.pendingMessages.push({
|
|
17615
|
+
role: "user",
|
|
17616
|
+
content: `<system-summary>${t("exec.plan_blocked", { step: String(deps.trackerRef.current?.getCurrentStep()?.id ?? "?"), max: MAX_PLAN_WARNINGS_BEFORE_BLOCK })}</system-summary>`
|
|
17617
|
+
});
|
|
17618
|
+
return t("exec.plan_blocked", {
|
|
17619
|
+
step: String(deps.trackerRef.current?.getCurrentStep()?.id ?? "?"),
|
|
17620
|
+
max: MAX_PLAN_WARNINGS_BEFORE_BLOCK
|
|
17621
|
+
});
|
|
17622
|
+
}
|
|
17623
|
+
} else {
|
|
17624
|
+
deps.state.consecutivePlanWarnings = 0;
|
|
17625
|
+
}
|
|
17626
|
+
return true;
|
|
17627
|
+
},
|
|
17628
|
+
onToolCall: (ctx) => {
|
|
17629
|
+
const toolName = ctx?.toolName;
|
|
17630
|
+
const args = ctx?.args;
|
|
17631
|
+
if (toolName && args) {
|
|
17632
|
+
deps.stuckDetector.recordToolCall(toolName, args);
|
|
17633
|
+
if (!deps.trackerRef.current && (toolName === "write_file" || toolName === "edit_file" || toolName === "bash" || toolName === "download_file")) {
|
|
17634
|
+
deps.state.mutationsWithoutPlan++;
|
|
17635
|
+
}
|
|
17636
|
+
}
|
|
17637
|
+
},
|
|
17638
|
+
onAfterTool: (ctx, call, result) => {
|
|
17639
|
+
if (call.name === "bash") {
|
|
17640
|
+
deps.stuckDetector.recordBashOutput(String(call.arguments?.command ?? ""), String(result.output ?? ""));
|
|
17641
|
+
}
|
|
17642
|
+
if (call.name === "delete_file" && result.success && deps.trackerRef.current) {
|
|
17643
|
+
const deletedPath = String(call.arguments?.path ?? "");
|
|
17644
|
+
if (deletedPath) {
|
|
17645
|
+
const plan = deps.trackerRef.current.getPlan();
|
|
17646
|
+
const tokens = extractFileLikeTokens(stripUrls(deletedPath));
|
|
17647
|
+
for (const step of plan.steps) {
|
|
17648
|
+
if (step.status !== "pending" && step.status !== "in_progress")
|
|
17649
|
+
continue;
|
|
17650
|
+
const stepTokens = extractFileLikeTokens(stripUrls(step.description));
|
|
17651
|
+
const overlap = tokens.some((t2) => stepTokens.some((st) => t2.endsWith(st) || st.endsWith(t2)));
|
|
17652
|
+
if (overlap && step.kind !== "delete") {
|
|
17653
|
+
step.kind = "delete";
|
|
17654
|
+
deps.store.saveActive(plan);
|
|
17655
|
+
break;
|
|
17656
|
+
}
|
|
17657
|
+
}
|
|
17658
|
+
}
|
|
17659
|
+
}
|
|
17660
|
+
const toolText = String(result.output ?? "");
|
|
17661
|
+
const hasTypeError = /error TS\d+|\[Project typecheck failed\]|\[Syntax check failed\]/.test(toolText);
|
|
17662
|
+
if (hasTypeError) {
|
|
17663
|
+
deps.stuckDetector.recordToolError(call.name, toolText.slice(0, 300));
|
|
17664
|
+
}
|
|
17665
|
+
if (call.name === "write_file" || call.name === "edit_file") {
|
|
17666
|
+
const broken = extractBrokenFiles(toolText);
|
|
17667
|
+
if (broken.length > 0) {
|
|
17668
|
+
for (const b of broken)
|
|
17669
|
+
deps.state.typecheckFailures.set(b.file, b.error);
|
|
17670
|
+
} else if (result.success) {
|
|
17671
|
+
deps.state.typecheckFailures.clear();
|
|
17672
|
+
}
|
|
17673
|
+
}
|
|
17674
|
+
if (!result.success) {
|
|
17675
|
+
if (call.name === "bash" && platform6() === "win32") {
|
|
17676
|
+
const cmd = String(call.arguments?.command ?? "");
|
|
17677
|
+
const forbidden = forbiddenWindowsCommand(cmd);
|
|
17678
|
+
if (forbidden) {
|
|
17679
|
+
const n = (deps.forbiddenBashFailures.get(forbidden) || 0) + 1;
|
|
17680
|
+
deps.forbiddenBashFailures.set(forbidden, n);
|
|
17681
|
+
if (n === 2) {
|
|
17682
|
+
deps.pendingMessages.push({
|
|
17683
|
+
role: "user",
|
|
17684
|
+
content: `<system-summary>${t("exec.forbidden_cmd", { cmd: forbidden })}</system-summary>`
|
|
17685
|
+
});
|
|
17686
|
+
}
|
|
17687
|
+
}
|
|
17688
|
+
}
|
|
17689
|
+
if (!hasTypeError) {
|
|
17690
|
+
deps.stuckDetector.recordToolError(call.name, result.output);
|
|
17691
|
+
}
|
|
17692
|
+
} else {
|
|
17693
|
+
deps.stuckDetector.recordToolSuccess();
|
|
17694
|
+
if (call.name === "bash" && result.success) {
|
|
17695
|
+
const cmd = String(call.arguments?.command ?? "");
|
|
17696
|
+
const testRun = detectTestResults(String(result.output ?? ""));
|
|
17697
|
+
if (testRun && testRun.failed > 0) {
|
|
17698
|
+
deps.pendingMessages.push({
|
|
17699
|
+
role: "user",
|
|
17700
|
+
content: `<system-summary>${testRun.framework} reported ${testRun.failed} FAILING test(s) (${testRun.passed} passing). Do NOT mark the current step as done — fix the failing tests (read the failure output, correct the code) and re-run them until all pass.</system-summary>`
|
|
17701
|
+
});
|
|
17702
|
+
} else if (testRun && testRun.failed === 0 && testRun.passed > 0) {
|
|
17703
|
+
deps.pendingMessages.push({
|
|
17704
|
+
role: "user",
|
|
17705
|
+
content: `<system-summary>${testRun.framework}: all ${testRun.passed} test(s) passed for "${cmd}". You may mark the current step as done via plan update step=N status=done.</system-summary>`
|
|
17706
|
+
});
|
|
17707
|
+
}
|
|
17708
|
+
}
|
|
17709
|
+
}
|
|
17710
|
+
if (result.success && (call.name === "write_file" || call.name === "edit_file")) {
|
|
17711
|
+
const filePath = call.arguments?.path;
|
|
17712
|
+
if (filePath) {
|
|
17713
|
+
deps.stuckDetector.recordFileRewrite(filePath);
|
|
17714
|
+
if (deps.stuckDetector.hasExcessiveRewrites()) {
|
|
17715
|
+
const file = deps.stuckDetector.getExcessiveRewriteFile();
|
|
17716
|
+
const count = deps.stuckDetector.getFileRewriteCount(file);
|
|
17717
|
+
if (ctx.onMeta) {
|
|
17718
|
+
ctx.onMeta(t("exec.file_rewrite_warning", {
|
|
17719
|
+
file,
|
|
17720
|
+
count: String(count)
|
|
17721
|
+
}));
|
|
17722
|
+
}
|
|
17723
|
+
}
|
|
17724
|
+
}
|
|
17725
|
+
deps.advancePlanIfStepComplete(ctx.contextManager, ctx.sessionLog);
|
|
17726
|
+
}
|
|
17727
|
+
deps.maybeSearchError(ctx, call);
|
|
17728
|
+
}
|
|
17729
|
+
};
|
|
17730
|
+
}
|
|
17731
|
+
var STUCK_RECOVERY_COOLDOWN = 5, MAX_PLAN_WARNINGS_BEFORE_BLOCK = 3, FORCE_SKIP_THRESHOLD = 10, PLAN_NUDGE_THRESHOLD = 2;
|
|
17732
|
+
var init_execution_plugin = __esm(() => {
|
|
17733
|
+
init_i18n();
|
|
17734
|
+
init_bash();
|
|
17735
|
+
init_windows_commands();
|
|
17736
|
+
init_js_identifiers();
|
|
17737
|
+
});
|
|
17738
|
+
|
|
17405
17739
|
// src/modules/execution/plan-tool.ts
|
|
17406
17740
|
function createPlanToolDefinitions(deps) {
|
|
17407
17741
|
return [
|
|
@@ -17708,6 +18042,18 @@ ${progress2}`,
|
|
|
17708
18042
|
}
|
|
17709
18043
|
}
|
|
17710
18044
|
}
|
|
18045
|
+
if (status === "done") {
|
|
18046
|
+
const blocked = stepTypecheckGate(deps.typecheckFailures, target.description);
|
|
18047
|
+
if (blocked) {
|
|
18048
|
+
return {
|
|
18049
|
+
success: false,
|
|
18050
|
+
output: t("plan.typecheck_failed", {
|
|
18051
|
+
step: String(stepId),
|
|
18052
|
+
error: blocked
|
|
18053
|
+
})
|
|
18054
|
+
};
|
|
18055
|
+
}
|
|
18056
|
+
}
|
|
17711
18057
|
tracker.updateStepStatus(stepId, status);
|
|
17712
18058
|
if (args.note)
|
|
17713
18059
|
tracker.addNote(Number(args.step), String(args.note));
|
|
@@ -17951,7 +18297,7 @@ ${lines.join(`
|
|
|
17951
18297
|
const step = args.step ? tracker.getStep(Number(args.step)) : tracker.getCurrentStep();
|
|
17952
18298
|
if (!step)
|
|
17953
18299
|
return { success: false, output: t("plan.step_not_found") };
|
|
17954
|
-
const result = await deps.verifier.verifyStep(step.description);
|
|
18300
|
+
const result = await deps.verifier.verifyStep(step.description, step.kind);
|
|
17955
18301
|
if (result.noFiles) {
|
|
17956
18302
|
return {
|
|
17957
18303
|
success: true,
|
|
@@ -17971,267 +18317,7 @@ ${lines.join(`
|
|
|
17971
18317
|
var init_plan_tool = __esm(() => {
|
|
17972
18318
|
init_i18n();
|
|
17973
18319
|
init_plan_coverage();
|
|
17974
|
-
|
|
17975
|
-
|
|
17976
|
-
// src/modules/execution/windows-commands.ts
|
|
17977
|
-
function firstWord(command) {
|
|
17978
|
-
const segs = command.trim().split(/[\s;|&]+/);
|
|
17979
|
-
return (segs[0] || "").replace(/[^\w-]/g, "").toLowerCase();
|
|
17980
|
-
}
|
|
17981
|
-
function forbiddenWindowsCommand(command) {
|
|
17982
|
-
const m = command.match(/^\s*cd\s+\S+\s*&&\s*(\S+)/);
|
|
17983
|
-
if (m)
|
|
17984
|
-
return forbiddenWindowsCommand(m[1]);
|
|
17985
|
-
const word = firstWord(command);
|
|
17986
|
-
if (word && FORBIDDEN_COMMANDS.has(word))
|
|
17987
|
-
return word;
|
|
17988
|
-
return null;
|
|
17989
|
-
}
|
|
17990
|
-
var FORBIDDEN_COMMANDS;
|
|
17991
|
-
var init_windows_commands = __esm(() => {
|
|
17992
|
-
FORBIDDEN_COMMANDS = new Set([
|
|
17993
|
-
"grep",
|
|
17994
|
-
"sed",
|
|
17995
|
-
"ls",
|
|
17996
|
-
"find",
|
|
17997
|
-
"rm",
|
|
17998
|
-
"touch",
|
|
17999
|
-
"which",
|
|
18000
|
-
"diff",
|
|
18001
|
-
"cp",
|
|
18002
|
-
"mv"
|
|
18003
|
-
]);
|
|
18004
|
-
});
|
|
18005
|
-
|
|
18006
|
-
// src/modules/execution/execution-plugin.ts
|
|
18007
|
-
import { platform as platform6 } from "os";
|
|
18008
|
-
function createExecutionPlugin(deps) {
|
|
18009
|
-
return {
|
|
18010
|
-
name: "execution",
|
|
18011
|
-
onBeforeThink: (ctx) => {
|
|
18012
|
-
if (ctx.contextManager && deps.pendingMessages.length > 0) {
|
|
18013
|
-
for (const m of deps.pendingMessages.splice(0)) {
|
|
18014
|
-
ctx.contextManager.addMessage(m);
|
|
18015
|
-
}
|
|
18016
|
-
}
|
|
18017
|
-
if (deps.trackerRef.current?.isComplete()) {
|
|
18018
|
-
deps.stuckDetector.resetStepProgress();
|
|
18019
|
-
deps.state.consecutivePlanWarnings = 0;
|
|
18020
|
-
deps.state.lastStepId = -1;
|
|
18021
|
-
deps.state.stuckNotified = false;
|
|
18022
|
-
deps.state.mutationsWithoutPlan = 0;
|
|
18023
|
-
deps.state.planNudgeSent = false;
|
|
18024
|
-
} else {
|
|
18025
|
-
const step = deps.trackerRef.current?.getCurrentStep();
|
|
18026
|
-
if (deps.trackerRef.current && step) {
|
|
18027
|
-
if (step.id !== deps.state.lastStepId) {
|
|
18028
|
-
deps.state.consecutivePlanWarnings = 0;
|
|
18029
|
-
deps.state.lastStepId = step.id;
|
|
18030
|
-
deps.state.stuckNotified = false;
|
|
18031
|
-
}
|
|
18032
|
-
deps.stuckDetector.setCurrentStep(step.id, step.description);
|
|
18033
|
-
deps.stuckDetector.recordIteration(step.id);
|
|
18034
|
-
deps.state.mutationsWithoutPlan = 0;
|
|
18035
|
-
deps.state.planNudgeSent = false;
|
|
18036
|
-
} else {
|
|
18037
|
-
deps.stuckDetector.reset();
|
|
18038
|
-
deps.state.consecutivePlanWarnings = 0;
|
|
18039
|
-
deps.state.lastStepId = -1;
|
|
18040
|
-
deps.state.stuckNotified = false;
|
|
18041
|
-
const mutations = deps.state.mutationsWithoutPlan;
|
|
18042
|
-
if (mutations >= PLAN_NUDGE_THRESHOLD && !deps.state.planNudgeSent && ctx.contextManager) {
|
|
18043
|
-
deps.state.planNudgeSent = true;
|
|
18044
|
-
ctx.contextManager.addMessage({
|
|
18045
|
-
role: "user",
|
|
18046
|
-
content: `<system-summary>${t("exec.plan_nudge", {
|
|
18047
|
-
count: String(mutations)
|
|
18048
|
-
})}</system-summary>`
|
|
18049
|
-
});
|
|
18050
|
-
}
|
|
18051
|
-
}
|
|
18052
|
-
}
|
|
18053
|
-
const stuckReason = deps.stuckDetector.getStuckReason();
|
|
18054
|
-
if (stuckReason) {
|
|
18055
|
-
const logIt = deps.stuckDetector.isStuck() ? !deps.state.stuckNotified : true;
|
|
18056
|
-
if (logIt) {
|
|
18057
|
-
ctx.logger?.warn(stuckReason);
|
|
18058
|
-
ctx.sessionLog?.plan("stuck-warning", stuckReason, typeof ctx.iteration === "number" ? ctx.iteration : undefined);
|
|
18059
|
-
if (deps.stuckDetector.isStuck())
|
|
18060
|
-
deps.state.stuckNotified = true;
|
|
18061
|
-
}
|
|
18062
|
-
}
|
|
18063
|
-
if (deps.stuckDetector.isStuck() || deps.stuckDetector.hasRepetitiveToolCalls() || deps.stuckDetector.hasReadOnlyLoop()) {
|
|
18064
|
-
const currentIter = typeof ctx.iteration === "number" ? ctx.iteration : 0;
|
|
18065
|
-
if (currentIter - deps.state.lastRecoveryIteration >= STUCK_RECOVERY_COOLDOWN) {
|
|
18066
|
-
const recovery = deps.stuckDetector.getRecoveryMessage();
|
|
18067
|
-
if (recovery && ctx.contextManager) {
|
|
18068
|
-
const lastError = deps.stuckDetector.getLastErrorOutput();
|
|
18069
|
-
const skillHint = lastError ? `
|
|
18070
|
-
If you have relevant skills available, consider loading one with load_skill for expert guidance.` : "";
|
|
18071
|
-
const actionableHints = deps.stuckDetector.getActionableHints();
|
|
18072
|
-
const actionableHintStr = actionableHints.length > 0 ? `
|
|
18073
|
-
${t("exec.hints", { hints: actionableHints.map((h) => `- ${h}`).join(`
|
|
18074
|
-
`) })}` : "";
|
|
18075
|
-
const alternative = deps.stuckDetector.getToolAlternative();
|
|
18076
|
-
const altHint = alternative ? `
|
|
18077
|
-
Tool "${deps.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}" instead.` : "";
|
|
18078
|
-
ctx.contextManager.addMessage({
|
|
18079
|
-
role: "user",
|
|
18080
|
-
content: `<system-summary>${recovery}${skillHint}${actionableHintStr}${altHint}</system-summary>`
|
|
18081
|
-
});
|
|
18082
|
-
}
|
|
18083
|
-
const hints = deps.stuckDetector.getHints();
|
|
18084
|
-
if (hints.length > 0 && ctx.contextManager) {
|
|
18085
|
-
const hintMsg = t("exec.hints", {
|
|
18086
|
-
hints: hints.map((h) => `- ${h}`).join(`
|
|
18087
|
-
`)
|
|
18088
|
-
});
|
|
18089
|
-
ctx.contextManager.addMessage({
|
|
18090
|
-
role: "user",
|
|
18091
|
-
content: `<system-summary>${hintMsg}</system-summary>`
|
|
18092
|
-
});
|
|
18093
|
-
}
|
|
18094
|
-
deps.stuckDetector.recordEscalation();
|
|
18095
|
-
deps.state.lastRecoveryIteration = currentIter;
|
|
18096
|
-
if (deps.stuckDetector.shouldEscalate() && ctx.onMeta) {
|
|
18097
|
-
const escalation = t("exec.escalation", {
|
|
18098
|
-
stepId: String(deps.trackerRef.current?.getCurrentStep()?.id ?? "?"),
|
|
18099
|
-
description: deps.trackerRef.current?.getCurrentStep()?.description ?? ""
|
|
18100
|
-
});
|
|
18101
|
-
ctx.onMeta(escalation);
|
|
18102
|
-
}
|
|
18103
|
-
if (deps.stuckDetector.getIterationsOnCurrentStep() >= FORCE_SKIP_THRESHOLD && ctx.contextManager) {
|
|
18104
|
-
const step = deps.trackerRef.current?.getCurrentStep();
|
|
18105
|
-
ctx.contextManager.addMessage({
|
|
18106
|
-
role: "user",
|
|
18107
|
-
content: `<system-summary>STOP. Step ${step?.id ?? "?"} ("${step?.description ?? ""}") took ${deps.stuckDetector.getIterationsOnCurrentStep()} iterations with no progress. DO NOT continue this step. Immediately call: plan update step=${step?.id ?? "?"} status=done (if code works despite warnings) OR plan update step=${step?.id ?? "?"} status=skipped note="reason". Do NOT make any other tool calls before updating the plan.</system-summary>`
|
|
18108
|
-
});
|
|
18109
|
-
}
|
|
18110
|
-
}
|
|
18111
|
-
}
|
|
18112
|
-
},
|
|
18113
|
-
onBeforeTool: (_ctx, call) => {
|
|
18114
|
-
const warning = deps.checkPlanAlignment(call);
|
|
18115
|
-
if (warning) {
|
|
18116
|
-
deps.pendingMessages.push({
|
|
18117
|
-
role: "user",
|
|
18118
|
-
content: `<system-summary>${warning}</system-summary>`
|
|
18119
|
-
});
|
|
18120
|
-
deps.state.consecutivePlanWarnings++;
|
|
18121
|
-
if (deps.state.consecutivePlanWarnings >= MAX_PLAN_WARNINGS_BEFORE_BLOCK) {
|
|
18122
|
-
deps.pendingMessages.push({
|
|
18123
|
-
role: "user",
|
|
18124
|
-
content: `<system-summary>${t("exec.plan_blocked", { step: String(deps.trackerRef.current?.getCurrentStep()?.id ?? "?"), max: MAX_PLAN_WARNINGS_BEFORE_BLOCK })}</system-summary>`
|
|
18125
|
-
});
|
|
18126
|
-
return t("exec.plan_blocked", {
|
|
18127
|
-
step: String(deps.trackerRef.current?.getCurrentStep()?.id ?? "?"),
|
|
18128
|
-
max: MAX_PLAN_WARNINGS_BEFORE_BLOCK
|
|
18129
|
-
});
|
|
18130
|
-
}
|
|
18131
|
-
} else {
|
|
18132
|
-
deps.state.consecutivePlanWarnings = 0;
|
|
18133
|
-
}
|
|
18134
|
-
return true;
|
|
18135
|
-
},
|
|
18136
|
-
onToolCall: (ctx) => {
|
|
18137
|
-
const toolName = ctx?.toolName;
|
|
18138
|
-
const args = ctx?.args;
|
|
18139
|
-
if (toolName && args) {
|
|
18140
|
-
deps.stuckDetector.recordToolCall(toolName, args);
|
|
18141
|
-
if (!deps.trackerRef.current && (toolName === "write_file" || toolName === "edit_file" || toolName === "bash" || toolName === "download_file")) {
|
|
18142
|
-
deps.state.mutationsWithoutPlan++;
|
|
18143
|
-
}
|
|
18144
|
-
}
|
|
18145
|
-
},
|
|
18146
|
-
onAfterTool: (ctx, call, result) => {
|
|
18147
|
-
if (call.name === "bash") {
|
|
18148
|
-
deps.stuckDetector.recordBashOutput(String(call.arguments?.command ?? ""), String(result.output ?? ""));
|
|
18149
|
-
}
|
|
18150
|
-
const toolText = String(result.output ?? "");
|
|
18151
|
-
const hasTypeError = /error TS\d+|\[Project typecheck failed\]|\[Syntax check failed\]/.test(toolText);
|
|
18152
|
-
if (hasTypeError) {
|
|
18153
|
-
deps.stuckDetector.recordToolError(call.name, toolText.slice(0, 300));
|
|
18154
|
-
}
|
|
18155
|
-
if (!result.success) {
|
|
18156
|
-
if (call.name === "bash" && platform6() === "win32") {
|
|
18157
|
-
const cmd = String(call.arguments?.command ?? "");
|
|
18158
|
-
const forbidden = forbiddenWindowsCommand(cmd);
|
|
18159
|
-
if (forbidden) {
|
|
18160
|
-
const n = (deps.forbiddenBashFailures.get(forbidden) || 0) + 1;
|
|
18161
|
-
deps.forbiddenBashFailures.set(forbidden, n);
|
|
18162
|
-
if (n === 2) {
|
|
18163
|
-
deps.pendingMessages.push({
|
|
18164
|
-
role: "user",
|
|
18165
|
-
content: `<system-summary>${t("exec.forbidden_cmd", { cmd: forbidden })}</system-summary>`
|
|
18166
|
-
});
|
|
18167
|
-
}
|
|
18168
|
-
}
|
|
18169
|
-
}
|
|
18170
|
-
if (!hasTypeError) {
|
|
18171
|
-
deps.stuckDetector.recordToolError(call.name, result.output);
|
|
18172
|
-
}
|
|
18173
|
-
const actionableHints = deps.stuckDetector.getActionableHints();
|
|
18174
|
-
const alternative = deps.stuckDetector.getToolAlternative();
|
|
18175
|
-
if (actionableHints.length > 0 || alternative) {
|
|
18176
|
-
const parts = [...actionableHints];
|
|
18177
|
-
if (alternative) {
|
|
18178
|
-
parts.push(`Tool "${call.name}" crashed. Try "${alternative}" instead.`);
|
|
18179
|
-
}
|
|
18180
|
-
deps.pendingMessages.push({
|
|
18181
|
-
role: "user",
|
|
18182
|
-
content: `<system-summary>${t("exec.hints", { hints: parts.map((h) => `- ${h}`).join(`
|
|
18183
|
-
`) })}</system-summary>`
|
|
18184
|
-
});
|
|
18185
|
-
}
|
|
18186
|
-
} else {
|
|
18187
|
-
deps.stuckDetector.recordToolSuccess();
|
|
18188
|
-
if (call.name === "bash" && result.success) {
|
|
18189
|
-
const cmd = String(call.arguments?.command ?? "");
|
|
18190
|
-
const testRun = detectTestResults(String(result.output ?? ""));
|
|
18191
|
-
if (testRun && testRun.failed > 0) {
|
|
18192
|
-
deps.pendingMessages.push({
|
|
18193
|
-
role: "user",
|
|
18194
|
-
content: `<system-summary>${testRun.framework} reported ${testRun.failed} FAILING test(s) (${testRun.passed} passing). Do NOT mark the current step as done — fix the failing tests (read the failure output, correct the code) and re-run them until all pass.</system-summary>`
|
|
18195
|
-
});
|
|
18196
|
-
} else if (testRun && testRun.failed === 0 && testRun.passed > 0) {
|
|
18197
|
-
deps.pendingMessages.push({
|
|
18198
|
-
role: "user",
|
|
18199
|
-
content: `<system-summary>${testRun.framework}: all ${testRun.passed} test(s) passed for "${cmd}". You may mark the current step as done via plan update step=N status=done.</system-summary>`
|
|
18200
|
-
});
|
|
18201
|
-
} else if (/node|tsx|ts-node|python|npm\s+(start|test|run)/.test(cmd)) {
|
|
18202
|
-
deps.pendingMessages.push({
|
|
18203
|
-
role: "user",
|
|
18204
|
-
content: `<system-summary>The command "${cmd}" completed successfully. If this was testing your code, mark the current step as done via plan update step=N status=done.</system-summary>`
|
|
18205
|
-
});
|
|
18206
|
-
}
|
|
18207
|
-
}
|
|
18208
|
-
}
|
|
18209
|
-
if (result.success && (call.name === "write_file" || call.name === "edit_file")) {
|
|
18210
|
-
const filePath = call.arguments?.path;
|
|
18211
|
-
if (filePath) {
|
|
18212
|
-
deps.stuckDetector.recordFileRewrite(filePath);
|
|
18213
|
-
if (deps.stuckDetector.hasExcessiveRewrites()) {
|
|
18214
|
-
const file = deps.stuckDetector.getExcessiveRewriteFile();
|
|
18215
|
-
const count = deps.stuckDetector.getFileRewriteCount(file);
|
|
18216
|
-
if (ctx.onMeta) {
|
|
18217
|
-
ctx.onMeta(t("exec.file_rewrite_warning", {
|
|
18218
|
-
file,
|
|
18219
|
-
count: String(count)
|
|
18220
|
-
}));
|
|
18221
|
-
}
|
|
18222
|
-
}
|
|
18223
|
-
}
|
|
18224
|
-
deps.advancePlanIfStepComplete(ctx.contextManager, ctx.sessionLog);
|
|
18225
|
-
}
|
|
18226
|
-
deps.maybeSearchError(ctx, call);
|
|
18227
|
-
}
|
|
18228
|
-
};
|
|
18229
|
-
}
|
|
18230
|
-
var STUCK_RECOVERY_COOLDOWN = 5, MAX_PLAN_WARNINGS_BEFORE_BLOCK = 3, FORCE_SKIP_THRESHOLD = 10, PLAN_NUDGE_THRESHOLD = 2;
|
|
18231
|
-
var init_execution_plugin = __esm(() => {
|
|
18232
|
-
init_i18n();
|
|
18233
|
-
init_bash();
|
|
18234
|
-
init_windows_commands();
|
|
18320
|
+
init_execution_plugin();
|
|
18235
18321
|
});
|
|
18236
18322
|
|
|
18237
18323
|
// src/modules/execution/module.ts
|
|
@@ -18263,7 +18349,8 @@ class ExecutionModule {
|
|
|
18263
18349
|
stuckNotified: false,
|
|
18264
18350
|
depsGateHints: new Map,
|
|
18265
18351
|
mutationsWithoutPlan: 0,
|
|
18266
|
-
planNudgeSent: false
|
|
18352
|
+
planNudgeSent: false,
|
|
18353
|
+
typecheckFailures: new Map
|
|
18267
18354
|
};
|
|
18268
18355
|
trackerRef = (() => {
|
|
18269
18356
|
const self = this;
|
|
@@ -18446,6 +18533,7 @@ class ExecutionModule {
|
|
|
18446
18533
|
stillExistingDeliverables: (s) => this.stillExistingDeliverables(s),
|
|
18447
18534
|
parseKinds: (a, st) => this.parseKinds(a, st),
|
|
18448
18535
|
getTaskText: (c) => this.getTaskText(c),
|
|
18536
|
+
typecheckFailures: this.state.typecheckFailures,
|
|
18449
18537
|
baseDir: this.baseDir
|
|
18450
18538
|
});
|
|
18451
18539
|
}
|
|
@@ -18456,6 +18544,7 @@ class ExecutionModule {
|
|
|
18456
18544
|
pendingMessages: this.pendingMessages,
|
|
18457
18545
|
forbiddenBashFailures: this.forbiddenBashFailures,
|
|
18458
18546
|
state: this.state,
|
|
18547
|
+
store: this.store,
|
|
18459
18548
|
checkPlanAlignment: (call) => this.checkPlanAlignment(call),
|
|
18460
18549
|
advancePlanIfStepComplete: (cm, sl) => this.advancePlanIfStepComplete(cm, sl),
|
|
18461
18550
|
maybeSearchError: (ctx, call) => this.maybeSearchError(ctx, call)
|
|
@@ -21192,8 +21281,6 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21192
21281
|
exitOnComplete,
|
|
21193
21282
|
contextManager,
|
|
21194
21283
|
activeToolTags,
|
|
21195
|
-
sessionId: sessionManager.getActiveMeta()?.id,
|
|
21196
|
-
sessionContext: sessionManager.getSessionContext() ?? undefined,
|
|
21197
21284
|
recursionDepth: 0,
|
|
21198
21285
|
fileOperationsCount: 0,
|
|
21199
21286
|
sessionHistory: {
|
|
@@ -21221,6 +21308,14 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21221
21308
|
}
|
|
21222
21309
|
}
|
|
21223
21310
|
};
|
|
21311
|
+
Object.defineProperty(toolCtx, "sessionId", {
|
|
21312
|
+
get: () => sessionManager.getActiveMeta()?.id,
|
|
21313
|
+
configurable: true
|
|
21314
|
+
});
|
|
21315
|
+
Object.defineProperty(toolCtx, "sessionContext", {
|
|
21316
|
+
get: () => sessionManager.getSessionContext() ?? undefined,
|
|
21317
|
+
configurable: true
|
|
21318
|
+
});
|
|
21224
21319
|
const toolExecutor = new ToolExecutor(toolRegistry, toolCtx, pluginManager);
|
|
21225
21320
|
toolCtx.llmProvider = llmProvider;
|
|
21226
21321
|
toolCtx.toolExecutor = toolExecutor;
|
|
@@ -21393,6 +21488,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21393
21488
|
sessionManager,
|
|
21394
21489
|
skillsModule,
|
|
21395
21490
|
pluginManager,
|
|
21491
|
+
toolCtx,
|
|
21396
21492
|
configDir: dir,
|
|
21397
21493
|
baseDir,
|
|
21398
21494
|
noAgentsMd: skipAgentsMd
|