omnius 1.0.457 → 1.0.459
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 +594 -46
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14315,7 +14315,7 @@ var init_file_edit = __esm({
|
|
|
14315
14315
|
path: { type: "string", description: "Absolute or relative file path" },
|
|
14316
14316
|
old_string: {
|
|
14317
14317
|
type: "string",
|
|
14318
|
-
description: "The exact string to search for and replace. Must be unique in the file (or use replace_all). Use old_string_base64 when JSON escaping is fragile."
|
|
14318
|
+
description: "The exact current string to search for and replace, copied from the most recent file_read for this file. Must be unique in the file (or use replace_all). Use old_string_base64 when JSON escaping is fragile."
|
|
14319
14319
|
},
|
|
14320
14320
|
old_string_base64: {
|
|
14321
14321
|
type: "string",
|
|
@@ -14340,14 +14340,14 @@ var init_file_edit = __esm({
|
|
|
14340
14340
|
},
|
|
14341
14341
|
expected_hash: {
|
|
14342
14342
|
type: "string",
|
|
14343
|
-
description: "
|
|
14343
|
+
description: "SHA-256 from the most recent file_read for this file. The runner refuses unverified exact replacements that omit or mismatch this hash."
|
|
14344
14344
|
},
|
|
14345
14345
|
dry_run: {
|
|
14346
14346
|
type: "boolean",
|
|
14347
14347
|
description: "Validate the edit and preview the diff without modifying disk."
|
|
14348
14348
|
}
|
|
14349
14349
|
},
|
|
14350
|
-
required: ["path"],
|
|
14350
|
+
required: ["path", "expected_hash"],
|
|
14351
14351
|
allOf: [
|
|
14352
14352
|
{ anyOf: [{ required: ["old_string"] }, { required: ["old_string_base64"] }] },
|
|
14353
14353
|
{ anyOf: [{ required: ["new_string"] }, { required: ["new_string_base64"] }] }
|
|
@@ -28570,7 +28570,7 @@ var init_batch_edit = __esm({
|
|
|
28570
28570
|
},
|
|
28571
28571
|
old_string: {
|
|
28572
28572
|
type: "string",
|
|
28573
|
-
description: "Exact string to find and replace
|
|
28573
|
+
description: "Exact current string to find and replace, copied from the most recent file_read for this file. Must be unique unless replace_all. Use old_string_base64 when JSON escaping is fragile."
|
|
28574
28574
|
},
|
|
28575
28575
|
old_string_base64: {
|
|
28576
28576
|
type: "string",
|
|
@@ -28595,10 +28595,10 @@ var init_batch_edit = __esm({
|
|
|
28595
28595
|
},
|
|
28596
28596
|
expected_hash: {
|
|
28597
28597
|
type: "string",
|
|
28598
|
-
description: "SHA-256 from the most recent file_read for this file. All edits for a file must use the same hash
|
|
28598
|
+
description: "SHA-256 from the most recent file_read for this file. All edits for a file must use the same verified hash."
|
|
28599
28599
|
}
|
|
28600
28600
|
},
|
|
28601
|
-
required: ["path"],
|
|
28601
|
+
required: ["path", "expected_hash"],
|
|
28602
28602
|
allOf: [
|
|
28603
28603
|
{ anyOf: [{ required: ["old_string"] }, { required: ["old_string_base64"] }] },
|
|
28604
28604
|
{ anyOf: [{ required: ["new_string"] }, { required: ["new_string_base64"] }] }
|
|
@@ -566824,6 +566824,7 @@ function shouldIgnore(relPath, base3, patterns) {
|
|
|
566824
566824
|
function scanWorkspace(opts) {
|
|
566825
566825
|
const root = opts.root;
|
|
566826
566826
|
const maxFiles = Math.max(1, Math.min(2e3, opts.maxFiles ?? 200));
|
|
566827
|
+
const maxDirs = Math.max(1, Math.min(5e3, opts.maxDirs ?? 1e3));
|
|
566827
566828
|
const noGitignore = opts.noGitignore === true;
|
|
566828
566829
|
const noDefaults = opts.noDefaults === true;
|
|
566829
566830
|
const patterns = [];
|
|
@@ -566834,6 +566835,7 @@ function scanWorkspace(opts) {
|
|
|
566834
566835
|
if (opts.extraIgnore)
|
|
566835
566836
|
patterns.push(...opts.extraIgnore);
|
|
566836
566837
|
const files = [];
|
|
566838
|
+
const dirs = [];
|
|
566837
566839
|
let totalBytes = 0;
|
|
566838
566840
|
let truncated = false;
|
|
566839
566841
|
let dirsVisited = 0;
|
|
@@ -566849,6 +566851,17 @@ function scanWorkspace(opts) {
|
|
|
566849
566851
|
continue;
|
|
566850
566852
|
visited.add(dir);
|
|
566851
566853
|
dirsVisited++;
|
|
566854
|
+
if (dirs.length < maxDirs) {
|
|
566855
|
+
try {
|
|
566856
|
+
const st = statSync32(dir);
|
|
566857
|
+
dirs.push({
|
|
566858
|
+
abs: dir,
|
|
566859
|
+
rel: relative8(root, dir) || ".",
|
|
566860
|
+
mtimeMs: st.mtimeMs
|
|
566861
|
+
});
|
|
566862
|
+
} catch {
|
|
566863
|
+
}
|
|
566864
|
+
}
|
|
566852
566865
|
let entries = [];
|
|
566853
566866
|
try {
|
|
566854
566867
|
entries = readdirSync30(dir);
|
|
@@ -566883,7 +566896,87 @@ function scanWorkspace(opts) {
|
|
|
566883
566896
|
}
|
|
566884
566897
|
}
|
|
566885
566898
|
files.sort((a2, b) => a2.rel.localeCompare(b.rel));
|
|
566886
|
-
|
|
566899
|
+
dirs.sort((a2, b) => a2.rel.localeCompare(b.rel));
|
|
566900
|
+
return { files, dirs, totalBytes, truncated, dirsVisited };
|
|
566901
|
+
}
|
|
566902
|
+
function humanBytes(n2) {
|
|
566903
|
+
if (n2 < 1024)
|
|
566904
|
+
return `${n2}B`;
|
|
566905
|
+
if (n2 < 1024 * 1024)
|
|
566906
|
+
return `${(n2 / 1024).toFixed(1)}KB`;
|
|
566907
|
+
return `${(n2 / 1024 / 1024).toFixed(1)}MB`;
|
|
566908
|
+
}
|
|
566909
|
+
function ensureTreeNode(root, rel) {
|
|
566910
|
+
if (!rel || rel === ".")
|
|
566911
|
+
return root;
|
|
566912
|
+
let node = root;
|
|
566913
|
+
for (const part of rel.split("/").filter(Boolean)) {
|
|
566914
|
+
let child = node.children.get(part);
|
|
566915
|
+
if (!child) {
|
|
566916
|
+
child = { name: part, children: /* @__PURE__ */ new Map(), directory: true };
|
|
566917
|
+
node.children.set(part, child);
|
|
566918
|
+
}
|
|
566919
|
+
node = child;
|
|
566920
|
+
}
|
|
566921
|
+
return node;
|
|
566922
|
+
}
|
|
566923
|
+
function renderWorkspaceTree(scan, opts = {}) {
|
|
566924
|
+
const maxLines = Math.max(10, Math.min(2e3, opts.maxLines ?? 120));
|
|
566925
|
+
const includeFileSizes = opts.includeFileSizes !== false;
|
|
566926
|
+
const root = {
|
|
566927
|
+
name: ".",
|
|
566928
|
+
children: /* @__PURE__ */ new Map(),
|
|
566929
|
+
directory: true
|
|
566930
|
+
};
|
|
566931
|
+
for (const dir of scan.dirs)
|
|
566932
|
+
ensureTreeNode(root, dir.rel).directory = true;
|
|
566933
|
+
for (const file of scan.files) {
|
|
566934
|
+
const parts = file.rel.split("/").filter(Boolean);
|
|
566935
|
+
const name10 = parts.pop();
|
|
566936
|
+
if (!name10)
|
|
566937
|
+
continue;
|
|
566938
|
+
const parent = ensureTreeNode(root, parts.join("/"));
|
|
566939
|
+
parent.children.set(name10, {
|
|
566940
|
+
name: name10,
|
|
566941
|
+
children: /* @__PURE__ */ new Map(),
|
|
566942
|
+
file,
|
|
566943
|
+
directory: false
|
|
566944
|
+
});
|
|
566945
|
+
}
|
|
566946
|
+
const lines = ["./"];
|
|
566947
|
+
let truncated = false;
|
|
566948
|
+
const walk2 = (node, depth) => {
|
|
566949
|
+
const children2 = [...node.children.values()].sort((a2, b) => {
|
|
566950
|
+
if (a2.directory !== b.directory)
|
|
566951
|
+
return a2.directory ? -1 : 1;
|
|
566952
|
+
return a2.name.localeCompare(b.name);
|
|
566953
|
+
});
|
|
566954
|
+
for (const child of children2) {
|
|
566955
|
+
if (lines.length >= maxLines) {
|
|
566956
|
+
truncated = true;
|
|
566957
|
+
return;
|
|
566958
|
+
}
|
|
566959
|
+
const indent2 = " ".repeat(depth);
|
|
566960
|
+
if (child.directory) {
|
|
566961
|
+
lines.push(`${indent2}${child.name}/`);
|
|
566962
|
+
walk2(child, depth + 1);
|
|
566963
|
+
if (truncated)
|
|
566964
|
+
return;
|
|
566965
|
+
} else {
|
|
566966
|
+
const size = includeFileSizes && child.file ? ` (${humanBytes(child.file.bytes)})` : "";
|
|
566967
|
+
lines.push(`${indent2}${child.name}${size}`);
|
|
566968
|
+
}
|
|
566969
|
+
}
|
|
566970
|
+
};
|
|
566971
|
+
walk2(root, 1);
|
|
566972
|
+
if (truncated || scan.truncated) {
|
|
566973
|
+
if (lines.length >= maxLines)
|
|
566974
|
+
lines[lines.length - 1] = "... [workspace tree truncated]";
|
|
566975
|
+
else
|
|
566976
|
+
lines.push("... [workspace tree truncated]");
|
|
566977
|
+
truncated = true;
|
|
566978
|
+
}
|
|
566979
|
+
return { text: lines.join("\n"), lineCount: lines.length, truncated };
|
|
566887
566980
|
}
|
|
566888
566981
|
var UNIVERSAL_DEFAULTS;
|
|
566889
566982
|
var init_world_state_disk_scan = __esm({
|
|
@@ -567578,9 +567671,9 @@ function regenerate(opts) {
|
|
|
567578
567671
|
lines.push(` No files found in workspace (excluding ignored paths).`);
|
|
567579
567672
|
} else {
|
|
567580
567673
|
const totalBytes = files.reduce((sum, f2) => sum + f2.bytes, 0);
|
|
567581
|
-
lines.push(` ${files.length} file(s)${truncated ? " (truncated — more exist)" : ""}, total ${
|
|
567674
|
+
lines.push(` ${files.length} file(s)${truncated ? " (truncated — more exist)" : ""}, total ${humanBytes2(totalBytes)}.`);
|
|
567582
567675
|
if (lastWriteFile) {
|
|
567583
|
-
lines.push(` Most recently modified: ${lastWriteFile.rel} (${
|
|
567676
|
+
lines.push(` Most recently modified: ${lastWriteFile.rel} (${humanBytes2(lastWriteFile.bytes)}, ${ago(nowMs - lastWriteFile.mtimeMs)}).`);
|
|
567584
567677
|
}
|
|
567585
567678
|
const topDirs = /* @__PURE__ */ new Map();
|
|
567586
567679
|
for (const f2 of files) {
|
|
@@ -567676,7 +567769,7 @@ function reconciledMark(t2) {
|
|
|
567676
567769
|
return "BLOCK";
|
|
567677
567770
|
}
|
|
567678
567771
|
}
|
|
567679
|
-
function
|
|
567772
|
+
function humanBytes2(n2) {
|
|
567680
567773
|
if (n2 < 1024)
|
|
567681
567774
|
return `${n2}B`;
|
|
567682
567775
|
if (n2 < 1024 * 1024)
|
|
@@ -572253,6 +572346,20 @@ var init_streaming_executor = __esm({
|
|
|
572253
572346
|
setExecutor(fn) {
|
|
572254
572347
|
this.executeFn = fn;
|
|
572255
572348
|
}
|
|
572349
|
+
/** Rename a queued streaming tool entry when the provider reveals its real id late. */
|
|
572350
|
+
rename(oldId, newId) {
|
|
572351
|
+
if (!oldId || !newId || oldId === newId)
|
|
572352
|
+
return;
|
|
572353
|
+
const entry = this.tools.get(oldId);
|
|
572354
|
+
if (!entry || this.tools.has(newId))
|
|
572355
|
+
return;
|
|
572356
|
+
this.tools.delete(oldId);
|
|
572357
|
+
entry.id = newId;
|
|
572358
|
+
this.tools.set(newId, entry);
|
|
572359
|
+
const idx = this.insertionOrder.indexOf(oldId);
|
|
572360
|
+
if (idx >= 0)
|
|
572361
|
+
this.insertionOrder[idx] = newId;
|
|
572362
|
+
}
|
|
572256
572363
|
/** Update the parsed-input concurrency classifier. */
|
|
572257
572364
|
setConcurrencyResolver(fn) {
|
|
572258
572365
|
this.config.concurrencyResolver = fn;
|
|
@@ -572490,7 +572597,7 @@ var init_streaming_executor = __esm({
|
|
|
572490
572597
|
entry.state = "executing";
|
|
572491
572598
|
entry.startedAt = Date.now();
|
|
572492
572599
|
const exec7 = this.executeFn;
|
|
572493
|
-
entry.promise = exec7(entry.name, entry.args).then((result) => {
|
|
572600
|
+
entry.promise = exec7(entry.id, entry.name, entry.args).then((result) => {
|
|
572494
572601
|
entry.state = "completed";
|
|
572495
572602
|
entry.result = result;
|
|
572496
572603
|
entry.completedAt = Date.now();
|
|
@@ -573437,6 +573544,7 @@ var init_evidenceLedger = __esm({
|
|
|
573437
573544
|
this.entries.set(path12, {
|
|
573438
573545
|
...existing,
|
|
573439
573546
|
content: keepNew ? built.text : existing.content,
|
|
573547
|
+
contentHash: input.contentHash ?? existing.contentHash,
|
|
573440
573548
|
fidelity: keepNew ? built.fidelity : existing.fidelity,
|
|
573441
573549
|
ranges: mergeRanges([...existing.ranges, range]),
|
|
573442
573550
|
lastReadTurn: turn,
|
|
@@ -573447,6 +573555,7 @@ var init_evidenceLedger = __esm({
|
|
|
573447
573555
|
}
|
|
573448
573556
|
this.entries.set(path12, {
|
|
573449
573557
|
path: path12,
|
|
573558
|
+
contentHash: input.contentHash,
|
|
573450
573559
|
readVersion: fileVersion,
|
|
573451
573560
|
mtimeMs: input.mtimeMs ?? 0,
|
|
573452
573561
|
lastReadTurn: turn,
|
|
@@ -573475,7 +573584,7 @@ var init_evidenceLedger = __esm({
|
|
|
573475
573584
|
* like a manual chmod, device reconnect, or human edit), mark as stale.
|
|
573476
573585
|
* Returns true if evidence was valid, false if became stale or stat failed.
|
|
573477
573586
|
*/
|
|
573478
|
-
validateFreshness(path12) {
|
|
573587
|
+
validateFreshness(path12, statPath = path12) {
|
|
573479
573588
|
const e2 = this.entries.get(path12);
|
|
573480
573589
|
if (!e2)
|
|
573481
573590
|
return false;
|
|
@@ -573484,7 +573593,7 @@ var init_evidenceLedger = __esm({
|
|
|
573484
573593
|
if (e2.mtimeMs <= 0)
|
|
573485
573594
|
return true;
|
|
573486
573595
|
try {
|
|
573487
|
-
const st = statSync36(
|
|
573596
|
+
const st = statSync36(statPath, { throwIfNoEntry: false });
|
|
573488
573597
|
if (!st)
|
|
573489
573598
|
return true;
|
|
573490
573599
|
if (st.mtimeMs > e2.mtimeMs) {
|
|
@@ -573499,6 +573608,11 @@ var init_evidenceLedger = __esm({
|
|
|
573499
573608
|
get(path12) {
|
|
573500
573609
|
return this.entries.get(path12);
|
|
573501
573610
|
}
|
|
573611
|
+
markStale(path12) {
|
|
573612
|
+
const e2 = this.entries.get(path12);
|
|
573613
|
+
if (e2)
|
|
573614
|
+
e2.stale = true;
|
|
573615
|
+
}
|
|
573502
573616
|
size() {
|
|
573503
573617
|
return this.entries.size;
|
|
573504
573618
|
}
|
|
@@ -573521,12 +573635,12 @@ var init_evidenceLedger = __esm({
|
|
|
573521
573635
|
];
|
|
573522
573636
|
let used = lines.join("\n").length;
|
|
573523
573637
|
for (const e2 of sorted) {
|
|
573524
|
-
const header = e2.stale ? `▸ ${e2.path} @v${e2.readVersion} [STALE — changed since read; re-read needed] (${rangeLabel(e2.ranges)})` : `▸ ${e2.path} @v${e2.readVersion} [FRESH] (${rangeLabel(e2.ranges)}):`;
|
|
573638
|
+
const header = e2.stale ? `▸ ${e2.path} @v${e2.readVersion} [STALE — changed since read; re-read needed] (${rangeLabel(e2.ranges)})` : `▸ ${e2.path} @v${e2.readVersion} [FRESH${e2.contentHash ? ` sha256=${e2.contentHash}` : ""}] (${rangeLabel(e2.ranges)}):`;
|
|
573525
573639
|
const body = e2.stale ? "" : "\n" + indent(e2.content);
|
|
573526
573640
|
const chunk = `${header}${body}
|
|
573527
573641
|
`;
|
|
573528
573642
|
if (used + chunk.length > maxChars) {
|
|
573529
|
-
const stub = `▸ ${e2.path} @v${e2.readVersion} [${e2.stale ? "STALE" :
|
|
573643
|
+
const stub = `▸ ${e2.path} @v${e2.readVersion} [${e2.stale ? "STALE" : `FRESH${e2.contentHash ? ` sha256=${e2.contentHash}` : ""}`}] (${rangeLabel(e2.ranges)})
|
|
573530
573644
|
`;
|
|
573531
573645
|
if (used + stub.length <= maxChars) {
|
|
573532
573646
|
lines.push(stub);
|
|
@@ -574603,9 +574717,22 @@ ${input.error}`;
|
|
|
574603
574717
|
}
|
|
574604
574718
|
if (input.realFileMutation)
|
|
574605
574719
|
diagnoses.add("project-file-mutation");
|
|
574606
|
-
const
|
|
574607
|
-
|
|
574608
|
-
|
|
574720
|
+
const focusDecision = input.focusDecision && typeof input.focusDecision === "object" ? input.focusDecision : null;
|
|
574721
|
+
const focusDecisionKind = typeof focusDecision?.["kind"] === "string" ? focusDecision["kind"] : null;
|
|
574722
|
+
if (focusDecisionKind === "block_tool_call") {
|
|
574723
|
+
if (focusDecision?.["success"] === true || input.success) {
|
|
574724
|
+
diagnoses.add("focus-supervisor-cached-evidence");
|
|
574725
|
+
} else {
|
|
574726
|
+
diagnoses.add("focus-supervisor-block");
|
|
574727
|
+
}
|
|
574728
|
+
} else {
|
|
574729
|
+
const focusDecisionJson = previewJson(input.focusDecision ?? {});
|
|
574730
|
+
if (focusDecisionJson.includes("block_tool_call")) {
|
|
574731
|
+
if (input.success)
|
|
574732
|
+
diagnoses.add("focus-supervisor-cached-evidence");
|
|
574733
|
+
else
|
|
574734
|
+
diagnoses.add("focus-supervisor-block");
|
|
574735
|
+
}
|
|
574609
574736
|
}
|
|
574610
574737
|
const focusJson = previewJson(input.focusSupervisor ?? {});
|
|
574611
574738
|
if (focusJson.includes("block_tool_call") || focusJson.includes("requiredNextAction")) {
|
|
@@ -574627,8 +574754,87 @@ function diagnoseContextDump(record) {
|
|
|
574627
574754
|
if (record.metrics.estimatedTokens > 1e5) {
|
|
574628
574755
|
diagnoses.add("large-context-window");
|
|
574629
574756
|
}
|
|
574757
|
+
if (hasToolResultBindingMismatch(record)) {
|
|
574758
|
+
diagnoses.add("tool-result-binding-mismatch");
|
|
574759
|
+
}
|
|
574630
574760
|
return [...diagnoses].sort();
|
|
574631
574761
|
}
|
|
574762
|
+
function hasToolResultBindingMismatch(record) {
|
|
574763
|
+
const messages2 = Array.isArray(record.request?.["messages"]) ? record.request["messages"] : [];
|
|
574764
|
+
if (messages2.length === 0)
|
|
574765
|
+
return false;
|
|
574766
|
+
const callsById = /* @__PURE__ */ new Map();
|
|
574767
|
+
for (const message2 of messages2) {
|
|
574768
|
+
if (message2["role"] !== "assistant")
|
|
574769
|
+
continue;
|
|
574770
|
+
const calls = Array.isArray(message2["tool_calls"]) ? message2["tool_calls"] : [];
|
|
574771
|
+
for (const call of calls) {
|
|
574772
|
+
const id2 = typeof call["id"] === "string" ? call["id"] : "";
|
|
574773
|
+
const fn = call["function"] && typeof call["function"] === "object" ? call["function"] : {};
|
|
574774
|
+
const name10 = typeof fn["name"] === "string" ? fn["name"] : "";
|
|
574775
|
+
const argsRaw = typeof fn["arguments"] === "string" ? fn["arguments"] : "{}";
|
|
574776
|
+
let args = {};
|
|
574777
|
+
try {
|
|
574778
|
+
args = JSON.parse(argsRaw);
|
|
574779
|
+
} catch {
|
|
574780
|
+
args = {};
|
|
574781
|
+
}
|
|
574782
|
+
if (id2)
|
|
574783
|
+
callsById.set(id2, { name: name10, args });
|
|
574784
|
+
}
|
|
574785
|
+
}
|
|
574786
|
+
for (const message2 of messages2) {
|
|
574787
|
+
if (message2["role"] !== "tool")
|
|
574788
|
+
continue;
|
|
574789
|
+
const id2 = typeof message2["tool_call_id"] === "string" ? message2["tool_call_id"] : "";
|
|
574790
|
+
const call = id2 ? callsById.get(id2) : void 0;
|
|
574791
|
+
if (!call)
|
|
574792
|
+
continue;
|
|
574793
|
+
const requested = extractToolTarget(call.args);
|
|
574794
|
+
if (!requested)
|
|
574795
|
+
continue;
|
|
574796
|
+
const content = typeof message2["content"] === "string" ? message2["content"] : "";
|
|
574797
|
+
const reported = extractReportedToolTarget(content);
|
|
574798
|
+
if (!reported)
|
|
574799
|
+
continue;
|
|
574800
|
+
if (!targetsCompatible(requested, reported))
|
|
574801
|
+
return true;
|
|
574802
|
+
}
|
|
574803
|
+
return false;
|
|
574804
|
+
}
|
|
574805
|
+
function extractToolTarget(args) {
|
|
574806
|
+
const value2 = args["path"] ?? args["file"] ?? args["file_path"] ?? args["filepath"] ?? args["directory"] ?? args["cwd"];
|
|
574807
|
+
return typeof value2 === "string" ? value2.trim() : "";
|
|
574808
|
+
}
|
|
574809
|
+
function extractReportedToolTarget(content) {
|
|
574810
|
+
const patterns = [
|
|
574811
|
+
/^target=([^\n\r]+)/m,
|
|
574812
|
+
/^path=([^\n\r]+)/m,
|
|
574813
|
+
/\bfile\s+([^\s]+)\s+already contains/i,
|
|
574814
|
+
/\bEdited\s+([^\s]+)\s+at line/i,
|
|
574815
|
+
/\bat\s+([^\s]+)\s+\(sha256\b/i,
|
|
574816
|
+
/\bRefusing to (?:edit|overwrite existing file)\s+([^\s]+)/i
|
|
574817
|
+
];
|
|
574818
|
+
for (const pattern of patterns) {
|
|
574819
|
+
const match = content.match(pattern);
|
|
574820
|
+
const raw = match?.[1]?.trim();
|
|
574821
|
+
if (raw)
|
|
574822
|
+
return raw.replace(/[),.;:]+$/, "");
|
|
574823
|
+
}
|
|
574824
|
+
return "";
|
|
574825
|
+
}
|
|
574826
|
+
function targetsCompatible(requested, reported) {
|
|
574827
|
+
const left = normalizeTargetForCompare(requested);
|
|
574828
|
+
const right = normalizeTargetForCompare(reported);
|
|
574829
|
+
if (!left || !right)
|
|
574830
|
+
return true;
|
|
574831
|
+
if (left === right)
|
|
574832
|
+
return true;
|
|
574833
|
+
return left.endsWith(`/${right}`) || right.endsWith(`/${left}`);
|
|
574834
|
+
}
|
|
574835
|
+
function normalizeTargetForCompare(value2) {
|
|
574836
|
+
return value2.trim().replace(/^["']|["']$/g, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/\/$/, "");
|
|
574837
|
+
}
|
|
574632
574838
|
function summarizeToolEvent(toolName, success, diagnoses, command) {
|
|
574633
574839
|
const status = success ? "success" : "failure";
|
|
574634
574840
|
const parts = [`${toolName} ${status}`];
|
|
@@ -574736,9 +574942,11 @@ function writeContract(contractPath) {
|
|
|
574736
574942
|
"",
|
|
574737
574943
|
"- `shell-brace-whitespace`: a shell command used brace expansion containing whitespace, which can split an intended path set into unrelated shell words.",
|
|
574738
574944
|
"- `successful-command-needs-post-state-audit`: the command exited zero but its shape is risky enough that filesystem state should be inspected.",
|
|
574739
|
-
"- `focus-supervisor-block`: the tool result or supervisor state shows
|
|
574945
|
+
"- `focus-supervisor-block`: the tool result or supervisor state shows an unsuccessful blocked next action.",
|
|
574946
|
+
"- `focus-supervisor-cached-evidence`: the focus supervisor short-circuited a call successfully by reusing current cached evidence.",
|
|
574740
574947
|
"- `background-task-id-missing`: task status lookup could not find the spawned task id.",
|
|
574741
574948
|
"- `raw-discovery-dominates-context`: context-window metrics show low signal/noise around raw discovery output.",
|
|
574949
|
+
"- `tool-result-binding-mismatch`: the outbound model transcript contains a tool result whose reported target does not match the assistant tool call it is attached to.",
|
|
574742
574950
|
""
|
|
574743
574951
|
].join("\n");
|
|
574744
574952
|
writeFileSync49(contractPath, body, "utf-8");
|
|
@@ -577523,7 +577731,7 @@ RECOVERY: cd to the directory containing '${file}', run a plain install with no
|
|
|
577523
577731
|
import { existsSync as _fsExistsSync, readFileSync as _fsReadFileSync, writeFileSync as _fsWriteFileSync, appendFileSync as _fsAppendFileSync, unlinkSync as _fsUnlinkSync, mkdirSync as _fsMkdirSync, statSync as _fsStatSync, readdirSync as _fsReaddirSync } from "node:fs";
|
|
577524
577732
|
import { execFile as _execFile, spawn as _spawn } from "node:child_process";
|
|
577525
577733
|
import { createHash as _createHash } from "node:crypto";
|
|
577526
|
-
import { join as _pathJoin, resolve as _pathResolve } from "node:path";
|
|
577734
|
+
import { join as _pathJoin, relative as _pathRelative, resolve as _pathResolve } from "node:path";
|
|
577527
577735
|
import { tmpdir as _osTmpdir } from "node:os";
|
|
577528
577736
|
import { homedir as _osHomedir } from "node:os";
|
|
577529
577737
|
import { z as z17 } from "zod";
|
|
@@ -578016,27 +578224,39 @@ function sanitizeHistoryThink(messages2) {
|
|
|
578016
578224
|
const sanitized = [];
|
|
578017
578225
|
for (let i2 = 0; i2 < stripped.length; i2++) {
|
|
578018
578226
|
const current = stripped[i2];
|
|
578019
|
-
|
|
578020
|
-
if (isOrphanDuplicateAssistantToolAnchor(current, next, referencedToolCallIds)) {
|
|
578227
|
+
if (isOrphanDuplicateAssistantToolAnchor(stripped, i2, referencedToolCallIds)) {
|
|
578021
578228
|
continue;
|
|
578022
578229
|
}
|
|
578023
578230
|
sanitized.push(current);
|
|
578024
578231
|
}
|
|
578025
578232
|
return sanitized;
|
|
578026
578233
|
}
|
|
578027
|
-
function isOrphanDuplicateAssistantToolAnchor(
|
|
578028
|
-
|
|
578234
|
+
function isOrphanDuplicateAssistantToolAnchor(messages2, index, referencedToolCallIds) {
|
|
578235
|
+
const current = messages2[index];
|
|
578236
|
+
if (!current)
|
|
578029
578237
|
return false;
|
|
578030
|
-
if (current.role !== "assistant"
|
|
578238
|
+
if (current.role !== "assistant")
|
|
578031
578239
|
return false;
|
|
578032
|
-
if (!Array.isArray(current.tool_calls) ||
|
|
578240
|
+
if (!Array.isArray(current.tool_calls) || current.tool_calls.length === 0) {
|
|
578033
578241
|
return false;
|
|
578034
578242
|
}
|
|
578035
|
-
if (current.
|
|
578243
|
+
if (assistantVisibleText(current).length > 0)
|
|
578036
578244
|
return false;
|
|
578245
|
+
let next;
|
|
578246
|
+
for (let i2 = index + 1; i2 < Math.min(messages2.length, index + 8); i2++) {
|
|
578247
|
+
const candidate = messages2[i2];
|
|
578248
|
+
if (candidate.role === "system")
|
|
578249
|
+
continue;
|
|
578250
|
+
if (candidate.role !== "assistant")
|
|
578251
|
+
return false;
|
|
578252
|
+
next = candidate;
|
|
578253
|
+
break;
|
|
578037
578254
|
}
|
|
578038
|
-
if (
|
|
578255
|
+
if (!next)
|
|
578039
578256
|
return false;
|
|
578257
|
+
if (!Array.isArray(next.tool_calls) || next.tool_calls.length === 0) {
|
|
578258
|
+
return false;
|
|
578259
|
+
}
|
|
578040
578260
|
if (toolCallsFingerprint(current.tool_calls) !== toolCallsFingerprint(next.tool_calls)) {
|
|
578041
578261
|
return false;
|
|
578042
578262
|
}
|
|
@@ -578186,6 +578406,7 @@ var init_agenticRunner = __esm({
|
|
|
578186
578406
|
init_lesson_bank();
|
|
578187
578407
|
init_intervention_replay();
|
|
578188
578408
|
init_world_state_regenerator();
|
|
578409
|
+
init_world_state_disk_scan();
|
|
578189
578410
|
init_backward_pass_runner();
|
|
578190
578411
|
init_world_state_plan_reconciler();
|
|
578191
578412
|
init_process_async2();
|
|
@@ -581019,7 +581240,7 @@ ${result.error ?? ""}`;
|
|
|
581019
581240
|
if (result.success !== true)
|
|
581020
581241
|
return false;
|
|
581021
581242
|
if (toolName === "file_read") {
|
|
581022
|
-
return targetPaths.length > 0 && targetPaths.some((path12) => this._evidenceLedger.hasFresh(path12));
|
|
581243
|
+
return targetPaths.length > 0 && targetPaths.some((path12) => this._evidenceLedger.hasFresh(this._normalizeEvidencePath(path12)));
|
|
581023
581244
|
}
|
|
581024
581245
|
return toolName === "list_directory" || toolName === "find_files" || toolName === "grep_search";
|
|
581025
581246
|
}
|
|
@@ -583128,6 +583349,133 @@ ${latest.output || ""}`.trim();
|
|
|
583128
583349
|
return null;
|
|
583129
583350
|
}
|
|
583130
583351
|
}
|
|
583352
|
+
/**
|
|
583353
|
+
* Render a fresh, bounded workspace tree from disk for the active context
|
|
583354
|
+
* frame, and persist the fuller capped tree under .omnius/world-state/tree.
|
|
583355
|
+
* This is deliberately independent of tool history: it answers "what exists
|
|
583356
|
+
* where right now?" without forcing the model to list_directory for basic
|
|
583357
|
+
* orientation.
|
|
583358
|
+
*/
|
|
583359
|
+
_renderWorkspaceTreeBlock(turn) {
|
|
583360
|
+
const rawEnabled = String(process.env["OMNIUS_CONTEXT_WORKSPACE_TREE"] ?? "1").trim().toLowerCase();
|
|
583361
|
+
if (rawEnabled === "0" || rawEnabled === "false" || rawEnabled === "off") {
|
|
583362
|
+
return null;
|
|
583363
|
+
}
|
|
583364
|
+
const intEnv = (name10, fallback, min, max) => {
|
|
583365
|
+
const parsed = Number.parseInt(process.env[name10] ?? "", 10);
|
|
583366
|
+
return Number.isFinite(parsed) ? Math.max(min, Math.min(max, parsed)) : fallback;
|
|
583367
|
+
};
|
|
583368
|
+
const root = this.authoritativeWorkingDirectory();
|
|
583369
|
+
const maxFiles = intEnv("OMNIUS_CONTEXT_TREE_MAX_FILES", 1e3, 20, 2e3);
|
|
583370
|
+
const maxDirs = intEnv("OMNIUS_CONTEXT_TREE_MAX_DIRS", 1500, 20, 5e3);
|
|
583371
|
+
const contextLines = intEnv("OMNIUS_CONTEXT_TREE_LINES", 90, 20, 400);
|
|
583372
|
+
const artifactLines = intEnv("OMNIUS_CONTEXT_TREE_ARTIFACT_LINES", 1800, 100, 4e3);
|
|
583373
|
+
try {
|
|
583374
|
+
const scan = scanWorkspace({ root, maxFiles, maxDirs });
|
|
583375
|
+
const compactTree = renderWorkspaceTree(scan, { maxLines: contextLines });
|
|
583376
|
+
const fullTree = renderWorkspaceTree(scan, { maxLines: artifactLines });
|
|
583377
|
+
const totalBytes = scan.files.reduce((sum, file) => sum + file.bytes, 0);
|
|
583378
|
+
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
583379
|
+
const focusSnapshot = this._focusSupervisor?.snapshot();
|
|
583380
|
+
const recentActions = this._adversaryToolOutcomes.slice(-12).map((item) => ({
|
|
583381
|
+
turn: item.turn,
|
|
583382
|
+
tool: item.tool,
|
|
583383
|
+
success: item.succeeded,
|
|
583384
|
+
path: item.path,
|
|
583385
|
+
stateVersion: item.stateVersion,
|
|
583386
|
+
preview: item.preview.slice(0, 240)
|
|
583387
|
+
}));
|
|
583388
|
+
const recentActionLines = recentActions.slice(-6).map((item) => {
|
|
583389
|
+
const path12 = item.path ? ` path=${item.path}` : "";
|
|
583390
|
+
return `- turn=${item.turn} ${item.tool} ${item.success ? "ok" : "err"}${path12}: ${item.preview.replace(/\s+/g, " ").slice(0, 160)}`;
|
|
583391
|
+
});
|
|
583392
|
+
const treeDir = _pathJoin(this.omniusStateDir(), "world-state", "tree");
|
|
583393
|
+
const turnName = `turn-${String(turn).padStart(4, "0")}`;
|
|
583394
|
+
const latestTextPath = _pathJoin(treeDir, "latest.txt");
|
|
583395
|
+
const latestJsonPath = _pathJoin(treeDir, "latest.json");
|
|
583396
|
+
const turnTextPath = _pathJoin(treeDir, `${turnName}.txt`);
|
|
583397
|
+
const turnJsonPath = _pathJoin(treeDir, `${turnName}.json`);
|
|
583398
|
+
let artifactDisplay = latestTextPath;
|
|
583399
|
+
try {
|
|
583400
|
+
_fsMkdirSync(treeDir, { recursive: true });
|
|
583401
|
+
const header = [
|
|
583402
|
+
`WORKSPACE TREE SNAPSHOT`,
|
|
583403
|
+
`generated_at=${generatedAt}`,
|
|
583404
|
+
`turn=${turn}`,
|
|
583405
|
+
`session=${this._sessionId ?? ""}`,
|
|
583406
|
+
`root=${root}`,
|
|
583407
|
+
`files=${scan.files.length}${scan.truncated ? "+" : ""}`,
|
|
583408
|
+
`dirs=${scan.dirs.length}`,
|
|
583409
|
+
`bytes=${totalBytes}`,
|
|
583410
|
+
focusSnapshot?.directive?.requiredNextAction ? `supervisor_required_next_action=${focusSnapshot.directive.requiredNextAction}` : `supervisor_required_next_action=none`,
|
|
583411
|
+
recentActionLines.length ? `recent_actions=${recentActions.length}` : `recent_actions=0`,
|
|
583412
|
+
recentActionLines.length ? recentActionLines.join("\n") : "",
|
|
583413
|
+
""
|
|
583414
|
+
].join("\n");
|
|
583415
|
+
const text2 = `${header}${fullTree.text}
|
|
583416
|
+
`;
|
|
583417
|
+
const payload = {
|
|
583418
|
+
generatedAt,
|
|
583419
|
+
turn,
|
|
583420
|
+
sessionId: this._sessionId,
|
|
583421
|
+
root,
|
|
583422
|
+
supervisor: focusSnapshot ? {
|
|
583423
|
+
state: focusSnapshot.state,
|
|
583424
|
+
lastDecision: focusSnapshot.lastDecision,
|
|
583425
|
+
lastReason: focusSnapshot.lastReason,
|
|
583426
|
+
requiredNextAction: focusSnapshot.directive?.requiredNextAction ?? null,
|
|
583427
|
+
directiveReason: focusSnapshot.directive?.reason ?? null
|
|
583428
|
+
} : null,
|
|
583429
|
+
recentActions,
|
|
583430
|
+
stats: {
|
|
583431
|
+
files: scan.files.length,
|
|
583432
|
+
dirs: scan.dirs.length,
|
|
583433
|
+
totalBytes,
|
|
583434
|
+
truncated: scan.truncated || fullTree.truncated,
|
|
583435
|
+
dirsVisited: scan.dirsVisited
|
|
583436
|
+
},
|
|
583437
|
+
files: scan.files.map((file) => ({
|
|
583438
|
+
path: file.rel,
|
|
583439
|
+
bytes: file.bytes,
|
|
583440
|
+
mtimeMs: file.mtimeMs
|
|
583441
|
+
})),
|
|
583442
|
+
dirs: scan.dirs.map((dir) => ({
|
|
583443
|
+
path: dir.rel,
|
|
583444
|
+
mtimeMs: dir.mtimeMs
|
|
583445
|
+
}))
|
|
583446
|
+
};
|
|
583447
|
+
_fsWriteFileSync(latestTextPath, text2, "utf8");
|
|
583448
|
+
_fsWriteFileSync(turnTextPath, text2, "utf8");
|
|
583449
|
+
_fsWriteFileSync(latestJsonPath, JSON.stringify(payload, null, 2), "utf8");
|
|
583450
|
+
_fsWriteFileSync(turnJsonPath, JSON.stringify(payload, null, 2), "utf8");
|
|
583451
|
+
const rel = _pathRelative(root, latestTextPath).replace(/\\/g, "/");
|
|
583452
|
+
if (rel && !rel.startsWith(".."))
|
|
583453
|
+
artifactDisplay = rel;
|
|
583454
|
+
} catch {
|
|
583455
|
+
artifactDisplay = "(workspace tree artifact write failed; inline digest still current)";
|
|
583456
|
+
}
|
|
583457
|
+
return [
|
|
583458
|
+
"[WORKSPACE TREE — fresh per-turn disk crawl]",
|
|
583459
|
+
`generated_at=${generatedAt}`,
|
|
583460
|
+
`root=${root}`,
|
|
583461
|
+
`files=${scan.files.length}${scan.truncated ? "+" : ""} dirs=${scan.dirs.length} total_bytes=${totalBytes}`,
|
|
583462
|
+
`artifact=${artifactDisplay}`,
|
|
583463
|
+
focusSnapshot?.directive?.requiredNextAction ? `supervisor_required_next_action=${focusSnapshot.directive.requiredNextAction}` : `supervisor_required_next_action=none`,
|
|
583464
|
+
recentActionLines.length ? `recent_actions:
|
|
583465
|
+
${recentActionLines.join("\n")}` : "recent_actions=none",
|
|
583466
|
+
"Use this tree for path orientation. It includes empty directories; it does not include file contents.",
|
|
583467
|
+
compactTree.truncated || scan.truncated ? "Inline tree is truncated; read the artifact path above for the fuller capped tree before broad rediscovery." : "Inline tree is complete within the configured scan cap.",
|
|
583468
|
+
compactTree.text
|
|
583469
|
+
].join("\n");
|
|
583470
|
+
} catch (error) {
|
|
583471
|
+
return [
|
|
583472
|
+
"[WORKSPACE TREE — fresh per-turn disk crawl]",
|
|
583473
|
+
`root=${root}`,
|
|
583474
|
+
`scan_failed=${error instanceof Error ? error.message : String(error)}`,
|
|
583475
|
+
"Do not assume the tree is current; use list_directory/find_files if path orientation is required."
|
|
583476
|
+
].join("\n");
|
|
583477
|
+
}
|
|
583478
|
+
}
|
|
583131
583479
|
/**
|
|
583132
583480
|
* REG-2: Render a compact "files known to me" block from `_worldFacts`.
|
|
583133
583481
|
* Goal: tell the model what it has already touched this run so it stops
|
|
@@ -583667,6 +584015,7 @@ ${chunk.content}`, {
|
|
|
583667
584015
|
this._renderRuntimeRootBlock(),
|
|
583668
584016
|
this._taskState.goal ? `Active task: (see user message above — the goal block defers to the user message as the authoritative source)` : null
|
|
583669
584017
|
].filter(Boolean).join("\n\n");
|
|
584018
|
+
const workspaceTreeBlock = this._renderWorkspaceTreeBlock(turn);
|
|
583670
584019
|
const filesystemBlock = this._renderFilesystemStateBlock(turn);
|
|
583671
584020
|
const artifactContractBlock = this._contractRegistry.format(15);
|
|
583672
584021
|
const todoBlock = this._renderTodoStateBlock(turn);
|
|
@@ -583711,6 +584060,13 @@ ${this._lastPprMemoryLines.slice(0, 5).join("\n")}` : null;
|
|
|
583711
584060
|
createdTurn: turn,
|
|
583712
584061
|
ttlTurns: 1
|
|
583713
584062
|
}),
|
|
584063
|
+
signalFromBlock("known_files", "turn.workspace-tree", workspaceTreeBlock, {
|
|
584064
|
+
id: "workspace-tree",
|
|
584065
|
+
dedupeKey: "turn.workspace-tree",
|
|
584066
|
+
priority: 84,
|
|
584067
|
+
createdTurn: turn,
|
|
584068
|
+
ttlTurns: 1
|
|
584069
|
+
}),
|
|
583714
584070
|
signalFromBlock("known_files", "turn.artifact-contracts", artifactContractBlock, {
|
|
583715
584071
|
id: "artifact-contracts",
|
|
583716
584072
|
dedupeKey: "turn.artifact-contracts",
|
|
@@ -583799,7 +584155,7 @@ ${this._lastPprMemoryLines.slice(0, 5).join("\n")}` : null;
|
|
|
583799
584155
|
// Raised from 10k to fit the durable read-evidence content (known_files)
|
|
583800
584156
|
// that replaces the re-read loop; the per-kind budget below caps it.
|
|
583801
584157
|
maxChars: 13e3,
|
|
583802
|
-
kindCharBudget: { known_files:
|
|
584158
|
+
kindCharBudget: { known_files: 8500 },
|
|
583803
584159
|
includeDiagnostics: process.env["OMNIUS_CONTEXT_FABRIC_DIAGNOSTICS"] === "1"
|
|
583804
584160
|
});
|
|
583805
584161
|
this._lastContextFrameDiagnostics = frame.diagnostics;
|
|
@@ -584003,10 +584359,12 @@ ${blob}
|
|
|
584003
584359
|
if (p2 && content.length >= 100) {
|
|
584004
584360
|
try {
|
|
584005
584361
|
this._evidenceLedger.recordRead({
|
|
584006
|
-
path: p2,
|
|
584362
|
+
path: this._normalizeEvidencePath(p2),
|
|
584007
584363
|
content,
|
|
584364
|
+
contentHash: this._extractFileReadSha256(content) ?? void 0,
|
|
584008
584365
|
range: { start: 0, end: Number.POSITIVE_INFINITY },
|
|
584009
584366
|
fileVersion: this._worldFacts.files.get(p2)?.writeCount ?? 0,
|
|
584367
|
+
mtimeMs: this._statMtimeMsForToolPath(p2),
|
|
584010
584368
|
turn: this._taskState?.toolCallCount ?? 0
|
|
584011
584369
|
});
|
|
584012
584370
|
} catch {
|
|
@@ -587905,6 +588263,18 @@ ${memoryLines.join("\n")}`
|
|
|
587905
588263
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
587906
588264
|
});
|
|
587907
588265
|
}
|
|
588266
|
+
for (const tc of msg.toolCalls) {
|
|
588267
|
+
const patched = this._attachFreshExpectedHashesToEditArgs(tc.name, tc.arguments ?? {});
|
|
588268
|
+
if (patched.patchedCount > 0) {
|
|
588269
|
+
tc.arguments = patched.args;
|
|
588270
|
+
this.emit({
|
|
588271
|
+
type: "status",
|
|
588272
|
+
content: `Edit freshness: attached expected_hash to ${patched.patchedCount} ${tc.name} edit target${patched.patchedCount === 1 ? "" : "s"} from fresh file_read evidence`,
|
|
588273
|
+
turn,
|
|
588274
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
588275
|
+
});
|
|
588276
|
+
}
|
|
588277
|
+
}
|
|
587908
588278
|
messages2.push({
|
|
587909
588279
|
role: "assistant",
|
|
587910
588280
|
content: msg.content || null,
|
|
@@ -588644,7 +589014,8 @@ Read the current file if needed, make a different concrete edit, or move to veri
|
|
|
588644
589014
|
const readArgs = tc.arguments;
|
|
588645
589015
|
const readPath2 = String(readArgs?.["path"] ?? readArgs?.["file"] ?? "");
|
|
588646
589016
|
if (readPath2) {
|
|
588647
|
-
const
|
|
589017
|
+
const evidencePath = this._normalizeEvidencePath(readPath2);
|
|
589018
|
+
const wasFresh = evidencePath && this._evidenceLedger.validateFreshness(evidencePath, this._absoluteToolPath(readPath2));
|
|
588648
589019
|
if (!wasFresh) {
|
|
588649
589020
|
recentToolResults.delete(toolFingerprint);
|
|
588650
589021
|
dedupHitCount.delete(toolFingerprint);
|
|
@@ -588774,13 +589145,13 @@ ${cachedResult}`,
|
|
|
588774
589145
|
error: this.unknownToolError(tc.name)
|
|
588775
589146
|
};
|
|
588776
589147
|
} else {
|
|
588777
|
-
let validationError =
|
|
588778
|
-
if (tool.inputSchema) {
|
|
589148
|
+
let validationError = this._validateFreshExpectedHashesForEdit(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
|
|
589149
|
+
if (!validationError && tool.inputSchema) {
|
|
588779
589150
|
const parseResult = tool.inputSchema.safeParse(tc.arguments);
|
|
588780
589151
|
if (!parseResult.success) {
|
|
588781
589152
|
validationError = parseResult.error.issues.map((iss) => `${iss.path.join(".")}: ${iss.message}`).join("; ");
|
|
588782
589153
|
}
|
|
588783
|
-
} else if (tool.parameters && typeof tool.parameters === "object") {
|
|
589154
|
+
} else if (!validationError && tool.parameters && typeof tool.parameters === "object") {
|
|
588784
589155
|
const required = tool.parameters.required;
|
|
588785
589156
|
if (Array.isArray(required)) {
|
|
588786
589157
|
const missing = required.filter((field) => tc.arguments[field] === void 0 || tc.arguments[field] === null);
|
|
@@ -589021,7 +589392,7 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
589021
589392
|
lastWriteTurn: turn,
|
|
589022
589393
|
writeCount: nextWriteCount
|
|
589023
589394
|
});
|
|
589024
|
-
this._evidenceLedger.markMutated(p2, nextWriteCount, turn);
|
|
589395
|
+
this._evidenceLedger.markMutated(this._normalizeEvidencePath(p2), nextWriteCount, turn);
|
|
589025
589396
|
}
|
|
589026
589397
|
if (paths.length > 0) {
|
|
589027
589398
|
this._writesSinceLastTodoWrite += paths.length;
|
|
@@ -589065,11 +589436,12 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
589065
589436
|
const start3 = rOffset === void 0 && rLimit === void 0 ? 0 : Math.max(1, rOffset ?? 1);
|
|
589066
589437
|
const end = rOffset === void 0 && rLimit === void 0 ? Number.POSITIVE_INFINITY : rLimit !== void 0 ? Math.max(1, rOffset ?? 1) + Math.max(0, rLimit) - 1 : Number.POSITIVE_INFINITY;
|
|
589067
589438
|
this._evidenceLedger.recordRead({
|
|
589068
|
-
path: p2,
|
|
589439
|
+
path: this._normalizeEvidencePath(p2),
|
|
589069
589440
|
content: result.output,
|
|
589441
|
+
contentHash: typeof result.beforeHash === "string" ? result.beforeHash : void 0,
|
|
589070
589442
|
range: { start: start3, end },
|
|
589071
589443
|
fileVersion: this._worldFacts.files.get(p2)?.writeCount ?? 0,
|
|
589072
|
-
mtimeMs:
|
|
589444
|
+
mtimeMs: this._statMtimeMsForToolPath(p2),
|
|
589073
589445
|
turn
|
|
589074
589446
|
});
|
|
589075
589447
|
}
|
|
@@ -590290,6 +590662,7 @@ Evidence: ${evidencePreview}`.slice(0, 500);
|
|
|
590290
590662
|
focusSupervisor: focusAfterToolResult,
|
|
590291
590663
|
focusDecision: !focusDecision || focusDecision.kind === "pass" ? void 0 : {
|
|
590292
590664
|
kind: focusDecision.kind,
|
|
590665
|
+
success: focusDecision.kind === "block_tool_call" ? focusDecision.success : void 0,
|
|
590293
590666
|
state: focusDecision.directive.state,
|
|
590294
590667
|
reason: focusDecision.directive.reason,
|
|
590295
590668
|
requiredNextAction: focusDecision.directive.requiredNextAction
|
|
@@ -590540,10 +590913,12 @@ Then use file_read on individual FILES inside it.`);
|
|
|
590540
590913
|
const rawToolCalls = msg.toolCalls;
|
|
590541
590914
|
if (this.options.streamEnabled && this._streamingExecutor.hasTools) {
|
|
590542
590915
|
const streamFpInFlight = /* @__PURE__ */ new Map();
|
|
590543
|
-
this._streamingExecutor.setExecutor(async (name10, args) => {
|
|
590544
|
-
|
|
590916
|
+
this._streamingExecutor.setExecutor(async (id2, name10, args) => {
|
|
590917
|
+
const argsFingerprint = this._buildToolFingerprint(name10, args);
|
|
590918
|
+
const exactArgMatches = rawToolCalls.filter((tc) => tc.name === name10 && this._buildToolFingerprint(tc.name, tc.arguments ?? {}) === argsFingerprint);
|
|
590919
|
+
let matchTc = rawToolCalls.find((tc) => tc.id === id2) ?? (exactArgMatches.length === 1 ? exactArgMatches[0] : void 0);
|
|
590545
590920
|
if (!matchTc) {
|
|
590546
|
-
const synthId = globalThis.crypto?.randomUUID?.() || `call_${Date.now()}`;
|
|
590921
|
+
const synthId = id2 || globalThis.crypto?.randomUUID?.() || `call_${Date.now()}`;
|
|
590547
590922
|
matchTc = { id: synthId, name: name10, arguments: args };
|
|
590548
590923
|
messages2.push({
|
|
590549
590924
|
role: "assistant",
|
|
@@ -592764,13 +593139,14 @@ ${marker}` : marker);
|
|
|
592764
593139
|
const displayOutput = this.unwrapToolOutputForDisplay(output);
|
|
592765
593140
|
if (toolName === "file_read") {
|
|
592766
593141
|
const path13 = this.extractPrimaryToolPath(args);
|
|
592767
|
-
|
|
593142
|
+
const evidencePath = path13 ? this._normalizeEvidencePath(path13) : "";
|
|
593143
|
+
if (!evidencePath || !this._evidenceLedger.hasFresh(evidencePath))
|
|
592768
593144
|
return output;
|
|
592769
|
-
const entry = this._evidenceLedger.get(
|
|
593145
|
+
const entry = this._evidenceLedger.get(evidencePath);
|
|
592770
593146
|
return this.wrapToolOutputForModel(toolName, [
|
|
592771
593147
|
"[DISCOVERY COMPACTED - file_read evidence captured]",
|
|
592772
593148
|
`path=${path13}`,
|
|
592773
|
-
`captured=${this.countTextLines(displayOutput)} lines, ${displayOutput.length} chars${entry ? `, fidelity=${entry.fidelity}` : ""}`,
|
|
593149
|
+
`captured=${this.countTextLines(displayOutput)} lines, ${displayOutput.length} chars${entry ? `, fidelity=${entry.fidelity}${entry.contentHash ? `, sha256=${entry.contentHash}` : ""}` : ""}`,
|
|
592774
593150
|
'active_context="Evidence already gathered this run"',
|
|
592775
593151
|
"Use the active evidence frame. Re-read only if that frame marks this file STALE or you need a distinct range."
|
|
592776
593152
|
].join("\n"));
|
|
@@ -592916,6 +593292,175 @@ ${marker}` : marker);
|
|
|
592916
593292
|
return trimmed.replace(/\\/g, "/").replace(/^\.\/+/, "");
|
|
592917
593293
|
}
|
|
592918
593294
|
}
|
|
593295
|
+
_absoluteToolPath(path12) {
|
|
593296
|
+
return _pathResolve(this.authoritativeWorkingDirectory(), path12.trim() || ".");
|
|
593297
|
+
}
|
|
593298
|
+
_normalizeEvidencePath(path12) {
|
|
593299
|
+
const trimmed = path12.trim();
|
|
593300
|
+
if (!trimmed)
|
|
593301
|
+
return "";
|
|
593302
|
+
try {
|
|
593303
|
+
const root = this.authoritativeWorkingDirectory();
|
|
593304
|
+
const abs = _pathResolve(root, trimmed);
|
|
593305
|
+
const rel = _pathRelative(root, abs).replace(/\\/g, "/");
|
|
593306
|
+
if (rel && !rel.startsWith("..") && rel !== ".")
|
|
593307
|
+
return rel;
|
|
593308
|
+
if (rel === "")
|
|
593309
|
+
return ".";
|
|
593310
|
+
return abs.replace(/\\/g, "/");
|
|
593311
|
+
} catch {
|
|
593312
|
+
return trimmed.replace(/\\/g, "/").replace(/^\.\/+/, "");
|
|
593313
|
+
}
|
|
593314
|
+
}
|
|
593315
|
+
_statMtimeMsForToolPath(path12) {
|
|
593316
|
+
try {
|
|
593317
|
+
const st = _fsStatSync(this._absoluteToolPath(path12), {
|
|
593318
|
+
throwIfNoEntry: false
|
|
593319
|
+
});
|
|
593320
|
+
return st?.mtimeMs;
|
|
593321
|
+
} catch {
|
|
593322
|
+
return void 0;
|
|
593323
|
+
}
|
|
593324
|
+
}
|
|
593325
|
+
_normalizeExpectedHashValue(value2) {
|
|
593326
|
+
if (typeof value2 !== "string")
|
|
593327
|
+
return null;
|
|
593328
|
+
const raw = value2.trim();
|
|
593329
|
+
if (!raw)
|
|
593330
|
+
return null;
|
|
593331
|
+
const stripped = raw.replace(/^sha256[:=]/i, "").toLowerCase();
|
|
593332
|
+
return /^[a-f0-9]{64}$/.test(stripped) ? stripped : null;
|
|
593333
|
+
}
|
|
593334
|
+
_extractFileReadSha256(text2) {
|
|
593335
|
+
const match = text2.match(/\bsha256=([a-f0-9]{64})\b/i);
|
|
593336
|
+
return match ? match[1].toLowerCase() : null;
|
|
593337
|
+
}
|
|
593338
|
+
_rawExpectedHashValue(rec) {
|
|
593339
|
+
return rec["expected_hash"] ?? rec["expectedHash"] ?? rec["before_hash"] ?? rec["beforeHash"];
|
|
593340
|
+
}
|
|
593341
|
+
_freshReadHashForEditPath(path12) {
|
|
593342
|
+
const key = this._normalizeEvidencePath(path12);
|
|
593343
|
+
if (!key)
|
|
593344
|
+
return null;
|
|
593345
|
+
const entry = this._evidenceLedger.get(key);
|
|
593346
|
+
if (!entry || entry.stale || !entry.contentHash)
|
|
593347
|
+
return null;
|
|
593348
|
+
const statPath = this._absoluteToolPath(path12);
|
|
593349
|
+
if (!this._evidenceLedger.validateFreshness(key, statPath))
|
|
593350
|
+
return null;
|
|
593351
|
+
const fresh = this._evidenceLedger.get(key);
|
|
593352
|
+
if (!fresh || fresh.stale || !fresh.contentHash)
|
|
593353
|
+
return null;
|
|
593354
|
+
return {
|
|
593355
|
+
key,
|
|
593356
|
+
hash: fresh.contentHash,
|
|
593357
|
+
lastReadTurn: fresh.lastReadTurn
|
|
593358
|
+
};
|
|
593359
|
+
}
|
|
593360
|
+
_attachFreshExpectedHashesToEditArgs(toolName, args) {
|
|
593361
|
+
if (process.env["OMNIUS_ALLOW_UNVERIFIED_OLD_STRING_EDIT"] === "1") {
|
|
593362
|
+
return { args, patchedCount: 0 };
|
|
593363
|
+
}
|
|
593364
|
+
if (toolName === "file_edit") {
|
|
593365
|
+
if (this._normalizeExpectedHashValue(this._rawExpectedHashValue(args))) {
|
|
593366
|
+
return { args, patchedCount: 0 };
|
|
593367
|
+
}
|
|
593368
|
+
const path12 = this.extractPrimaryToolPath(args);
|
|
593369
|
+
const fresh = path12 ? this._freshReadHashForEditPath(path12) : null;
|
|
593370
|
+
if (!fresh)
|
|
593371
|
+
return { args, patchedCount: 0 };
|
|
593372
|
+
return { args: { ...args, expected_hash: fresh.hash }, patchedCount: 1 };
|
|
593373
|
+
}
|
|
593374
|
+
if (toolName !== "batch_edit" || !Array.isArray(args["edits"])) {
|
|
593375
|
+
return { args, patchedCount: 0 };
|
|
593376
|
+
}
|
|
593377
|
+
let patchedCount = 0;
|
|
593378
|
+
const edits = args["edits"].map((edit) => {
|
|
593379
|
+
if (!edit || typeof edit !== "object" || Array.isArray(edit))
|
|
593380
|
+
return edit;
|
|
593381
|
+
const rec = edit;
|
|
593382
|
+
if (this._normalizeExpectedHashValue(this._rawExpectedHashValue(rec))) {
|
|
593383
|
+
return rec;
|
|
593384
|
+
}
|
|
593385
|
+
const path12 = typeof rec["path"] === "string" ? rec["path"] : typeof rec["file"] === "string" ? rec["file"] : "";
|
|
593386
|
+
const fresh = path12 ? this._freshReadHashForEditPath(path12) : null;
|
|
593387
|
+
if (!fresh)
|
|
593388
|
+
return rec;
|
|
593389
|
+
patchedCount++;
|
|
593390
|
+
return { ...rec, expected_hash: fresh.hash };
|
|
593391
|
+
});
|
|
593392
|
+
return patchedCount > 0 ? { args: { ...args, edits }, patchedCount } : { args, patchedCount: 0 };
|
|
593393
|
+
}
|
|
593394
|
+
_validateFreshExpectedHashesForEdit(toolName, args) {
|
|
593395
|
+
if (process.env["OMNIUS_ALLOW_UNVERIFIED_OLD_STRING_EDIT"] === "1") {
|
|
593396
|
+
return null;
|
|
593397
|
+
}
|
|
593398
|
+
const targets = [];
|
|
593399
|
+
if (toolName === "file_edit") {
|
|
593400
|
+
const path12 = this.extractPrimaryToolPath(args);
|
|
593401
|
+
if (path12) {
|
|
593402
|
+
targets.push({
|
|
593403
|
+
label: path12,
|
|
593404
|
+
path: path12,
|
|
593405
|
+
expectedHash: this._normalizeExpectedHashValue(this._rawExpectedHashValue(args)),
|
|
593406
|
+
rawExpectedHash: this._rawExpectedHashValue(args)
|
|
593407
|
+
});
|
|
593408
|
+
}
|
|
593409
|
+
} else if (toolName === "batch_edit" && Array.isArray(args["edits"])) {
|
|
593410
|
+
args["edits"].forEach((edit, index) => {
|
|
593411
|
+
if (!edit || typeof edit !== "object" || Array.isArray(edit))
|
|
593412
|
+
return;
|
|
593413
|
+
const rec = edit;
|
|
593414
|
+
const path12 = typeof rec["path"] === "string" ? rec["path"] : typeof rec["file"] === "string" ? rec["file"] : "";
|
|
593415
|
+
if (!path12)
|
|
593416
|
+
return;
|
|
593417
|
+
targets.push({
|
|
593418
|
+
label: `edit #${index + 1} ${path12}`,
|
|
593419
|
+
path: path12,
|
|
593420
|
+
expectedHash: this._normalizeExpectedHashValue(this._rawExpectedHashValue(rec)),
|
|
593421
|
+
rawExpectedHash: this._rawExpectedHashValue(rec)
|
|
593422
|
+
});
|
|
593423
|
+
});
|
|
593424
|
+
} else {
|
|
593425
|
+
return null;
|
|
593426
|
+
}
|
|
593427
|
+
if (targets.length === 0)
|
|
593428
|
+
return null;
|
|
593429
|
+
const problems = [];
|
|
593430
|
+
for (const target of targets) {
|
|
593431
|
+
const fresh = this._freshReadHashForEditPath(target.path);
|
|
593432
|
+
if (target.rawExpectedHash !== void 0 && !target.expectedHash) {
|
|
593433
|
+
problems.push(`${target.label}: expected_hash is present but is not a valid 64-character SHA-256`);
|
|
593434
|
+
continue;
|
|
593435
|
+
}
|
|
593436
|
+
if (!fresh && target.expectedHash) {
|
|
593437
|
+
continue;
|
|
593438
|
+
}
|
|
593439
|
+
if (!fresh) {
|
|
593440
|
+
problems.push(`${target.label}: missing expected_hash and no fresh file_read hash is available for this file in the current run`);
|
|
593441
|
+
continue;
|
|
593442
|
+
}
|
|
593443
|
+
if (!target.expectedHash) {
|
|
593444
|
+
problems.push(`${target.label}: missing expected_hash; use sha256=${fresh.hash} from the fresh file_read evidence`);
|
|
593445
|
+
continue;
|
|
593446
|
+
}
|
|
593447
|
+
if (target.expectedHash !== fresh.hash) {
|
|
593448
|
+
problems.push(`${target.label}: expected_hash=${target.expectedHash} does not match fresh file_read sha256=${fresh.hash}`);
|
|
593449
|
+
}
|
|
593450
|
+
}
|
|
593451
|
+
if (problems.length === 0)
|
|
593452
|
+
return null;
|
|
593453
|
+
return [
|
|
593454
|
+
"[EDIT FRESHNESS CONTRACT]",
|
|
593455
|
+
"Exact replacement edits must be built from verified current file content, not remembered text.",
|
|
593456
|
+
"Before file_edit or batch_edit can run, each target must carry expected_hash from file_read. If the runner has fresh read evidence, it will attach that hash automatically; otherwise the edit tool verifies the provided hash against disk before mutating.",
|
|
593457
|
+
"For multiple edits to the same file, use one batch_edit against the same expected_hash so all replacements validate atomically before the file changes.",
|
|
593458
|
+
"",
|
|
593459
|
+
...problems.map((problem) => `- ${problem}`),
|
|
593460
|
+
"",
|
|
593461
|
+
"Next action: file_read the target file or range, then retry the edit with old_string copied exactly from that read and expected_hash set to the read's sha256."
|
|
593462
|
+
].join("\n");
|
|
593463
|
+
}
|
|
592919
593464
|
staleEditFamilyKey(toolName, pathKey, errorKind, targetHash, latestFileHash) {
|
|
592920
593465
|
return [
|
|
592921
593466
|
toolName,
|
|
@@ -596763,14 +597308,17 @@ ${description}`
|
|
|
596763
597308
|
}
|
|
596764
597309
|
}
|
|
596765
597310
|
const acc = toolCallAccumulators.get(idx);
|
|
597311
|
+
if (chunk.toolCallId && chunk.toolCallId !== acc.id) {
|
|
597312
|
+
const previousId = acc.id;
|
|
597313
|
+
acc.id = chunk.toolCallId;
|
|
597314
|
+
this._streamingExecutor.rename(previousId, acc.id);
|
|
597315
|
+
}
|
|
596766
597316
|
if (chunk.toolCallName) {
|
|
596767
597317
|
acc.name = chunk.toolCallName;
|
|
596768
597318
|
if (!this._streamingExecutor.getStates().has(acc.id) && acc.name) {
|
|
596769
597319
|
this._streamingExecutor.queue(acc.id, acc.name);
|
|
596770
597320
|
}
|
|
596771
597321
|
}
|
|
596772
|
-
if (chunk.toolCallId)
|
|
596773
|
-
acc.id = chunk.toolCallId;
|
|
596774
597322
|
if (chunk.toolCallArgs) {
|
|
596775
597323
|
acc.args += chunk.toolCallArgs;
|
|
596776
597324
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.459",
|
|
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.459",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
|
@@ -4138,9 +4138,9 @@
|
|
|
4138
4138
|
}
|
|
4139
4139
|
},
|
|
4140
4140
|
"node_modules/iconv-lite": {
|
|
4141
|
-
"version": "0.7.
|
|
4142
|
-
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.
|
|
4143
|
-
"integrity": "sha512-
|
|
4141
|
+
"version": "0.7.3",
|
|
4142
|
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
|
4143
|
+
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
|
|
4144
4144
|
"license": "MIT",
|
|
4145
4145
|
"dependencies": {
|
|
4146
4146
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
package/package.json
CHANGED