omnius 1.0.343 → 1.0.345

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 CHANGED
@@ -187,8 +187,8 @@ function printInfo(message2) {
187
187
  process.stdout.write(`${c.cyan("i")} ${message2}
188
188
  `);
189
189
  }
190
- function printKeyValue(key, value2, indent = 0) {
191
- const pad = " ".repeat(indent);
190
+ function printKeyValue(key, value2, indent2 = 0) {
191
+ const pad = " ".repeat(indent2);
192
192
  process.stdout.write(`${pad}${c.dim(key + ":")} ${value2}
193
193
  `);
194
194
  }
@@ -14652,12 +14652,12 @@ function chooseRetrievalWeights(input) {
14652
14652
  let vectorWeight = input.vectorWeight;
14653
14653
  let graphWeight = input.graphWeight;
14654
14654
  if (lexicalWeight === void 0 && vectorWeight === void 0 && graphWeight === void 0) {
14655
- const queryTerms = terms(input.query).size;
14656
- if (queryTerms <= 2) {
14655
+ const queryTerms2 = terms(input.query).size;
14656
+ if (queryTerms2 <= 2) {
14657
14657
  lexicalWeight = 0.55;
14658
14658
  vectorWeight = 0.3;
14659
14659
  graphWeight = 0.15;
14660
- } else if (queryTerms >= 6) {
14660
+ } else if (queryTerms2 >= 6) {
14661
14661
  lexicalWeight = 0.3;
14662
14662
  vectorWeight = 0.55;
14663
14663
  graphWeight = 0.15;
@@ -16993,9 +16993,9 @@ var init_episodeStore = __esm({
16993
16993
  if (query.query) {
16994
16994
  const queryLower = query.query.toLowerCase();
16995
16995
  const contentLower = ep.content.toLowerCase();
16996
- const queryTerms = queryLower.split(/\s+/).filter((t2) => t2.length > 2);
16997
- const matched = queryTerms.filter((t2) => contentLower.includes(t2)).length;
16998
- lex = queryTerms.length > 0 ? matched / queryTerms.length : 0;
16996
+ const queryTerms2 = queryLower.split(/\s+/).filter((t2) => t2.length > 2);
16997
+ const matched = queryTerms2.filter((t2) => contentLower.includes(t2)).length;
16998
+ lex = queryTerms2.length > 0 ? matched / queryTerms2.length : 0;
16999
16999
  }
17000
17000
  let emb = 0;
17001
17001
  if (qEmb && ep.embedding && ep.embedding.length === qEmb.length) {
@@ -23939,9 +23939,9 @@ import { resolve as resolve13, join as join23, basename as basename2 } from "nod
23939
23939
  import { existsSync as existsSync23 } from "node:fs";
23940
23940
  import { homedir as homedir7 } from "node:os";
23941
23941
  function termMatchScore(query, document2) {
23942
- const queryTerms = tokenize2(query);
23942
+ const queryTerms2 = tokenize2(query);
23943
23943
  const docTerms = tokenize2(document2);
23944
- if (queryTerms.length === 0 || docTerms.length === 0)
23944
+ if (queryTerms2.length === 0 || docTerms.length === 0)
23945
23945
  return 0;
23946
23946
  const docSet = new Set(docTerms);
23947
23947
  const docBigrams = /* @__PURE__ */ new Set();
@@ -23951,7 +23951,7 @@ function termMatchScore(query, document2) {
23951
23951
  let matchedTerms = 0;
23952
23952
  let matchedBigrams = 0;
23953
23953
  let totalWeight = 0;
23954
- for (const term of queryTerms) {
23954
+ for (const term of queryTerms2) {
23955
23955
  totalWeight += 1;
23956
23956
  if (docSet.has(term)) {
23957
23957
  matchedTerms += 1;
@@ -23959,8 +23959,8 @@ function termMatchScore(query, document2) {
23959
23959
  matchedTerms += 0.5;
23960
23960
  }
23961
23961
  }
23962
- for (let i2 = 0; i2 < queryTerms.length - 1; i2++) {
23963
- const bigram = `${queryTerms[i2]} ${queryTerms[i2 + 1]}`;
23962
+ for (let i2 = 0; i2 < queryTerms2.length - 1; i2++) {
23963
+ const bigram = `${queryTerms2[i2]} ${queryTerms2[i2 + 1]}`;
23964
23964
  totalWeight += 1;
23965
23965
  if (docBigrams.has(bigram)) {
23966
23966
  matchedBigrams += 1;
@@ -26395,7 +26395,7 @@ var init_codebase_map = __esm({
26395
26395
  if (depth > maxDepth)
26396
26396
  return "";
26397
26397
  const lines = [];
26398
- const indent = " ".repeat(depth);
26398
+ const indent2 = " ".repeat(depth);
26399
26399
  try {
26400
26400
  const entries = readdirSync10(dir, { withFileTypes: true }).filter((e2) => !e2.name.startsWith(".") || e2.name === ".github").sort((a2, b) => {
26401
26401
  if (a2.isDirectory() && !b.isDirectory())
@@ -26409,20 +26409,20 @@ var init_codebase_map = __esm({
26409
26409
  for (const d2 of dirs) {
26410
26410
  const subPath = join28(dir, d2.name);
26411
26411
  const fileCount = this.countFilesShallow(subPath);
26412
- lines.push(`${indent}${d2.name}/ (${fileCount} files)`);
26412
+ lines.push(`${indent2}${d2.name}/ (${fileCount} files)`);
26413
26413
  const subtree = this.buildTree(subPath, rootDir, depth + 1, maxDepth, showFiles);
26414
26414
  if (subtree)
26415
26415
  lines.push(subtree);
26416
26416
  }
26417
26417
  if (showFiles) {
26418
26418
  for (const f2 of files.slice(0, 20)) {
26419
- lines.push(`${indent}${f2.name}`);
26419
+ lines.push(`${indent2}${f2.name}`);
26420
26420
  }
26421
26421
  if (files.length > 20) {
26422
- lines.push(`${indent}... ${files.length - 20} more files`);
26422
+ lines.push(`${indent2}... ${files.length - 20} more files`);
26423
26423
  }
26424
26424
  } else if (depth === 0 && files.length > 0) {
26425
- lines.push(`${indent}(${files.length} root files)`);
26425
+ lines.push(`${indent2}(${files.length} root files)`);
26426
26426
  }
26427
26427
  } catch {
26428
26428
  }
@@ -57725,21 +57725,21 @@ var init_src21 = __esm({
57725
57725
  });
57726
57726
 
57727
57727
  // ../node_modules/@libp2p/logger/dist/src/index.js
57728
- function formatError(v, indent = "") {
57728
+ function formatError(v, indent2 = "") {
57729
57729
  const message2 = notEmpty(v.message);
57730
57730
  const stack = notEmpty(v.stack);
57731
57731
  if (message2 != null && stack != null) {
57732
57732
  if (stack.includes(message2)) {
57733
57733
  return `${stack.split("\n").join(`
57734
- ${indent}`)}`;
57734
+ ${indent2}`)}`;
57735
57735
  }
57736
57736
  return `${message2}
57737
- ${indent}${stack.split("\n").join(`
57738
- ${indent}`)}`;
57737
+ ${indent2}${stack.split("\n").join(`
57738
+ ${indent2}`)}`;
57739
57739
  }
57740
57740
  if (stack != null) {
57741
57741
  return `${stack.split("\n").join(`
57742
- ${indent}`)}`;
57742
+ ${indent2}`)}`;
57743
57743
  }
57744
57744
  if (message2 != null) {
57745
57745
  return `${message2}`;
@@ -57749,21 +57749,21 @@ ${indent}`)}`;
57749
57749
  function isAggregateError(err) {
57750
57750
  return err instanceof AggregateError || err?.name === "AggregateError" && Array.isArray(err.errors);
57751
57751
  }
57752
- function printError2(err, indent = "") {
57752
+ function printError2(err, indent2 = "") {
57753
57753
  if (isAggregateError(err)) {
57754
- let output = formatError(err, indent);
57754
+ let output = formatError(err, indent2);
57755
57755
  if (err.errors.length > 0) {
57756
- indent = `${indent} `;
57756
+ indent2 = `${indent2} `;
57757
57757
  output += `
57758
- ${indent}${err.errors.map((err2) => `${printError2(err2, `${indent}`)}`).join(`
57759
- ${indent}`)}`;
57758
+ ${indent2}${err.errors.map((err2) => `${printError2(err2, `${indent2}`)}`).join(`
57759
+ ${indent2}`)}`;
57760
57760
  } else {
57761
57761
  output += `
57762
- ${indent}[Error list was empty]`;
57762
+ ${indent2}[Error list was empty]`;
57763
57763
  }
57764
57764
  return output.trim();
57765
57765
  }
57766
- return formatError(err, indent);
57766
+ return formatError(err, indent2);
57767
57767
  }
57768
57768
  function createDisabledLogger(namespace2) {
57769
57769
  const logger2 = () => {
@@ -93897,8 +93897,8 @@ var require_error_helpers = __commonJS({
93897
93897
  const argName = params.split(",")[idx].trim();
93898
93898
  return `"${argName}" at position #${idx}`;
93899
93899
  }
93900
- function composeErrorMessage(msg, e2, indent = " ") {
93901
- return [msg, ...e2.message.split("\n").map((l2) => indent + l2)].join("\n");
93900
+ function composeErrorMessage(msg, e2, indent2 = " ") {
93901
+ return [msg, ...e2.message.split("\n").map((l2) => indent2 + l2)].join("\n");
93902
93902
  }
93903
93903
  function formatErrorCtor(ctor, paramIdx, error) {
93904
93904
  const [, params = null] = ctor.toString().match(/constructor\(([\w, ]+)\)/) || [];
@@ -119099,11 +119099,11 @@ var require_asn1 = __commonJS({
119099
119099
  if (level > 0) {
119100
119100
  rval += "\n";
119101
119101
  }
119102
- var indent = "";
119102
+ var indent2 = "";
119103
119103
  for (var i2 = 0; i2 < level * indentation; ++i2) {
119104
- indent += " ";
119104
+ indent2 += " ";
119105
119105
  }
119106
- rval += indent + "Tag: ";
119106
+ rval += indent2 + "Tag: ";
119107
119107
  switch (obj.tagClass) {
119108
119108
  case asn1.Class.UNIVERSAL:
119109
119109
  rval += "Universal:";
@@ -119189,7 +119189,7 @@ var require_asn1 = __commonJS({
119189
119189
  rval += obj.type;
119190
119190
  }
119191
119191
  rval += "\n";
119192
- rval += indent + "Constructed: " + obj.constructed + "\n";
119192
+ rval += indent2 + "Constructed: " + obj.constructed + "\n";
119193
119193
  if (obj.composed) {
119194
119194
  var subvalues = 0;
119195
119195
  var sub2 = "";
@@ -119202,9 +119202,9 @@ var require_asn1 = __commonJS({
119202
119202
  }
119203
119203
  }
119204
119204
  }
119205
- rval += indent + "Sub values: " + subvalues + sub2;
119205
+ rval += indent2 + "Sub values: " + subvalues + sub2;
119206
119206
  } else {
119207
- rval += indent + "Value: ";
119207
+ rval += indent2 + "Value: ";
119208
119208
  if (obj.type === asn1.Type.OID) {
119209
119209
  var oid = asn1.derToOid(obj.value);
119210
119210
  rval += oid;
@@ -434334,7 +434334,7 @@ ${lanes.join("\n")}
434334
434334
  var resetEscapeSequence = "\x1B[0m";
434335
434335
  var ellipsis = "...";
434336
434336
  var halfIndent = " ";
434337
- var indent = " ";
434337
+ var indent2 = " ";
434338
434338
  function getCategoryFormat(category) {
434339
434339
  switch (category) {
434340
434340
  case 1:
@@ -434436,10 +434436,10 @@ ${lanes.join("\n")}
434436
434436
  if (file) {
434437
434437
  output += host.getNewLine();
434438
434438
  output += halfIndent + formatLocation(file, start2, host);
434439
- output += formatCodeSpan(file, start2, length22, indent, "\x1B[96m", host);
434439
+ output += formatCodeSpan(file, start2, length22, indent2, "\x1B[96m", host);
434440
434440
  }
434441
434441
  output += host.getNewLine();
434442
- output += indent + flattenDiagnosticMessageText(messageText, host.getNewLine());
434442
+ output += indent2 + flattenDiagnosticMessageText(messageText, host.getNewLine());
434443
434443
  }
434444
434444
  }
434445
434445
  output += host.getNewLine();
@@ -447189,11 +447189,11 @@ ${lanes.join("\n")}
447189
447189
  return `${d2.getHours().toString().padStart(2, "0")}:${d2.getMinutes().toString().padStart(2, "0")}:${d2.getSeconds().toString().padStart(2, "0")}.${d2.getMilliseconds().toString().padStart(3, "0")}`;
447190
447190
  }
447191
447191
  var indentStr = "\n ";
447192
- function indent2(str) {
447192
+ function indent22(str) {
447193
447193
  return indentStr + str.replace(/\n/g, indentStr);
447194
447194
  }
447195
447195
  function stringifyIndented(json) {
447196
- return indent2(JSON.stringify(json, void 0, 2));
447196
+ return indent22(JSON.stringify(json, void 0, 2));
447197
447197
  }
447198
447198
  function isTypingUpToDate(cachedTyping, availableTypingVersions) {
447199
447199
  const availableVersion = new Version(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest"));
@@ -496948,7 +496948,7 @@ ${options2.prefix}` : "\n" : options2.prefix
496948
496948
  getLocationInNewDocument: () => getLocationInNewDocument,
496949
496949
  hasArgument: () => hasArgument,
496950
496950
  hasNoTypeScriptSource: () => hasNoTypeScriptSource,
496951
- indent: () => indent2,
496951
+ indent: () => indent22,
496952
496952
  isBackgroundProject: () => isBackgroundProject,
496953
496953
  isConfigFile: () => isConfigFile,
496954
496954
  isConfiguredProject: () => isConfiguredProject,
@@ -506521,9 +506521,9 @@ ${json}${newLine}`;
506521
506521
  logErrorWorker(err, cmd, fileRequest) {
506522
506522
  let msg = "Exception on executing command " + cmd;
506523
506523
  if (err.message) {
506524
- msg += ":\n" + indent2(err.message);
506524
+ msg += ":\n" + indent22(err.message);
506525
506525
  if (err.stack) {
506526
- msg += "\n" + indent2(err.stack);
506526
+ msg += "\n" + indent22(err.stack);
506527
506527
  }
506528
506528
  }
506529
506529
  if (this.logger.hasLevel(
@@ -506538,7 +506538,7 @@ ${json}${newLine}`;
506538
506538
  const text2 = getSnapshotText(scriptInfo.getSnapshot());
506539
506539
  msg += `
506540
506540
 
506541
- File text of ${fileRequest.file}:${indent2(text2)}
506541
+ File text of ${fileRequest.file}:${indent22(text2)}
506542
506542
  `;
506543
506543
  }
506544
506544
  } catch {
@@ -508536,7 +508536,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
508536
508536
  3
508537
508537
  /* verbose */
508538
508538
  )) {
508539
- this.logger.info(`request:${indent2(this.toStringMessage(message2))}`);
508539
+ this.logger.info(`request:${indent22(this.toStringMessage(message2))}`);
508540
508540
  }
508541
508541
  }
508542
508542
  let request;
@@ -509704,7 +509704,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
509704
509704
  getLocationInNewDocument: () => getLocationInNewDocument,
509705
509705
  hasArgument: () => hasArgument,
509706
509706
  hasNoTypeScriptSource: () => hasNoTypeScriptSource,
509707
- indent: () => indent2,
509707
+ indent: () => indent22,
509708
509708
  isBackgroundProject: () => isBackgroundProject,
509709
509709
  isConfigFile: () => isConfigFile,
509710
509710
  isConfiguredProject: () => isConfiguredProject,
@@ -567057,6 +567057,609 @@ context_fabric: included=${included.length} dropped=${dropped.length} truncated=
567057
567057
  }
567058
567058
  });
567059
567059
 
567060
+ // packages/orchestrator/dist/evidenceLedger.js
567061
+ function buildExtract(content) {
567062
+ const lines = content.split("\n");
567063
+ if (lines.length <= SMALL_LINES && content.length <= SMALL_CHARS) {
567064
+ return { text: content, fidelity: "full" };
567065
+ }
567066
+ const head = lines.slice(0, EXTRACT_HEAD);
567067
+ const tail = lines.slice(-EXTRACT_TAIL);
567068
+ const signatures = [];
567069
+ for (let i2 = EXTRACT_HEAD; i2 < lines.length - EXTRACT_TAIL; i2++) {
567070
+ const ln = lines[i2];
567071
+ if (SIGNATURE_RE.test(ln))
567072
+ signatures.push(` ${i2 + 1}: ${ln.trim().slice(0, 120)}`);
567073
+ if (signatures.length >= 30)
567074
+ break;
567075
+ }
567076
+ const parts = [
567077
+ head.join("\n"),
567078
+ signatures.length ? ` … (${lines.length - EXTRACT_HEAD - EXTRACT_TAIL} lines elided; signatures:)
567079
+ ${signatures.join("\n")}` : ` … (${lines.length - EXTRACT_HEAD - EXTRACT_TAIL} lines elided) …`,
567080
+ tail.join("\n")
567081
+ ];
567082
+ return { text: parts.join("\n"), fidelity: "extract" };
567083
+ }
567084
+ function mergeRanges(ranges) {
567085
+ if (ranges.length <= 1)
567086
+ return ranges;
567087
+ const sorted = [...ranges].sort((a2, b) => a2.start - b.start);
567088
+ const out = [sorted[0]];
567089
+ for (let i2 = 1; i2 < sorted.length; i2++) {
567090
+ const r2 = sorted[i2];
567091
+ const last2 = out[out.length - 1];
567092
+ if (r2.start <= last2.end + 1)
567093
+ last2.end = Math.max(last2.end, r2.end);
567094
+ else
567095
+ out.push({ ...r2 });
567096
+ }
567097
+ return out;
567098
+ }
567099
+ function rangeLabel(ranges) {
567100
+ return ranges.map((r2) => r2.end === Infinity || r2.start === 0 ? "whole file" : `lines ${r2.start}-${r2.end}`).join(", ");
567101
+ }
567102
+ function indent(text2) {
567103
+ return text2.split("\n").map((l2) => ` ${l2}`).join("\n");
567104
+ }
567105
+ var SMALL_LINES, SMALL_CHARS, EXTRACT_HEAD, EXTRACT_TAIL, SIGNATURE_RE, EvidenceLedger;
567106
+ var init_evidenceLedger = __esm({
567107
+ "packages/orchestrator/dist/evidenceLedger.js"() {
567108
+ "use strict";
567109
+ SMALL_LINES = 60;
567110
+ SMALL_CHARS = 2048;
567111
+ EXTRACT_HEAD = 20;
567112
+ EXTRACT_TAIL = 8;
567113
+ SIGNATURE_RE = /^\s*(export\s+)?(async\s+)?(function|class|interface|type|const|def|public|private|protected|fn|impl|struct|enum|module|package|import|from|#include|CREATE\s+TABLE)\b/i;
567114
+ EvidenceLedger = class {
567115
+ entries = /* @__PURE__ */ new Map();
567116
+ /** Record a successful read. `fileVersion` is the file's current writeCount. */
567117
+ recordRead(input) {
567118
+ const { path: path12, content, range, fileVersion, turn } = input;
567119
+ if (!path12 || !content)
567120
+ return;
567121
+ const built = buildExtract(content);
567122
+ const existing = this.entries.get(path12);
567123
+ if (existing && existing.readVersion === fileVersion && !existing.stale) {
567124
+ const keepNew = built.text.length >= existing.content.length;
567125
+ this.entries.set(path12, {
567126
+ ...existing,
567127
+ content: keepNew ? built.text : existing.content,
567128
+ fidelity: keepNew ? built.fidelity : existing.fidelity,
567129
+ ranges: mergeRanges([...existing.ranges, range]),
567130
+ lastReadTurn: turn,
567131
+ stale: false
567132
+ });
567133
+ return;
567134
+ }
567135
+ this.entries.set(path12, {
567136
+ path: path12,
567137
+ readVersion: fileVersion,
567138
+ lastReadTurn: turn,
567139
+ ranges: [range],
567140
+ content: built.text,
567141
+ fidelity: built.fidelity,
567142
+ stale: false
567143
+ });
567144
+ }
567145
+ /** Mark a file's evidence stale because it was mutated to `newVersion`. */
567146
+ markMutated(path12, newVersion, _turn) {
567147
+ const e2 = this.entries.get(path12);
567148
+ if (!e2)
567149
+ return;
567150
+ if (newVersion > e2.readVersion)
567151
+ e2.stale = true;
567152
+ }
567153
+ /** Is there fresh (non-stale) evidence covering this read? */
567154
+ hasFresh(path12) {
567155
+ const e2 = this.entries.get(path12);
567156
+ return !!e2 && !e2.stale;
567157
+ }
567158
+ get(path12) {
567159
+ return this.entries.get(path12);
567160
+ }
567161
+ size() {
567162
+ return this.entries.size;
567163
+ }
567164
+ clear() {
567165
+ this.entries.clear();
567166
+ }
567167
+ /**
567168
+ * Render the evidence block for the ACTIVE CONTEXT FRAME. Freshest reads
567169
+ * first; stale entries are flagged (and kept short — they only need to say
567170
+ * "re-read me"). Bounded to `maxChars`; ContextFrameBuilder budgets again.
567171
+ */
567172
+ renderBlock(maxChars = 6e3) {
567173
+ if (this.entries.size === 0)
567174
+ return null;
567175
+ const sorted = [...this.entries.values()].sort((a2, b) => b.lastReadTurn - a2.lastReadTurn);
567176
+ const lines = [
567177
+ "Evidence already gathered this run — you ALREADY have the content below.",
567178
+ "Do NOT re-read a FRESH file; use this. Re-read ONLY entries marked STALE.",
567179
+ ""
567180
+ ];
567181
+ let used = lines.join("\n").length;
567182
+ for (const e2 of sorted) {
567183
+ 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)}):`;
567184
+ const body = e2.stale ? "" : "\n" + indent(e2.content);
567185
+ const chunk = `${header}${body}
567186
+ `;
567187
+ if (used + chunk.length > maxChars) {
567188
+ const stub = `▸ ${e2.path} @v${e2.readVersion} [${e2.stale ? "STALE" : "FRESH"}] (${rangeLabel(e2.ranges)})
567189
+ `;
567190
+ if (used + stub.length <= maxChars) {
567191
+ lines.push(stub);
567192
+ used += stub.length;
567193
+ }
567194
+ continue;
567195
+ }
567196
+ lines.push(chunk);
567197
+ used += chunk.length;
567198
+ }
567199
+ return lines.join("\n");
567200
+ }
567201
+ };
567202
+ }
567203
+ });
567204
+
567205
+ // packages/orchestrator/dist/adversaryStream.js
567206
+ function adversarySystemPrompt() {
567207
+ return [
567208
+ "You are the ADVERSARY: a skeptical auditor running adjacent to a coding agent.",
567209
+ "Your sole job is to instill doubt and DEMAND evidence. You never approve work to be polite.",
567210
+ "The agent has a documented optimism bias — it claims completeness before proving it.",
567211
+ "",
567212
+ "Treat every claim as UNPROVEN until an INDEPENDENT check confirms it. Specifically:",
567213
+ " • started ≠ running — a PID or a log line is not a liveness probe.",
567214
+ " • exit code 0 / 'build complete' ≠ success — the specific artifact must exist.",
567215
+ " • an edit ≠ a fix — the failing command must be re-run and pass.",
567216
+ " • simulation / mock / placeholder ≠ real.",
567217
+ " • partial progress ≠ done.",
567218
+ "Mixed results are the norm: do NOT let one success excuse an unproven completion claim.",
567219
+ "",
567220
+ "Given the agent's latest message and recent tool outcomes, decide whether the claim is proven.",
567221
+ "Respond with ONLY a JSON object, no prose, no code fences:",
567222
+ '{"class":"false_success|unproven_claim|weak_evidence|false_failure|ok",',
567223
+ ' "shortText":"<=12 word headline",',
567224
+ ' "confidence":0.0-1.0, // how strongly the claim is NOT proven',
567225
+ ' "details":"2-4 sentence skeptical critique citing the specific gap",',
567226
+ ' "demand":"the ONE concrete independent check the agent must run next"}',
567227
+ "",
567228
+ 'Use class "ok" ONLY when the recent tool evidence genuinely and independently proves the claim.',
567229
+ "Be specific: name the file, command, or symbol whose verification is missing."
567230
+ ].join("\n");
567231
+ }
567232
+ function buildObservationPrompt(obs, recentLedger) {
567233
+ const outcomes = obs.recentToolOutcomes.slice(-8).map((o2) => ` - ${o2.tool}: ${o2.succeeded ? "OK" : "FAIL"} — ${o2.preview.slice(0, 120)}`).join("\n");
567234
+ const priorDoubts = recentLedger.slice(-3).filter((e2) => e2.verdict !== "ok").map((e2) => ` - turn ${e2.turn}: ${e2.verdict} — demanded: ${e2.demand}`).join("\n");
567235
+ return [
567236
+ obs.claimsCompletion ? "The agent is asserting COMPLETION this turn." : "The agent produced a progress/success-flavored claim this turn.",
567237
+ "",
567238
+ "Agent's latest message:",
567239
+ obs.assistantText.slice(0, 1800) || "(empty)",
567240
+ "",
567241
+ "Recent tool outcomes (evidence available):",
567242
+ outcomes || " (none)",
567243
+ priorDoubts ? `
567244
+ Unresolved doubts you raised earlier:
567245
+ ${priorDoubts}` : "",
567246
+ "",
567247
+ "Audit this. Return ONLY the JSON object."
567248
+ ].join("\n");
567249
+ }
567250
+ function parseAdversaryCritique(raw) {
567251
+ if (!raw)
567252
+ return null;
567253
+ let text2 = raw.trim().replace(/^```(?:json)?/i, "").replace(/```$/i, "").trim();
567254
+ const start2 = text2.indexOf("{");
567255
+ const end = text2.lastIndexOf("}");
567256
+ if (start2 < 0 || end <= start2)
567257
+ return null;
567258
+ let obj;
567259
+ try {
567260
+ obj = JSON.parse(text2.slice(start2, end + 1));
567261
+ } catch {
567262
+ return null;
567263
+ }
567264
+ const cls = String(obj["class"] ?? "").toLowerCase();
567265
+ const valid = [
567266
+ "false_success",
567267
+ "unproven_claim",
567268
+ "weak_evidence",
567269
+ "false_failure",
567270
+ "ok"
567271
+ ];
567272
+ const klass = valid.includes(cls) ? cls : "unproven_claim";
567273
+ let confidence2 = Number(obj["confidence"]);
567274
+ if (!Number.isFinite(confidence2))
567275
+ confidence2 = klass === "ok" ? 0.1 : 0.7;
567276
+ confidence2 = Math.min(1, Math.max(0, confidence2));
567277
+ return {
567278
+ class: klass,
567279
+ shortText: String(obj["shortText"] ?? obj["short_text"] ?? "claim unproven").slice(0, 120),
567280
+ confidence: confidence2,
567281
+ details: String(obj["details"] ?? "").slice(0, 1200),
567282
+ demand: String(obj["demand"] ?? "").slice(0, 400)
567283
+ };
567284
+ }
567285
+ var SUCCESS_LANGUAGE, AdversaryStream;
567286
+ var init_adversaryStream = __esm({
567287
+ "packages/orchestrator/dist/adversaryStream.js"() {
567288
+ "use strict";
567289
+ SUCCESS_LANGUAGE = /\b(done|fixed|complete|completed|works|working|verified|validated|passed|all set|successfully|ready|live|hydrated|confirmed)\b/i;
567290
+ AdversaryStream = class {
567291
+ backend;
567292
+ onCritique;
567293
+ persistPath;
567294
+ minConfidence;
567295
+ timeoutMs;
567296
+ ledger = [];
567297
+ pending = null;
567298
+ lastAuditedSignature = "";
567299
+ inFlight = false;
567300
+ constructor(opts) {
567301
+ this.backend = opts.backend;
567302
+ this.onCritique = opts.onCritique;
567303
+ this.persistPath = opts.persistPath ?? null;
567304
+ this.minConfidence = opts.minConfidence ?? 0.5;
567305
+ this.timeoutMs = opts.timeoutMs ?? 2e4;
567306
+ this.load();
567307
+ }
567308
+ get ledgerSize() {
567309
+ return this.ledger.length;
567310
+ }
567311
+ /**
567312
+ * Decide whether this turn carries a high-signal claim worth auditing. Cheap
567313
+ * + synchronous. Only completion assertions or explicit success language gate
567314
+ * an inference call, keeping cost bounded.
567315
+ */
567316
+ shouldAudit(obs) {
567317
+ if (obs.claimsCompletion)
567318
+ return true;
567319
+ return SUCCESS_LANGUAGE.test(obs.assistantText);
567320
+ }
567321
+ /** Ingest an observation. Replaces any prior un-audited pending observation. */
567322
+ observe(obs) {
567323
+ if (!this.shouldAudit(obs))
567324
+ return;
567325
+ const sig = `${obs.turn}:${obs.assistantText.slice(0, 200)}`;
567326
+ if (sig === this.lastAuditedSignature)
567327
+ return;
567328
+ this.pending = obs;
567329
+ }
567330
+ /**
567331
+ * Fire the adversary inference if there is a pending observation and no call
567332
+ * in flight. Detached/non-blocking — resolves when (or if) a critique lands.
567333
+ * Returns the critique for testing; callers in the loop ignore the promise.
567334
+ */
567335
+ async tick() {
567336
+ if (this.inFlight || !this.pending)
567337
+ return null;
567338
+ const obs = this.pending;
567339
+ this.pending = null;
567340
+ this.lastAuditedSignature = `${obs.turn}:${obs.assistantText.slice(0, 200)}`;
567341
+ this.inFlight = true;
567342
+ try {
567343
+ const resp = await this.backend.chatCompletion({
567344
+ messages: [
567345
+ { role: "system", content: adversarySystemPrompt() },
567346
+ { role: "user", content: buildObservationPrompt(obs, this.ledger) }
567347
+ ],
567348
+ tools: [],
567349
+ temperature: 0,
567350
+ maxTokens: 400,
567351
+ timeoutMs: this.timeoutMs
567352
+ });
567353
+ const content = resp.choices?.[0]?.message?.content ?? "";
567354
+ const critique2 = parseAdversaryCritique(content);
567355
+ if (!critique2)
567356
+ return null;
567357
+ this.ledger.push({
567358
+ ts: Date.now(),
567359
+ turn: obs.turn,
567360
+ claim: obs.assistantText.slice(0, 240),
567361
+ verdict: critique2.class,
567362
+ confidence: critique2.confidence,
567363
+ demand: critique2.demand
567364
+ });
567365
+ if (this.ledger.length > 100)
567366
+ this.ledger = this.ledger.slice(-100);
567367
+ this.persist();
567368
+ if (critique2.class !== "ok" && critique2.confidence >= this.minConfidence) {
567369
+ this.onCritique(critique2, obs.turn);
567370
+ return critique2;
567371
+ }
567372
+ return null;
567373
+ } catch {
567374
+ return null;
567375
+ } finally {
567376
+ this.inFlight = false;
567377
+ }
567378
+ }
567379
+ /** Format a critique as the system-prompt injection the main loop receives. */
567380
+ static formatInjection(c8) {
567381
+ return [
567382
+ `[ADVERSARY CRITIQUE — ${c8.class} · ${Math.round(c8.confidence * 100)}% unproven]`,
567383
+ c8.details,
567384
+ c8.demand ? `Required independent check before claiming this again: ${c8.demand}` : ""
567385
+ ].filter(Boolean).join("\n");
567386
+ }
567387
+ load() {
567388
+ if (!this.persistPath)
567389
+ return;
567390
+ try {
567391
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = __require("node:fs");
567392
+ if (existsSync164(this.persistPath)) {
567393
+ const data = JSON.parse(readFileSync134(this.persistPath, "utf-8"));
567394
+ if (Array.isArray(data?.ledger))
567395
+ this.ledger = data.ledger.slice(-100);
567396
+ }
567397
+ } catch {
567398
+ }
567399
+ }
567400
+ persist() {
567401
+ if (!this.persistPath)
567402
+ return;
567403
+ try {
567404
+ const { writeFileSync: writeFileSync91, mkdirSync: mkdirSync106, existsSync: existsSync164 } = __require("node:fs");
567405
+ const { dirname: dirname54 } = __require("node:path");
567406
+ const dir = dirname54(this.persistPath);
567407
+ if (!existsSync164(dir))
567408
+ mkdirSync106(dir, { recursive: true });
567409
+ writeFileSync91(this.persistPath, JSON.stringify({ ledger: this.ledger }, null, 2));
567410
+ } catch {
567411
+ }
567412
+ }
567413
+ };
567414
+ }
567415
+ });
567416
+
567417
+ // packages/orchestrator/dist/evidenceBranch.js
567418
+ function queryTerms(query) {
567419
+ return [
567420
+ ...new Set(query.toLowerCase().replace(/[^a-z0-9_<>./-]+/g, " ").split(/\s+/).filter((w) => w.length > 2 && !STOPWORDS2.has(w)))
567421
+ ];
567422
+ }
567423
+ function selectWindows(lines, terms2) {
567424
+ const matched = [];
567425
+ for (let i2 = 0; i2 < lines.length; i2++) {
567426
+ const lower = lines[i2].toLowerCase();
567427
+ let score = 0;
567428
+ for (const t2 of terms2)
567429
+ if (lower.includes(t2))
567430
+ score++;
567431
+ if (score > 0)
567432
+ matched.push({ idx: i2, score });
567433
+ }
567434
+ const intervals = [
567435
+ { start: 0, end: Math.min(lines.length, HEAD_LINES2) - 1, score: 0.5 }
567436
+ ];
567437
+ matched.sort((a2, b) => b.score - a2.score).slice(0, 30).forEach((m2) => {
567438
+ intervals.push({
567439
+ start: Math.max(0, m2.idx - SNIPPET_CONTEXT),
567440
+ end: Math.min(lines.length - 1, m2.idx + SNIPPET_CONTEXT),
567441
+ score: m2.score
567442
+ });
567443
+ });
567444
+ intervals.sort((a2, b) => a2.start - b.start);
567445
+ const merged = [];
567446
+ for (const iv of intervals) {
567447
+ const last2 = merged[merged.length - 1];
567448
+ if (last2 && iv.start <= last2.end + 1) {
567449
+ last2.end = Math.max(last2.end, iv.end);
567450
+ last2.score = Math.max(last2.score, iv.score);
567451
+ } else
567452
+ merged.push({ ...iv });
567453
+ }
567454
+ let budget = MAX_SNIPPET_LINES;
567455
+ const head = merged.find((m2) => m2.start === 0);
567456
+ const rest = merged.filter((m2) => m2 !== head).sort((a2, b) => b.score - a2.score);
567457
+ const kept = (head ? [head] : []).concat(rest);
567458
+ const chosen = [];
567459
+ for (const m2 of kept) {
567460
+ const len = m2.end - m2.start + 1;
567461
+ if (budget - len < 0)
567462
+ continue;
567463
+ budget -= len;
567464
+ chosen.push(m2);
567465
+ }
567466
+ return chosen.sort((a2, b) => a2.start - b.start).map((m2) => ({
567467
+ start: m2.start + 1,
567468
+ end: m2.end + 1,
567469
+ text: lines.slice(m2.start, m2.end + 1).join("\n"),
567470
+ score: m2.score
567471
+ }));
567472
+ }
567473
+ function extractionPrompt(query, path12, windows) {
567474
+ const blocks = windows.map((w) => `--- ${path12} lines ${w.start}-${w.end} ---
567475
+ ${w.text}`).join("\n\n");
567476
+ return [
567477
+ `You are an extraction worker in a throwaway context. Extract ONLY what answers the query; do not summarize the whole file.`,
567478
+ `Query: ${query}`,
567479
+ ``,
567480
+ `File excerpts:`,
567481
+ blocks,
567482
+ ``,
567483
+ `Respond with ONLY a JSON object, no prose, no fences:`,
567484
+ `{"claim":"the specific facts that answer the query, quoting exact values",`,
567485
+ ` "source_start":<1-based line where the answer is, or null>,`,
567486
+ ` "source_end":<1-based end line, or null>,`,
567487
+ ` "confidence":0.0-1.0, // how sure the excerpts actually contain the answer`,
567488
+ ` "found":true|false}`
567489
+ ].join("\n");
567490
+ }
567491
+ function parseExtraction(raw) {
567492
+ if (!raw)
567493
+ return null;
567494
+ const s2 = raw.indexOf("{");
567495
+ const e2 = raw.lastIndexOf("}");
567496
+ if (s2 < 0 || e2 <= s2)
567497
+ return null;
567498
+ let o2;
567499
+ try {
567500
+ o2 = JSON.parse(raw.slice(s2, e2 + 1));
567501
+ } catch {
567502
+ return null;
567503
+ }
567504
+ const num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
567505
+ let conf = Number(o2["confidence"]);
567506
+ if (!Number.isFinite(conf))
567507
+ conf = 0.5;
567508
+ return {
567509
+ claim: String(o2["claim"] ?? "").slice(0, 800),
567510
+ sourceStart: num2(o2["source_start"]),
567511
+ sourceEnd: num2(o2["source_end"]),
567512
+ confidence: Math.min(1, Math.max(0, conf)),
567513
+ found: o2["found"] !== false
567514
+ };
567515
+ }
567516
+ async function extractEvidence(opts) {
567517
+ const { path: path12, query, content, fileVersion, backend } = opts;
567518
+ const lines = content.split("\n");
567519
+ const terms2 = queryTerms(query);
567520
+ if (terms2.length > 0) {
567521
+ const lowers = lines.map((l2) => l2.toLowerCase());
567522
+ const N = Math.max(1, lines.length);
567523
+ const weight = /* @__PURE__ */ new Map();
567524
+ for (const t2 of terms2) {
567525
+ let df = 0;
567526
+ for (const l2 of lowers)
567527
+ if (l2.includes(t2))
567528
+ df++;
567529
+ weight.set(t2, df === 0 ? 0 : Math.log(N / df) + 0.1);
567530
+ }
567531
+ const hits = [];
567532
+ for (let i2 = 0; i2 < lines.length; i2++) {
567533
+ const lower = lowers[i2];
567534
+ let score = 0;
567535
+ for (const t2 of terms2)
567536
+ if (lower.includes(t2))
567537
+ score += weight.get(t2) ?? 0;
567538
+ if (score > 0)
567539
+ hits.push({ idx: i2, score });
567540
+ }
567541
+ if (hits.length > 0) {
567542
+ const CHAR_BUDGET = 900;
567543
+ const ranked = [...hits].sort((a2, b) => b.score - a2.score).slice(0, 8);
567544
+ const MAX_LINE = 200;
567545
+ const snippets = ranked.map((h) => {
567546
+ const lo = Math.max(0, h.idx - 2);
567547
+ const hi = Math.min(lines.length - 1, h.idx + 2);
567548
+ const text2 = lines.slice(lo, hi + 1).map((l2, k) => {
567549
+ const v = l2.length > MAX_LINE ? l2.slice(0, MAX_LINE) + "…" : l2;
567550
+ return `${lo + k + 1}: ${v}`;
567551
+ }).join("\n");
567552
+ return { score: h.score, start: lo + 1, end: hi + 1, text: text2 };
567553
+ });
567554
+ const kept = [];
567555
+ let used = 0;
567556
+ for (const s2 of snippets) {
567557
+ if (used + s2.text.length + 1 > CHAR_BUDGET && kept.length > 0)
567558
+ continue;
567559
+ kept.push(s2);
567560
+ used += s2.text.length + 1;
567561
+ }
567562
+ kept.sort((a2, b) => a2.start - b.start);
567563
+ const claim2 = kept.map((s2) => s2.text).join("\n …\n");
567564
+ const starts = kept.map((s2) => s2.start);
567565
+ const ends = kept.map((s2) => s2.end);
567566
+ const snippetLower = claim2.toLowerCase();
567567
+ const covered = terms2.filter((t2) => snippetLower.includes(t2)).length;
567568
+ return {
567569
+ path: path12,
567570
+ query,
567571
+ claim: claim2,
567572
+ sourceStart: starts.length ? Math.min(...starts) : null,
567573
+ sourceEnd: ends.length ? Math.max(...ends) : null,
567574
+ fileVersion,
567575
+ confidence: Math.min(1, covered / Math.max(1, terms2.length)),
567576
+ exploredLines: lines.length,
567577
+ injectedChars: claim2.length
567578
+ };
567579
+ }
567580
+ }
567581
+ const windows = lines.length <= WINDOW_LINES * 2 ? [{ start: 1, end: lines.length, text: content, score: 1 }] : selectWindows(lines, terms2);
567582
+ const exploredLines = windows.reduce((n2, w) => n2 + (w.end - w.start + 1), 0);
567583
+ let parsed = null;
567584
+ for (let attempt = 0; attempt < 2 && !parsed; attempt++) {
567585
+ try {
567586
+ const resp = await backend.chatCompletion({
567587
+ messages: [
567588
+ { role: "system", content: "You extract precise facts from file excerpts. Output ONLY a JSON object." },
567589
+ { role: "user", content: extractionPrompt(query, path12, windows) }
567590
+ ],
567591
+ tools: [],
567592
+ temperature: 0,
567593
+ maxTokens: 900,
567594
+ timeoutMs: opts.timeoutMs ?? 3e4
567595
+ });
567596
+ parsed = parseExtraction(resp.choices?.[0]?.message?.content ?? "");
567597
+ } catch {
567598
+ parsed = null;
567599
+ }
567600
+ }
567601
+ const claim = parsed && parsed.found && parsed.claim ? parsed.claim : `No evidence for "${query}" found in the explored windows of ${path12}.`;
567602
+ return {
567603
+ path: path12,
567604
+ query,
567605
+ claim,
567606
+ sourceStart: parsed?.sourceStart ?? null,
567607
+ sourceEnd: parsed?.sourceEnd ?? null,
567608
+ fileVersion,
567609
+ confidence: parsed?.found ? parsed.confidence : 0.2,
567610
+ exploredLines,
567611
+ injectedChars: claim.length
567612
+ };
567613
+ }
567614
+ function shouldBranchRead(contentLength, lineCount, hasExplicitSmallRange, thresholdChars = 8e3) {
567615
+ if (hasExplicitSmallRange)
567616
+ return false;
567617
+ return contentLength > thresholdChars || lineCount > 200;
567618
+ }
567619
+ var WINDOW_LINES, SNIPPET_CONTEXT, HEAD_LINES2, MAX_SNIPPET_LINES, STOPWORDS2;
567620
+ var init_evidenceBranch = __esm({
567621
+ "packages/orchestrator/dist/evidenceBranch.js"() {
567622
+ "use strict";
567623
+ WINDOW_LINES = 40;
567624
+ SNIPPET_CONTEXT = 4;
567625
+ HEAD_LINES2 = 10;
567626
+ MAX_SNIPPET_LINES = 220;
567627
+ STOPWORDS2 = /* @__PURE__ */ new Set([
567628
+ "the",
567629
+ "and",
567630
+ "for",
567631
+ "what",
567632
+ "which",
567633
+ "from",
567634
+ "with",
567635
+ "that",
567636
+ "this",
567637
+ "does",
567638
+ "use",
567639
+ "uses",
567640
+ "line",
567641
+ "file",
567642
+ "value",
567643
+ "values",
567644
+ "set",
567645
+ "sets",
567646
+ "is",
567647
+ "are",
567648
+ "of",
567649
+ "on",
567650
+ "in",
567651
+ "a",
567652
+ "an",
567653
+ "to",
567654
+ "its",
567655
+ "do",
567656
+ "answer",
567657
+ "report",
567658
+ "tell"
567659
+ ]);
567660
+ }
567661
+ });
567662
+
567060
567663
  // packages/orchestrator/dist/contextEngine.js
567061
567664
  function estimateTokens3(messages2) {
567062
567665
  const chars = messages2.reduce((sum, message2) => sum + message2.content.length + message2.role.length + (message2.name?.length ?? 0), 0);
@@ -568817,6 +569420,9 @@ var init_agenticRunner = __esm({
568817
569420
  init_modelProfile();
568818
569421
  init_failureHandoff();
568819
569422
  init_context_fabric();
569423
+ init_evidenceLedger();
569424
+ init_adversaryStream();
569425
+ init_evidenceBranch();
568820
569426
  init_contextEngine();
568821
569427
  init_prompt_cache();
568822
569428
  TOOL_SUBSETS = {
@@ -569308,6 +569914,16 @@ var init_agenticRunner = __esm({
569308
569914
  // ledger and emitted as one bounded frame before each model call.
569309
569915
  _contextLedger = new ContextLedger();
569310
569916
  _contextFrameBuilder = new ContextFrameBuilder();
569917
+ // Durable, version-aware record of what has ALREADY been read this run, with
569918
+ // the actual content — rebuilt into the ACTIVE CONTEXT FRAME each turn so it
569919
+ // survives compaction. The structural fix for the re-read loop: the model
569920
+ // sees the evidence it already has instead of re-deriving it. See
569921
+ // evidenceLedger.ts.
569922
+ _evidenceLedger = new EvidenceLedger();
569923
+ // Generative, inference-driven adversary running as an async memory stream
569924
+ // adjacent to the main loop. Initialized per run when the step critic is
569925
+ // enabled and a backend is available. See adversaryStream.ts.
569926
+ _adversaryStream = null;
569311
569927
  _lastContextFrameDiagnostics = null;
569312
569928
  _lastContextPressureSnapshot = null;
569313
569929
  _lastActiveForgettingReport = null;
@@ -569966,6 +570582,91 @@ Your hypotheses MUST address this specific error, not generic causes.
569966
570582
  return null;
569967
570583
  }
569968
570584
  }
570585
+ // ── Failing-approach detector (the "stop retrying variants" reflex) ───────
570586
+ // Encodes the behavior an effective agent uses and the dropbear 27× loop
570587
+ // lacked: when the SAME error recurs ~3× — especially while the same target
570588
+ // is edited again and again — the error is telling you the CHANGE is wrong
570589
+ // (an unsupported attribute, a wrong API/signature, a missing dep), not that
570590
+ // you haven't found the right value yet. Stop, diagnose the root cause from
570591
+ // the full error, verify the correct contract, then act — do NOT re-apply a
570592
+ // variant. Distinct from REG-58/60 (no-write / slow-write): this fires while
570593
+ // edits ARE landing but verification keeps failing the same way.
570594
+ _failingApproachCooldownUntil = -1;
570595
+ /**
570596
+ * Most-common normalized failure signature in the recent window, or null if
570597
+ * no signature recurs ≥3×. Normalization drops the VARYING tokens (quoted
570598
+ * names, paths, numbers) so "unrecognized attribute: 'nstack'" and
570599
+ * "...: 'narena'" collapse to one signature. Transient/network failures are
570600
+ * excluded — retrying those is legitimate, not a failing approach.
570601
+ */
570602
+ _recurringFailureSignature(turn, window2 = 10) {
570603
+ const recent = this._recentFailures.filter((f2) => turn - f2.turn <= window2);
570604
+ if (recent.length < 3)
570605
+ return null;
570606
+ const TRANSIENT = /timed? ?out|timeout|econnreset|econnrefused|etimedout|rate.?limit|503|502|temporarily|try again|socket hang|network|fetch failed/i;
570607
+ const norm = (s2) => s2.toLowerCase().replace(/['"`][^'"`]*['"`]/g, " ").replace(/\/[^\s:]+/g, " ").replace(/\d+/g, " ").replace(/\s+/g, " ").trim().slice(0, 80);
570608
+ const groups = /* @__PURE__ */ new Map();
570609
+ for (const f2 of recent) {
570610
+ const raw = (f2.error || f2.output || "").slice(0, 200);
570611
+ if (!raw || TRANSIENT.test(raw))
570612
+ continue;
570613
+ const sig = norm(raw);
570614
+ if (!sig)
570615
+ continue;
570616
+ const g = groups.get(sig) ?? { count: 0, sample: raw };
570617
+ g.count++;
570618
+ groups.set(sig, g);
570619
+ }
570620
+ let best = null;
570621
+ for (const [signature, g] of groups) {
570622
+ if (!best || g.count > best.count)
570623
+ best = { signature, count: g.count, sample: g.sample };
570624
+ }
570625
+ return best && best.count >= 3 ? best : null;
570626
+ }
570627
+ /**
570628
+ * Detect a failing approach and return a decisive root-cause directive, or
570629
+ * null. Fires when a non-transient error recurs ≥3× in the recent window
570630
+ * (optionally corroborated by the error-cluster tracker), self-cooldown 8
570631
+ * turns. OMNIUS_DISABLE_FAILING_APPROACH=1 disables.
570632
+ */
570633
+ _detectFailingApproach(turn) {
570634
+ if (process.env["OMNIUS_DISABLE_FAILING_APPROACH"] === "1")
570635
+ return null;
570636
+ if (turn <= this._failingApproachCooldownUntil)
570637
+ return null;
570638
+ const recurring = this._recurringFailureSignature(turn);
570639
+ if (!recurring)
570640
+ return null;
570641
+ let churnPath = null;
570642
+ let churnWrites = 0;
570643
+ const wf = this._worldFacts;
570644
+ if (wf) {
570645
+ for (const [p2, info] of wf.files) {
570646
+ const writes = info.writeCount ?? 0;
570647
+ const age = turn - (info.lastWriteTurn ?? -999);
570648
+ if (writes >= 3 && age <= 8 && writes > churnWrites) {
570649
+ churnWrites = writes;
570650
+ churnPath = p2;
570651
+ }
570652
+ }
570653
+ }
570654
+ this._failingApproachCooldownUntil = turn + 8;
570655
+ const target = churnPath ? `${churnPath} (edited ${churnWrites}× recently)` : "the same target";
570656
+ return [
570657
+ `[FAILING APPROACH DETECTED — stop retrying variants]`,
570658
+ `The SAME error has recurred ${recurring.count}× in your recent attempts while you keep changing ${target}:`,
570659
+ ` ${recurring.sample}`,
570660
+ ``,
570661
+ `Trying another variant of the same change is not converging. A repeating error means the CHANGE ITSELF is wrong — an unsupported attribute/option, a wrong API or signature, or a missing prerequisite — not that you haven't hit the right value yet.`,
570662
+ `MANDATORY before your next edit:`,
570663
+ ` 1. Re-read the FULL error above and name the EXACT token it rejects (attribute / symbol / flag / path).`,
570664
+ ` 2. VERIFY the correct contract for that token from an authoritative source — read the defining file, the schema, or the API/docs. Do NOT guess.`,
570665
+ ` 3. State the root cause in one sentence: "<token> fails because <reason>."`,
570666
+ ` 4. Then make ONE change that step 2 supports. If the thing you want is genuinely unsupported, REMOVE it and choose a supported alternative — do not re-add a variant.`,
570667
+ `Do NOT re-apply another variant of the rejected change.`
570668
+ ].join("\n");
570669
+ }
569969
570670
  /**
569970
570671
  * REG-61 sliding-window first-edit / sustained-edit nudge.
569971
570672
  *
@@ -572277,7 +572978,10 @@ ${latest.output || ""}`.trim();
572277
572978
  sections.push(`Last test outcome: ${wf.lastTest.passed ? "PASSED" : "FAILED"} (turn ${wf.lastTest.turn ?? "?"})`);
572278
572979
  }
572279
572980
  sections.push(`(turn ${turn} — this block is regenerated every turn from your tool history)`);
572280
- return sections.join("\n");
572981
+ const evidenceBlock = process.env["OMNIUS_DISABLE_EVIDENCE_FRAME"] === "1" ? null : this._evidenceLedger.renderBlock(6e3);
572982
+ return evidenceBlock ? `${evidenceBlock}
572983
+
572984
+ ${sections.join("\n")}` : sections.join("\n");
572281
572985
  }
572282
572986
  /**
572283
572987
  * REG-62: Pre-call knowledge injection. Builds a concise system message
@@ -572805,7 +573509,10 @@ ${this._lastPprMemoryLines.slice(0, 5).join("\n")}` : null;
572805
573509
  this._contextLedger.upsertMany(signals.filter(Boolean));
572806
573510
  const frame = this._contextFrameBuilder.build(this._contextLedger.values(), {
572807
573511
  turn,
572808
- maxChars: 1e4,
573512
+ // Raised from 10k to fit the durable read-evidence content (known_files)
573513
+ // that replaces the re-read loop; the per-kind budget below caps it.
573514
+ maxChars: 13e3,
573515
+ kindCharBudget: { known_files: 6500 },
572809
573516
  includeDiagnostics: process.env["OMNIUS_CONTEXT_FABRIC_DIAGNOSTICS"] === "1"
572810
573517
  });
572811
573518
  this._lastContextFrameDiagnostics = frame.diagnostics;
@@ -573048,6 +573755,70 @@ ${blob}
573048
573755
  const canonical = this.lookupRegisteredTool(name10)?.name ?? name10;
573049
573756
  return `${canonical}:${this._buildExactArgsKey(args)}`;
573050
573757
  }
573758
+ // ── REG-71: region-aware read dedup ────────────────────────────────────────
573759
+ // The exact-args fingerprint treats file_read(offset=1,limit=5) and
573760
+ // file_read(offset=1,limit=3) as DISTINCT calls, so the REG-69 cache never
573761
+ // matches overlapping sub-region reads of the same file. Verified in the
573762
+ // wild: one session re-read an unedited file 27× with nudged ranges
573763
+ // (1-20, 1-5, 1-3, 1-2, 1-10…), every one a cache miss + real disk read.
573764
+ // We coalesce a read whose [start,end] is a subset of an already-seen read
573765
+ // of the same path onto that wider read's fingerprint, so the existing
573766
+ // cache-serve + hit-counter + hard-block machinery catches the loop.
573767
+ // Per path we keep up to 8 distinct covering intervals (disjoint regions of
573768
+ // a large file stay independent). Explicit-range reads return exactly their
573769
+ // range, so subset coverage is content-correct; a whole-file read only
573770
+ // covers other whole-file reads (large files return a preview, not the
573771
+ // full body, so it must not be claimed to cover an inner range).
573772
+ _readCoverage = /* @__PURE__ */ new Map();
573773
+ /** Extract (path, [start,end], whole) for a region-coalesceable read, else null. */
573774
+ _readIntervalFromArgs(name10, args) {
573775
+ const canonical = this.lookupRegisteredTool(name10)?.name ?? name10;
573776
+ if (canonical !== "file_read")
573777
+ return null;
573778
+ const a2 = args ?? {};
573779
+ const path12 = typeof a2["path"] === "string" && a2["path"] || typeof a2["file"] === "string" && a2["file"] || typeof a2["file_path"] === "string" && a2["file_path"] || "";
573780
+ if (!path12)
573781
+ return null;
573782
+ const offset = typeof a2["offset"] === "number" ? a2["offset"] : void 0;
573783
+ const limit = typeof a2["limit"] === "number" ? a2["limit"] : void 0;
573784
+ const whole = offset === void 0 && limit === void 0;
573785
+ const start2 = Math.max(1, offset ?? 1);
573786
+ const end = whole ? Number.POSITIVE_INFINITY : limit !== void 0 ? start2 + Math.max(0, limit) - 1 : Number.POSITIVE_INFINITY;
573787
+ return { key: `${canonical}|${path12}`, start: start2, end, whole };
573788
+ }
573789
+ /**
573790
+ * Resolve the fingerprint to use for cache identity. For file_read whose
573791
+ * region is already covered by a wider seen read of the same file, returns
573792
+ * that read's fingerprint (so the repeat is recognized); otherwise returns
573793
+ * the exact fingerprint unchanged.
573794
+ */
573795
+ _resolveReadCoverageFingerprint(name10, args, exactFingerprint) {
573796
+ const iv = this._readIntervalFromArgs(name10, args);
573797
+ if (!iv)
573798
+ return exactFingerprint;
573799
+ const intervals = this._readCoverage.get(iv.key);
573800
+ if (!intervals)
573801
+ return exactFingerprint;
573802
+ for (const cov of intervals) {
573803
+ const covered = iv.whole ? cov.whole : !cov.whole && cov.start <= iv.start && iv.end <= cov.end;
573804
+ if (covered)
573805
+ return cov.fingerprint;
573806
+ }
573807
+ return exactFingerprint;
573808
+ }
573809
+ /** Register a read's region under the fingerprint that cached its result. */
573810
+ _registerReadCoverage(name10, args, fingerprint) {
573811
+ const iv = this._readIntervalFromArgs(name10, args);
573812
+ if (!iv)
573813
+ return;
573814
+ const list = this._readCoverage.get(iv.key) ?? [];
573815
+ const pruned = list.filter((cov) => !(cov.whole === iv.whole && iv.start <= cov.start && cov.end <= iv.end && cov.fingerprint !== fingerprint));
573816
+ if (!pruned.some((cov) => cov.fingerprint === fingerprint)) {
573817
+ pruned.push({ start: iv.start, end: iv.end, whole: iv.whole, fingerprint });
573818
+ }
573819
+ pruned.sort((a2, b) => b.end - b.start - (a2.end - a2.start));
573820
+ this._readCoverage.set(iv.key, pruned.slice(0, 8));
573821
+ }
573051
573822
  _dedupeToolCallsForResponse(toolCalls, turn) {
573052
573823
  if (toolCalls.length <= 1)
573053
573824
  return toolCalls;
@@ -573910,6 +574681,7 @@ Respond with your assessment, then take action.`;
573910
574681
  this._contextTree = null;
573911
574682
  this._lastSurfacedAnchorIds.clear();
573912
574683
  this._contextLedger = new ContextLedger();
574684
+ this._evidenceLedger = new EvidenceLedger();
573913
574685
  this._lastContextFrameDiagnostics = null;
573914
574686
  this._lastContextPressureSnapshot = null;
573915
574687
  this._lastActiveForgettingReport = null;
@@ -574412,6 +575184,35 @@ TASK: ${scrubbedTask}` : scrubbedTask;
574412
575184
  this._selfConsistencyVotes = 0;
574413
575185
  this._retrievalContextCache = null;
574414
575186
  this._adversaryMode = this.options.adversaryMode ?? "both";
575187
+ if (this.options.disableAdversaryCritic !== true && this.backend && typeof this.backend.chatCompletion === "function") {
575188
+ const persistPath = this._workingDirectory ? _pathJoin(this._workingDirectory, ".omnius", "memory", "adversary-stream.json") : null;
575189
+ this._adversaryStream = new AdversaryStream({
575190
+ backend: this.backend,
575191
+ persistPath,
575192
+ onCritique: (critique2, sourceTurn) => {
575193
+ if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
575194
+ this.pendingUserMessages.push(AdversaryStream.formatInjection(critique2));
575195
+ }
575196
+ this.emit({
575197
+ type: "adversary_reaction",
575198
+ adversary: {
575199
+ class: critique2.class === "false_failure" ? "false_failure" : critique2.class === "false_success" ? "false_success" : "guidance",
575200
+ shortText: critique2.shortText,
575201
+ confidence: critique2.confidence,
575202
+ details: AdversaryStream.formatInjection(critique2)
575203
+ },
575204
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
575205
+ });
575206
+ this.emit({
575207
+ type: "status",
575208
+ content: `Adversary (generative) flagged turn ${sourceTurn}: ${critique2.class} (${Math.round(critique2.confidence * 100)}%)`,
575209
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
575210
+ });
575211
+ }
575212
+ });
575213
+ } else {
575214
+ this._adversaryStream = null;
575215
+ }
574415
575216
  this._worldFacts = { files: /* @__PURE__ */ new Map(), lastTest: {}, lastLists: /* @__PURE__ */ new Map() };
574416
575217
  this._argCohorts.clear();
574417
575218
  this._adversaryRedundantSignals.clear();
@@ -574800,6 +575601,28 @@ TASK: ${scrubbedTask}` : scrubbedTask;
574800
575601
  });
574801
575602
  }
574802
575603
  this._runReg61Check(turn, toolCallLog, messages2);
575604
+ if (turn > stagnationCooldownUntilTurn) {
575605
+ const failingApproach = this._detectFailingApproach(turn);
575606
+ if (failingApproach) {
575607
+ messages2.push({ role: "system", content: failingApproach });
575608
+ stagnationCooldownUntilTurn = turn + 4;
575609
+ this.emit({
575610
+ type: "adversary_reaction",
575611
+ adversary: {
575612
+ class: "guidance",
575613
+ shortText: "Failing approach — same error recurring; diagnose root cause",
575614
+ confidence: 0.9,
575615
+ details: failingApproach
575616
+ },
575617
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
575618
+ });
575619
+ this.emit({
575620
+ type: "status",
575621
+ content: `FAILING-APPROACH detected at turn ${turn} — injected root-cause directive`,
575622
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
575623
+ });
575624
+ }
575625
+ }
574803
575626
  const REG58_NO_WRITE_BUDGET = 30;
574804
575627
  if (turn > stagnationCooldownUntilTurn && this._lastFileWriteTurn >= 0 && turn - this._lastFileWriteTurn >= REG58_NO_WRITE_BUDGET && process.env["OMNIUS_DISABLE_REG58"] !== "1") {
574805
575628
  const gap = turn - this._lastFileWriteTurn;
@@ -576795,7 +577618,8 @@ Corrective action: try a different approach first: read relevant files, adjust a
576795
577618
  }
576796
577619
  toolCallBudget.set(tc.name, budgetRemaining - 1);
576797
577620
  }
576798
- const toolFingerprint = this._buildToolFingerprint(tc.name, tc.arguments ?? {});
577621
+ const exactToolFingerprint = this._buildToolFingerprint(tc.name, tc.arguments ?? {});
577622
+ const toolFingerprint = this._resolveReadCoverageFingerprint(tc.name, tc.arguments ?? {}, exactToolFingerprint);
576799
577623
  if (tc.name === "memory_write" && noopedMemoryWriteFingerprints.has(toolFingerprint)) {
576800
577624
  this.emit({
576801
577625
  type: "tool_call",
@@ -577214,14 +578038,16 @@ Respond with EXACTLY this structure before your next tool call:
577214
578038
  const paths = realMutationPaths.length > 0 ? realMutationPaths : this._extractToolTargetPaths(tc.name, tc.arguments, result);
577215
578039
  for (const p2 of paths) {
577216
578040
  const prev = this._worldFacts.files.get(p2);
578041
+ const nextWriteCount = (prev?.writeCount ?? 0) + 1;
577217
578042
  this._worldFacts.files.set(p2, {
577218
578043
  exists: true,
577219
578044
  size: prev?.size,
577220
578045
  hashSample: prev?.hashSample,
577221
578046
  lastSeenTurn: turn,
577222
578047
  lastWriteTurn: turn,
577223
- writeCount: (prev?.writeCount ?? 0) + 1
578048
+ writeCount: nextWriteCount
577224
578049
  });
578050
+ this._evidenceLedger.markMutated(p2, nextWriteCount, turn);
577225
578051
  }
577226
578052
  if (paths.length > 0) {
577227
578053
  this._writesSinceLastTodoWrite += paths.length;
@@ -577259,6 +578085,19 @@ Respond with EXACTLY this structure before your next tool call:
577259
578085
  writeCount: prev?.writeCount
577260
578086
  });
577261
578087
  }
578088
+ if (p2 && result.success && result.output) {
578089
+ const rOffset = typeof tc.arguments?.["offset"] === "number" ? tc.arguments["offset"] : void 0;
578090
+ const rLimit = typeof tc.arguments?.["limit"] === "number" ? tc.arguments["limit"] : void 0;
578091
+ const start3 = rOffset === void 0 && rLimit === void 0 ? 0 : Math.max(1, rOffset ?? 1);
578092
+ 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;
578093
+ this._evidenceLedger.recordRead({
578094
+ path: p2,
578095
+ content: result.output,
578096
+ range: { start: start3, end },
578097
+ fileVersion: this._worldFacts.files.get(p2)?.writeCount ?? 0,
578098
+ turn
578099
+ });
578100
+ }
577262
578101
  if (this._fileSummaryStore && result.success && result.output && result.output.length > 100) {
577263
578102
  try {
577264
578103
  const existing = this._fileSummaryStore.get(p2);
@@ -577797,6 +578636,9 @@ Respond with EXACTLY this structure before your next tool call:
577797
578636
  result: tc.name === "shell" ? this._buildShellCacheResult(tc.arguments, result) : (result.output ?? "").slice(0, 2e3),
577798
578637
  compacted: false
577799
578638
  });
578639
+ if (isReadLike && result.success) {
578640
+ this._registerReadCoverage(tc.name, tc.arguments ?? {}, toolFingerprint);
578641
+ }
577800
578642
  if (recentToolResults.size > 500) {
577801
578643
  const firstKey = recentToolResults.keys().next().value;
577802
578644
  if (firstKey !== void 0) {
@@ -577826,6 +578668,10 @@ Respond with EXACTLY this structure before your next tool call:
577826
578668
  if (key.includes(mp))
577827
578669
  recentToolResults.delete(key);
577828
578670
  }
578671
+ for (const covKey of Array.from(this._readCoverage.keys())) {
578672
+ if (covKey.includes(mp))
578673
+ this._readCoverage.delete(covKey);
578674
+ }
577829
578675
  }
577830
578676
  } else if (dedupHitCount.size > 0) {
577831
578677
  dedupHitCount.clear();
@@ -577984,6 +578830,44 @@ Respond with EXACTLY this structure before your next tool call:
577984
578830
  result = await this.offloadEmbeddedImageResult(result, tc.name, turn);
577985
578831
  }
577986
578832
  let output = this.normalizeToolOutput(result, tc.name, tc.arguments, turn);
578833
+ if (process.env["OMNIUS_DISABLE_BRANCH_EXTRACT"] !== "1" && this.lookupRegisteredTool(tc.name)?.name === "file_read" && result.success && typeof result.output === "string" && this.backend && typeof this.backend.chatCompletion === "function") {
578834
+ const a2 = tc.arguments ?? {};
578835
+ const hasSmallRange = typeof a2["limit"] === "number" && a2["limit"] <= 80;
578836
+ const lineCount = result.output.split("\n").length;
578837
+ if (shouldBranchRead(result.output.length, lineCount, hasSmallRange)) {
578838
+ const p2 = String(a2["path"] ?? a2["file"] ?? a2["file_path"] ?? "");
578839
+ const lastAssistant = [...messages2].reverse().find((m2) => m2.role === "assistant" && typeof m2.content === "string");
578840
+ const query = [
578841
+ this._taskState.goal ?? "",
578842
+ typeof lastAssistant?.content === "string" ? lastAssistant.content : ""
578843
+ ].join(" ").trim().slice(0, 400) || "key facts, configuration, and structure";
578844
+ try {
578845
+ const ev = await extractEvidence({
578846
+ path: p2,
578847
+ query,
578848
+ content: result.output,
578849
+ fileVersion: this._worldFacts.files.get(p2)?.writeCount ?? 0,
578850
+ backend: this.backend,
578851
+ timeoutMs: 3e4
578852
+ });
578853
+ output = [
578854
+ `[BRANCH-EXTRACT] ${p2} is large (${lineCount} lines, ${result.output.length} chars) — read in an isolated branch so it does not flood your context.`,
578855
+ `Distilled for: "${query.slice(0, 160)}"`,
578856
+ `Relevant evidence (lines ${ev.sourceStart ?? "?"}-${ev.sourceEnd ?? "?"}, confidence ${ev.confidence.toFixed(2)}):`,
578857
+ ev.claim,
578858
+ `If you need a different region, call file_read with a specific offset+limit, or extract_evidence(path, query) with a sharper question.`
578859
+ ].join("\n");
578860
+ this.emit({
578861
+ type: "status",
578862
+ toolName: tc.name,
578863
+ content: `Branch-extract: ${p2} (${lineCount} lines) → ${ev.injectedChars} chars to context (${(result.output.length / Math.max(1, ev.injectedChars)).toFixed(0)}× smaller)`,
578864
+ turn,
578865
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
578866
+ });
578867
+ } catch {
578868
+ }
578869
+ }
578870
+ }
577987
578871
  if (criticGuidance) {
577988
578872
  output += `
577989
578873
 
@@ -580527,11 +581411,9 @@ ${errOutput}`);
580527
581411
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
580528
581412
  });
580529
581413
  try {
580530
- const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = __require("node:fs");
580531
- const { join: join179 } = __require("node:path");
580532
- const resultsDir = join179(this.omniusStateDir(), "tool-results");
580533
- mkdirSync106(resultsDir, { recursive: true });
580534
- writeFileSync91(join179(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
581414
+ const resultsDir = _pathJoin(this.omniusStateDir(), "tool-results");
581415
+ _fsMkdirSync(resultsDir, { recursive: true });
581416
+ _fsWriteFileSync(_pathJoin(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
580535
581417
  # Turn: ${turn}
580536
581418
  # Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
580537
581419
  # Size: ${result.output.length} chars, ${lineCount} lines
@@ -580539,8 +581421,7 @@ ${errOutput}`);
580539
581421
  ${result.output}`, "utf-8");
580540
581422
  } catch {
580541
581423
  }
580542
- const { join: _pj } = __require("node:path");
580543
- const savedPath = _pj(this.omniusStateDir(), "tool-results", `${handleId}.txt`);
581424
+ const savedPath = _pathJoin(this.omniusStateDir(), "tool-results", `${handleId}.txt`);
580544
581425
  const folded = this.foldOutput(modelContent, maxLen);
580545
581426
  return this.wrapToolOutputForModel(toolName, `[Tool output truncated — ${result.output.length} chars, ${lineCount} lines]
580546
581427
  Full output saved to: ${savedPath}
@@ -581817,6 +582698,20 @@ ${trimmedNew}`;
581817
582698
  */
581818
582699
  adversaryObserve(messages2, turn) {
581819
582700
  const recent = messages2.slice(-6);
582701
+ if (this._adversaryStream) {
582702
+ const lastAssistantMsg = [...recent].reverse().find((m2) => m2.role === "assistant" && typeof m2.content === "string");
582703
+ const assistantText = typeof lastAssistantMsg?.content === "string" ? lastAssistantMsg.content.replace(/<think>[\s\S]*?<\/think>/g, "").trim() : "";
582704
+ if (assistantText) {
582705
+ this._adversaryStream.observe({
582706
+ turn,
582707
+ assistantText,
582708
+ recentToolOutcomes: this._adversaryToolOutcomes.slice(-8).map((o2) => ({ tool: o2.tool, succeeded: o2.succeeded, preview: o2.preview })),
582709
+ claimsCompletion: /task.?complete|all tests pass|\bdone\b|\bcomplete(d)?\b/i.test(assistantText)
582710
+ });
582711
+ void this._adversaryStream.tick().catch(() => {
582712
+ });
582713
+ }
582714
+ }
581820
582715
  for (const msg of recent) {
581821
582716
  if (msg.role === "tool" && typeof msg.content === "string") {
581822
582717
  const isError2 = msg.content.startsWith("Error:") || /^(FAIL|ERR!|TypeError)/i.test(msg.content);
@@ -583058,7 +583953,7 @@ ${transcript}`
583058
583953
  const allTools = Array.from(this.tools.values()).filter((tool) => tool.name !== "tool_search");
583059
583954
  const tier = this.options.modelTier ?? "large";
583060
583955
  const taskGoal = this._taskState.goal || "";
583061
- const STOPWORDS3 = /* @__PURE__ */ new Set([
583956
+ const STOPWORDS4 = /* @__PURE__ */ new Set([
583062
583957
  "with",
583063
583958
  "that",
583064
583959
  "this",
@@ -583144,7 +584039,7 @@ Example: ${tool.name}(${JSON.stringify(meta.examples[0].args ?? {})})` : "";
583144
584039
  const getIndexLabel = (tool) => {
583145
584040
  const meta = getCustomToolMetadata(tool);
583146
584041
  const desc = `${getDesc(tool)} ${aliasText(tool)} ${customToolSearchText(tool)}`.toLowerCase().replace(/[`"'()[\]{}:;,.!?/\\|-]+/g, " ");
583147
- const keywords2 = Array.from(new Set(desc.split(/\s+/).filter((word2) => word2.length > 2 && !STOPWORDS3.has(word2) && !tool.name.toLowerCase().includes(word2)))).slice(0, 4);
584042
+ const keywords2 = Array.from(new Set(desc.split(/\s+/).filter((word2) => word2.length > 2 && !STOPWORDS4.has(word2) && !tool.name.toLowerCase().includes(word2)))).slice(0, 4);
583148
584043
  const base3 = keywords2.length > 0 ? `${tool.name}(${keywords2.join(",")})` : tool.name;
583149
584044
  if (!meta)
583150
584045
  return base3;
@@ -586963,16 +587858,16 @@ function parseSimpleYaml(text2) {
586963
587858
  const match = withoutComment.match(/^(\s*)([A-Za-z0-9_-]+):(?:\s*(.*))?$/);
586964
587859
  if (!match)
586965
587860
  continue;
586966
- const indent = match[1].length;
587861
+ const indent2 = match[1].length;
586967
587862
  const key = match[2];
586968
587863
  const rawValue = match[3] ?? "";
586969
- while (stack.length > 1 && indent <= stack[stack.length - 1].indent)
587864
+ while (stack.length > 1 && indent2 <= stack[stack.length - 1].indent)
586970
587865
  stack.pop();
586971
587866
  const parent = stack[stack.length - 1].value;
586972
587867
  if (!rawValue.trim()) {
586973
587868
  const nested = {};
586974
587869
  parent[key] = nested;
586975
- stack.push({ indent, value: nested });
587870
+ stack.push({ indent: indent2, value: nested });
586976
587871
  } else {
586977
587872
  parent[key] = parseScalar(rawValue.trim());
586978
587873
  }
@@ -589220,7 +590115,7 @@ function readServicesManifest(missionDir) {
589220
590115
  commandArrayField = null;
589221
590116
  };
589222
590117
  for (const line of content.split("\n")) {
589223
- const indent = line.match(/^\s*/)?.[0].length ?? 0;
590118
+ const indent2 = line.match(/^\s*/)?.[0].length ?? 0;
589224
590119
  const t2 = line.trim();
589225
590120
  if (!t2)
589226
590121
  continue;
@@ -589270,12 +590165,12 @@ function readServicesManifest(missionDir) {
589270
590165
  continue;
589271
590166
  }
589272
590167
  if (section === "services" && curSvc.name) {
589273
- if (serviceArrayField === "dependsOn" && indent >= 6 && t2.startsWith("- ")) {
590168
+ if (serviceArrayField === "dependsOn" && indent2 >= 6 && t2.startsWith("- ")) {
589274
590169
  curSvc.dependsOn ??= [];
589275
590170
  curSvc.dependsOn.push(unquoteScalar(t2.slice(2)));
589276
590171
  continue;
589277
590172
  }
589278
- if (inEnvironment && indent >= 6 && /^[A-Za-z_][A-Za-z0-9_.-]*:/.test(t2)) {
590173
+ if (inEnvironment && indent2 >= 6 && /^[A-Za-z_][A-Za-z0-9_.-]*:/.test(t2)) {
589279
590174
  const idx = t2.indexOf(":");
589280
590175
  curSvc.environment ??= {};
589281
590176
  curSvc.environment[t2.slice(0, idx).trim()] = unquoteScalar(t2.slice(idx + 1));
@@ -589303,7 +590198,7 @@ function readServicesManifest(missionDir) {
589303
590198
  }
589304
590199
  }
589305
590200
  if (section === "commands" && curCmd.name) {
589306
- if (commandArrayField === "requiresServices" && indent >= 6 && t2.startsWith("- ")) {
590201
+ if (commandArrayField === "requiresServices" && indent2 >= 6 && t2.startsWith("- ")) {
589307
590202
  curCmd.requiresServices ??= [];
589308
590203
  curCmd.requiresServices.push(unquoteScalar(t2.slice(2)));
589309
590204
  continue;
@@ -589875,14 +590770,14 @@ function buildFolderListing(dirPath, cwd4, limit = 200) {
589875
590770
  for (const d2 of dirs) {
589876
590771
  if (count >= limit)
589877
590772
  break;
589878
- const indent = " ".repeat(depth);
589879
- lines.push(`${indent}- ${d2}/`);
590773
+ const indent2 = " ".repeat(depth);
590774
+ lines.push(`${indent2}- ${d2}/`);
589880
590775
  count++;
589881
590776
  }
589882
590777
  for (const f2 of files) {
589883
590778
  if (count >= limit)
589884
590779
  break;
589885
- const indent = " ".repeat(depth);
590780
+ const indent2 = " ".repeat(depth);
589886
590781
  const full = join117(current, f2);
589887
590782
  let meta = "?";
589888
590783
  try {
@@ -589900,7 +590795,7 @@ function buildFolderListing(dirPath, cwd4, limit = 200) {
589900
590795
  } catch {
589901
590796
  meta = "?";
589902
590797
  }
589903
- lines.push(`${indent}- ${f2} (${meta})`);
590798
+ lines.push(`${indent2}- ${f2} (${meta})`);
589904
590799
  count++;
589905
590800
  }
589906
590801
  if (count < limit) {
@@ -602480,7 +603375,7 @@ function keywords(text2) {
602480
603375
  const seen = /* @__PURE__ */ new Set();
602481
603376
  for (const raw of text2.toLowerCase().match(/[a-z0-9_.-]{4,}/g) ?? []) {
602482
603377
  const token = raw.replace(/^[.-]+|[.-]+$/g, "");
602483
- if (token.length < 4 || STOPWORDS2.has(token) || seen.has(token)) continue;
603378
+ if (token.length < 4 || STOPWORDS3.has(token) || seen.has(token)) continue;
602484
603379
  seen.add(token);
602485
603380
  out.push(token);
602486
603381
  if (out.length >= 8) break;
@@ -602765,7 +603660,7 @@ function renderScopedPersonalityContext(doc) {
602765
603660
  function buildScopedPersonalityContext(scope) {
602766
603661
  return renderScopedPersonalityContext(loadScopedPersonality(scope));
602767
603662
  }
602768
- var PROFILE_VERSION, MAX_PROFILE_OBSERVATIONS, MAX_PROFILE_DURABLE_OBSERVATIONS, MAX_PROFILE_RELATIONSHIP_EVENTS, MAX_PROFILE_SAMPLES, MAX_PROFILE_TAGS, STOPWORDS2;
603663
+ var PROFILE_VERSION, MAX_PROFILE_OBSERVATIONS, MAX_PROFILE_DURABLE_OBSERVATIONS, MAX_PROFILE_RELATIONSHIP_EVENTS, MAX_PROFILE_SAMPLES, MAX_PROFILE_TAGS, STOPWORDS3;
602769
603664
  var init_scoped_personality = __esm({
602770
603665
  "packages/cli/src/tui/scoped-personality.ts"() {
602771
603666
  "use strict";
@@ -602775,7 +603670,7 @@ var init_scoped_personality = __esm({
602775
603670
  MAX_PROFILE_RELATIONSHIP_EVENTS = 120;
602776
603671
  MAX_PROFILE_SAMPLES = 16;
602777
603672
  MAX_PROFILE_TAGS = 12;
602778
- STOPWORDS2 = /* @__PURE__ */ new Set([
603673
+ STOPWORDS3 = /* @__PURE__ */ new Set([
602779
603674
  "about",
602780
603675
  "after",
602781
603676
  "again",
@@ -613475,8 +614370,8 @@ ${CONTENT_BG_SEQ}`);
613475
614370
  for (const pattern of patterns) {
613476
614371
  const match = visible.match(pattern);
613477
614372
  if (match?.[1]) {
613478
- const indent = match[1];
613479
- return indent.slice(0, Math.min(indent.length, Math.max(0, width - 4)));
614373
+ const indent2 = match[1];
614374
+ return indent2.slice(0, Math.min(indent2.length, Math.max(0, width - 4)));
613480
614375
  }
613481
614376
  }
613482
614377
  const leading = visible.match(/^\s*/)?.[0] ?? "";
@@ -618220,11 +619115,11 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
618220
619115
  return ` ${c3.dim("│")}${content}${" ".repeat(pad)}${c3.dim("│")}
618221
619116
  `;
618222
619117
  };
618223
- const boxWrappedDimLine = (content, indent = " ") => {
619118
+ const boxWrappedDimLine = (content, indent2 = " ") => {
618224
619119
  const formatted = formatMarkdownBlock(content);
618225
- const lines = wrapText2(formatted, Math.max(1, boxW - visibleLen2(indent)));
619120
+ const lines = wrapText2(formatted, Math.max(1, boxW - visibleLen2(indent2)));
618226
619121
  for (const line of lines) {
618227
- process.stdout.write(boxLine(`${indent}${c3.dim(line)}`));
619122
+ process.stdout.write(boxLine(`${indent2}${c3.dim(line)}`));
618228
619123
  }
618229
619124
  };
618230
619125
  const hLine = (ch) => ` ${c3.dim(ch + "─".repeat(boxW) + (ch === "╭" ? "╮" : ch === "├" ? "┤" : "╯"))}
@@ -698982,7 +699877,7 @@ function getAsyncApiSpec() {
698982
699877
  }
698983
699878
  };
698984
699879
  }
698985
- function jsonToYaml(value2, indent = 0) {
699880
+ function jsonToYaml(value2, indent2 = 0) {
698986
699881
  const pad = (n2) => " ".repeat(n2);
698987
699882
  if (value2 === null) return "null";
698988
699883
  if (value2 === void 0) return "null";
@@ -698992,7 +699887,7 @@ function jsonToYaml(value2, indent = 0) {
698992
699887
  if (value2.length === 0) return '""';
698993
699888
  if (/[\n\r]/.test(value2)) {
698994
699889
  const lines = value2.replace(/\r\n?/g, "\n").split("\n");
698995
- return "|-\n" + lines.map((l2) => pad(indent + 1) + l2).join("\n");
699890
+ return "|-\n" + lines.map((l2) => pad(indent2 + 1) + l2).join("\n");
698996
699891
  }
698997
699892
  if (/^(true|false|null|yes|no|on|off|~|\d|-\d|\.\d|\.inf|\.nan|@|`|\*|&|!|\?|\||>|%|"|')/i.test(value2) || /[#:,\[\]{}]/.test(value2) || /^\s|\s$/.test(value2)) {
698998
699893
  return JSON.stringify(value2);
@@ -699002,13 +699897,13 @@ function jsonToYaml(value2, indent = 0) {
699002
699897
  if (Array.isArray(value2)) {
699003
699898
  if (value2.length === 0) return "[]";
699004
699899
  return "\n" + value2.map((item) => {
699005
- const rendered = jsonToYaml(item, indent + 1);
699900
+ const rendered = jsonToYaml(item, indent2 + 1);
699006
699901
  if (rendered.startsWith("\n")) {
699007
- return pad(indent) + "-" + rendered.replace(/^\n/, "\n");
699902
+ return pad(indent2) + "-" + rendered.replace(/^\n/, "\n");
699008
699903
  }
699009
699904
  const lines = rendered.split("\n");
699010
- if (lines.length === 1) return pad(indent) + "- " + lines[0];
699011
- return pad(indent) + "- " + lines[0] + "\n" + lines.slice(1).map((l2) => pad(indent + 1) + l2.replace(/^ /, "")).join("\n");
699905
+ if (lines.length === 1) return pad(indent2) + "- " + lines[0];
699906
+ return pad(indent2) + "- " + lines[0] + "\n" + lines.slice(1).map((l2) => pad(indent2 + 1) + l2.replace(/^ /, "")).join("\n");
699012
699907
  }).join("\n");
699013
699908
  }
699014
699909
  if (typeof value2 === "object") {
@@ -699018,11 +699913,11 @@ function jsonToYaml(value2, indent = 0) {
699018
699913
  return "\n" + keys.map((k) => {
699019
699914
  const v = obj[k];
699020
699915
  const safeKey = /^[a-zA-Z_][a-zA-Z0-9_./-]*$/.test(k) && !/^(true|false|null|yes|no|on|off)$/i.test(k) ? k : JSON.stringify(k);
699021
- const rendered = jsonToYaml(v, indent + 1);
699916
+ const rendered = jsonToYaml(v, indent2 + 1);
699022
699917
  if (rendered.startsWith("\n")) {
699023
- return pad(indent) + safeKey + ":" + rendered;
699918
+ return pad(indent2) + safeKey + ":" + rendered;
699024
699919
  }
699025
- return pad(indent) + safeKey + ": " + rendered;
699920
+ return pad(indent2) + safeKey + ": " + rendered;
699026
699921
  }).join("\n");
699027
699922
  }
699028
699923
  return JSON.stringify(value2);
@@ -713725,14 +714620,18 @@ ${entry.fullContent}`
713725
714620
  adversaryBuffer.splice(0, adversaryBuffer.length - 50);
713726
714621
  }
713727
714622
  if (lm.intervention) {
714623
+ const lines = [String(lm.intervention)];
714624
+ if (lm.details && showAdversary) {
714625
+ for (const d2 of String(lm.details).split("\n").filter(Boolean))
714626
+ lines.push(d2);
714627
+ }
713728
714628
  contentWrite(() => {
713729
- renderWarning(`Adversary: ${lm.intervention}`);
713730
- });
713731
- } else if (lm.details && showAdversary) {
713732
- contentWrite(() => {
713733
- renderInfo(
713734
- `Adversary details: ${String(lm.details).split("\n").filter(Boolean).join(" | ")}`
713735
- );
714629
+ renderBoxedBlock({
714630
+ title: "⚠ Adversary",
714631
+ lines,
714632
+ colorCode: ADVERSARY_COLOR,
714633
+ kind: "plain"
714634
+ });
713736
714635
  });
713737
714636
  }
713738
714637
  }
@@ -713740,16 +714639,24 @@ ${entry.fullContent}`
713740
714639
  case "adversary_reaction":
713741
714640
  if (event.adversary) {
713742
714641
  const adv = event.adversary;
713743
- const conf = adv.confidence != null ? ` (${Math.round(adv.confidence * 100)}%)` : "";
713744
- const text2 = adv.shortText + conf;
713745
- contentWrite(() => {
713746
- renderWarning(`Adversary ${adv.class}: ${text2}`);
713747
- });
714642
+ const conf = adv.confidence != null ? `${Math.round(adv.confidence * 100)}%` : "";
714643
+ const lines = [adv.shortText];
713748
714644
  if (adv.details) {
714645
+ for (const d2 of String(adv.details).split("\n").filter(Boolean))
714646
+ lines.push(d2);
713749
714647
  adversaryBuffer.push(adv.details);
713750
714648
  if (adversaryBuffer.length > 50)
713751
714649
  adversaryBuffer.splice(0, adversaryBuffer.length - 50);
713752
714650
  }
714651
+ contentWrite(() => {
714652
+ renderBoxedBlock({
714653
+ title: `⚠ Adversary · ${adv.class}`,
714654
+ metrics: conf,
714655
+ lines,
714656
+ colorCode: ADVERSARY_COLOR,
714657
+ kind: "plain"
714658
+ });
714659
+ });
713753
714660
  }
713754
714661
  break;
713755
714662
  }
@@ -720435,7 +721342,7 @@ Rules:
720435
721342
  process.exit(1);
720436
721343
  }
720437
721344
  }
720438
- var NEXUS_DIRECTORY_ORIGIN3, NEXUS_AGENT_DIRECTORY_URL, NEXUS_SPONSORS_URL3, _generativeProgressSink, _interactiveSessionActive, _interactiveSessionReason, _voiceChatSession2, taskManager, _apiCallbacks, _shellToolRef, _replToolRef, _fullSubAgentToolRef, _agentToolRef, _sendMessageToolRef, _agentLifecycleMgr, _activeRunnerRef, _parentRunnerForArchive, _wireSubAgentCallbacks, _wireAgentToolCallbacks, _wireSubAgentToolCallbacks, _autoUpdatedThisSession, _mcpManager, _pluginManager, _mcpTools, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
721345
+ var NEXUS_DIRECTORY_ORIGIN3, NEXUS_AGENT_DIRECTORY_URL, NEXUS_SPONSORS_URL3, ADVERSARY_COLOR, _generativeProgressSink, _interactiveSessionActive, _interactiveSessionReason, _voiceChatSession2, taskManager, _apiCallbacks, _shellToolRef, _replToolRef, _fullSubAgentToolRef, _agentToolRef, _sendMessageToolRef, _agentLifecycleMgr, _activeRunnerRef, _parentRunnerForArchive, _wireSubAgentCallbacks, _wireAgentToolCallbacks, _wireSubAgentToolCallbacks, _autoUpdatedThisSession, _mcpManager, _pluginManager, _mcpTools, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
720439
721346
  var init_interactive = __esm({
720440
721347
  "packages/cli/src/tui/interactive.ts"() {
720441
721348
  "use strict";
@@ -720501,6 +721408,7 @@ var init_interactive = __esm({
720501
721408
  NEXUS_DIRECTORY_ORIGIN3 = (process.env["OMNIUS_NEXUS_DIRECTORY_ORIGIN"] || process.env["OMNIUS_NEXUS_SIGNALING_SERVER"] || "https://openagents.nexus").replace(/\/+$/, "");
720502
721409
  NEXUS_AGENT_DIRECTORY_URL = `${NEXUS_DIRECTORY_ORIGIN3}/api/v1/directory`;
720503
721410
  NEXUS_SPONSORS_URL3 = `${NEXUS_DIRECTORY_ORIGIN3}/api/v1/sponsors`;
721411
+ ADVERSARY_COLOR = 214;
720504
721412
  _generativeProgressSink = null;
720505
721413
  _interactiveSessionActive = false;
720506
721414
  _interactiveSessionReason = "";