omnius 1.0.376 → 1.0.378
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/index.js +282 -19
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -559711,13 +559711,6 @@ var init_completionLedger = __esm({
|
|
|
559711
559711
|
// packages/orchestrator/dist/completionAutoFinalize.js
|
|
559712
559712
|
function buildTruthBasedCompletion(input) {
|
|
559713
559713
|
const maxAge = input.maxValidationAgeTurns ?? 8;
|
|
559714
|
-
if (input.todos.length === 0) {
|
|
559715
|
-
return { ready: false, reason: "no active todo tree" };
|
|
559716
|
-
}
|
|
559717
|
-
const open2 = input.todos.filter((todo) => todo.status !== "completed");
|
|
559718
|
-
if (open2.length > 0) {
|
|
559719
|
-
return { ready: false, reason: `${open2.length} open todo(s)` };
|
|
559720
|
-
}
|
|
559721
559714
|
if (input.verifyFailureCount > 0) {
|
|
559722
559715
|
return {
|
|
559723
559716
|
ready: false,
|
|
@@ -559735,6 +559728,33 @@ function buildTruthBasedCompletion(input) {
|
|
|
559735
559728
|
};
|
|
559736
559729
|
}
|
|
559737
559730
|
const files = (input.filesEdited ?? []).filter((file) => file.path.trim().length > 0).slice(0, 12);
|
|
559731
|
+
if (input.todos.length === 0) {
|
|
559732
|
+
if (files.length === 0) {
|
|
559733
|
+
return { ready: false, reason: "no active todo tree or changed files" };
|
|
559734
|
+
}
|
|
559735
|
+
if (typeof input.lastMutationTurn === "number" && input.lastMutationTurn >= 0 && input.lastValidationTurn < input.lastMutationTurn) {
|
|
559736
|
+
return {
|
|
559737
|
+
ready: false,
|
|
559738
|
+
reason: "validation happened before the last mutation"
|
|
559739
|
+
};
|
|
559740
|
+
}
|
|
559741
|
+
const fileLines2 = files.map((file) => `- ${file.action ? `${file.action} ` : ""}${file.path}`).join("\n");
|
|
559742
|
+
const summary2 = [
|
|
559743
|
+
"Completed with direct task evidence.",
|
|
559744
|
+
fileLines2 ? `Files changed:
|
|
559745
|
+
${fileLines2}` : null,
|
|
559746
|
+
`Validation passed after the last mutation: ${input.lastValidationCommand}`
|
|
559747
|
+
].filter((line) => Boolean(line)).join("\n\n");
|
|
559748
|
+
return {
|
|
559749
|
+
ready: true,
|
|
559750
|
+
reason: `changed files validated ${age} turn(s) ago`,
|
|
559751
|
+
summary: summary2
|
|
559752
|
+
};
|
|
559753
|
+
}
|
|
559754
|
+
const open2 = input.todos.filter((todo) => todo.status !== "completed");
|
|
559755
|
+
if (open2.length > 0) {
|
|
559756
|
+
return { ready: false, reason: `${open2.length} open todo(s)` };
|
|
559757
|
+
}
|
|
559738
559758
|
const todoLines = input.todos.slice(0, 12).map((todo) => {
|
|
559739
559759
|
const id = todo.id ? `${todo.id}: ` : "";
|
|
559740
559760
|
return `- ${id}${todo.content}`;
|
|
@@ -573462,6 +573482,9 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
573462
573482
|
const realFileMutation = input.realFileMutation ?? this._isRealProjectMutation(input.toolName, input.result);
|
|
573463
573483
|
const attemptedTargetPaths = this._extractToolTargetPaths(input.toolName, input.args, input.result);
|
|
573464
573484
|
const realMutationPaths = input.realMutationPaths ?? (realFileMutation ? attemptedTargetPaths : []);
|
|
573485
|
+
if (this._shouldSuppressCompletionDiscoveryEvidence(input.toolName, input.result, attemptedTargetPaths)) {
|
|
573486
|
+
return;
|
|
573487
|
+
}
|
|
573465
573488
|
this._completionLedger = recordToolEvidence(this._completionLedger, {
|
|
573466
573489
|
name: input.toolName,
|
|
573467
573490
|
success: input.result.success,
|
|
@@ -573483,6 +573506,14 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
573483
573506
|
}
|
|
573484
573507
|
this._saveCompletionLedgerSafe();
|
|
573485
573508
|
}
|
|
573509
|
+
_shouldSuppressCompletionDiscoveryEvidence(toolName, result, targetPaths) {
|
|
573510
|
+
if (result.success !== true)
|
|
573511
|
+
return false;
|
|
573512
|
+
if (toolName === "file_read") {
|
|
573513
|
+
return targetPaths.length > 0 && targetPaths.some((path12) => this._evidenceLedger.hasFresh(path12));
|
|
573514
|
+
}
|
|
573515
|
+
return toolName === "list_directory" || toolName === "find_files" || toolName === "grep_search";
|
|
573516
|
+
}
|
|
573486
573517
|
_isAtomicBatchEditAbort(toolName, result) {
|
|
573487
573518
|
if (toolName !== "batch_edit" || !result || result.success !== false) {
|
|
573488
573519
|
return false;
|
|
@@ -578285,6 +578316,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
578285
578316
|
currentTurn: turn,
|
|
578286
578317
|
lastValidationTurn: this._lastBuildSuccessTurn,
|
|
578287
578318
|
lastValidationCommand: this._lastBuildSuccessCommand,
|
|
578319
|
+
lastMutationTurn: this._lastFileWriteTurn,
|
|
578288
578320
|
verifyFailureCount: this._verifyFailures.size,
|
|
578289
578321
|
filesEdited: [...this._taskState.modifiedFiles.entries()].map(([path12, action]) => ({ path: path12, action }))
|
|
578290
578322
|
});
|
|
@@ -580568,6 +580600,43 @@ Use the saved fact to continue the promised synthesis or next concrete step, or
|
|
|
580568
580600
|
systemGuidance: staleEditBlock
|
|
580569
580601
|
};
|
|
580570
580602
|
}
|
|
580603
|
+
const staleRewriteBlock = this.staleEditOverwritePreflightBlock(tc.name, tc.arguments ?? {});
|
|
580604
|
+
if (staleRewriteBlock) {
|
|
580605
|
+
this.emit({
|
|
580606
|
+
type: "tool_call",
|
|
580607
|
+
toolName: tc.name,
|
|
580608
|
+
toolArgs: tc.arguments,
|
|
580609
|
+
turn,
|
|
580610
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
580611
|
+
});
|
|
580612
|
+
this.emit({
|
|
580613
|
+
type: "tool_result",
|
|
580614
|
+
toolName: tc.name,
|
|
580615
|
+
success: false,
|
|
580616
|
+
content: staleRewriteBlock.slice(0, 120),
|
|
580617
|
+
turn,
|
|
580618
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
580619
|
+
});
|
|
580620
|
+
this._tagSyntheticFailure({
|
|
580621
|
+
mode: "step_repetition",
|
|
580622
|
+
rationale: "full-file overwrite attempted while a stale narrow-edit repair lock is active"
|
|
580623
|
+
});
|
|
580624
|
+
if (this._completionLedger) {
|
|
580625
|
+
this._completionLedger = recordToolEvidence(this._completionLedger, {
|
|
580626
|
+
name: tc.name,
|
|
580627
|
+
success: false,
|
|
580628
|
+
outputPreview: staleRewriteBlock.slice(0, 500),
|
|
580629
|
+
argsKey: tc.arguments ? JSON.stringify(tc.arguments).slice(0, 300) : ""
|
|
580630
|
+
});
|
|
580631
|
+
this._saveCompletionLedgerSafe();
|
|
580632
|
+
}
|
|
580633
|
+
return {
|
|
580634
|
+
tc,
|
|
580635
|
+
output: staleRewriteBlock,
|
|
580636
|
+
success: false,
|
|
580637
|
+
systemGuidance: staleRewriteBlock
|
|
580638
|
+
};
|
|
580639
|
+
}
|
|
580571
580640
|
const baseIsReadLike = ![
|
|
580572
580641
|
"file_write",
|
|
580573
580642
|
"file_edit",
|
|
@@ -581517,8 +581586,10 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
581517
581586
|
if (tc.name === "shell") {
|
|
581518
581587
|
const _shellCmd2 = String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "");
|
|
581519
581588
|
const _declaredVerify = this._matchedDeclaredVerifyCommand(_shellCmd2);
|
|
581589
|
+
const _lastVerifier = this._lastVerifierResult;
|
|
581590
|
+
const _noTodoDirectValidation = !_declaredVerify && (this.readSessionTodos() || []).length === 0 && this._taskState.modifiedFiles.size > 0 && _lastVerifier?.outcomeClass === "verified";
|
|
581520
581591
|
const _legacyGenericValidation = process.env["OMNIUS_ENABLE_GENERIC_COMPLETION_COMMAND_HEURISTIC"] === "1" && /\b(build|test|run\b|start\b|serve\b|verify|check)\b/i.test(_shellCmd2);
|
|
581521
|
-
if (_declaredVerify || _legacyGenericValidation) {
|
|
581592
|
+
if (_declaredVerify || _noTodoDirectValidation || _legacyGenericValidation) {
|
|
581522
581593
|
this._lastBuildSuccessTurn = turn;
|
|
581523
581594
|
this._lastBuildSuccessCommand = (_declaredVerify || _shellCmd2).slice(0, 200);
|
|
581524
581595
|
this._truthAutoCompleteBlockedValidationTurn = -1;
|
|
@@ -582409,7 +582480,7 @@ Then use file_read on individual FILES inside it.`);
|
|
|
582409
582480
|
handledIds.add(matchTc.id);
|
|
582410
582481
|
const output = sr.result.success ? sr.result.output : `Error: ${sr.result.error || "unknown"}
|
|
582411
582482
|
${sr.result.output}`;
|
|
582412
|
-
messages2.push(this.
|
|
582483
|
+
messages2.push(this.buildModelFacingToolMessage(output, matchTc.id, matchTc.name, matchTc.arguments, sr.result.success));
|
|
582413
582484
|
if (matchTc.name === "task_complete") {
|
|
582414
582485
|
if (!sr.result.success) {
|
|
582415
582486
|
messages2.push({
|
|
@@ -582477,7 +582548,7 @@ ${sr.result.output}`;
|
|
|
582477
582548
|
break;
|
|
582478
582549
|
const r2 = await executeSingle(tc);
|
|
582479
582550
|
if (r2) {
|
|
582480
|
-
messages2.push(this.
|
|
582551
|
+
messages2.push(this.buildModelFacingToolMessage(r2.output, r2.tc.id, r2.tc.name, r2.tc.arguments, r2.success));
|
|
582481
582552
|
if (r2.systemGuidance) {
|
|
582482
582553
|
messages2.push({
|
|
582483
582554
|
role: "system",
|
|
@@ -582588,7 +582659,7 @@ ${sr.result.output}`;
|
|
|
582588
582659
|
}, 5);
|
|
582589
582660
|
for (const r2 of results) {
|
|
582590
582661
|
if (r2) {
|
|
582591
|
-
messages2.push(this.
|
|
582662
|
+
messages2.push(this.buildModelFacingToolMessage(r2.output, r2.tc.id, r2.tc.name, r2.tc.arguments, r2.success));
|
|
582592
582663
|
if (r2.systemGuidance) {
|
|
582593
582664
|
messages2.push({
|
|
582594
582665
|
role: "system",
|
|
@@ -583481,7 +583552,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
583481
583552
|
} else {
|
|
583482
583553
|
this._consecutiveEnoent = 0;
|
|
583483
583554
|
}
|
|
583484
|
-
const toolMsg = this.
|
|
583555
|
+
const toolMsg = this.buildModelFacingToolMessage(output, tc.id, tc.name, tc.arguments, result.success);
|
|
583485
583556
|
messages2.push(toolMsg);
|
|
583486
583557
|
if (tc.name === "task_complete") {
|
|
583487
583558
|
if (!result.success) {
|
|
@@ -583630,6 +583701,60 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
583630
583701
|
}
|
|
583631
583702
|
}
|
|
583632
583703
|
}
|
|
583704
|
+
if (!completed && !this._completionIncompleteVerification && process.env["OMNIUS_DISABLE_TRUTH_AUTOCOMPLETE"] !== "1") {
|
|
583705
|
+
try {
|
|
583706
|
+
const _finalTurn = Math.max(this._lastBuildSuccessTurn, this._lastFileWriteTurn, toolCallLog.at(-1)?.turn ?? -1, 0);
|
|
583707
|
+
const _todos = this.readSessionTodos() || [];
|
|
583708
|
+
const _truthCompletion = buildTruthBasedCompletion({
|
|
583709
|
+
todos: _todos,
|
|
583710
|
+
currentTurn: _finalTurn,
|
|
583711
|
+
lastValidationTurn: this._lastBuildSuccessTurn,
|
|
583712
|
+
lastValidationCommand: this._lastBuildSuccessCommand,
|
|
583713
|
+
lastMutationTurn: this._lastFileWriteTurn,
|
|
583714
|
+
verifyFailureCount: this._verifyFailures.size,
|
|
583715
|
+
filesEdited: [...this._taskState.modifiedFiles.entries()].map(([path12, action]) => ({ path: path12, action }))
|
|
583716
|
+
});
|
|
583717
|
+
if (_truthCompletion.ready && this._truthAutoCompleteBlockedValidationTurn !== this._lastBuildSuccessTurn) {
|
|
583718
|
+
const _summary = _truthCompletion.summary || "Completed.";
|
|
583719
|
+
const _args = { summary: _summary };
|
|
583720
|
+
if (!holdTaskCompleteGates(_args, _finalTurn)) {
|
|
583721
|
+
const _bpFinalTruth = await this._runBackwardPassReview(_finalTurn, toolCallLog, _summary);
|
|
583722
|
+
if (!_bpFinalTruth || _bpFinalTruth.proceed) {
|
|
583723
|
+
completed = true;
|
|
583724
|
+
summary = _summary;
|
|
583725
|
+
this.emit({
|
|
583726
|
+
type: "status",
|
|
583727
|
+
content: `REG-31: run-end truth-based completion synthesized (${_truthCompletion.reason})`,
|
|
583728
|
+
turn: _finalTurn,
|
|
583729
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
583730
|
+
});
|
|
583731
|
+
this._onTypedEvent?.({
|
|
583732
|
+
type: "completion_requested",
|
|
583733
|
+
runId: this._sessionId ?? "unknown",
|
|
583734
|
+
summary: summary.slice(0, 500),
|
|
583735
|
+
sourcePath: "direct",
|
|
583736
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
583737
|
+
});
|
|
583738
|
+
if (summary && !this._assistantTextEmitted) {
|
|
583739
|
+
this.emit({
|
|
583740
|
+
type: "assistant_text",
|
|
583741
|
+
content: summary,
|
|
583742
|
+
source: "task_complete_summary",
|
|
583743
|
+
turn: _finalTurn,
|
|
583744
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
583745
|
+
});
|
|
583746
|
+
this._assistantTextEmitted = true;
|
|
583747
|
+
}
|
|
583748
|
+
} else if (_bpFinalTruth.feedback) {
|
|
583749
|
+
emitBackwardPassAdvisory(_bpFinalTruth.feedback, _finalTurn);
|
|
583750
|
+
}
|
|
583751
|
+
} else {
|
|
583752
|
+
this._truthAutoCompleteBlockedValidationTurn = this._lastBuildSuccessTurn;
|
|
583753
|
+
}
|
|
583754
|
+
}
|
|
583755
|
+
} catch {
|
|
583756
|
+
}
|
|
583757
|
+
}
|
|
583633
583758
|
const durationMs = Date.now() - start2;
|
|
583634
583759
|
const incompleteVerification = this._completionIncompleteVerification;
|
|
583635
583760
|
if (incompleteVerification && !summary) {
|
|
@@ -584460,6 +584585,75 @@ ${marker}` : marker);
|
|
|
584460
584585
|
}
|
|
584461
584586
|
return { role: "tool", content: messageContent, tool_call_id: toolCallId };
|
|
584462
584587
|
}
|
|
584588
|
+
buildModelFacingToolMessage(output, toolCallId, toolName, args, success) {
|
|
584589
|
+
return this.buildToolMessage(this.compactDiscoveryOutputForModel(toolName, args, output, success), toolCallId, toolName);
|
|
584590
|
+
}
|
|
584591
|
+
compactDiscoveryOutputForModel(toolName, args, output, success) {
|
|
584592
|
+
if (success !== true)
|
|
584593
|
+
return output;
|
|
584594
|
+
if (this.shouldBypassDiscoveryCompaction(output))
|
|
584595
|
+
return output;
|
|
584596
|
+
const displayOutput = this.unwrapToolOutputForDisplay(output);
|
|
584597
|
+
if (toolName === "file_read") {
|
|
584598
|
+
const path13 = this.extractPrimaryToolPath(args);
|
|
584599
|
+
if (!path13 || !this._evidenceLedger.hasFresh(path13))
|
|
584600
|
+
return output;
|
|
584601
|
+
const entry = this._evidenceLedger.get(path13);
|
|
584602
|
+
return this.wrapToolOutputForModel(toolName, [
|
|
584603
|
+
"[DISCOVERY COMPACTED - file_read evidence captured]",
|
|
584604
|
+
`path=${path13}`,
|
|
584605
|
+
`captured=${this.countTextLines(displayOutput)} lines, ${displayOutput.length} chars${entry ? `, fidelity=${entry.fidelity}` : ""}`,
|
|
584606
|
+
'active_context="Evidence already gathered this run"',
|
|
584607
|
+
"Use the active evidence frame. Re-read only if that frame marks this file STALE or you need a distinct range."
|
|
584608
|
+
].join("\n"));
|
|
584609
|
+
}
|
|
584610
|
+
const previewSpec = toolName === "list_directory" ? { label: "directory listing", maxLines: 40, maxChars: 2400 } : toolName === "find_files" ? { label: "file discovery", maxLines: 60, maxChars: 3e3 } : toolName === "grep_search" ? { label: "search matches", maxLines: 40, maxChars: 3e3 } : null;
|
|
584611
|
+
if (!previewSpec)
|
|
584612
|
+
return output;
|
|
584613
|
+
const path12 = this.extractPrimaryToolPath(args);
|
|
584614
|
+
const preview = this.boundedDiscoveryPreview(displayOutput, previewSpec.maxLines, previewSpec.maxChars);
|
|
584615
|
+
return this.wrapToolOutputForModel(toolName, [
|
|
584616
|
+
`[DISCOVERY BOUNDED - ${previewSpec.label}]`,
|
|
584617
|
+
path12 ? `path=${path12}` : "",
|
|
584618
|
+
`captured=${this.countTextLines(displayOutput)} lines, ${displayOutput.length} chars`,
|
|
584619
|
+
`preview_lines=${preview.keptLines}/${preview.totalLines}`,
|
|
584620
|
+
"Keep these discovered candidates in mind; repeat this discovery only if the underlying filesystem/search scope has changed.",
|
|
584621
|
+
"",
|
|
584622
|
+
preview.text
|
|
584623
|
+
].filter(Boolean).join("\n"));
|
|
584624
|
+
}
|
|
584625
|
+
shouldBypassDiscoveryCompaction(output) {
|
|
584626
|
+
return output.includes("[IMAGE_BASE64:") || output.includes("[BRANCH-EXTRACT]") || output.includes("[STOP RE-READING") || output.includes("[Tool output truncated") || output.includes(TRIAGE_ENVELOPE_MARKER);
|
|
584627
|
+
}
|
|
584628
|
+
countTextLines(text2) {
|
|
584629
|
+
if (!text2)
|
|
584630
|
+
return 0;
|
|
584631
|
+
return text2.split("\n").length;
|
|
584632
|
+
}
|
|
584633
|
+
boundedDiscoveryPreview(text2, maxLines, maxChars) {
|
|
584634
|
+
const lines = text2.split("\n");
|
|
584635
|
+
const kept = [];
|
|
584636
|
+
let used = 0;
|
|
584637
|
+
for (const line of lines) {
|
|
584638
|
+
if (kept.length >= maxLines)
|
|
584639
|
+
break;
|
|
584640
|
+
const next = line.slice(0, Math.max(0, maxChars - used));
|
|
584641
|
+
if (next.length === 0 && line.length > 0)
|
|
584642
|
+
break;
|
|
584643
|
+
kept.push(next);
|
|
584644
|
+
used += next.length + 1;
|
|
584645
|
+
if (used >= maxChars)
|
|
584646
|
+
break;
|
|
584647
|
+
}
|
|
584648
|
+
if (kept.length < lines.length) {
|
|
584649
|
+
kept.push(`[... ${lines.length - kept.length} additional line(s) compacted ...]`);
|
|
584650
|
+
}
|
|
584651
|
+
return {
|
|
584652
|
+
text: kept.join("\n"),
|
|
584653
|
+
totalLines: lines.length,
|
|
584654
|
+
keptLines: Math.min(kept.length, lines.length)
|
|
584655
|
+
};
|
|
584656
|
+
}
|
|
584463
584657
|
// -------------------------------------------------------------------------
|
|
584464
584658
|
// Output folding — keep head + tail, omit middle (preserves errors at end)
|
|
584465
584659
|
// -------------------------------------------------------------------------
|
|
@@ -584544,15 +584738,32 @@ ${marker}` : marker);
|
|
|
584544
584738
|
return "stale_old_string";
|
|
584545
584739
|
return null;
|
|
584546
584740
|
}
|
|
584547
|
-
|
|
584548
|
-
|
|
584741
|
+
staleEditPathKey(path12) {
|
|
584742
|
+
const trimmed = path12.trim();
|
|
584743
|
+
if (!trimmed)
|
|
584744
|
+
return "";
|
|
584745
|
+
try {
|
|
584746
|
+
return _pathResolve(this._workingDirectory || process.cwd(), trimmed).replace(/\\/g, "/");
|
|
584747
|
+
} catch {
|
|
584748
|
+
return trimmed.replace(/\\/g, "/").replace(/^\.\/+/, "");
|
|
584749
|
+
}
|
|
584750
|
+
}
|
|
584751
|
+
staleEditFamilyKey(toolName, pathKey, errorKind, targetHash, latestFileHash) {
|
|
584752
|
+
return [
|
|
584753
|
+
toolName,
|
|
584754
|
+
pathKey || "(unknown)",
|
|
584755
|
+
errorKind,
|
|
584756
|
+
targetHash,
|
|
584757
|
+
latestFileHash || "unknown-file-hash"
|
|
584758
|
+
].join(":");
|
|
584549
584759
|
}
|
|
584550
584760
|
staleEditPreflightBlock(toolName, args) {
|
|
584551
584761
|
const target = this.staleEditTarget(toolName, args);
|
|
584552
584762
|
if (!target)
|
|
584553
584763
|
return null;
|
|
584764
|
+
const pathKey = this.staleEditPathKey(target.path);
|
|
584554
584765
|
for (const entry of this._staleEditFamilies.values()) {
|
|
584555
|
-
if (entry.tool !== toolName || entry.
|
|
584766
|
+
if (entry.tool !== toolName || entry.pathKey !== pathKey || entry.targetHash !== target.targetHash)
|
|
584556
584767
|
continue;
|
|
584557
584768
|
const hasFreshRead = entry.lastReadTurn > entry.lastFailureTurn;
|
|
584558
584769
|
const hasFreshMutation = entry.lastMutationTurn > entry.lastFailureTurn;
|
|
@@ -584569,23 +584780,65 @@ ${marker}` : marker);
|
|
|
584569
584780
|
}
|
|
584570
584781
|
return null;
|
|
584571
584782
|
}
|
|
584783
|
+
staleEditOverwritePreflightBlock(toolName, args) {
|
|
584784
|
+
if (toolName !== "file_write")
|
|
584785
|
+
return null;
|
|
584786
|
+
if (process.env["OMNIUS_ALLOW_STALE_REPAIR_OVERWRITE"] === "1")
|
|
584787
|
+
return null;
|
|
584788
|
+
if (this.options.modelTier !== "small" && this.options.modelTier !== "medium")
|
|
584789
|
+
return null;
|
|
584790
|
+
if (args?.["dry_run"] === true || args?.["dryRun"] === true)
|
|
584791
|
+
return null;
|
|
584792
|
+
const path12 = this.extractPrimaryToolPath(args);
|
|
584793
|
+
if (!path12)
|
|
584794
|
+
return null;
|
|
584795
|
+
const pathKey = this.staleEditPathKey(path12);
|
|
584796
|
+
const active = [...this._staleEditFamilies.values()].filter((entry) => entry.pathKey === pathKey).sort((a2, b) => b.lastFailureTurn - a2.lastFailureTurn).find((entry) => {
|
|
584797
|
+
const hasFreshRead = entry.lastReadTurn > entry.lastFailureTurn;
|
|
584798
|
+
const hasFreshMutation = entry.lastMutationTurn > entry.lastFailureTurn;
|
|
584799
|
+
return !hasFreshMutation && (entry.count >= 2 || !hasFreshRead);
|
|
584800
|
+
});
|
|
584801
|
+
if (!active)
|
|
584802
|
+
return null;
|
|
584803
|
+
return [
|
|
584804
|
+
`[EDIT REPAIR LOCK] A recent narrow edit to ${active.path} failed because the model-visible target diverged from disk (${active.errorKind}; latest_file_hash=${active.latestFileHash || "unknown"}).`,
|
|
584805
|
+
`This full-file overwrite was NOT executed. A stale narrow edit must not be repaired by broad file regeneration on ${this.options.modelTier ?? "unknown"} tier models.`,
|
|
584806
|
+
``,
|
|
584807
|
+
`Allowed next actions:`,
|
|
584808
|
+
`1. file_read ${active.path} once and construct file_edit from exact current text.`,
|
|
584809
|
+
`2. file_patch/file_edit against the latest file hash or a different target.`,
|
|
584810
|
+
`3. file_write with dry_run=true only to validate a full rewrite proposal without changing disk.`,
|
|
584811
|
+
`4. run verification if the desired change is already present, or report the explicit blocker instead of completing.`,
|
|
584812
|
+
``,
|
|
584813
|
+
`Stale target preview: ${active.preview}`
|
|
584814
|
+
].join("\n");
|
|
584815
|
+
}
|
|
584572
584816
|
noteStaleEditGuardOutcome(toolName, args, result, turn) {
|
|
584573
584817
|
const path12 = this.extractPrimaryToolPath(args);
|
|
584818
|
+
const pathKey = path12 ? this.staleEditPathKey(path12) : "";
|
|
584574
584819
|
if (toolName === "file_read" && path12 && result.success) {
|
|
584575
584820
|
for (const entry of this._staleEditFamilies.values()) {
|
|
584576
|
-
if (entry.
|
|
584821
|
+
if (entry.pathKey === pathKey)
|
|
584577
584822
|
entry.lastReadTurn = turn;
|
|
584578
584823
|
}
|
|
584579
584824
|
return;
|
|
584580
584825
|
}
|
|
584826
|
+
if (toolName === "file_write" && path12 && result.success && result.mutated !== false) {
|
|
584827
|
+
for (const [key2, entry] of this._staleEditFamilies) {
|
|
584828
|
+
if (entry.pathKey === pathKey)
|
|
584829
|
+
this._staleEditFamilies.delete(key2);
|
|
584830
|
+
}
|
|
584831
|
+
return;
|
|
584832
|
+
}
|
|
584581
584833
|
if (!this.isEditToolName(toolName))
|
|
584582
584834
|
return;
|
|
584583
584835
|
const target = this.staleEditTarget(toolName, args);
|
|
584584
584836
|
if (!target)
|
|
584585
584837
|
return;
|
|
584838
|
+
const targetPathKey = this.staleEditPathKey(target.path);
|
|
584586
584839
|
if (result.success && result.mutated !== false) {
|
|
584587
584840
|
for (const [key2, entry] of this._staleEditFamilies) {
|
|
584588
|
-
if (entry.
|
|
584841
|
+
if (entry.pathKey === targetPathKey)
|
|
584589
584842
|
this._staleEditFamilies.delete(key2);
|
|
584590
584843
|
}
|
|
584591
584844
|
return;
|
|
@@ -584593,14 +584846,17 @@ ${marker}` : marker);
|
|
|
584593
584846
|
const errorKind = this.classifyStaleEditFailure(toolName, result);
|
|
584594
584847
|
if (!errorKind)
|
|
584595
584848
|
return;
|
|
584596
|
-
const
|
|
584849
|
+
const latestFileHash = typeof result.beforeHash === "string" && result.beforeHash.trim() ? result.beforeHash.trim() : typeof result.afterHash === "string" && result.afterHash.trim() ? result.afterHash.trim() : "unknown-file-hash";
|
|
584850
|
+
const key = this.staleEditFamilyKey(toolName, targetPathKey, errorKind, target.targetHash, latestFileHash);
|
|
584597
584851
|
const existing = this._staleEditFamilies.get(key);
|
|
584598
584852
|
this._staleEditFamilies.set(key, {
|
|
584599
584853
|
count: (existing?.count ?? 0) + 1,
|
|
584600
584854
|
path: target.path,
|
|
584855
|
+
pathKey: targetPathKey,
|
|
584601
584856
|
tool: toolName,
|
|
584602
584857
|
errorKind,
|
|
584603
584858
|
targetHash: target.targetHash,
|
|
584859
|
+
latestFileHash,
|
|
584604
584860
|
lastFailureTurn: turn,
|
|
584605
584861
|
lastReadTurn: existing?.lastReadTurn ?? -1,
|
|
584606
584862
|
lastMutationTurn: existing?.lastMutationTurn ?? -1,
|
|
@@ -652150,7 +652406,7 @@ function getModelTier(modelName) {
|
|
|
652150
652406
|
if (sizeMatch) {
|
|
652151
652407
|
const size = parseInt(sizeMatch[1], 10);
|
|
652152
652408
|
if (size >= 30) return "large";
|
|
652153
|
-
if (size >=
|
|
652409
|
+
if (size >= 14) return "medium";
|
|
652154
652410
|
return "small";
|
|
652155
652411
|
}
|
|
652156
652412
|
if (/\b(small|mini|nano|tiny)\b/.test(m2)) return "small";
|
|
@@ -725784,6 +726040,7 @@ async function runCommand2(opts, config) {
|
|
|
725784
726040
|
await runJson(opts.task, mergedConfig, opts.repoPath);
|
|
725785
726041
|
} else {
|
|
725786
726042
|
await runWithTUI(opts.task, mergedConfig, opts.repoPath);
|
|
726043
|
+
if (shouldForceSingleRunExit()) process.exit(0);
|
|
725787
726044
|
}
|
|
725788
726045
|
} else {
|
|
725789
726046
|
await startInteractive(mergedConfig, opts.repoPath);
|
|
@@ -725883,6 +726140,12 @@ function shouldForceJsonExit() {
|
|
|
725883
726140
|
return false;
|
|
725884
726141
|
return true;
|
|
725885
726142
|
}
|
|
726143
|
+
function shouldForceSingleRunExit() {
|
|
726144
|
+
if (process.env["OMNIUS_SINGLE_RUN_NO_FORCE_EXIT"] === "1") return false;
|
|
726145
|
+
if (process.env["VITEST"] === "true" || process.env["NODE_ENV"] === "test")
|
|
726146
|
+
return false;
|
|
726147
|
+
return true;
|
|
726148
|
+
}
|
|
725886
726149
|
function extractSummary(captured) {
|
|
725887
726150
|
const all2 = captured.join("");
|
|
725888
726151
|
const match = all2.match(/task_complete.*?summary[:\s]*["']?([^"'\n]+)/i);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.378",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.378",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED