omnius 1.0.533 → 1.0.535

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
@@ -6981,14 +6981,14 @@ var init_file_write = __esm({
6981
6981
  init_text_encoding();
6982
6982
  FileWriteTool = class {
6983
6983
  name = "file_write";
6984
- description = "Write UTF-8 text to a file, creating directories as needed. For content with heavy quoting, raw JSON, control characters, or large full-file payloads, pass content_base64 instead of shell heredocs/cat/tee.";
6984
+ description = "Create new files or deliberately replace small, empty, or placeholder files; use file_edit/file_patch for local changes. For content with heavy quoting, raw JSON, control characters, or large full-file payloads, pass content_base64 instead of shell heredocs/cat/tee.";
6985
6985
  parameters = {
6986
6986
  type: "object",
6987
6987
  properties: {
6988
6988
  path: { type: "string", description: "Absolute or relative file path" },
6989
6989
  content: {
6990
6990
  type: "string",
6991
- description: "UTF-8 text content to write. Use content_base64 when JSON escaping is fragile."
6991
+ description: "Complete UTF-8 file content. Do not send an existing large file merely to change one region; use file_edit/file_patch."
6992
6992
  },
6993
6993
  content_base64: {
6994
6994
  type: "string",
@@ -119389,7 +119389,7 @@ var require_auto = __commonJS({
119389
119389
  // ../node_modules/acme-client/src/client.js
119390
119390
  var require_client = __commonJS({
119391
119391
  "../node_modules/acme-client/src/client.js"(exports, module) {
119392
- var { createHash: createHash51 } = __require("crypto");
119392
+ var { createHash: createHash53 } = __require("crypto");
119393
119393
  var { getPemBodyAsB64u } = require_crypto();
119394
119394
  var { log: log22 } = require_logger();
119395
119395
  var HttpClient = require_http();
@@ -119700,14 +119700,14 @@ var require_client = __commonJS({
119700
119700
  */
119701
119701
  async getChallengeKeyAuthorization(challenge) {
119702
119702
  const jwk = this.http.getJwk();
119703
- const keysum = createHash51("sha256").update(JSON.stringify(jwk));
119703
+ const keysum = createHash53("sha256").update(JSON.stringify(jwk));
119704
119704
  const thumbprint = keysum.digest("base64url");
119705
119705
  const result = `${challenge.token}.${thumbprint}`;
119706
119706
  if (challenge.type === "http-01") {
119707
119707
  return result;
119708
119708
  }
119709
119709
  if (challenge.type === "dns-01") {
119710
- return createHash51("sha256").update(result).digest("base64url");
119710
+ return createHash53("sha256").update(result).digest("base64url");
119711
119711
  }
119712
119712
  if (challenge.type === "tls-alpn-01") {
119713
119713
  return result;
@@ -262387,7 +262387,7 @@ var require_websocket2 = __commonJS({
262387
262387
  var http6 = __require("http");
262388
262388
  var net5 = __require("net");
262389
262389
  var tls2 = __require("tls");
262390
- var { randomBytes: randomBytes31, createHash: createHash51 } = __require("crypto");
262390
+ var { randomBytes: randomBytes31, createHash: createHash53 } = __require("crypto");
262391
262391
  var { Duplex: Duplex3, Readable } = __require("stream");
262392
262392
  var { URL: URL3 } = __require("url");
262393
262393
  var PerMessageDeflate3 = require_permessage_deflate2();
@@ -263047,7 +263047,7 @@ var require_websocket2 = __commonJS({
263047
263047
  abortHandshake(websocket, socket, "Invalid Upgrade header");
263048
263048
  return;
263049
263049
  }
263050
- const digest3 = createHash51("sha1").update(key + GUID).digest("base64");
263050
+ const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
263051
263051
  if (res.headers["sec-websocket-accept"] !== digest3) {
263052
263052
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
263053
263053
  return;
@@ -263414,7 +263414,7 @@ var require_websocket_server = __commonJS({
263414
263414
  var EventEmitter15 = __require("events");
263415
263415
  var http6 = __require("http");
263416
263416
  var { Duplex: Duplex3 } = __require("stream");
263417
- var { createHash: createHash51 } = __require("crypto");
263417
+ var { createHash: createHash53 } = __require("crypto");
263418
263418
  var extension3 = require_extension2();
263419
263419
  var PerMessageDeflate3 = require_permessage_deflate2();
263420
263420
  var subprotocol3 = require_subprotocol();
@@ -263715,7 +263715,7 @@ var require_websocket_server = __commonJS({
263715
263715
  );
263716
263716
  }
263717
263717
  if (this._state > RUNNING) return abortHandshake(socket, 503);
263718
- const digest3 = createHash51("sha1").update(key + GUID).digest("base64");
263718
+ const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
263719
263719
  const headers = [
263720
263720
  "HTTP/1.1 101 Switching Protocols",
263721
263721
  "Upgrade: websocket",
@@ -276522,13 +276522,13 @@ Justification: ${justification || "(none provided)"}`,
276522
276522
  }
276523
276523
  const snapshot = JSON.stringify(this.selfState, null, 2);
276524
276524
  try {
276525
- const { createHash: createHash51 } = await import("node:crypto");
276525
+ const { createHash: createHash53 } = await import("node:crypto");
276526
276526
  const snapshotDir = join44(this.cwd, ".omnius", "identity", "snapshots");
276527
276527
  await mkdir7(snapshotDir, { recursive: true });
276528
276528
  const version5 = this.selfState.version;
276529
276529
  const snapshotPath = join44(snapshotDir, `v${version5}.json`);
276530
276530
  await writeFile12(snapshotPath, snapshot, "utf8");
276531
- const hash = createHash51("sha256").update(snapshot).digest("hex");
276531
+ const hash = createHash53("sha256").update(snapshot).digest("hex");
276532
276532
  await writeFile12(join44(this.cwd, ".omnius", "identity", "latest-hash.txt"), hash, "utf8");
276533
276533
  let ipfsCid = "";
276534
276534
  try {
@@ -276661,8 +276661,8 @@ New: ${newNarrative.slice(0, 200)}...`,
276661
276661
  }
276662
276662
  // ── Helpers ──────────────────────────────────────────────────────────────
276663
276663
  createDefaultState() {
276664
- const { createHash: createHash51 } = __require("node:crypto");
276665
- const machineId = createHash51("sha256").update(this.cwd).digest("hex").slice(0, 12);
276664
+ const { createHash: createHash53 } = __require("node:crypto");
276665
+ const machineId = createHash53("sha256").update(this.cwd).digest("hex").slice(0, 12);
276666
276666
  return {
276667
276667
  self_id: `omnius-${machineId}`,
276668
276668
  version: 1,
@@ -276744,9 +276744,9 @@ New: ${newNarrative.slice(0, 200)}...`,
276744
276744
  let cid;
276745
276745
  if (this.selfState.version > prevVersion) {
276746
276746
  try {
276747
- const { createHash: createHash51 } = await import("node:crypto");
276747
+ const { createHash: createHash53 } = await import("node:crypto");
276748
276748
  const stateJson = JSON.stringify(this.selfState);
276749
- const hash = createHash51("sha256").update(stateJson).digest("hex").slice(0, 32);
276749
+ const hash = createHash53("sha256").update(stateJson).digest("hex").slice(0, 32);
276750
276750
  const cidsPath = join44(this.cwd, ".omnius", "identity", "cids.json");
276751
276751
  const cidsData = { latest: "", hash, version: this.selfState.version };
276752
276752
  try {
@@ -297713,6 +297713,12 @@ function updateWorkboardCard(workingDir, input) {
297713
297713
  updates.lane = "blocked";
297714
297714
  if ((updates.status === "open" || updates.status === "in_progress") && card.lane === "blocked" && !updates.lane)
297715
297715
  updates.lane = "worker";
297716
+ validateSpecialCardAdmission({
297717
+ ...card,
297718
+ ...updates,
297719
+ evidenceRequirements: updates.evidenceRequirements ?? card.evidenceRequirements,
297720
+ ownedFiles: updates.ownedFiles ?? card.ownedFiles
297721
+ });
297716
297722
  const decisionReason = cleanString(input.decisionReason);
297717
297723
  const decision2 = decisionReason ? makeDecision(updates.assignee && updates.assignee !== card.assignee ? "reassigned" : updates.status === "blocked" ? "blocked" : "note", decisionReason, { cardId: card.id, actor: input.actor, createdAt: now2 }) : void 0;
297718
297724
  return appendWorkboardEvents(workingDir, runId, [{
@@ -297992,6 +297998,23 @@ function verifyCompileCardEvidence(card) {
297992
297998
  missing: ["fresh verifier output after patch"]
297993
297999
  };
297994
298000
  }
298001
+ function compactWorkboardCard(card) {
298002
+ return definedOnly({
298003
+ id: truncateForModel(card.id),
298004
+ title: truncateForModel(card.title),
298005
+ status: card.status,
298006
+ lane: card.lane,
298007
+ assignee: truncateForModel(card.assignee),
298008
+ dependencies: truncateStringArrayForModel(card.dependencies),
298009
+ evidenceCount: card.evidence.length,
298010
+ evidenceRequirements: truncateStringArrayForModel(card.evidenceRequirements),
298011
+ blocker: truncateForModel(card.blocker),
298012
+ diagnosticFingerprint: truncateForModel(card.diagnosticFingerprint),
298013
+ ownedFiles: truncateStringArrayForModel(card.ownedFiles),
298014
+ verifierCommand: truncateForModel(card.verifierCommand),
298015
+ rank: card.rank
298016
+ });
298017
+ }
297995
298018
  function compactWorkboardSnapshot(snapshot, maxCards = 24) {
297996
298019
  const counts = {
297997
298020
  open: 0,
@@ -298003,26 +298026,17 @@ function compactWorkboardSnapshot(snapshot, maxCards = 24) {
298003
298026
  };
298004
298027
  for (const card of snapshot.cards)
298005
298028
  counts[card.status]++;
298006
- const cards = snapshot.cards.slice(0, maxCards).map((card) => ({
298007
- id: card.id,
298008
- title: card.title,
298009
- status: card.status,
298010
- lane: card.lane,
298011
- assignee: card.assignee,
298012
- dependencies: card.dependencies,
298013
- evidenceCount: card.evidence.length,
298014
- evidenceRequirements: card.evidenceRequirements,
298015
- blocker: card.blocker
298016
- }));
298029
+ const cardLimit = Math.max(0, Math.min(50, Math.floor(maxCards)));
298030
+ const cards = snapshot.cards.slice(0, cardLimit).map(compactWorkboardCard);
298017
298031
  return {
298018
- runId: snapshot.runId,
298032
+ runId: truncateRequiredForModel(snapshot.runId),
298019
298033
  status: snapshot.status,
298020
- owner: snapshot.owner,
298034
+ owner: truncateRequiredForModel(snapshot.owner),
298021
298035
  updatedAt: snapshot.updatedAt,
298022
298036
  counts,
298023
298037
  cards,
298024
298038
  hiddenCardCount: Math.max(0, snapshot.cards.length - cards.length),
298025
- diagnostics: snapshot.diagnostics.slice(0, 12)
298039
+ diagnostics: snapshot.diagnostics.slice(0, WORKBOARD_MODEL_MAX_DIAGNOSTICS).map(compactWorkboardDiagnosticForModel)
298026
298040
  };
298027
298041
  }
298028
298042
  function formatWorkboardCompact(snapshot, maxCards = 24) {
@@ -298136,7 +298150,7 @@ function normalizeCardInput(input, timestamp) {
298136
298150
  assertEnum(input.role, VALID_ROLES, "role");
298137
298151
  const dependencies = normalizeStringArray(input.dependencies);
298138
298152
  const evidenceRequirements = normalizeStringArray(input.evidenceRequirements);
298139
- return {
298153
+ const card = {
298140
298154
  id: cleanString(input.id) || newCardId(),
298141
298155
  title,
298142
298156
  description: cleanString(input.description) || "",
@@ -298158,6 +298172,8 @@ function normalizeCardInput(input, timestamp) {
298158
298172
  verifierCommand: cleanString(input.verifierCommand),
298159
298173
  rank: typeof input.rank === "number" && Number.isFinite(input.rank) ? input.rank : void 0
298160
298174
  };
298175
+ validateSpecialCardAdmission(card);
298176
+ return card;
298161
298177
  }
298162
298178
  function normalizeCardUpdates(input) {
298163
298179
  const updates = {};
@@ -298199,6 +298215,26 @@ function normalizeCardUpdates(input) {
298199
298215
  throw new WorkboardError("empty_update", "at least one card field must be updated");
298200
298216
  return updates;
298201
298217
  }
298218
+ function validateSpecialCardAdmission(card) {
298219
+ const compileLike = card.id.startsWith("compile-") || Boolean(card.diagnosticFingerprint) || card.assignee?.startsWith("fixer:compile-") === true;
298220
+ if (compileLike) {
298221
+ const missing = [];
298222
+ if (!cleanString(card.diagnosticFingerprint))
298223
+ missing.push("diagnosticFingerprint");
298224
+ if (!cleanString(card.verifierCommand))
298225
+ missing.push("verifierCommand");
298226
+ if (!Array.isArray(card.ownedFiles) || card.ownedFiles.length === 0)
298227
+ missing.push("ownedFiles");
298228
+ if (missing.length > 0) {
298229
+ throw new WorkboardError("invalid_compile_card", `compile cards require ${missing.join(", ")}`, { cardId: card.id, missing });
298230
+ }
298231
+ }
298232
+ if (card.id.startsWith("failure-") && card.evidenceRequirements.length === 0) {
298233
+ throw new WorkboardError("invalid_failure_card", "failure recovery cards require explicit evidence requirements", {
298234
+ cardId: card.id
298235
+ });
298236
+ }
298237
+ }
298202
298238
  function validateDependencies(cardId, dependencies, knownCardIds) {
298203
298239
  for (const dependency of dependencies) {
298204
298240
  if (dependency === cardId) {
@@ -298398,6 +298434,75 @@ function evidenceMatchesRequirement(evidence, lowercaseRequirement) {
298398
298434
  function diagnosticKey(diagnostic) {
298399
298435
  return `${diagnostic.code}:${diagnostic.cardId ?? ""}:${diagnostic.assignee ?? ""}`;
298400
298436
  }
298437
+ function compactWorkboardDiagnosticForModel(diagnostic) {
298438
+ return definedOnly({
298439
+ ...diagnostic,
298440
+ id: truncateForModel(diagnostic.id),
298441
+ message: truncateForModel(diagnostic.message),
298442
+ cardId: truncateForModel(diagnostic.cardId),
298443
+ actor: truncateForModel(diagnostic.actor),
298444
+ assignee: truncateForModel(diagnostic.assignee),
298445
+ suggestedAction: truncateForModel(diagnostic.suggestedAction),
298446
+ details: diagnostic.details ? compactWorkboardToolPayload(diagnostic.details) : void 0
298447
+ });
298448
+ }
298449
+ function compactWorkboardToolPayload(value2, depth = 0) {
298450
+ if (depth > 5)
298451
+ return "[truncated]";
298452
+ if (typeof value2 === "string")
298453
+ return truncateForModel(value2);
298454
+ if (Array.isArray(value2)) {
298455
+ return value2.slice(0, WORKBOARD_MODEL_MAX_ARRAY_ITEMS).map((item) => compactWorkboardToolPayload(item, depth + 1));
298456
+ }
298457
+ if (!value2 || typeof value2 !== "object")
298458
+ return value2;
298459
+ if (isWorkboardSnapshot(value2))
298460
+ return compactWorkboardSnapshot(value2, WORKBOARD_MODEL_MAX_CARDS);
298461
+ if (isWorkboardCard(value2))
298462
+ return compactWorkboardCard(value2);
298463
+ const out = {};
298464
+ for (const [key, item] of Object.entries(value2)) {
298465
+ if (key === "snapshot" && isWorkboardSnapshot(item)) {
298466
+ out["board"] = compactWorkboardSnapshot(item, WORKBOARD_MODEL_MAX_CARDS);
298467
+ continue;
298468
+ }
298469
+ if (key === "card" && isWorkboardCard(item)) {
298470
+ out[key] = compactWorkboardCard(item);
298471
+ continue;
298472
+ }
298473
+ if (key === "cards" && Array.isArray(item)) {
298474
+ out[key] = item.slice(0, WORKBOARD_MODEL_MAX_CARDS).map((card) => isWorkboardCard(card) ? compactWorkboardCard(card) : compactWorkboardToolPayload(card, depth + 1));
298475
+ continue;
298476
+ }
298477
+ out[key] = compactWorkboardToolPayload(item, depth + 1);
298478
+ }
298479
+ return out;
298480
+ }
298481
+ function isWorkboardSnapshot(value2) {
298482
+ const record = value2;
298483
+ return record.schemaVersion === WORKBOARD_SCHEMA_VERSION && Array.isArray(record.cards) && typeof record.runId === "string";
298484
+ }
298485
+ function isWorkboardCard(value2) {
298486
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
298487
+ return false;
298488
+ const record = value2;
298489
+ return typeof record.id === "string" && typeof record.title === "string" && typeof record.status === "string" && Array.isArray(record.evidence);
298490
+ }
298491
+ function truncateForModel(value2) {
298492
+ if (!value2)
298493
+ return void 0;
298494
+ if (value2.length <= WORKBOARD_MODEL_MAX_STRING)
298495
+ return value2;
298496
+ return `${value2.slice(0, WORKBOARD_MODEL_MAX_STRING - 15)}...[truncated]`;
298497
+ }
298498
+ function truncateRequiredForModel(value2) {
298499
+ return truncateForModel(value2) ?? "";
298500
+ }
298501
+ function truncateStringArrayForModel(value2) {
298502
+ if (!Array.isArray(value2))
298503
+ return [];
298504
+ return value2.slice(0, WORKBOARD_MODEL_MAX_ARRAY_ITEMS).map((item) => truncateForModel(item)).filter((item) => Boolean(item));
298505
+ }
298401
298506
  function defaultLaneForStatus(status) {
298402
298507
  if (status === "blocked")
298403
298508
  return "blocked";
@@ -298660,11 +298765,15 @@ function enumArg(args, name10, allowed) {
298660
298765
  assertEnum(value2, allowed, name10);
298661
298766
  return value2;
298662
298767
  }
298663
- var WORKBOARD_SCHEMA_VERSION, WorkboardError, activeWorkboardWrites, VALID_LANES, VALID_STATUSES, VALID_ROLES, VALID_EVIDENCE_KINDS, REPEATED_FAILURE_THRESHOLD, WorkboardBaseTool, WorkboardCreateTool, WorkboardAddCardTool, WorkboardUpdateCardTool, WorkboardAttachEvidenceTool, WorkboardCompleteCardTool, WorkboardShowTool;
298768
+ var WORKBOARD_SCHEMA_VERSION, WORKBOARD_MODEL_MAX_CARDS, WORKBOARD_MODEL_MAX_ARRAY_ITEMS, WORKBOARD_MODEL_MAX_DIAGNOSTICS, WORKBOARD_MODEL_MAX_STRING, WorkboardError, activeWorkboardWrites, VALID_LANES, VALID_STATUSES, VALID_ROLES, VALID_EVIDENCE_KINDS, REPEATED_FAILURE_THRESHOLD, WorkboardBaseTool, WorkboardCreateTool, WorkboardAddCardTool, WorkboardUpdateCardTool, WorkboardAttachEvidenceTool, WorkboardCompleteCardTool, WorkboardShowTool;
298664
298769
  var init_workboard = __esm({
298665
298770
  "packages/execution/dist/tools/workboard.js"() {
298666
298771
  "use strict";
298667
298772
  WORKBOARD_SCHEMA_VERSION = 1;
298773
+ WORKBOARD_MODEL_MAX_CARDS = 8;
298774
+ WORKBOARD_MODEL_MAX_ARRAY_ITEMS = 8;
298775
+ WORKBOARD_MODEL_MAX_DIAGNOSTICS = 8;
298776
+ WORKBOARD_MODEL_MAX_STRING = 260;
298668
298777
  WorkboardError = class extends Error {
298669
298778
  code;
298670
298779
  details;
@@ -298691,18 +298800,22 @@ var init_workboard = __esm({
298691
298800
  }
298692
298801
  result(start2, payload, mutated, runId) {
298693
298802
  const mutatedFiles = mutated && runId ? [workboardPaths(this.workingDir, runId).eventsPath, workboardPaths(this.workingDir, runId).activePath] : void 0;
298803
+ const modelPayload = compactWorkboardToolPayload(payload);
298694
298804
  return {
298695
298805
  success: true,
298696
298806
  output: JSON.stringify(payload),
298807
+ llmContent: JSON.stringify(modelPayload),
298697
298808
  durationMs: performance.now() - start2,
298698
298809
  mutated,
298699
298810
  mutatedFiles
298700
298811
  };
298701
298812
  }
298702
298813
  failure(start2, code8, message2, details, output) {
298814
+ const payload = output ?? { ok: false, code: code8, message: message2, details };
298703
298815
  return {
298704
298816
  success: false,
298705
- output: JSON.stringify(output ?? { ok: false, code: code8, message: message2, details }),
298817
+ output: JSON.stringify(payload),
298818
+ llmContent: JSON.stringify(compactWorkboardToolPayload(payload)),
298706
298819
  error: message2,
298707
298820
  durationMs: performance.now() - start2
298708
298821
  };
@@ -298747,7 +298860,7 @@ var init_workboard = __esm({
298747
298860
  actor: stringArg(args, "actor"),
298748
298861
  cards: normalizeCardsArg(args["cards"])
298749
298862
  });
298750
- return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), snapshot }, true, runId);
298863
+ return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot) }, true, runId);
298751
298864
  } catch (err) {
298752
298865
  return this.catchFailure(start2, err);
298753
298866
  }
@@ -298784,7 +298897,7 @@ var init_workboard = __esm({
298784
298897
  actor: stringArg(args, "actor"),
298785
298898
  decisionReason: stringArg(args, "decision_reason", "decisionReason")
298786
298899
  });
298787
- return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), card: snapshot.cards.at(-1) }, true, runId);
298900
+ return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), card: compactWorkboardCard(snapshot.cards.at(-1)) }, true, runId);
298788
298901
  } catch (err) {
298789
298902
  return this.catchFailure(start2, err);
298790
298903
  }
@@ -298826,7 +298939,8 @@ var init_workboard = __esm({
298826
298939
  decisionReason: stringArg(args, "decision_reason", "decisionReason"),
298827
298940
  updates
298828
298941
  });
298829
- return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), card: snapshot.cards.find((card) => card.id === cardId) }, true, runId);
298942
+ const card = snapshot.cards.find((card2) => card2.id === cardId);
298943
+ return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), ...card ? { card: compactWorkboardCard(card) } : {} }, true, runId);
298830
298944
  } catch (err) {
298831
298945
  return this.catchFailure(start2, err);
298832
298946
  }
@@ -298873,7 +298987,8 @@ var init_workboard = __esm({
298873
298987
  actor: stringArg(args, "actor"),
298874
298988
  evidence
298875
298989
  });
298876
- return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), card: snapshot.cards.find((card) => card.id === cardId) }, true, runId);
298990
+ const card = snapshot.cards.find((card2) => card2.id === cardId);
298991
+ return this.result(start2, { ok: true, board: compactWorkboardSnapshot(snapshot), ...card ? { card: compactWorkboardCard(card) } : {} }, true, runId);
298877
298992
  } catch (err) {
298878
298993
  return this.catchFailure(start2, err);
298879
298994
  }
@@ -298925,7 +299040,12 @@ var init_workboard = __esm({
298925
299040
  board: compactWorkboardSnapshot(result.snapshot)
298926
299041
  });
298927
299042
  }
298928
- return this.result(start2, { ok: true, message: result.message, board: compactWorkboardSnapshot(result.snapshot), card: result.card }, true, runId);
299043
+ return this.result(start2, {
299044
+ ok: true,
299045
+ message: result.message,
299046
+ board: compactWorkboardSnapshot(result.snapshot),
299047
+ ...result.card ? { card: compactWorkboardCard(result.card) } : {}
299048
+ }, true, runId);
298929
299049
  } catch (err) {
298930
299050
  return this.catchFailure(start2, err);
298931
299051
  }
@@ -553029,7 +553149,28 @@ print(json.dumps({"ok": False, "error": "No whisper backend available"}))
553029
553149
 
553030
553150
  // packages/execution/dist/tools/full-sub-agent.js
553031
553151
  import { spawn as spawn19, ChildProcess } from "node:child_process";
553032
- import { randomBytes as randomBytes18 } from "node:crypto";
553152
+ import { createHash as createHash24, randomBytes as randomBytes18 } from "node:crypto";
553153
+ function fullSubAgentTaskHash(task) {
553154
+ return createHash24("sha256").update(task).digest("hex").slice(0, 12);
553155
+ }
553156
+ function sanitizeFullSubAgentModelText(value2, maxChars = FULL_SUB_AGENT_MODEL_MAX_CHARS) {
553157
+ const stripped = value2.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, "").replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/<think>[\s\S]*$/gi, "");
553158
+ const lines = stripped.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).filter((line) => !/^🔊/.test(line)).filter((line) => !/SHELL TRANSCRIPT/i.test(line)).filter((line) => !/^Task:\s/i.test(line)).filter((line) => !/^E Task timeout/i.test(line)).filter((line) => !/^E Incomplete:/i.test(line)).filter((line) => !/^⚠ Task incomplete/i.test(line)).slice(-FULL_SUB_AGENT_MODEL_MAX_LINES);
553159
+ const joined = lines.join("\n");
553160
+ return joined.length > maxChars ? `${joined.slice(0, Math.max(0, maxChars - 14)).trimEnd()}...[truncated]` : joined;
553161
+ }
553162
+ function fullSubAgentModelContent(input) {
553163
+ const taskPreview = sanitizeFullSubAgentModelText(input.task, 220);
553164
+ const resultPreview = input.output ? sanitizeFullSubAgentModelText(input.output) : "";
553165
+ return [
553166
+ `[full_sub_agent] id=${input.id} status=${input.status} exit_code=${input.exitCode ?? "unknown"} task_sha256=${fullSubAgentTaskHash(input.task)} output_lines=${input.outputLines ?? 0}`,
553167
+ taskPreview ? `task_preview:
553168
+ ${taskPreview}` : null,
553169
+ resultPreview ? `result_preview:
553170
+ ${resultPreview}` : null,
553171
+ `full_output_available_via=full_sub_agent action=output id=${input.id}`
553172
+ ].filter((line) => Boolean(line)).join("\n");
553173
+ }
553033
553174
  function buildSubProcessArgs(opts) {
553034
553175
  const args = [];
553035
553176
  args.push(opts.task);
@@ -553193,7 +553334,7 @@ function killAllFullSubAgents() {
553193
553334
  function removeFullSubAgent(id2) {
553194
553335
  _activeSubProcesses.delete(id2);
553195
553336
  }
553196
- var _activeSubProcesses, FullSubAgentTool;
553337
+ var _activeSubProcesses, FULL_SUB_AGENT_MODEL_MAX_LINES, FULL_SUB_AGENT_MODEL_MAX_CHARS, FullSubAgentTool;
553197
553338
  var init_full_sub_agent = __esm({
553198
553339
  "packages/execution/dist/tools/full-sub-agent.js"() {
553199
553340
  "use strict";
@@ -553201,6 +553342,8 @@ var init_full_sub_agent = __esm({
553201
553342
  init_model_broker();
553202
553343
  init_process_lifecycle();
553203
553344
  _activeSubProcesses = /* @__PURE__ */ new Map();
553345
+ FULL_SUB_AGENT_MODEL_MAX_LINES = 6;
553346
+ FULL_SUB_AGENT_MODEL_MAX_CHARS = 900;
553204
553347
  FullSubAgentTool = class {
553205
553348
  name = "full_sub_agent";
553206
553349
  description = "Spawn a COMPLETE Omnius sub-process with ALL tools and capabilities. Unlike sub_agent (shared process, limited tools), this spawns a separate omnius instance with its own clean context window, full tool set, memory, skills, and COHERE access. Use for complex multi-file tasks that benefit from a fresh context. The sub-process runs omnius --non-interactive until task_complete, abort, or timeout. By default this tool returns immediately with a process ID for monitoring; set wait=true to block until the child exits.";
@@ -553326,6 +553469,14 @@ var init_full_sub_agent = __esm({
553326
553469
  Output lines: ${entry.outputBuffer.length}` + (tail ? `
553327
553470
 
553328
553471
  ${tail}` : ""),
553472
+ llmContent: fullSubAgentModelContent({
553473
+ id: entry.id,
553474
+ task,
553475
+ status: "completed",
553476
+ exitCode,
553477
+ output: tail || output,
553478
+ outputLines: entry.outputBuffer.length
553479
+ }),
553329
553480
  durationMs
553330
553481
  };
553331
553482
  }
@@ -553334,19 +553485,35 @@ ${tail}` : ""),
553334
553485
  output: output ? `Full Omnius sub-agent failed: ${entry.id}
553335
553486
 
553336
553487
  ${tail || output}` : "",
553488
+ llmContent: fullSubAgentModelContent({
553489
+ id: entry.id,
553490
+ task,
553491
+ status: "failed",
553492
+ exitCode,
553493
+ output: tail || output,
553494
+ outputLines: entry.outputBuffer.length
553495
+ }),
553337
553496
  error: `Full Omnius sub-agent exited before successful completion (exit code ${exitCode ?? "unknown"}).`,
553338
553497
  durationMs
553339
553498
  };
553340
553499
  }
553500
+ const taskPreview = sanitizeFullSubAgentModelText(task, 220);
553341
553501
  return {
553342
553502
  success: true,
553343
553503
  output: `Full Omnius sub-agent spawned: ${entry.id}
553344
553504
  PID: ${entry.pid}
553345
553505
  Model: ${model}
553346
- Task: ${task.slice(0, 100)}
553347
- Use full_sub_agent(action='status', id='${entry.id}') to check progress.
553506
+ task_sha256=${fullSubAgentTaskHash(task)}
553507
+ ` + (taskPreview ? ` task_preview: ${taskPreview.replace(/\n/g, " ")}
553508
+ ` : "") + ` Use full_sub_agent(action='status', id='${entry.id}') to check progress.
553348
553509
  Use full_sub_agent(action='output', id='${entry.id}') to see output.
553349
553510
  Use full_sub_agent(action='stop', id='${entry.id}') to kill it.`,
553511
+ llmContent: fullSubAgentModelContent({
553512
+ id: entry.id,
553513
+ task,
553514
+ status: "running",
553515
+ outputLines: entry.outputBuffer.length
553516
+ }),
553350
553517
  durationMs: performance.now() - start2
553351
553518
  };
553352
553519
  }
@@ -553362,6 +553529,13 @@ ${tail || output}` : "",
553362
553529
  output: `${id2} [${entry.status}] PID:${entry.pid} ${runtime}s
553363
553530
  Task: ${entry.task.slice(0, 100)}
553364
553531
  Output lines: ${entry.outputBuffer.length}`,
553532
+ llmContent: fullSubAgentModelContent({
553533
+ id: id2,
553534
+ task: entry.task,
553535
+ status: entry.status,
553536
+ exitCode: entry.exitCode,
553537
+ outputLines: entry.outputBuffer.length
553538
+ }),
553365
553539
  durationMs: performance.now() - start2
553366
553540
  };
553367
553541
  }
@@ -553372,7 +553546,18 @@ ${tail || output}` : "",
553372
553546
  const runtime = ((Date.now() - e2.startedAt) / 1e3).toFixed(0);
553373
553547
  return `${e2.id} [${e2.status}] PID:${e2.pid} ${runtime}s — ${e2.task.slice(0, 60)}`;
553374
553548
  });
553375
- return { success: true, output: lines.join("\n"), durationMs: performance.now() - start2 };
553549
+ return {
553550
+ success: true,
553551
+ output: lines.join("\n"),
553552
+ llmContent: all2.map((e2) => fullSubAgentModelContent({
553553
+ id: e2.id,
553554
+ task: e2.task,
553555
+ status: e2.status,
553556
+ exitCode: e2.exitCode,
553557
+ outputLines: e2.outputBuffer.length
553558
+ })).join("\n\n"),
553559
+ durationMs: performance.now() - start2
553560
+ };
553376
553561
  }
553377
553562
  case "list":
553378
553563
  return this.execute({ ...args, action: "status" });
@@ -553382,8 +553567,20 @@ ${tail || output}` : "",
553382
553567
  if (!entry)
553383
553568
  return { success: false, output: "", error: `Unknown sub-agent: ${id2}`, durationMs: performance.now() - start2 };
553384
553569
  const tail = entry.outputBuffer.slice(-50).join("\n");
553385
- return { success: true, output: `${id2} output (last 50 lines):
553386
- ${tail}`, durationMs: performance.now() - start2 };
553570
+ return {
553571
+ success: true,
553572
+ output: `${id2} output (last 50 lines):
553573
+ ${tail}`,
553574
+ llmContent: fullSubAgentModelContent({
553575
+ id: id2,
553576
+ task: entry.task,
553577
+ status: entry.status,
553578
+ exitCode: entry.exitCode,
553579
+ output: tail,
553580
+ outputLines: entry.outputBuffer.length
553581
+ }),
553582
+ durationMs: performance.now() - start2
553583
+ };
553387
553584
  }
553388
553585
  case "stop": {
553389
553586
  const id2 = String(args["id"] ?? "");
@@ -555507,7 +555704,7 @@ var init_client3 = __esm({
555507
555704
  import { existsSync as existsSync73, readFileSync as readFileSync52, writeFileSync as writeFileSync35, mkdirSync as mkdirSync44, chmodSync, statSync as statSync30 } from "node:fs";
555508
555705
  import { join as join85, dirname as dirname23 } from "node:path";
555509
555706
  import { homedir as homedir23 } from "node:os";
555510
- import { randomBytes as randomBytes19, createHash as createHash24 } from "node:crypto";
555707
+ import { randomBytes as randomBytes19, createHash as createHash25 } from "node:crypto";
555511
555708
  function secretsPath(scope, repoRoot) {
555512
555709
  return scope === "global" ? join85(homedir23(), ".omnius", "secrets.json") : join85(repoRoot, ".omnius", "secrets.json");
555513
555710
  }
@@ -555548,7 +555745,7 @@ function sanitizeHint(hint) {
555548
555745
  return hint.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 32) || "GENERIC";
555549
555746
  }
555550
555747
  function shortDigest(value2) {
555551
- return createHash24("sha256").update(value2).digest("hex").slice(0, 6);
555748
+ return createHash25("sha256").update(value2).digest("hex").slice(0, 6);
555552
555749
  }
555553
555750
  function randomSuffix() {
555554
555751
  return randomBytes19(3).toString("hex");
@@ -557362,7 +557559,7 @@ var init_environment_snapshot = __esm({
557362
557559
  import { existsSync as existsSync77, mkdirSync as mkdirSync46, writeFileSync as writeFileSync38, readFileSync as readFileSync56, readdirSync as readdirSync26, unlinkSync as unlinkSync16, rmSync as rmSync10 } from "node:fs";
557363
557560
  import { join as join88, basename as basename18, isAbsolute as isAbsolute8, resolve as resolve46 } from "node:path";
557364
557561
  import { homedir as homedir26 } from "node:os";
557365
- import { createHash as createHash25 } from "node:crypto";
557562
+ import { createHash as createHash26 } from "node:crypto";
557366
557563
  function isYouTubeUrl2(url) {
557367
557564
  return /(?:youtube\.com\/(?:watch|shorts|live|embed|v\/)|youtu\.be\/)/i.test(url);
557368
557565
  }
@@ -557447,7 +557644,7 @@ async function extractAudioIfPresent(videoPath, audioPath, probe) {
557447
557644
  function imageHash(imagePath) {
557448
557645
  try {
557449
557646
  const data = readFileSync56(imagePath);
557450
- return createHash25("md5").update(data).digest("hex").slice(0, 12);
557647
+ return createHash26("md5").update(data).digest("hex").slice(0, 12);
557451
557648
  } catch {
557452
557649
  return "unknown";
557453
557650
  }
@@ -569125,11 +569322,6 @@ var init_personality = __esm({
569125
569322
  // packages/orchestrator/dist/critic.js
569126
569323
  function buildCriticGuidanceMessage(call, hits, opts = {}) {
569127
569324
  const argPreview = JSON.stringify(call.args ?? {}).slice(0, 200);
569128
- const actionReason = call.actionReason ? [
569129
- call.actionReason.scope ? `scope=${call.actionReason.scope}` : "",
569130
- call.actionReason.intent ? `intent=${call.actionReason.intent}` : "",
569131
- call.actionReason.evidence ? `evidence=${call.actionReason.evidence}` : ""
569132
- ].filter(Boolean).join("; ").slice(0, 500) : "";
569133
569325
  const cached = opts.cachedResult ? `
569134
569326
  Prior evidence preview:
569135
569327
  ${opts.cachedResult.slice(0, 700)}` : "";
@@ -569137,8 +569329,7 @@ ${opts.cachedResult.slice(0, 700)}` : "";
569137
569329
  return `[RUNTIME EVIDENCE CACHE — non-blocking]
569138
569330
  Observation: ${source}
569139
569331
  Call: ${call.tool}(${argPreview})
569140
- ` + (actionReason ? `Action reason: ${actionReason}
569141
- ` : "") + `State: exact prior evidence exists for these arguments in the current state version.
569332
+ State: exact prior evidence exists for these arguments in the current state version.
569142
569333
  Next action contract: let this result inform the next step once, then pivot to a concrete action.
569143
569334
  Suggested next actions: edit/write the implicated file, run verification, read a different specific file, or complete with evidence. Prefer not to repeat this exact call again unless the filesystem, browser, or page state changed.${cached}`;
569144
569335
  }
@@ -569147,10 +569338,13 @@ function buildCachedResultEnvelope(result) {
569147
569338
  ${result}`;
569148
569339
  }
569149
569340
  function evaluate2(inputs) {
569150
- const { proposedCall, fingerprint, isReadLike, recentToolResults, dedupHitCount, adversaryRedundantSignal } = inputs;
569151
- if (adversaryRedundantSignal) {
569341
+ const { proposedCall, fingerprint, recentToolResults, dedupHitCount, adversaryRedundantSignal } = inputs;
569342
+ const cacheEligible = proposedCall.tool === "memory_write" || NOOP_WRITE_CACHE_TOOLS.has(proposedCall.tool);
569343
+ if (adversaryRedundantSignal && cacheEligible) {
569152
569344
  const cached = recentToolResults.get(fingerprint);
569153
- const cachedResult = cached ? buildCachedResultEnvelope(cached.result) : void 0;
569345
+ if (!cached)
569346
+ return { decision: "pass" };
569347
+ const cachedResult = buildCachedResultEnvelope(cached.result);
569154
569348
  return {
569155
569349
  decision: "guidance",
569156
569350
  reason: "Adversary flagged this fingerprint as redundant",
@@ -569163,7 +569357,6 @@ function evaluate2(inputs) {
569163
569357
  compacted: cached?.compacted
569164
569358
  };
569165
569359
  }
569166
- const cacheEligible = isReadLike || proposedCall.tool === "shell" || proposedCall.tool === "memory_write" || NOOP_WRITE_CACHE_TOOLS.has(proposedCall.tool);
569167
569360
  if (cacheEligible) {
569168
569361
  const cached = recentToolResults.get(fingerprint);
569169
569362
  if (cached !== void 0) {
@@ -569598,14 +569791,14 @@ var init_artifact_inspector = __esm({
569598
569791
  // packages/orchestrator/dist/lesson-bank.js
569599
569792
  import { existsSync as existsSync91, mkdirSync as mkdirSync52, appendFileSync as appendFileSync7, readFileSync as readFileSync69 } from "node:fs";
569600
569793
  import { join as join101, dirname as dirname30 } from "node:path";
569601
- import { createHash as createHash26 } from "node:crypto";
569794
+ import { createHash as createHash27 } from "node:crypto";
569602
569795
  function tokenize4(text2) {
569603
569796
  if (!text2)
569604
569797
  return [];
569605
569798
  return text2.toLowerCase().split(TOKENIZE_RE).filter((t2) => t2.length >= 3).slice(0, 80);
569606
569799
  }
569607
569800
  function shortHash(s2) {
569608
- return createHash26("sha256").update(s2).digest("hex").slice(0, 16);
569801
+ return createHash27("sha256").update(s2).digest("hex").slice(0, 16);
569609
569802
  }
569610
569803
  function solicit(args) {
569611
569804
  const { taskGoal, stem, reflections, successOutputPreview } = args;
@@ -569701,7 +569894,7 @@ var init_lesson_bank = __esm({
569701
569894
  // packages/orchestrator/dist/intervention-replay.js
569702
569895
  import { existsSync as existsSync92, mkdirSync as mkdirSync53, readFileSync as readFileSync70, writeFileSync as writeFileSync43, readdirSync as readdirSync29 } from "node:fs";
569703
569896
  import { join as join102, dirname as dirname31 } from "node:path";
569704
- import { createHash as createHash27 } from "node:crypto";
569897
+ import { createHash as createHash28 } from "node:crypto";
569705
569898
  function checkpointDir2(workingDir) {
569706
569899
  return workingDir ? join102(workingDir, ".omnius", "checkpoints") : join102(process.env["HOME"] || ".", ".omnius", "checkpoints");
569707
569900
  }
@@ -569735,7 +569928,7 @@ function sanitizeMessagesForCheckpoint(messages2) {
569735
569928
  deduped.push(m2);
569736
569929
  continue;
569737
569930
  }
569738
- const digest3 = createHash27("sha1").update(content).digest("hex");
569931
+ const digest3 = createHash28("sha1").update(content).digest("hex");
569739
569932
  if (seenSystemDigests.has(digest3))
569740
569933
  continue;
569741
569934
  seenSystemDigests.add(digest3);
@@ -572807,13 +573000,13 @@ var init_reflectionBuffer = __esm({
572807
573000
  case "tool_misuse":
572808
573001
  return {
572809
573002
  whatFailed: `Wrong tool or arguments for the task. Tool ${lastFailedTool?.tool ?? "unknown"} failed: ${lastFailedTool?.error?.slice(0, 60) ?? lastError.slice(0, 60)}`,
572810
- whatToDoDifferently: `Try a different tool. If file_edit failed, try file_write. If shell failed with a complex command, break it into simpler steps. Read the file first before editing.`,
573003
+ whatToDoDifferently: `Correct the tool contract without broadening mutation scope. If file_edit failed, read the current target and use exact text or a line-range file_patch; do not fall back to file_write. If shell failed with a complex command, break it into simpler diagnostic steps.`,
572811
573004
  confidence: 0.8
572812
573005
  };
572813
573006
  case "repetition":
572814
573007
  return {
572815
573008
  whatFailed: `Got stuck in a loop after ${turnsSpent} turns trying ${failedApproaches.length} approaches. The same tools kept failing with similar errors.`,
572816
- whatToDoDifferently: "Stop and try a completely different strategy. If you were editing, try rewriting from scratch. If searching failed, try a broader or narrower query. Ask yourself: what assumption am I making that might be wrong?",
573009
+ whatToDoDifferently: "Stop and change the diagnosis, not the mutation radius. If you were editing, refresh the implicated range and patch only the verified fault; never rewrite an existing file from scratch as loop recovery. If searching failed, try a broader or narrower query. Ask which assumption is wrong.",
572817
573010
  confidence: 0.9
572818
573011
  };
572819
573012
  case "timeout":
@@ -573691,12 +573884,12 @@ var init_codeGraphLink = __esm({
573691
573884
  });
573692
573885
 
573693
573886
  // packages/orchestrator/dist/artifactContract.js
573694
- import { createHash as createHash28 } from "node:crypto";
573887
+ import { createHash as createHash29 } from "node:crypto";
573695
573888
  function shortHash2(content) {
573696
573889
  if (!content)
573697
573890
  return "empty";
573698
573891
  try {
573699
- return createHash28("sha256").update(content.slice(0, 4096)).digest("hex").slice(0, 8);
573892
+ return createHash29("sha256").update(content.slice(0, 4096)).digest("hex").slice(0, 8);
573700
573893
  } catch {
573701
573894
  let h = 2166136261;
573702
573895
  for (let i2 = 0; i2 < Math.min(content.length, 4096); i2++) {
@@ -576096,9 +576289,6 @@ function classifyFailureKind(text2, args) {
576096
576289
  }
576097
576290
  if (/Unknown tool\b|Unknown tool ['"`]/i.test(text2))
576098
576291
  return "missing_tool";
576099
- if (/\[TOOL ACTION REASON CONTRACT\]|must include action_reason|action_reason must/i.test(text2)) {
576100
- return "action_reason_missing";
576101
- }
576102
576292
  if (/\bexpected_hash\b|hash mismatch|fresh file_read|stale edit|stale target|FULL FILE REWRITE CONTRACT|old_string (?:not found|does not match|must be unique|appears \d+)/i.test(text2)) {
576103
576293
  return "stale_hash";
576104
576294
  }
@@ -576339,16 +576529,6 @@ var init_failure_taxonomy = __esm({
576339
576529
  ],
576340
576530
  createRecoveryCard: true
576341
576531
  },
576342
- action_reason_missing: {
576343
- severity: "warning",
576344
- retryable: true,
576345
- guidance: "A side-effectful tool call lacked the required public action_reason envelope. Retry only with compact task-state metadata, or use a read-only/control-plane tool if no mutation is intended.",
576346
- workboardEvidenceRequirements: [
576347
- "corrected action_reason envelope",
576348
- "same intended operation through the right tool"
576349
- ],
576350
- createRecoveryCard: false
576351
- },
576352
576532
  workboard_noop: {
576353
576533
  severity: "warning",
576354
576534
  retryable: true,
@@ -577080,7 +577260,7 @@ var init_context_fabric = __esm({
577080
577260
  const header = [
577081
577261
  "[ACTIVE CONTEXT FRAME]",
577082
577262
  options2.turn !== void 0 ? `turn: ${options2.turn}` : null,
577083
- "Scope: runtime state for the next action. Treat this as the single merged context intake; do not re-read or re-emit it unless state changes."
577263
+ "Scope: runtime state for the next action. Do not quote or re-emit this frame. Prior evidence is orientation; execute a narrow file_read or the declared verifier whenever current text/hash or post-mutation proof is required."
577084
577264
  ].filter(Boolean);
577085
577265
  let content = [...header, "", ...sectionLines].join("\n").trim();
577086
577266
  const controlChars = included.filter(isControlSignal).reduce((sum2, signal) => sum2 + signal.content.length, 0);
@@ -577239,6 +577419,46 @@ function hasConcreteGoalMessage(messages2) {
577239
577419
  function hasUserMessage(messages2) {
577240
577420
  return messages2.some((message2) => message2.role === "user" && messageText(message2.content).trim().length > 0);
577241
577421
  }
577422
+ function hasAssistantPayload(message2) {
577423
+ const text2 = messageText(message2.content).trim();
577424
+ if (text2 && !/^(null|undefined)$/i.test(text2))
577425
+ return true;
577426
+ const record = message2;
577427
+ if (Array.isArray(record["tool_calls"]) && record["tool_calls"].length > 0)
577428
+ return true;
577429
+ return Boolean(record["function_call"]);
577430
+ }
577431
+ function staleToolFailureKey(content) {
577432
+ const text2 = content.replace(/\s+/g, " ").trim();
577433
+ if (!/(FAILED:|failed again|doom-loop|result compacted|Earlier read of .* cleared)/i.test(text2)) {
577434
+ return null;
577435
+ }
577436
+ const tool = text2.match(/^\[?([a-zA-Z_][a-zA-Z0-9_]*)\(/)?.[1] ?? "tool";
577437
+ const path16 = text2.match(/"path"\s*:\s*"([^"]+)"/)?.[1] ?? text2.match(/Earlier read of ([^ ]+) cleared/)?.[1] ?? "";
577438
+ const family = text2.match(/FAILED:\s*\[([^\]\n]+)/i)?.[1] ?? text2.match(/(doom-loop[^.]+)/i)?.[1] ?? text2.match(/(Earlier read of [^ ]+ cleared)/i)?.[1] ?? "failure";
577439
+ return [tool, path16, family].join("|").toLowerCase().replace(/[a-f0-9]{16,}/g, "<hash>").replace(/\d+/g, "#");
577440
+ }
577441
+ function retireDuplicateToolFailures(messages2) {
577442
+ const seen = /* @__PURE__ */ new Set();
577443
+ const out = [...messages2];
577444
+ for (let index = out.length - 1; index >= 0; index--) {
577445
+ const message2 = out[index];
577446
+ if (message2.role !== "tool" || typeof message2.content !== "string")
577447
+ continue;
577448
+ const key = staleToolFailureKey(message2.content);
577449
+ if (!key)
577450
+ continue;
577451
+ if (!seen.has(key)) {
577452
+ seen.add(key);
577453
+ continue;
577454
+ }
577455
+ out[index] = {
577456
+ ...message2,
577457
+ content: "[retired_duplicate_tool_failure] a newer matching failure appears later. Use that latest diagnostic; retry only after refreshing prerequisite evidence or correcting the arguments."
577458
+ };
577459
+ }
577460
+ return out;
577461
+ }
577242
577462
  function prepareModelFacingApiMessages(input) {
577243
577463
  const preserveFirstSystem = input.preserveFirstSystem !== false;
577244
577464
  const sanitized = [];
@@ -577255,6 +577475,16 @@ function prepareModelFacingApiMessages(input) {
577255
577475
  sanitized.push({ ...message2, content: cleaned });
577256
577476
  continue;
577257
577477
  }
577478
+ if (message2.role === "assistant" && !hasAssistantPayload(message2)) {
577479
+ continue;
577480
+ }
577481
+ if (message2.role === "tool" && typeof message2.content === "string") {
577482
+ const cleaned = sanitizeModelVisibleContextText(message2.content);
577483
+ if (!cleaned)
577484
+ continue;
577485
+ sanitized.push({ ...message2, content: cleaned });
577486
+ continue;
577487
+ }
577258
577488
  sanitized.push({ ...message2 });
577259
577489
  }
577260
577490
  const keep = new Array(sanitized.length).fill(true);
@@ -577274,7 +577504,7 @@ function prepareModelFacingApiMessages(input) {
577274
577504
  }
577275
577505
  seenSystemKeys.add(key);
577276
577506
  }
577277
- const deduped = sanitized.filter((_message, index) => keep[index]);
577507
+ const deduped = retireDuplicateToolFailures(sanitized.filter((_message, index) => keep[index]));
577278
577508
  if (!hasUserMessage(deduped) && !hasConcreteGoalMessage(deduped)) {
577279
577509
  const goal = deriveCurrentGoal({
577280
577510
  explicitGoal: input.currentGoal,
@@ -577530,8 +577760,8 @@ var init_evidenceLedger = __esm({
577530
577760
  return null;
577531
577761
  const sorted = [...this.entries.values()].sort((a2, b) => b.lastReadTurn - a2.lastReadTurn);
577532
577762
  const lines = [
577533
- "Evidence already gathered this run you ALREADY have the content below.",
577534
- "Do NOT re-read a FRESH file; use this. Re-read ONLY entries marked STALE.",
577763
+ "Earlier file evidence from this run is shown below for orientation.",
577764
+ "Use a displayed full-fidelity snapshot when it is sufficient, but file_read is allowed and required when an edit/hash guard asks for current text, a displayed body is elided, or external state may have changed.",
577535
577765
  ""
577536
577766
  ];
577537
577767
  let used = lines.join("\n").length;
@@ -577574,7 +577804,7 @@ var init_evidenceLedger = __esm({
577574
577804
  import { existsSync as existsSync102, mkdirSync as mkdirSync58, readdirSync as readdirSync32, readFileSync as readFileSync78, statSync as statSync39, unlinkSync as unlinkSync17, writeFileSync as writeFileSync48, appendFileSync as appendFileSync9 } from "node:fs";
577575
577805
  import { homedir as homedir35 } from "node:os";
577576
577806
  import { join as join111, resolve as resolve54 } from "node:path";
577577
- import { createHash as createHash29 } from "node:crypto";
577807
+ import { createHash as createHash30 } from "node:crypto";
577578
577808
  function contextWindowDumpDir(cwd4 = process.cwd()) {
577579
577809
  const envDir = process.env["OMNIUS_CONTEXT_WINDOW_DUMP_DIR"]?.trim();
577580
577810
  if (envDir)
@@ -577625,9 +577855,7 @@ function recordContextWindowDump(input) {
577625
577855
  const payload = JSON.stringify(record, null, 2);
577626
577856
  writeFileSync48(filePath, payload, "utf-8");
577627
577857
  writeFileSync48(join111(dir, `latest-${record.agentType}.json`), payload, "utf-8");
577628
- if (record.agentType === "main" || record.agentType === "sub-agent" || record.agentType === "adversary") {
577629
- writeFileSync48(join111(dir, "latest.json"), payload, "utf-8");
577630
- }
577858
+ writeFileSync48(join111(dir, "latest.json"), payload, "utf-8");
577631
577859
  appendFileSync9(join111(dir, "index.jsonl"), JSON.stringify(toSummary(record, filePath)) + "\n", "utf-8");
577632
577860
  maybePruneOldDumpFiles(dir);
577633
577861
  } catch {
@@ -577921,7 +578149,7 @@ function safeId(value2) {
577921
578149
  return String(value2 || "unknown").replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 160);
577922
578150
  }
577923
578151
  function shortHash3(value2) {
577924
- return createHash29("sha256").update(value2).digest("hex").slice(0, 10);
578152
+ return createHash30("sha256").update(value2).digest("hex").slice(0, 10);
577925
578153
  }
577926
578154
  function pruneOldDumpFiles(dir) {
577927
578155
  const raw = Number(process.env["OMNIUS_CONTEXT_WINDOW_DUMP_MAX_FILES"]);
@@ -578008,8 +578236,6 @@ ${obs.stateDigest.slice(0, 1800)}
578008
578236
  `This is a loop. Reason about WHY — for THIS specific call, not generically.`,
578009
578237
  ls2.alreadyHave ? `Evidence the agent ALREADY obtained from a prior identical call:
578010
578238
  ${ls2.alreadyHave.slice(0, 900)}` : `(No cached result available for the repeated call.)`,
578011
- ls2.actionReason ? `Agent's stated action reason:
578012
- scope=${ls2.actionReason.scope ?? ""}; intent=${ls2.actionReason.intent ?? ""}; evidence=${ls2.actionReason.evidence ?? ""}; expected=${ls2.actionReason.expected_result ?? ""}`.slice(0, 700) : "",
578013
578239
  "",
578014
578240
  stateDigest.trim(),
578015
578241
  "",
@@ -578334,7 +578560,7 @@ var init_adversaryStream = __esm({
578334
578560
 
578335
578561
  // packages/orchestrator/dist/debugArtifactLibrary.js
578336
578562
  import { appendFileSync as appendFileSync10, existsSync as existsSync103, mkdirSync as mkdirSync59, readFileSync as readFileSync79, statSync as statSync40, writeFileSync as writeFileSync49 } from "node:fs";
578337
- import { createHash as createHash30 } from "node:crypto";
578563
+ import { createHash as createHash31 } from "node:crypto";
578338
578564
  import { basename as basename24, join as join112, relative as relative12, resolve as resolve55 } from "node:path";
578339
578565
  function debugArtifactRoot(cwd4 = process.cwd(), stateDir) {
578340
578566
  const envDir = process.env["OMNIUS_DEBUG_ARTIFACT_DIR"]?.trim();
@@ -578413,7 +578639,6 @@ function recordDebugToolEvent(input) {
578413
578639
  },
578414
578640
  ...input.focusSupervisor ? { focusSupervisor: input.focusSupervisor } : {},
578415
578641
  ...input.focusDecision ? { focusDecision: input.focusDecision } : {},
578416
- ...input.actionReason ? { actionReason: compactDebugValue(input.actionReason) } : {},
578417
578642
  ...input.repeatShortCircuit !== void 0 ? { repeatShortCircuit: input.repeatShortCircuit } : {},
578418
578643
  ...input.runtimeAuthored !== void 0 ? { runtimeAuthored: input.runtimeAuthored } : {},
578419
578644
  ...input.runtimeGuidance ? { runtimeGuidancePreview: trim(input.runtimeGuidance, 1200) } : {},
@@ -579102,35 +579327,11 @@ function trim(value2, max) {
579102
579327
  return `${value2.slice(0, max)}
579103
579328
  [truncated ${value2.length - max} chars]`;
579104
579329
  }
579105
- function compactDebugValue(value2, depth = 0) {
579106
- if (value2 == null)
579107
- return value2;
579108
- if (typeof value2 === "string") {
579109
- return value2.length > 500 ? `${value2.slice(0, 497)}...` : value2;
579110
- }
579111
- if (typeof value2 === "number" || typeof value2 === "boolean")
579112
- return value2;
579113
- if (Array.isArray(value2)) {
579114
- if (depth >= 2)
579115
- return `[array:${value2.length}]`;
579116
- return value2.slice(0, 8).map((entry) => compactDebugValue(entry, depth + 1));
579117
- }
579118
- if (typeof value2 === "object") {
579119
- if (depth >= 2)
579120
- return "[object]";
579121
- const out = {};
579122
- for (const [key, entry] of Object.entries(value2).slice(0, 12)) {
579123
- out[key] = compactDebugValue(entry, depth + 1);
579124
- }
579125
- return out;
579126
- }
579127
- return String(value2);
579128
- }
579129
579330
  function safeId2(value2) {
579130
579331
  return String(value2 || "unknown").replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 160);
579131
579332
  }
579132
579333
  function shortHash4(value2) {
579133
- return createHash30("sha256").update(value2).digest("hex").slice(0, 10);
579334
+ return createHash31("sha256").update(value2).digest("hex").slice(0, 10);
579134
579335
  }
579135
579336
  var DEBUG_LIBRARY_DIR, RUN_EVENTS_LIMIT, PREVIEW_LIMIT;
579136
579337
  var init_debugArtifactLibrary = __esm({
@@ -579309,17 +579510,6 @@ function meaningfulCachedEvidencePreview(text2) {
579309
579510
  }
579310
579511
  return preview.join(" | ").slice(0, 700);
579311
579512
  }
579312
- function actionReasonSummary(actionReason) {
579313
- if (!actionReason)
579314
- return "";
579315
- const parts = [
579316
- actionReason.scope ? `scope=${actionReason.scope}` : "",
579317
- actionReason.intent ? `intent=${actionReason.intent}` : "",
579318
- actionReason.evidence ? `evidence=${actionReason.evidence}` : "",
579319
- actionReason.expected_result ? `expected=${actionReason.expected_result}` : ""
579320
- ].filter(Boolean);
579321
- return parts.length > 0 ? `Action reason observed: ${parts.join("; ").slice(0, 700)}` : "";
579322
- }
579323
579513
  function normalizeShellForFamily(command, cwd4) {
579324
579514
  let s2 = String(command || "").replace(/\\\r?\n/g, " ").replace(/\s+/g, " ").trim();
579325
579515
  if (cwd4 && cwd4.length > 1) {
@@ -579630,7 +579820,6 @@ var init_focusSupervisor = __esm({
579630
579820
  `${reason}.`,
579631
579821
  `Required next action: ${prior.requiredNextAction}.`,
579632
579822
  `Blocked action family: ${family}.`,
579633
- actionReasonSummary(input.actionReason),
579634
579823
  "This block is not counted as a new ignored directive."
579635
579824
  ].filter(Boolean).join("\n"), false);
579636
579825
  }
@@ -579657,7 +579846,6 @@ var init_focusSupervisor = __esm({
579657
579846
  "[FOCUS SUPERVISOR BLOCK: LOOP CONTROL]",
579658
579847
  `Directive ${prior.id} was repeatedly ignored with ${family}.`,
579659
579848
  `Required next action: ${directive.requiredNextAction}.`,
579660
- actionReasonSummary(input.actionReason),
579661
579849
  "Stop trying this action-family repeatedly. Pivot to a materially different approach or web_search the blocker, then continue."
579662
579850
  ].filter(Boolean).join("\n"), false);
579663
579851
  }
@@ -579697,7 +579885,6 @@ var init_focusSupervisor = __esm({
579697
579885
  `[FOCUS SUPERVISOR BLOCK] The previous directive was ignored: ${prior.reason}`,
579698
579886
  `Required next action: ${directive.requiredNextAction}.`,
579699
579887
  `Blocked action family: ${family}.`,
579700
- actionReasonSummary(input.actionReason),
579701
579888
  directive.requiredNextAction === "creative_pivot_or_research" ? "Stop trying variants of what failed. The task is NOT over — pivot to a fundamentally different approach or web_search the exact blocker, then act." : "Take the required next action before trying another variant."
579702
579889
  ].filter(Boolean).join("\n"), false);
579703
579890
  }
@@ -579713,7 +579900,6 @@ var init_focusSupervisor = __esm({
579713
579900
  return this.block(directive, [
579714
579901
  input.stalePreflightMessage,
579715
579902
  "",
579716
- actionReasonSummary(input.actionReason),
579717
579903
  "[FOCUS SUPERVISOR] Required next action: file_read the authoritative current target once, then build a new edit from current evidence or report incomplete."
579718
579904
  ].filter(Boolean).join("\n"), false);
579719
579905
  }
@@ -579735,7 +579921,6 @@ var init_focusSupervisor = __esm({
579735
579921
  input.cachedResultFailed ? "[FOCUS SUPERVISOR: CACHED FAILURE]" : "[FOCUS SUPERVISOR: CACHED EVIDENCE]",
579736
579922
  `This ${input.toolName} action family has already produced evidence and should not be re-executed unchanged.`,
579737
579923
  `Required next action: ${directive.requiredNextAction}.`,
579738
- actionReasonSummary(input.actionReason),
579739
579924
  "",
579740
579925
  compactCachedEvidence(input.cachedResult)
579741
579926
  ].filter(Boolean).join("\n"), !input.cachedResultFailed);
@@ -581211,7 +581396,7 @@ var init_domainDetector = __esm({
581211
581396
  });
581212
581397
 
581213
581398
  // packages/orchestrator/dist/compile-error-fix-loop.js
581214
- import { createHash as createHash31 } from "node:crypto";
581399
+ import { createHash as createHash32 } from "node:crypto";
581215
581400
  import path7 from "node:path";
581216
581401
  function rankCompilerDiagnostics(diags) {
581217
581402
  const normalized = diags.map((diag, index) => ({
@@ -581492,7 +581677,7 @@ function isCompileFixDiagnostic(value2) {
581492
581677
  return Boolean(value2 && typeof value2.fingerprint === "string" && typeof value2.rank === "number");
581493
581678
  }
581494
581679
  function shortHash5(value2) {
581495
- return createHash31("sha256").update(value2).digest("hex").slice(0, 10);
581680
+ return createHash32("sha256").update(value2).digest("hex").slice(0, 10);
581496
581681
  }
581497
581682
  function fence(value2) {
581498
581683
  return ["```", value2.trim(), "```"].join("\n");
@@ -583061,7 +583246,7 @@ var init_prompt_cache = __esm({
583061
583246
 
583062
583247
  // packages/orchestrator/dist/git-progress.js
583063
583248
  import { existsSync as existsSync104, readFileSync as readFileSync80, statSync as statSync41 } from "node:fs";
583064
- import { createHash as createHash32 } from "node:crypto";
583249
+ import { createHash as createHash33 } from "node:crypto";
583065
583250
  import { relative as relative13, resolve as resolve56, sep as sep4 } from "node:path";
583066
583251
  function isRunnerOwnedGitPath(path16) {
583067
583252
  const normalized = normalizeGitPath(path16);
@@ -583088,7 +583273,7 @@ function pathHash(repoRoot, relPath) {
583088
583273
  const st = statSync41(absolute);
583089
583274
  if (!st.isFile())
583090
583275
  return `non-file:${st.size}:${Math.floor(st.mtimeMs)}`;
583091
- return createHash32("sha256").update(readFileSync80(absolute)).digest("hex");
583276
+ return createHash33("sha256").update(readFileSync80(absolute)).digest("hex");
583092
583277
  } catch {
583093
583278
  return void 0;
583094
583279
  }
@@ -583925,7 +584110,7 @@ __export(preflightSnapshot_exports, {
583925
584110
  import { existsSync as existsSync105, readFileSync as readFileSync81, statSync as statSync42, statfsSync as statfsSync6 } from "node:fs";
583926
584111
  import { homedir as homedir36, platform as platform4, arch as arch2, totalmem as totalmem4, freemem as freemem3, hostname as hostname3 } from "node:os";
583927
584112
  import { join as join113 } from "node:path";
583928
- import { createHash as createHash33 } from "node:crypto";
584113
+ import { createHash as createHash34 } from "node:crypto";
583929
584114
  function capturePreflightSnapshot(workingDir) {
583930
584115
  const warnings = [];
583931
584116
  const configFingerprints = {};
@@ -584094,7 +584279,7 @@ function expandPath(p2) {
584094
584279
  return p2;
584095
584280
  }
584096
584281
  function sha2564(s2) {
584097
- return createHash33("sha256").update(s2).digest("hex").slice(0, 16);
584282
+ return createHash34("sha256").update(s2).digest("hex").slice(0, 16);
584098
584283
  }
584099
584284
  function freeDiskBytes(path16 = "/tmp") {
584100
584285
  try {
@@ -584996,9 +585181,6 @@ import { join as _pathJoin, relative as _pathRelative, resolve as _pathResolve }
584996
585181
  import { tmpdir as _osTmpdir } from "node:os";
584997
585182
  import { homedir as _osHomedir } from "node:os";
584998
585183
  import { z as z17 } from "zod";
584999
- function cleanToolActionReasonField(value2) {
585000
- return String(value2 ?? "").replace(/\s+/g, " ").trim();
585001
- }
585002
585184
  function stripShellQuotedSegments(command) {
585003
585185
  let out = "";
585004
585186
  let quote2 = null;
@@ -585737,7 +585919,7 @@ function classifyThinkOutcome(raw) {
585737
585919
  }
585738
585920
  return null;
585739
585921
  }
585740
- var TOOL_SUBSETS, TOOL_AUTO_DEMOTE_TURNS, TOOL_ACTION_REASON_KEYS, TOOL_ACTION_REASON_SCOPES, READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS, STATE_UPDATE_ACTION_REASON_SYNTHESIS_TOOLS, TOOL_ACTION_REASON_SCHEMA, SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, VISUAL_TOOLS, AUDIO_TOOLS, SOCIAL_TOOLS, SPATIAL_TOOLS, CODE_TOOLS, AgenticRunner, OllamaAgenticBackend;
585922
+ var TOOL_SUBSETS, TOOL_AUTO_DEMOTE_TURNS, LEGACY_ACTION_REASON_KEYS, SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, VISUAL_TOOLS, AUDIO_TOOLS, SOCIAL_TOOLS, SPATIAL_TOOLS, CODE_TOOLS, AgenticRunner, OllamaAgenticBackend;
585741
585923
  var init_agenticRunner = __esm({
585742
585924
  "packages/orchestrator/dist/agenticRunner.js"() {
585743
585925
  "use strict";
@@ -585835,75 +586017,7 @@ var init_agenticRunner = __esm({
585835
586017
  skill: ["skill_list", "skill_extract", "skill_execute", "skill_search"]
585836
586018
  };
585837
586019
  TOOL_AUTO_DEMOTE_TURNS = 10;
585838
- TOOL_ACTION_REASON_KEYS = /* @__PURE__ */ new Set([
585839
- "action_reason",
585840
- "actionReason",
585841
- "justification"
585842
- ]);
585843
- TOOL_ACTION_REASON_SCOPES = /* @__PURE__ */ new Set([
585844
- "discovery",
585845
- "targeted_patch",
585846
- "new_file",
585847
- "full_file_rewrite",
585848
- "verification",
585849
- "state_update",
585850
- "delegation",
585851
- "completion",
585852
- "other"
585853
- ]);
585854
- READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS = /* @__PURE__ */ new Set([
585855
- "file_read",
585856
- "file_explore",
585857
- "list_directory",
585858
- "grep_search",
585859
- "grep",
585860
- "glob_find",
585861
- "find_files",
585862
- "todo_read",
585863
- "memory_read",
585864
- "memory_search",
585865
- "semantic_map",
585866
- "code_graph",
585867
- "graph_query",
585868
- "graph_traverse",
585869
- "web_search",
585870
- "web_fetch",
585871
- "tool_search",
585872
- "task_status",
585873
- "task_output"
585874
- ]);
585875
- STATE_UPDATE_ACTION_REASON_SYNTHESIS_TOOLS = /* @__PURE__ */ new Set([
585876
- "todo_write",
585877
- "working_notes"
585878
- ]);
585879
- TOOL_ACTION_REASON_SCHEMA = {
585880
- type: "object",
585881
- description: "Compact public action contract for this exact tool call. Do not include hidden chain-of-thought; use concise task-state facts.",
585882
- properties: {
585883
- task_anchor: {
585884
- type: "string",
585885
- description: "One compact phrase tying this call to the active user goal/current focus."
585886
- },
585887
- intent: {
585888
- type: "string",
585889
- description: "One sentence explaining why this tool is the next action."
585890
- },
585891
- evidence: {
585892
- type: "string",
585893
- description: "Fresh evidence or contract authorizing the action: file hash, focus directive, cached evidence, user request, or explicit absence."
585894
- },
585895
- expected_result: {
585896
- type: "string",
585897
- description: "The concrete new state or information expected from this call."
585898
- },
585899
- scope: {
585900
- type: "string",
585901
- enum: Array.from(TOOL_ACTION_REASON_SCOPES),
585902
- description: "Classify the action scope. Use targeted_patch for constrained edits; full_file_rewrite only for deliberate whole-file replacement."
585903
- }
585904
- },
585905
- required: ["task_anchor", "intent", "evidence", "expected_result", "scope"]
585906
- };
586020
+ LEGACY_ACTION_REASON_KEYS = /* @__PURE__ */ new Set(["action_reason", "actionReason"]);
585907
586021
  SYSTEM_PROMPT = loadPrompt("agentic/system-large.md");
585908
586022
  SYSTEM_PROMPT_MEDIUM = loadPrompt("agentic/system-medium.md");
585909
586023
  SYSTEM_PROMPT_SMALL = loadPrompt("agentic/system-small.md");
@@ -587120,10 +587234,8 @@ ${parts.join("\n")}
587120
587234
  if (ts.failedApproaches.length > 0) {
587121
587235
  lines.push(`recent_failed_approaches=${ts.failedApproaches.slice(-3).join(" | ").replace(/\s+/g, " ").slice(0, 420)}`);
587122
587236
  }
587123
- lines.push("tool_call_contract=Mutating/side-effectful tool calls require action_reason {task_anchor,intent,evidence,expected_result,scope}; read-only evidence tools may include it but must never be blocked only for missing metadata. Compact public facts only, no hidden chain-of-thought.");
587124
587237
  lines.push("edit_transport_contract=file_edit is for exact unique current text copied from file_read; file_patch is for line-range delete/replace/insert using file_read line numbers and expected_hash/current target evidence. A failed file_edit invalidates the edit premise; rebuild from current evidence instead of broadening into file_write unless the task is truly whole-file replacement.");
587125
587238
  lines.push("range_patch_contract=If patch_ready=true or current path+start_line+end_line+expected_hash are known, call file_patch. If read_required=true or a stale exact edit lacks current range/hash, call file_read once. Do not call file_read when patch_ready=true.");
587126
- lines.push(`scope_contract=${Array.from(TOOL_ACTION_REASON_SCOPES).join("|")}; use targeted_patch for constrained code edits and full_file_rewrite only for deliberate whole-file replacement.`);
587127
587239
  const gitContract = renderGitProgressActionContract(this._gitProgress);
587128
587240
  if (gitContract)
587129
587241
  lines.push(gitContract);
@@ -587993,7 +588105,8 @@ Emit AT MOST 6 tool calls per response. Smaller batches receive better feedback
587993
588105
  };
587994
588106
  const batchGuidance = _BATCH_GUIDANCE[this.options.modelTier ?? "large"] ?? _BATCH_GUIDANCE.large;
587995
588107
  const shellGuidance = "\n\n## Shell command patterns\n\nWhen investigating a build/test/install failure, RUN THE COMMAND WITHOUT TRUNCATION FIRST to see the full error.\nAvoid `| tail -N` / `| head -N` / `| sed -n '1,Np'` on commands you don't yet trust — they drop the part of the output where errors usually appear.\nPipefail is on by default in this orchestrator: a pipeline's exit code reflects the FIRST failing stage, not just the last. So `<cmd> | tail -80` returns non-zero if `<cmd>` failed.\nWhen you DO want to limit context (after diagnosis), prefer `<cmd> 2>&1 | tail -300` (or larger) so you keep enough output to see the actual error block.\nIf your command exited 0 but produced suspiciously short output (~< 800 chars), the orchestrator will inject a [HINT — pipe-to-truncator detected] block telling you to re-run without truncation.";
587996
- const basePromptWithBatching = basePrompt + batchGuidance + shellGuidance;
588108
+ const editTransportGuidance = "\n\n## Existing-file edit loop\n\nFor an existing non-trivial file, use this loop: (1) file_read the implicated range or whole small file, (2) file_patch a contiguous line range or file_edit exact current text, (3) inspect the resulting diff/changed range, and (4) run the declared verifier live. Use batch_edit only for multiple exact replacements built from one fresh read.\nfile_write is for new files, empty/placeholder files, and deliberate replacement of a genuinely small file. Never use file_write as a fallback for stale hashes, old_string mismatches, malformed patch arguments, or repeated edit failures. A 'different approach' means refresh evidence or change the diagnostic/patch shape; it does not mean broaden a local repair into a whole-file rewrite.\nPreviously observed or compacted results are orientation only. Re-run file_read whenever a freshness/hash guard asks for current text, and re-run the exact verifier after every relevant mutation; cached output never proves current file state or completion.";
588109
+ const basePromptWithBatching = basePrompt + batchGuidance + shellGuidance + editTransportGuidance;
587997
588110
  sections.push({
587998
588111
  label: "c_instr",
587999
588112
  content: basePromptWithBatching,
@@ -589827,11 +589940,8 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
589827
589940
  const realFileMutation = input.realFileMutation ?? this._isRealProjectMutation(input.toolName, input.result);
589828
589941
  const attemptedTargetPaths = this._extractToolTargetPaths(input.toolName, input.args, input.result);
589829
589942
  const realMutationPaths = input.realMutationPaths ?? (realFileMutation ? attemptedTargetPaths : []);
589830
- const shellActionReasonScope = input.toolName === "shell" ? input.actionReason?.scope : void 0;
589831
- const shellActionReasonDeclaresVerification = shellActionReasonScope === "verification";
589832
- const shellActionReasonDeclaresNonVerification = typeof shellActionReasonScope === "string" && shellActionReasonScope.length > 0 && shellActionReasonScope !== "verification";
589833
- const shellVerification = input.toolName === "shell" && (shellActionReasonDeclaresVerification || !shellActionReasonDeclaresNonVerification && input.result.runtimeAuthored !== true && this._shellResultLooksLikeVerification(input.args, input.result));
589834
- const shellVerificationFamily = shellVerification ? this._shellVerificationFamily(input.args, input.actionReason) : "";
589943
+ const shellVerification = input.toolName === "shell" && input.result.runtimeAuthored !== true && this._shellResultLooksLikeVerification(input.args, input.result);
589944
+ const shellVerificationFamily = shellVerification ? this._shellVerificationFamily(input.args) : "";
589835
589945
  if (input.result.success === true && this._isProjectEditTool(input.toolName) && !realFileMutation && input.result.alreadyApplied !== true) {
589836
589946
  return;
589837
589947
  }
@@ -589865,17 +589975,7 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
589865
589975
  }
589866
589976
  this._saveCompletionLedgerSafe();
589867
589977
  }
589868
- _shellVerificationFamily(args, actionReason) {
589869
- if (actionReason?.scope === "verification") {
589870
- const stableParts = [
589871
- actionReason.task_anchor,
589872
- actionReason.expected_result
589873
- ].map((part) => String(part ?? "").trim()).filter(Boolean);
589874
- const semanticKey = (stableParts.length > 0 ? stableParts : [String(actionReason.intent ?? "").trim()].filter(Boolean)).join(" | ");
589875
- const normalized2 = normalizeCompletionKey(semanticKey || "shell verification", "shell_verification").slice(0, 140);
589876
- if (normalized2)
589877
- return `shell-action:${normalized2}`;
589878
- }
589978
+ _shellVerificationFamily(args) {
589879
589979
  const command = String(args?.["command"] ?? args?.["cmd"] ?? "").trim();
589880
589980
  const normalized = normalizeShellCommand(command);
589881
589981
  return `shell:${(normalized || command || "verification").slice(0, 160)}`;
@@ -592198,13 +592298,11 @@ ${latest.output || ""}`.trim();
592198
592298
  success: item.succeeded,
592199
592299
  path: item.path,
592200
592300
  stateVersion: item.stateVersion,
592201
- preview: item.preview.slice(0, 240),
592202
- actionReason: item.actionReason ?? void 0
592301
+ preview: item.preview.slice(0, 240)
592203
592302
  }));
592204
592303
  const recentActionLines = recentActions.slice(-6).map((item) => {
592205
592304
  const path16 = item.path ? ` path=${item.path}` : "";
592206
- const reason = item.actionReason ? ` reason=${[item.actionReason.scope, item.actionReason.intent].filter(Boolean).join(":").replace(/\s+/g, " ").slice(0, 120)}` : "";
592207
- return `- turn=${item.turn} ${item.tool} ${item.success ? "ok" : "err"}${path16}${reason}: ${item.preview.replace(/\s+/g, " ").slice(0, 160)}`;
592305
+ return `- turn=${item.turn} ${item.tool} ${item.success ? "ok" : "err"}${path16}: ${item.preview.replace(/\s+/g, " ").slice(0, 160)}`;
592208
592306
  });
592209
592307
  const treeDir = _pathJoin(this.omniusStateDir(), "world-state", "tree");
592210
592308
  const turnName = `turn-${String(turn).padStart(4, "0")}`;
@@ -592506,10 +592604,10 @@ ${sections.join("\n")}` : sections.join("\n");
592506
592604
  }
592507
592605
  }
592508
592606
  const sections = [
592509
- "[KNOWLEDGE — recent tool results for reference. Re-reading a file after an edit is encouraged to capture the latest content; exact re-reads are NOT blocked and always return fresh, up-to-date data.]"
592607
+ "[KNOWLEDGE — prior observations for orientation only. A file_read requested for current text/hash and a verifier requested after mutation execute live; this history is never substituted for fresh evidence.]"
592510
592608
  ];
592511
592609
  if (compactedCount > 0) {
592512
- sections.push(`Compacted cached entries still count as already-known results (${compactedCount}); an exact repeat will be served from cache or skipped, not produce new information.`);
592610
+ sections.push(`Compacted historical entries: ${compactedCount}. They show what was observed earlier, not what is currently on disk. Re-run the narrow read or verifier when freshness matters.`);
592513
592611
  }
592514
592612
  if (filesRead.length > 0) {
592515
592613
  const unique2 = [...new Set(filesRead)].slice(0, 30);
@@ -593352,11 +593450,11 @@ ${blob}
593352
593450
  const meta = metaForResult(idx);
593353
593451
  let stub;
593354
593452
  if (p2) {
593355
- stub = `[Earlier read of ${p2} cleared its content is preserved in your ACTIVE CONTEXT FRAME (Evidence already gathered). Do NOT re-read it; use the frame.]`;
593453
+ stub = `[Earlier read of ${p2} compacted. A snapshot may appear in the ACTIVE CONTEXT FRAME; file_read the narrow current range again whenever exact text/hash or unelided content is needed.]`;
593356
593454
  } else {
593357
593455
  const firstLine = content.split("\n").find((l2) => l2.trim())?.trim().slice(0, 140) ?? "";
593358
593456
  const failed = /\berror\b|\bfail|✗|exit code [1-9]|traceback/i.test(content);
593359
- stub = `[${meta?.name ?? "tool"}(${meta?.argsPreview ?? ""}) result compacted to save context — ${failed ? "FAILED" : "ok"}${firstLine ? `: ${firstLine}` : ""}. Re-run ONLY if the underlying state has since changed.]`;
593457
+ stub = `[${meta?.name ?? "tool"}(${meta?.argsPreview ?? ""}) result compacted to save context — ${failed ? "FAILED" : "ok"}${firstLine ? `: ${firstLine}` : ""}. This is historical orientation, not current-state proof; re-run a verifier or narrow state read when freshness matters.]`;
593360
593458
  }
593361
593459
  messages2[idx] = { ...msg, content: stub };
593362
593460
  cleared++;
@@ -593443,7 +593541,7 @@ ${blob}
593443
593541
  * size. The hash is computed over the full canonical value.
593444
593542
  */
593445
593543
  _buildExactArgsKey(args) {
593446
- return Object.entries(args ?? {}).filter(([key]) => !TOOL_ACTION_REASON_KEYS.has(key)).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${k}=${this._formatExactArgValue(v)}`).join(",");
593544
+ return Object.entries(args ?? {}).filter(([key]) => !LEGACY_ACTION_REASON_KEYS.has(key)).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${k}=${this._formatExactArgValue(v)}`).join(",");
593447
593545
  }
593448
593546
  _buildToolFingerprint(name10, args) {
593449
593547
  const canonical = this.lookupRegisteredTool(name10)?.name ?? name10;
@@ -593735,7 +593833,7 @@ ${blob}
593735
593833
  if (seen.has(value2))
593736
593834
  return "#cycle";
593737
593835
  seen.add(value2);
593738
- const entries = Object.entries(value2).filter(([key]) => !TOOL_ACTION_REASON_KEYS.has(key)).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${JSON.stringify(k)}:${this._canonicalArgValue(v, seen)}`);
593836
+ const entries = Object.entries(value2).filter(([key]) => !LEGACY_ACTION_REASON_KEYS.has(key)).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${JSON.stringify(k)}:${this._canonicalArgValue(v, seen)}`);
593739
593837
  return `#object:{${entries.join(",")}}`;
593740
593838
  }
593741
593839
  return String(value2);
@@ -593925,8 +594023,7 @@ Rewrite it now for ${ctx3.model}.`;
593925
594023
  const unknownKeys = providedKeys.filter((key) => !props.has(key));
593926
594024
  const aliases = this.suggestArgumentAliases(missingRequired, providedKeys, args, props);
593927
594025
  const corrected = this.buildCorrectedArgsPreview(args, props, aliases);
593928
- const actionReasonOnlyFailure = validationError.includes("[TOOL ACTION REASON CONTRACT]");
593929
- const siblingMatches = actionReasonOnlyFailure ? [] : this.findSiblingToolSchemaMatches(toolName, providedKeys);
594026
+ const siblingMatches = this.findSiblingToolSchemaMatches(toolName, providedKeys);
593930
594027
  const lines = [
593931
594028
  `[RUNTIME TOOL ARGUMENT REPAIR]`,
593932
594029
  `Tool call failed before execution: ${toolName}`,
@@ -594152,6 +594249,10 @@ ${notice}`;
594152
594249
  injectUserMessage(content) {
594153
594250
  this.pendingUserMessages.push(this.scrubUserInput(content, "injected-user-message"));
594154
594251
  }
594252
+ /** Inject bounded runtime guidance without treating it as user steering. */
594253
+ injectRuntimeGuidance(content) {
594254
+ this.enqueueRuntimeGuidance(content);
594255
+ }
594155
594256
  enqueueRuntimeGuidance(content) {
594156
594257
  const cleaned = this.scrubUserInput(content, "runtime-guidance").trim();
594157
594258
  if (cleaned)
@@ -596231,7 +596332,7 @@ ${_staleSamples.join("\n")}` : ``,
596231
596332
  ``,
596232
596333
  ` (a) RUN-AND-READ: Run the EXACT command that fails (test/typecheck/build) and READ THE FULL ERROR MESSAGE LITERALLY. Do not summarize it from memory; paste it back into context. The current write hasn't been validated against any error.`,
596233
596334
  ``,
596234
- ` (b) DELETE-AND-RESTART: If the file has been rewritten ${_wtWorstCount} times, the current approach is wrong. Either delete the file and try a fundamentally different design, OR revert to a known-good earlier version (use git, working_notes, or memory_search to find one).`,
596335
+ ` (b) DIFF-AND-RESET-THE-PREMISE: Inspect git diff for ${_wtWorstPath}, then file_read only the implicated current range. Keep correct changes, identify the first wrong hunk, and repair that hunk with file_patch/file_edit. Do not delete or regenerate the file.`,
596235
596336
  ``,
596236
596337
  ` (c) ERROR-INFORMED LOCAL TRIAGE: use the exact failing local command and error line to identify one implicated path/symbol/config key, then inspect or change only that target. Do not search online for a codebase-local failure.`,
596237
596338
  ``,
@@ -596864,6 +596965,8 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
596864
596965
  };
596865
596966
  const ceCompactOutput = await this._contextEngine.compact(ceCompactInput);
596866
596967
  if (ceCompactOutput.compacted && ceCompactOutput.compactedMessages.length > 0 && ceCompactOutput.compactedMessages.length < compacted.length) {
596968
+ const beforeCount = compacted.length;
596969
+ const afterCount = ceCompactOutput.compactedMessages.length;
596867
596970
  messages2.length = 0;
596868
596971
  messages2.push(...ceCompactOutput.compactedMessages.map((m2) => ({
596869
596972
  role: m2.role,
@@ -596871,6 +596974,11 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
596871
596974
  ...m2.name ? { name: m2.name } : {}
596872
596975
  })));
596873
596976
  compacted = messages2;
596977
+ this.emit({
596978
+ type: "compaction",
596979
+ content: `Compacted ${beforeCount - afterCount} messages (context engine) | ${beforeCount} -> ${afterCount} messages retained`,
596980
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
596981
+ });
596874
596982
  }
596875
596983
  } catch {
596876
596984
  }
@@ -596881,8 +596989,8 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
596881
596989
  if (process.env["OMNIUS_DISABLE_ADAPTIVE_RETRIEVAL"] !== "1") {
596882
596990
  const goalForSig = (this._taskState.goal || "").slice(0, 200);
596883
596991
  const recentTools = this._toolSequence.slice(-5).join("|");
596884
- const { createHash: createHash51 } = await import("node:crypto");
596885
- const sig = createHash51("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
596992
+ const { createHash: createHash53 } = await import("node:crypto");
596993
+ const sig = createHash53("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
596886
596994
  if (this._lastPprSig === sig && this._lastPprMemoryLines.length > 0) {
596887
596995
  compacted.push({
596888
596996
  role: "system",
@@ -597497,7 +597605,6 @@ ${memoryLines.join("\n")}`
597497
597605
  executeSingle = async (tc) => {
597498
597606
  if (this.aborted)
597499
597607
  return null;
597500
- const actionReasonForAdvisory = this._toolActionReasonForCall(tc.name, tc.arguments ?? {});
597501
597608
  const cohortKey = this.buildArgCohortKey(tc.name, tc.arguments);
597502
597609
  const cohort = this._argCohorts.get(cohortKey);
597503
597610
  if (cohort && cohort.failure >= 3 && cohort.success === 0) {
@@ -597858,7 +597965,6 @@ Read the current file if needed, make a different concrete edit, or move to veri
597858
597965
  turn,
597859
597966
  toolName: tc.name,
597860
597967
  args: tc.arguments ?? {},
597861
- actionReason: actionReasonForAdvisory,
597862
597968
  fingerprint: toolFingerprint,
597863
597969
  isReadLike: false,
597864
597970
  stalePreflightMessage: staleEditBlock,
@@ -597924,7 +598030,6 @@ Read the current file if needed, make a different concrete edit, or move to veri
597924
598030
  turn,
597925
598031
  toolName: tc.name,
597926
598032
  args: tc.arguments ?? {},
597927
- actionReason: actionReasonForAdvisory,
597928
598033
  fingerprint: toolFingerprint,
597929
598034
  isReadLike: false,
597930
598035
  stalePreflightMessage: staleRewriteBlock,
@@ -597990,7 +598095,6 @@ Read the current file if needed, make a different concrete edit, or move to veri
597990
598095
  turn,
597991
598096
  toolName: tc.name,
597992
598097
  args: tc.arguments ?? {},
597993
- actionReason: actionReasonForAdvisory,
597994
598098
  fingerprint: toolFingerprint,
597995
598099
  isReadLike: false,
597996
598100
  stalePreflightMessage: editReversalBlock,
@@ -598124,8 +598228,7 @@ Read the current file if needed, make a different concrete edit, or move to veri
598124
598228
  } : evaluate2({
598125
598229
  proposedCall: {
598126
598230
  tool: tc.name,
598127
- args: tc.arguments ?? {},
598128
- actionReason: actionReasonForAdvisory ?? void 0
598231
+ args: tc.arguments ?? {}
598129
598232
  },
598130
598233
  fingerprint: toolFingerprint,
598131
598234
  isReadLike,
@@ -598175,7 +598278,6 @@ Read the current file if needed, make a different concrete edit, or move to veri
598175
598278
  tool: tc.name,
598176
598279
  target: _target,
598177
598280
  count: criticDecision.hitNumber,
598178
- actionReason: actionReasonForAdvisory ?? void 0,
598179
598281
  alreadyHave: _existingFp?.result
598180
598282
  }
598181
598283
  });
@@ -598280,7 +598382,6 @@ ${cachedResult}`,
598280
598382
  turn,
598281
598383
  toolName: tc.name,
598282
598384
  args: tc.arguments ?? {},
598283
- actionReason: actionReasonForAdvisory,
598284
598385
  completionStatus: completionStatusFromTaskCompleteArgs(tc.arguments),
598285
598386
  fingerprint: toolFingerprint,
598286
598387
  isReadLike,
@@ -598358,7 +598459,6 @@ ${cachedResult}`,
598358
598459
  const tool = resolvedTool?.tool;
598359
598460
  let result;
598360
598461
  let runtimeSystemGuidance = null;
598361
- let toolActionReason = actionReasonForAdvisory;
598362
598462
  if (repeatShortCircuit) {
598363
598463
  result = repeatShortCircuit;
598364
598464
  } else if (tc.arguments && "_raw" in tc.arguments) {
@@ -598374,12 +598474,12 @@ ${cachedResult}`,
598374
598474
  error: this.unknownToolError(tc.name)
598375
598475
  };
598376
598476
  } else {
598377
- let validationError = this._validateToolActionReason(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
598477
+ let validationError = null;
598378
598478
  if (!validationError) {
598379
- tc.arguments = this._stripToolActionReasonArgs(tc.arguments ?? {});
598479
+ tc.arguments = this._stripLegacyActionReasonArgs(tc.arguments ?? {});
598380
598480
  tc.arguments = this._normalizeToolArgsForExecution(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
598381
598481
  tc.arguments = this._autoDeriveDelegationMutationScope(resolvedTool?.name ?? tc.name, tc.arguments ?? {}, turn);
598382
- validationError = this._validateFileWriteOverwriteContract(resolvedTool?.name ?? tc.name, tc.arguments ?? {}, toolActionReason);
598482
+ validationError = this._validateFileWriteOverwriteContract(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
598383
598483
  }
598384
598484
  if (!validationError) {
598385
598485
  validationError = this._validateFreshExpectedHashesForEdit(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
@@ -598632,8 +598732,7 @@ Respond with EXACTLY this structure before your next tool call:
598632
598732
  toolName: resolvedTool?.name ?? tc.name,
598633
598733
  toolCallId: tc.id,
598634
598734
  args: tc.arguments,
598635
- result,
598636
- actionReason: toolActionReason
598735
+ result
598637
598736
  });
598638
598737
  if (observedStateMutation) {
598639
598738
  this._markAdversaryObservedStateMutation();
@@ -599385,24 +599484,12 @@ Respond with EXACTLY this structure before your next tool call:
599385
599484
  }
599386
599485
  const cacheableMemoryNoop = tc.name === "memory_write" && result.success && result.noop;
599387
599486
  const cacheableProjectWriteNoop = this._isProjectEditTool(tc.name) && result.success && !this._isRealProjectMutation(tc.name, result) && (result.noop === true || result.mutated === false);
599388
- const cacheableShellResult = tc.name === "shell" && result.runtimeAuthored !== true && !shellLikelyMutatesFilesystem;
599389
- if (isReadLike && result.success && result.runtimeAuthored !== true || cacheableShellResult || cacheableMemoryNoop || cacheableProjectWriteNoop) {
599487
+ if (cacheableMemoryNoop || cacheableProjectWriteNoop) {
599390
599488
  recentToolResults.set(toolFingerprint, {
599391
- result: tc.name === "shell" ? this._buildShellCacheResult(tc.arguments, result) : (
599392
- // Read-like results are SERVED BACK to the model when the
599393
- // repeat gate fires, so they must stay complete enough to
599394
- // edit against — truncating to 2KB cut the tail off normal
599395
- // source files (the "old_string not found" cascade). Large
599396
- // files are handled by branch-extract upstream, so 16KB
599397
- // here covers ordinary files without bloating the cache.
599398
- isReadLike ? this.sanitizeCachedToolResult(tc.name, result.output ?? "").slice(0, 16e3) : (result.output ?? "").slice(0, 2e3)
599399
- ),
599489
+ result: (result.output ?? "").slice(0, 2e3),
599400
599490
  compacted: false,
599401
599491
  mutationEpoch: fileMutationEpoch
599402
599492
  });
599403
- if (isReadLike && result.success) {
599404
- this._registerReadCoverage(tc.name, tc.arguments ?? {}, toolFingerprint);
599405
- }
599406
599493
  if (recentToolResults.size > 500) {
599407
599494
  const firstKey = recentToolResults.keys().next().value;
599408
599495
  if (firstKey !== void 0) {
@@ -599915,7 +600002,6 @@ Evidence: ${evidencePreview}`.slice(0, 500);
599915
600002
  turn,
599916
600003
  toolName: tc.name,
599917
600004
  args: tc.arguments ?? {},
599918
- actionReason: toolActionReason,
599919
600005
  fingerprint: toolFingerprint,
599920
600006
  success: result.success,
599921
600007
  output: result.output ?? result.llmContent ?? "",
@@ -600128,7 +600214,6 @@ ${delegateDir}` : delegateDir;
600128
600214
  reason: focusDecision.directive.reason,
600129
600215
  requiredNextAction: focusDecision.directive.requiredNextAction
600130
600216
  },
600131
- actionReason: toolActionReason ?? void 0,
600132
600217
  repeatShortCircuit: Boolean(repeatShortCircuit),
600133
600218
  runtimeAuthored: result.runtimeAuthored === true,
600134
600219
  runtimeGuidance: runtimeSystemGuidance,
@@ -600166,20 +600251,20 @@ ${delegateDir}` : delegateDir;
600166
600251
  if (sameToolFailStreak >= 5 && (this.options.modelTier === "small" || this.options.modelTier === "medium")) {
600167
600252
  this.enqueueRuntimeGuidance(`[BRANCH — evaluate alternatives before acting]
600168
600253
  Tool "${tc.name}" has failed ${sameToolFailStreak} times. STOP and enumerate:
600169
- Option A: [describe a completely different approach]
600170
- Option B: [describe another alternative]
600171
- Option C: [the simplest possible fallback]
600172
- Pick the BEST option and explain why, then execute it. Do NOT retry ${tc.name} with similar arguments.`);
600254
+ Option A: refresh the exact evidence or correct the current tool arguments
600255
+ Option B: use a different narrow diagnostic or targeted edit transport
600256
+ Option C: verify whether the desired change is already present
600257
+ Pick the BEST option and explain why, then execute it. Do NOT retry ${tc.name} with similar arguments, and do not broaden a local edit into file_write.`);
600173
600258
  sameToolFailStreak = 0;
600174
600259
  sameToolFailName = null;
600175
600260
  }
600176
600261
  if (consecutiveSameTool >= 2 && (this.options.modelTier === "small" || this.options.modelTier === "medium")) {
600177
600262
  this.enqueueRuntimeGuidance(`[PIVOT REQUIRED] You have failed ${consecutiveSameTool + 1} times in a row with ${tc.name}. Your current approach is not working. You MUST try something fundamentally different:
600178
- - If file_edit keeps failing: re-read the file first, then use the EXACT text from the file
600263
+ - If file_edit/file_patch keeps failing: re-read the implicated current range, then correct the exact text/range/hash or inspect git diff
600179
600264
  - If shell keeps failing: try a different command or check prerequisites
600180
600265
  - If grep_search finds nothing: try broader patterns or list_directory
600181
- - Consider using a completely different tool or strategy
600182
- Do NOT retry ${tc.name} with similar arguments.`);
600266
+ - A different strategy means a different diagnosis or narrow transport, never a whole-file rewrite fallback
600267
+ Do NOT retry ${tc.name} with similar arguments and do NOT use file_write to escape a targeted-edit failure.`);
600183
600268
  }
600184
600269
  if (!this._taskState.failedApproaches.includes(failDesc)) {
600185
600270
  this._taskState.failedApproaches.push(failDesc);
@@ -600353,7 +600438,6 @@ Then use file_read on individual FILES inside it.`);
600353
600438
  toolName: tc.name,
600354
600439
  argsKey: tc.arguments ? JSON.stringify(tc.arguments) : "",
600355
600440
  args: tc.arguments,
600356
- actionReason: toolActionReason,
600357
600441
  result,
600358
600442
  outputPreview: this._toolEvidencePreview(result, output, 1200, tc.name),
600359
600443
  realFileMutation,
@@ -602803,200 +602887,24 @@ ${marker}` : marker);
602803
602887
  }
602804
602888
  return matchesFresh(args);
602805
602889
  }
602806
- _toolActionReasonPolicy(toolName, args) {
602807
- if (process.env["OMNIUS_DISABLE_TOOL_ACTION_REASON"] === "1") {
602808
- return "disabled";
602809
- }
602810
- if ((process.env["VITEST"] || process.env["NODE_ENV"] === "test") && process.env["OMNIUS_REQUIRE_TOOL_ACTION_REASON"] !== "1") {
602811
- return "disabled";
602812
- }
602813
- if (this.options.artifactMode === "internal")
602814
- return "disabled";
602815
- if (toolName.startsWith("__"))
602816
- return "disabled";
602817
- return this._toolActionReasonIsOptional(toolName, args) ? "optional" : "required";
602818
- }
602819
- _requiresToolActionReason(toolName, args) {
602820
- return this._toolActionReasonPolicy(toolName, args) === "required";
602821
- }
602822
- _toolActionReasonIsOptional(toolName, args) {
602823
- const resolved = this.lookupRegisteredTool(toolName);
602824
- const canonical = resolved?.name ?? toolName;
602825
- if (READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS.has(canonical))
602826
- return true;
602827
- const tool = resolved?.tool;
602828
- if (typeof tool?.isReadOnly === "function") {
602829
- try {
602830
- if (tool.isReadOnly(args ?? {}))
602831
- return true;
602832
- } catch {
602833
- }
602834
- }
602835
- return false;
602836
- }
602837
- _withToolActionReasonSchema(toolName, parameters) {
602838
- const policy = this._toolActionReasonPolicy(toolName);
602839
- if (policy === "disabled") {
602840
- return parameters ?? { type: "object", properties: {} };
602841
- }
602890
+ _publicToolParameters(parameters) {
602842
602891
  const base3 = parameters && typeof parameters === "object" && !Array.isArray(parameters) ? { ...parameters } : { type: "object" };
602843
602892
  const properties = base3["properties"] && typeof base3["properties"] === "object" && !Array.isArray(base3["properties"]) ? { ...base3["properties"] } : {};
602844
- properties["action_reason"] = TOOL_ACTION_REASON_SCHEMA;
602845
- const required = Array.isArray(base3["required"]) ? base3["required"].map(String) : [];
602893
+ for (const key of LEGACY_ACTION_REASON_KEYS)
602894
+ delete properties[key];
602895
+ const required = Array.isArray(base3["required"]) ? base3["required"].map(String).filter((key) => !LEGACY_ACTION_REASON_KEYS.has(key)) : [];
602846
602896
  return {
602847
602897
  ...base3,
602848
602898
  type: "object",
602849
602899
  properties,
602850
- required: policy === "required" ? [.../* @__PURE__ */ new Set([...required, "action_reason"])] : required
602851
- };
602852
- }
602853
- _extractToolActionReason(args) {
602854
- let raw = args["action_reason"] ?? args["actionReason"] ?? args["justification"];
602855
- if (typeof raw === "string") {
602856
- const trimmed = raw.trim();
602857
- if (!trimmed)
602858
- return null;
602859
- try {
602860
- raw = JSON.parse(trimmed);
602861
- } catch {
602862
- return { intent: trimmed };
602863
- }
602864
- }
602865
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
602866
- return null;
602867
- const rec = raw;
602868
- const reason = {
602869
- task_anchor: String(rec["task_anchor"] ?? rec["taskAnchor"] ?? "").trim(),
602870
- intent: String(rec["intent"] ?? "").trim(),
602871
- evidence: String(rec["evidence"] ?? "").trim(),
602872
- expected_result: String(rec["expected_result"] ?? rec["expectedResult"] ?? "").trim(),
602873
- scope: String(rec["scope"] ?? "").trim()
602874
- };
602875
- return reason;
602876
- }
602877
- _toolActionReasonForCall(toolName, args) {
602878
- const explicit = this._extractToolActionReason(args);
602879
- if (explicit) {
602880
- return this._completeToolActionReason(toolName, args, explicit);
602881
- }
602882
- if (this._shouldSynthesizeMissingToolActionReason(toolName, args)) {
602883
- return this._synthesizeStateUpdateToolActionReason(toolName, args);
602884
- }
602885
- if (this._toolActionReasonPolicy(toolName, args) !== "optional")
602886
- return null;
602887
- return this._synthesizeReadOnlyToolActionReason(toolName, args);
602888
- }
602889
- _completeToolActionReason(toolName, args, partial) {
602890
- const canonical = this.lookupRegisteredTool(toolName)?.name ?? toolName;
602891
- const goal = this._taskState.currentStep || this._taskState.nextAction || this._taskState.goal || this._taskState.originalGoal || "current task";
602892
- const targetPaths = this._extractToolTargetPaths(canonical, args).slice(0, 3);
602893
- const targetText = targetPaths.length > 0 ? ` for ${targetPaths.join(", ")}` : "";
602894
- const scope = TOOL_ACTION_REASON_SCOPES.has(String(partial.scope ?? "")) ? String(partial.scope) : this._defaultToolActionReasonScope(canonical);
602895
- return {
602896
- task_anchor: cleanToolActionReasonField(partial.task_anchor) || String(goal).replace(/\s+/g, " ").trim().slice(0, 160),
602897
- intent: cleanToolActionReasonField(partial.intent) || `Run ${canonical}${targetText} for the active task.`,
602898
- evidence: cleanToolActionReasonField(partial.evidence) || "Runtime completed partial public action metadata from the tool call contract before execution.",
602899
- expected_result: cleanToolActionReasonField(partial.expected_result) || this._defaultToolActionExpectedResult(canonical, targetText),
602900
- scope
602901
- };
602902
- }
602903
- _defaultToolActionReasonScope(toolName) {
602904
- if (toolName === "file_edit" || toolName === "file_patch" || toolName === "batch_edit") {
602905
- return "targeted_patch";
602906
- }
602907
- if (toolName === "create_structured_file")
602908
- return "new_file";
602909
- if (toolName === "task_complete")
602910
- return "completion";
602911
- if (READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS.has(toolName))
602912
- return "discovery";
602913
- return "other";
602914
- }
602915
- _defaultToolActionExpectedResult(toolName, targetText) {
602916
- switch (toolName) {
602917
- case "file_edit":
602918
- return `Requested exact edit is applied${targetText}, or a precise edit error is returned.`;
602919
- case "file_patch":
602920
- return `Requested line patch is applied${targetText}, or a precise patch error is returned.`;
602921
- case "batch_edit":
602922
- return `Requested edit batch is applied${targetText}, or per-edit failure evidence is returned.`;
602923
- case "file_write":
602924
- return `Requested file content is written${targetText}, or a precise write error is returned.`;
602925
- case "shell":
602926
- return "Command exits with output evidence for the next decision.";
602927
- default:
602928
- return `${toolName} completes and returns success or failure evidence.`;
602929
- }
602930
- }
602931
- _shouldSynthesizeMissingToolActionReason(toolName, _args) {
602932
- if (this._toolActionReasonPolicy(toolName, _args) === "disabled") {
602933
- return false;
602934
- }
602935
- const canonical = this.lookupRegisteredTool(toolName)?.name ?? toolName;
602936
- return STATE_UPDATE_ACTION_REASON_SYNTHESIS_TOOLS.has(canonical);
602937
- }
602938
- _synthesizeStateUpdateToolActionReason(toolName, args) {
602939
- const canonical = this.lookupRegisteredTool(toolName)?.name ?? toolName;
602940
- const goal = this._taskState.currentStep || this._taskState.nextAction || this._taskState.goal || this._taskState.originalGoal || "current task";
602941
- const todoCount = Array.isArray(args["todos"]) ? args["todos"].length : null;
602942
- return {
602943
- task_anchor: String(goal).replace(/\s+/g, " ").trim().slice(0, 160),
602944
- intent: `Update visible task state with ${canonical}.`,
602945
- evidence: todoCount === null ? "Model omitted public action_reason; runtime synthesized bookkeeping metadata without authorizing project mutation." : `Model supplied ${todoCount} todo item(s); runtime synthesized bookkeeping metadata without authorizing project mutation.`,
602946
- expected_result: "Session checklist reflects the current task state.",
602947
- scope: "state_update"
602948
- };
602949
- }
602950
- _synthesizeReadOnlyToolActionReason(toolName, args) {
602951
- const canonical = this.lookupRegisteredTool(toolName)?.name ?? toolName;
602952
- const goal = this._taskState.currentStep || this._taskState.nextAction || this._taskState.goal || this._taskState.originalGoal || "current task";
602953
- const targets = this._extractToolTargetPaths(canonical, args).slice(0, 3);
602954
- const targetText = targets.length > 0 ? ` for ${targets.join(", ")}` : "";
602955
- return {
602956
- task_anchor: String(goal).replace(/\s+/g, " ").trim().slice(0, 160),
602957
- intent: `Run read-only ${canonical}${targetText} to gather current evidence.`,
602958
- evidence: "Read-only metadata fallback; no project mutation is authorized by this action.",
602959
- expected_result: `Current ${canonical} evidence for the next decision.`,
602960
- scope: "discovery"
602900
+ required
602961
602901
  };
602962
602902
  }
602963
- _validateToolActionReason(toolName, args) {
602964
- const policy = this._toolActionReasonPolicy(toolName, args);
602965
- if (policy === "disabled")
602966
- return null;
602967
- const raw = args["action_reason"] ?? args["actionReason"] ?? args["justification"];
602968
- if (!raw || typeof raw === "string" && !raw.trim()) {
602969
- if (policy === "optional")
602970
- return null;
602971
- if (this._shouldSynthesizeMissingToolActionReason(toolName, args)) {
602972
- return null;
602973
- }
602974
- return [
602975
- "[TOOL ACTION REASON CONTRACT]",
602976
- `This side-effectful tool call must include action_reason: { task_anchor, intent, evidence, expected_result, scope }.`,
602977
- `Use compact public facts only; do not include hidden chain-of-thought.`,
602978
- `scope must be one of: ${Array.from(TOOL_ACTION_REASON_SCOPES).join(", ")}.`
602979
- ].join("\n");
602980
- }
602981
- const partialReason = this._extractToolActionReason(args);
602982
- if (!partialReason) {
602983
- if (policy === "optional")
602984
- return null;
602985
- return "[TOOL ACTION REASON CONTRACT] action_reason must be an object with compact public task-state fields.";
602986
- }
602987
- const reason = this._completeToolActionReason(toolName, args, partialReason);
602988
- if (!TOOL_ACTION_REASON_SCOPES.has(reason.scope)) {
602989
- if (policy === "optional")
602990
- return null;
602991
- return `[TOOL ACTION REASON CONTRACT] action_reason.scope="${reason.scope}" is invalid. Use one of: ${Array.from(TOOL_ACTION_REASON_SCOPES).join(", ")}.`;
602992
- }
602993
- return null;
602994
- }
602995
- _stripToolActionReasonArgs(args) {
602903
+ _stripLegacyActionReasonArgs(args) {
602996
602904
  let changed = false;
602997
602905
  const next = {};
602998
602906
  for (const [key, value2] of Object.entries(args)) {
602999
- if (TOOL_ACTION_REASON_KEYS.has(key)) {
602907
+ if (LEGACY_ACTION_REASON_KEYS.has(key)) {
603000
602908
  changed = true;
603001
602909
  continue;
603002
602910
  }
@@ -603113,7 +603021,7 @@ ${marker}` : marker);
603113
603021
  }
603114
603022
  return next;
603115
603023
  }
603116
- _validateFileWriteOverwriteContract(toolName, args, actionReason) {
603024
+ _validateFileWriteOverwriteContract(toolName, args) {
603117
603025
  if (toolName !== "file_write")
603118
603026
  return null;
603119
603027
  if (process.env["OMNIUS_ALLOW_UNVERIFIED_FILE_WRITE_OVERWRITE"] === "1") {
@@ -603135,20 +603043,13 @@ ${marker}` : marker);
603135
603043
  }
603136
603044
  if (!exists2)
603137
603045
  return null;
603138
- if (actionReason && actionReason.scope !== "full_file_rewrite") {
603139
- return [
603140
- "[FULL FILE REWRITE CONTRACT]",
603141
- `file_write targets an existing file: ${path16}.`,
603142
- `For constrained repairs, use file_patch, batch_edit, or file_edit instead of rewriting the full file.`,
603143
- `If a whole-file replacement is truly intended, set action_reason.scope="full_file_rewrite" and use expected_hash from a fresh file_read.`
603144
- ].join("\n");
603145
- }
603146
603046
  if (!this._toolCallUsesFreshFileReadEvidence(toolName, args)) {
603147
603047
  const fresh = this._freshReadHashForEditPath(path16);
603148
603048
  return [
603149
603049
  "[FULL FILE REWRITE CONTRACT]",
603150
603050
  `file_write would overwrite existing file ${path16}, but it is not anchored to fresh file_read evidence.`,
603151
- fresh ? `Use expected_hash=${fresh.hash} from the current active evidence, or prefer file_patch/batch_edit for a constrained change.` : `First file_read ${path16}, then prefer file_patch/batch_edit; only retry file_write with expected_hash if a whole-file rewrite is necessary.`
603051
+ "file_write is reserved for new, empty/placeholder, or genuinely small files needing deliberate total replacement; it is never recovery for a failed local edit.",
603052
+ fresh ? `Use expected_hash=${fresh.hash} from the current active evidence, or prefer file_patch/batch_edit for a constrained change.` : `First file_read ${path16}, then prefer file_patch/batch_edit; only retry file_write with expected_hash if a whole-file replacement is necessary.`
603152
603053
  ].join("\n");
603153
603054
  }
603154
603055
  return null;
@@ -604908,9 +604809,9 @@ ${postCompactRestore.join("\n")}`);
604908
604809
 
604909
604810
  **IMPORTANT:** You MUST invoke tools through the function calling interface. Do NOT write tool names as text, markdown, or code blocks — that does nothing. Call tools using the structured tool/function API.` : "";
604910
604811
  const readFilesList = Array.from(this._fileRegistry.entries()).filter(([, e2]) => e2.accessCount > 0).map(([p2]) => p2).slice(0, 10);
604911
- const antiRepetitionReminder = (tier === "small" || tier === "medium") && readFilesList.length > 0 ? `
604812
+ const fileFreshnessReminder = (tier === "small" || tier === "medium") && readFilesList.length > 0 ? `
604912
604813
 
604913
- **DO NOT RE-READ THESE FILES** (you already have their contents): ${readFilesList.join(", ")}. Use the information above to make progress. Reading the same file again wastes a turn.` : "";
604814
+ **PREVIOUSLY OBSERVED FILES:** ${readFilesList.join(", ")}. Treat restored or summarized text as orientation, not guaranteed current bytes. Before editing, make a narrow live read when the body is elided/truncated, the file may have changed, a hash or edit anchor is stale, or exact current text is otherwise required. Avoid only redundant reads when the latest complete authoritative content is still visible and unchanged.` : "";
604914
604815
  const ephemeralSkillPackReminder = this._ephemeralSkillPackContext ? `
604915
604816
 
604916
604817
  [Ephemeral skill-pack restore — current run only, do not persist]
@@ -604928,11 +604829,11 @@ ${scopedStickyDynamicContext}` : "";
604928
604829
  ${fullSummary}
604929
604830
  </compaction-summary>
604930
604831
 
604931
- [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}` : `[Context compacted${strategyLabel} — summary of earlier work]
604832
+ [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${fileFreshnessReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}` : `[Context compacted${strategyLabel} — summary of earlier work]
604932
604833
 
604933
604834
  ${fullSummary}
604934
604835
 
604935
- [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}`
604836
+ [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${fileFreshnessReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}`
604936
604837
  };
604937
604838
  this.persistCheckpoint(fullSummary);
604938
604839
  let narrowedHead = [...head];
@@ -604993,10 +604894,11 @@ ${telegramPersonaHead}` : stripped
604993
604894
  const tokenEst = Math.ceil(content.length / 4);
604994
604895
  if (recoveredTokens + tokenEst > fileRecoveryBudget)
604995
604896
  break;
604897
+ const truncated = content.length > 8e3;
604996
604898
  result.push({
604997
604899
  role: "system",
604998
- content: `<recovered-file path="${filePath}" status="${entry.modified ? "modified" : "read"}">
604999
- ${content.slice(0, 8e3)}
604900
+ content: `<recovered-file path="${filePath}" status="${entry.modified ? "modified" : "read"}" truncated="${truncated}">
604901
+ ${content.slice(0, 8e3)}${truncated ? "\n[truncated recovery; use a narrow live read for omitted/current text]" : ""}
605000
604902
  </recovered-file>`
605001
604903
  });
605002
604904
  recoveredFiles.push(filePath);
@@ -605283,7 +605185,6 @@ ${trimmedNew}`;
605283
605185
  fingerprint,
605284
605186
  stateVersion: this._adversaryStateVersion,
605285
605187
  succeeded: input.result.success === true,
605286
- actionReason: input.actionReason,
605287
605188
  ...outcomeEvidence
605288
605189
  });
605289
605190
  while (this._recentToolOutcomes.length > 40) {
@@ -605429,7 +605330,6 @@ ${trimmedNew}`;
605429
605330
  args = JSON.parse(tc.function.arguments);
605430
605331
  } catch {
605431
605332
  }
605432
- const actionReason = this._toolActionReasonForCall(name10, args);
605433
605333
  const argsKey = this._buildExactArgsKey(args);
605434
605334
  const fingerprint = this._buildToolFingerprint(name10, args);
605435
605335
  const prior = this._adversaryToolOutcomes.find((o2) => o2.succeeded && o2.tool === name10 && o2.fingerprint === fingerprint && o2.stateVersion === this._adversaryStateVersion && o2.turn < turn);
@@ -605443,7 +605343,6 @@ ${trimmedNew}`;
605443
605343
  tool: name10,
605444
605344
  target: argsKey.slice(0, 180),
605445
605345
  count: repeatCount,
605446
- actionReason: actionReason ?? void 0,
605447
605346
  alreadyHave: prior.preview
605448
605347
  }
605449
605348
  }, `possible repeated action ${name10} after prior same-state success`);
@@ -606677,7 +606576,7 @@ Example: ${tool.name}(${JSON.stringify(meta.examples[0].args ?? {})})` : "";
606677
606576
  function: {
606678
606577
  name: tool.name,
606679
606578
  description: compressDesc ? (desc.split(/\.\s/)[0]?.slice(0, 120) ?? desc.slice(0, 120)) + "." : desc,
606680
- parameters: this._withToolActionReasonSchema(tool.name, tool.parameters)
606579
+ parameters: this._publicToolParameters(tool.parameters)
606681
606580
  }
606682
606581
  };
606683
606582
  });
@@ -606699,7 +606598,7 @@ Example: ${tool.name}(${JSON.stringify(meta.examples[0].args ?? {})})` : "";
606699
606598
 
606700
606599
  Available tools (${deferred.length}):
606701
606600
  ${catalog}`,
606702
- parameters: this._withToolActionReasonSchema("tool_search", {
606601
+ parameters: this._publicToolParameters({
606703
606602
  type: "object",
606704
606603
  properties: {
606705
606604
  query: {
@@ -606750,7 +606649,7 @@ ${catalog}`,
606750
606649
  lines.push(`Aliases: ${tool.aliases.join(", ")}`);
606751
606650
  }
606752
606651
  lines.push(`${getDesc(tool)}${customToolDetails(tool)}`);
606753
- lines.push(`Parameters: ${JSON.stringify(this._withToolActionReasonSchema(tool.name, tool.parameters))}`);
606652
+ lines.push(`Parameters: ${JSON.stringify(this._publicToolParameters(tool.parameters))}`);
606754
606653
  }
606755
606654
  }
606756
606655
  if (alreadyAvailable.length > 0) {
@@ -606802,7 +606701,7 @@ ${catalog}`,
606802
606701
  for (const t2 of matches)
606803
606702
  activatedToolsRef.add(t2.name);
606804
606703
  const result = matches.map((t2) => {
606805
- const paramsStr = JSON.stringify(this._withToolActionReasonSchema(t2.name, t2.parameters), null, 2);
606704
+ const paramsStr = JSON.stringify(this._publicToolParameters(t2.parameters), null, 2);
606806
606705
  const aliases = t2.aliases?.length ? `
606807
606706
  Aliases: ${t2.aliases.join(", ")}` : "";
606808
606707
  return `## ${t2.name}${aliases}
@@ -610098,7 +609997,7 @@ var init_composite_scorer = __esm({
610098
609997
  });
610099
609998
 
610100
609999
  // packages/orchestrator/dist/memory/materialization-policy.js
610101
- import { createHash as createHash34 } from "node:crypto";
610000
+ import { createHash as createHash35 } from "node:crypto";
610102
610001
  function materializeMemoryItems(items, options2 = {}) {
610103
610002
  const config = options2.config ?? DEFAULT_WEIGHTING_CONFIG;
610104
610003
  const sorted = [...items].sort((a2, b) => b.weight - a2.weight || a2.id.localeCompare(b.id));
@@ -610336,7 +610235,7 @@ function estimateTokens4(text2) {
610336
610235
  return Math.max(1, Math.ceil(text2.length / 4));
610337
610236
  }
610338
610237
  function hashText(text2) {
610339
- return createHash34("sha256").update(text2).digest("hex");
610238
+ return createHash35("sha256").update(text2).digest("hex");
610340
610239
  }
610341
610240
  var init_materialization_policy = __esm({
610342
610241
  "packages/orchestrator/dist/memory/materialization-policy.js"() {
@@ -610500,7 +610399,7 @@ var init_config_loader = __esm({
610500
610399
  });
610501
610400
 
610502
610401
  // packages/orchestrator/dist/memory/stability-tracker.js
610503
- import { createHash as createHash35 } from "node:crypto";
610402
+ import { createHash as createHash36 } from "node:crypto";
610504
610403
  import { existsSync as existsSync109, mkdirSync as mkdirSync60, readFileSync as readFileSync84, writeFileSync as writeFileSync51 } from "node:fs";
610505
610404
  import { dirname as dirname36, join as join117 } from "node:path";
610506
610405
  function stabilityFilePath(repoRoot) {
@@ -610564,7 +610463,7 @@ function computeStabilityHash(item) {
610564
610463
  item.scope.name,
610565
610464
  item.topicKey
610566
610465
  ].join("|");
610567
- return createHash35("sha256").update(normalized).digest("hex");
610466
+ return createHash36("sha256").update(normalized).digest("hex");
610568
610467
  }
610569
610468
  function normalizeContent2(content) {
610570
610469
  return content.replace(/\s+/g, " ").trim();
@@ -614565,10 +614464,10 @@ var init_project_arc = __esm({
614565
614464
  });
614566
614465
 
614567
614466
  // packages/orchestrator/dist/dedup-gate.js
614568
- import { createHash as createHash36 } from "node:crypto";
614467
+ import { createHash as createHash37 } from "node:crypto";
614569
614468
  function fingerprintCall(name10, args) {
614570
614469
  const canon = canonicalize(args);
614571
- return createHash36("sha1").update(`${name10}\0${canon}`).digest("hex").slice(0, 16);
614470
+ return createHash37("sha1").update(`${name10}\0${canon}`).digest("hex").slice(0, 16);
614572
614471
  }
614573
614472
  function canonicalize(value2) {
614574
614473
  if (value2 === null || typeof value2 !== "object")
@@ -625482,7 +625381,7 @@ var require_websocket3 = __commonJS({
625482
625381
  var http6 = __require("http");
625483
625382
  var net5 = __require("net");
625484
625383
  var tls2 = __require("tls");
625485
- var { randomBytes: randomBytes31, createHash: createHash51 } = __require("crypto");
625384
+ var { randomBytes: randomBytes31, createHash: createHash53 } = __require("crypto");
625486
625385
  var { Duplex: Duplex3, Readable } = __require("stream");
625487
625386
  var { URL: URL3 } = __require("url");
625488
625387
  var PerMessageDeflate3 = require_permessage_deflate3();
@@ -626142,7 +626041,7 @@ var require_websocket3 = __commonJS({
626142
626041
  abortHandshake(websocket, socket, "Invalid Upgrade header");
626143
626042
  return;
626144
626043
  }
626145
- const digest3 = createHash51("sha1").update(key + GUID).digest("base64");
626044
+ const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
626146
626045
  if (res.headers["sec-websocket-accept"] !== digest3) {
626147
626046
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
626148
626047
  return;
@@ -626509,7 +626408,7 @@ var require_websocket_server2 = __commonJS({
626509
626408
  var EventEmitter15 = __require("events");
626510
626409
  var http6 = __require("http");
626511
626410
  var { Duplex: Duplex3 } = __require("stream");
626512
- var { createHash: createHash51 } = __require("crypto");
626411
+ var { createHash: createHash53 } = __require("crypto");
626513
626412
  var extension3 = require_extension3();
626514
626413
  var PerMessageDeflate3 = require_permessage_deflate3();
626515
626414
  var subprotocol3 = require_subprotocol2();
@@ -626810,7 +626709,7 @@ var require_websocket_server2 = __commonJS({
626810
626709
  );
626811
626710
  }
626812
626711
  if (this._state > RUNNING) return abortHandshake(socket, 503);
626813
- const digest3 = createHash51("sha1").update(key + GUID).digest("base64");
626712
+ const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
626814
626713
  const headers = [
626815
626714
  "HTTP/1.1 101 Switching Protocols",
626816
626715
  "Upgrade: websocket",
@@ -633591,14 +633490,14 @@ var init_voice_session = __esm({
633591
633490
  });
633592
633491
 
633593
633492
  // packages/cli/src/tui/scoped-personality.ts
633594
- import { createHash as createHash37 } from "node:crypto";
633493
+ import { createHash as createHash38 } from "node:crypto";
633595
633494
  import { appendFileSync as appendFileSync13, existsSync as existsSync120, mkdirSync as mkdirSync72, readFileSync as readFileSync97, writeFileSync as writeFileSync60 } from "node:fs";
633596
633495
  import { join as join131, resolve as resolve60 } from "node:path";
633597
633496
  function safeName(input) {
633598
633497
  return input.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "default";
633599
633498
  }
633600
633499
  function scopeHash(scope) {
633601
- return createHash37("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
633500
+ return createHash38("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
633602
633501
  }
633603
633502
  function scopedPersonalityDir(repoRoot, kind) {
633604
633503
  return resolve60(repoRoot, ".omnius", "scoped-personality", kind);
@@ -633969,7 +633868,7 @@ var init_scoped_personality = __esm({
633969
633868
  });
633970
633869
 
633971
633870
  // packages/cli/src/tui/voice-soul.ts
633972
- import { createHash as createHash38 } from "node:crypto";
633871
+ import { createHash as createHash39 } from "node:crypto";
633973
633872
  import { existsSync as existsSync121, readdirSync as readdirSync38, readFileSync as readFileSync98 } from "node:fs";
633974
633873
  import { basename as basename26, join as join132, resolve as resolve61 } from "node:path";
633975
633874
  function compactText(text2, limit) {
@@ -633984,7 +633883,7 @@ function blockText(text2, limit) {
633984
633883
  ... [truncated]`;
633985
633884
  }
633986
633885
  function scopeStateKey(scope, surface) {
633987
- return createHash38("sha1").update(`${surface}:${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
633886
+ return createHash39("sha1").update(`${surface}:${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
633988
633887
  }
633989
633888
  function safeName2(input) {
633990
633889
  return input.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "default";
@@ -636624,7 +636523,7 @@ var init_types3 = __esm({
636624
636523
  });
636625
636524
 
636626
636525
  // packages/cli/src/tui/p2p/secret-vault.ts
636627
- import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes23, scryptSync as scryptSync2, createHash as createHash39 } from "node:crypto";
636526
+ import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes23, scryptSync as scryptSync2, createHash as createHash40 } from "node:crypto";
636628
636527
  import { readFileSync as readFileSync100, writeFileSync as writeFileSync62, existsSync as existsSync123, mkdirSync as mkdirSync74 } from "node:fs";
636629
636528
  import { dirname as dirname39 } from "node:path";
636630
636529
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
@@ -636868,7 +636767,7 @@ var init_secret_vault = __esm({
636868
636767
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
636869
636768
  fingerprint() {
636870
636769
  const names = Array.from(this.secrets.keys()).sort();
636871
- const hash = createHash39("sha256");
636770
+ const hash = createHash40("sha256");
636872
636771
  for (const name10 of names) {
636873
636772
  hash.update(name10 + ":");
636874
636773
  hash.update(this.secrets.get(name10).value);
@@ -636883,7 +636782,7 @@ var init_secret_vault = __esm({
636883
636782
  // packages/cli/src/tui/p2p/peer-mesh.ts
636884
636783
  import { EventEmitter as EventEmitter9 } from "node:events";
636885
636784
  import { createServer as createServer6 } from "node:http";
636886
- import { randomBytes as randomBytes24, createHash as createHash40, generateKeyPairSync } from "node:crypto";
636785
+ import { randomBytes as randomBytes24, createHash as createHash41, generateKeyPairSync } from "node:crypto";
636887
636786
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
636888
636787
  var init_peer_mesh = __esm({
636889
636788
  "packages/cli/src/tui/p2p/peer-mesh.ts"() {
@@ -636899,7 +636798,7 @@ var init_peer_mesh = __esm({
636899
636798
  const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
636900
636799
  this.publicKey = publicKey2.export({ type: "spki", format: "der" });
636901
636800
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
636902
- this.peerId = createHash40("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
636801
+ this.peerId = createHash41("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
636903
636802
  this.capabilities = options2.capabilities;
636904
636803
  this.displayName = options2.displayName;
636905
636804
  this._authKey = options2.authKey ?? randomBytes24(24).toString("base64url");
@@ -638265,7 +638164,7 @@ __export(omnius_directory_exports, {
638265
638164
  import { appendFileSync as appendFileSync14, cpSync as cpSync2, existsSync as existsSync125, mkdirSync as mkdirSync76, readFileSync as readFileSync102, writeFileSync as writeFileSync64, readdirSync as readdirSync41, statSync as statSync51, unlinkSync as unlinkSync23, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync11, watch as fsWatch2 } from "node:fs";
638266
638165
  import { join as join136, relative as relative17, basename as basename27, dirname as dirname40, resolve as resolve62 } from "node:path";
638267
638166
  import { homedir as homedir42 } from "node:os";
638268
- import { createHash as createHash42 } from "node:crypto";
638167
+ import { createHash as createHash43 } from "node:crypto";
638269
638168
  function isGitRoot(dir) {
638270
638169
  const gitPath = join136(dir, ".git");
638271
638170
  if (!existsSync125(gitPath)) return false;
@@ -638747,7 +638646,7 @@ function buildHandoffPrompt(repoRoot) {
638747
638646
  return lines.join("\n");
638748
638647
  }
638749
638648
  function computeDedupeHash(task, savedAt) {
638750
- return createHash42("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
638649
+ return createHash43("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
638751
638650
  }
638752
638651
  function generateSessionId() {
638753
638652
  const timestamp = Date.now().toString(36);
@@ -665789,7 +665688,7 @@ __export(commands_exports, {
665789
665688
  });
665790
665689
  import * as nodeOs from "node:os";
665791
665690
  import { spawn as nodeSpawn2 } from "node:child_process";
665792
- import { createHash as createHash43 } from "node:crypto";
665691
+ import { createHash as createHash44 } from "node:crypto";
665793
665692
  import {
665794
665693
  existsSync as existsSync147,
665795
665694
  readFileSync as readFileSync119,
@@ -679149,7 +679048,7 @@ async function collectSponsorMediaStream(args) {
679149
679048
  };
679150
679049
  }
679151
679050
  if (artifact.sha256) {
679152
- const sha = createHash43("sha256").update(bytes).digest("hex");
679051
+ const sha = createHash44("sha256").update(bytes).digest("hex");
679153
679052
  if (sha !== artifact.sha256)
679154
679053
  return { ok: false, error: `Artifact hash mismatch for ${artifactId}` };
679155
679054
  }
@@ -693617,7 +693516,7 @@ import {
693617
693516
  unlinkSync as unlinkSync34
693618
693517
  } from "node:fs";
693619
693518
  import { join as join168 } from "node:path";
693620
- import { createHash as createHash44 } from "node:crypto";
693519
+ import { createHash as createHash45 } from "node:crypto";
693621
693520
  function safeFilePart(value2) {
693622
693521
  return value2.replace(/[^A-Za-z0-9_.-]+/g, "_").slice(0, 80) || "telegram";
693623
693522
  }
@@ -693625,7 +693524,7 @@ function daydreamRoot(repoRoot) {
693625
693524
  return join168(repoRoot, ".omnius", "telegram-daydreams");
693626
693525
  }
693627
693526
  function sessionDir(repoRoot, sessionKey) {
693628
- const hash = createHash44("sha1").update(sessionKey).digest("hex").slice(0, 20);
693527
+ const hash = createHash45("sha1").update(sessionKey).digest("hex").slice(0, 20);
693629
693528
  return join168(daydreamRoot(repoRoot), safeFilePart(hash));
693630
693529
  }
693631
693530
  function compactLine2(value2, max = 220) {
@@ -693736,7 +693635,7 @@ function buildReplyOpportunities(input, openQuestions) {
693736
693635
  return opportunities;
693737
693636
  }
693738
693637
  function daydreamOpportunityId(input, trigger) {
693739
- return createHash44("sha1").update(`${input.sessionKey}:${input.generatedAtMs}:${trigger}`).digest("hex").slice(0, 16);
693638
+ return createHash45("sha1").update(`${input.sessionKey}:${input.generatedAtMs}:${trigger}`).digest("hex").slice(0, 16);
693740
693639
  }
693741
693640
  function clamp0115(value2) {
693742
693641
  if (!Number.isFinite(value2)) return 0;
@@ -694141,7 +694040,7 @@ function buildTelegramChannelDaydream(input, corpus, extraction, extractionCommi
694141
694040
  const seed = `${input.sessionKey}:${input.generatedAtMs}:${input.history.length}`;
694142
694041
  return {
694143
694042
  version: 3,
694144
- id: createHash44("sha1").update(seed).digest("hex").slice(0, 16),
694043
+ id: createHash45("sha1").update(seed).digest("hex").slice(0, 16),
694145
694044
  sessionKey: input.sessionKey,
694146
694045
  chatId: input.chatId,
694147
694046
  chatTitle: input.chatTitle,
@@ -694453,12 +694352,12 @@ var init_telegram_channel_dmn = __esm({
694453
694352
  });
694454
694353
 
694455
694354
  // packages/cli/src/tui/telegram-reflection-corpus.ts
694456
- import { createHash as createHash45 } from "node:crypto";
694355
+ import { createHash as createHash46 } from "node:crypto";
694457
694356
  function telegramReflectionMemoryDbPaths(repoRoot) {
694458
694357
  return omniusMemoryDbPaths(repoRoot);
694459
694358
  }
694460
694359
  function stableHash2(value2, length4 = 16) {
694461
- return createHash45("sha1").update(value2).digest("hex").slice(0, length4);
694360
+ return createHash46("sha1").update(value2).digest("hex").slice(0, length4);
694462
694361
  }
694463
694362
  function clean3(value2) {
694464
694363
  return String(value2 ?? "").replace(/\s+/g, " ").trim();
@@ -695271,7 +695170,7 @@ var init_telegram_reflection_extraction = __esm({
695271
695170
  });
695272
695171
 
695273
695172
  // packages/cli/src/tui/telegram-social-state-types.ts
695274
- import { createHash as createHash46 } from "node:crypto";
695173
+ import { createHash as createHash47 } from "node:crypto";
695275
695174
  function telegramSocialActorKey(actor) {
695276
695175
  if (!actor) return "unknown";
695277
695176
  if (typeof actor.userId === "number") return `user:${actor.userId}`;
@@ -695304,7 +695203,7 @@ function appendUnique(items, value2, max) {
695304
695203
  return next.slice(-max);
695305
695204
  }
695306
695205
  function hashTelegramSocialId(parts) {
695307
- return createHash46("sha1").update(parts.map((part) => String(part ?? "")).join(":")).digest("hex").slice(0, 16);
695206
+ return createHash47("sha1").update(parts.map((part) => String(part ?? "")).join(":")).digest("hex").slice(0, 16);
695308
695207
  }
695309
695208
  function cleanUsername(value2) {
695310
695209
  if (typeof value2 !== "string") return void 0;
@@ -696364,7 +696263,7 @@ import {
696364
696263
  } from "node:path";
696365
696264
  import { homedir as homedir56 } from "node:os";
696366
696265
  import { writeFile as writeFileAsync } from "node:fs/promises";
696367
- import { createHash as createHash47, randomBytes as randomBytes28, randomInt } from "node:crypto";
696266
+ import { createHash as createHash48, randomBytes as randomBytes28, randomInt } from "node:crypto";
696368
696267
  function formatModelBytes(bytes) {
696369
696268
  if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
696370
696269
  const units = ["B", "KB", "MB", "GB", "TB"];
@@ -697609,7 +697508,7 @@ function buildTelegramRuntimeContext(now2 = /* @__PURE__ */ new Date(), repoRoot
697609
697508
  return buildConversationRuntimeContext(now2, repoRoot);
697610
697509
  }
697611
697510
  function telegramSessionIdFromKey(sessionKey) {
697612
- return `telegram-${createHash47("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
697511
+ return `telegram-${createHash48("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
697613
697512
  }
697614
697513
  function normalizeTelegramSubAgentLimit(value2) {
697615
697514
  const parsed = typeof value2 === "number" ? value2 : typeof value2 === "string" && value2.trim() ? Number(value2.trim()) : TELEGRAM_SUB_AGENT_DEFAULT_LIMIT;
@@ -699773,7 +699672,7 @@ Telegram link integrity contract:
699773
699672
  return !!this.adminAuthChallenge && this.adminAuthChallenge.expiresAtMs > Date.now();
699774
699673
  }
699775
699674
  hashAdminAuthCode(code8) {
699776
- return createHash47("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
699675
+ return createHash48("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
699777
699676
  }
699778
699677
  viewIdForMessage(msg) {
699779
699678
  return `telegram-${this.sessionKeyForMessage(msg).replace(/[^A-Za-z0-9_-]/g, "-")}`;
@@ -701845,11 +701744,11 @@ ${mediaContext}` : ""
701845
701744
  return payload;
701846
701745
  }
701847
701746
  telegramConversationPath(sessionKey) {
701848
- const safe = createHash47("sha1").update(sessionKey).digest("hex").slice(0, 20);
701747
+ const safe = createHash48("sha1").update(sessionKey).digest("hex").slice(0, 20);
701849
701748
  return join170(this.telegramConversationDir, `${safe}.json`);
701850
701749
  }
701851
701750
  telegramConversationLedgerPath(sessionKey) {
701852
- const safe = createHash47("sha1").update(sessionKey).digest("hex").slice(0, 20);
701751
+ const safe = createHash48("sha1").update(sessionKey).digest("hex").slice(0, 20);
701853
701752
  return join170(this.telegramConversationDir, `${safe}.events.jsonl`);
701854
701753
  }
701855
701754
  telegramDb() {
@@ -702082,7 +701981,7 @@ ${mediaContext}` : ""
702082
701981
  relationships: Array.isArray(raw.relationships) ? raw.relationships.slice(0, TELEGRAM_ASSOCIATIVE_RELATION_LIMIT).map((fact) => this.normalizeTelegramAssociativeFact(fact)) : [],
702083
701982
  actions: Array.isArray(raw.actions) ? raw.actions.slice(-TELEGRAM_ASSOCIATIVE_ACTION_LIMIT).map((action) => ({
702084
701983
  id: String(
702085
- action.id || createHash47("sha1").update(JSON.stringify(action)).digest("hex").slice(0, 12)
701984
+ action.id || createHash48("sha1").update(JSON.stringify(action)).digest("hex").slice(0, 12)
702086
701985
  ),
702087
701986
  ts: typeof action.ts === "number" ? action.ts : Date.now(),
702088
701987
  role: action.role === "assistant" ? "assistant" : "user",
@@ -702101,7 +702000,7 @@ ${mediaContext}` : ""
702101
702000
  const now2 = Date.now();
702102
702001
  return {
702103
702002
  id: String(
702104
- raw.id || createHash47("sha1").update(text2 || String(now2)).digest("hex").slice(0, 12)
702003
+ raw.id || createHash48("sha1").update(text2 || String(now2)).digest("hex").slice(0, 12)
702105
702004
  ),
702106
702005
  text: text2,
702107
702006
  tags: Array.isArray(raw.tags) ? raw.tags.map(String).slice(0, 16) : [],
@@ -702558,7 +702457,7 @@ ${mediaContext}` : ""
702558
702457
  telegramHistoryBackfillMessageId(sessionKey, entry, index) {
702559
702458
  if (typeof entry.messageId === "number" && Number.isFinite(entry.messageId))
702560
702459
  return entry.messageId;
702561
- const digest3 = createHash47("sha1").update(
702460
+ const digest3 = createHash48("sha1").update(
702562
702461
  `${sessionKey}:${index}:${entry.role}:${entry.ts ?? ""}:${entry.text}`
702563
702462
  ).digest("hex").slice(0, 8);
702564
702463
  return -Number.parseInt(digest3, 16);
@@ -703748,7 +703647,7 @@ ${mediaContext}` : ""
703748
703647
  const now2 = entry.ts ?? Date.now();
703749
703648
  memory.updatedAt = now2;
703750
703649
  const speaker = telegramHistorySpeaker(entry);
703751
- const actionId = createHash47("sha1").update(
703650
+ const actionId = createHash48("sha1").update(
703752
703651
  `${sessionKey}:${entry.role}:${entry.messageId ?? ""}:${now2}:${entry.text}`
703753
703652
  ).digest("hex").slice(0, 16);
703754
703653
  if (!memory.actions.some((action) => action.id === actionId)) {
@@ -703911,7 +703810,7 @@ ${mediaContext}` : ""
703911
703810
  let fact = facts.find((item) => item.text.toLowerCase() === key);
703912
703811
  if (!fact) {
703913
703812
  fact = {
703914
- id: createHash47("sha1").update(`${entry.chatId ?? ""}:${key}`).digest("hex").slice(0, 12),
703813
+ id: createHash48("sha1").update(`${entry.chatId ?? ""}:${key}`).digest("hex").slice(0, 12),
703915
703814
  text: clean5,
703916
703815
  tags: telegramMemoryTags(clean5, entry.mediaSummary),
703917
703816
  speakers: [],
@@ -703996,7 +703895,7 @@ ${mediaContext}` : ""
703996
703895
  const titleTags = tags.slice(0, 4);
703997
703896
  const title = titleTags.length > 0 ? `${speaker} / ${titleTags.join(" ")}` : `${speaker} / conversation`;
703998
703897
  const card = {
703999
- id: createHash47("sha1").update(`${sessionKey}:${now2}:${speaker}:${text2}`).digest("hex").slice(0, 12),
703898
+ id: createHash48("sha1").update(`${sessionKey}:${now2}:${speaker}:${text2}`).digest("hex").slice(0, 12),
704000
703899
  title,
704001
703900
  notes: [],
704002
703901
  tags: [],
@@ -706760,7 +706659,7 @@ ${list}` : "No shared group target is currently known for this sender. Ask in th
706760
706659
  }
706761
706660
  telegramRunnerStateDir(sessionKey) {
706762
706661
  if (!this.repoRoot) return void 0;
706763
- const safe = createHash47("sha1").update(sessionKey).digest("hex").slice(0, 20);
706662
+ const safe = createHash48("sha1").update(sessionKey).digest("hex").slice(0, 20);
706764
706663
  return join170(this.repoRoot, ".omnius", "telegram-runner-state", safe);
706765
706664
  }
706766
706665
  buildTelegramAdminOverviewContext(currentSessionKey) {
@@ -717455,14 +717354,14 @@ var init_access_policy = __esm({
717455
717354
  });
717456
717355
 
717457
717356
  // packages/cli/src/api/project-preferences.ts
717458
- import { createHash as createHash48 } from "node:crypto";
717357
+ import { createHash as createHash49 } from "node:crypto";
717459
717358
  import { existsSync as existsSync162, mkdirSync as mkdirSync100, readFileSync as readFileSync133, renameSync as renameSync16, writeFileSync as writeFileSync87, unlinkSync as unlinkSync37 } from "node:fs";
717460
717359
  import { homedir as homedir58 } from "node:os";
717461
717360
  import { join as join172, resolve as resolve75 } from "node:path";
717462
717361
  import { randomUUID as randomUUID20 } from "node:crypto";
717463
717362
  function projectKey(root) {
717464
717363
  const canonical = resolve75(root);
717465
- return createHash48("sha256").update(canonical).digest("hex").slice(0, 16);
717364
+ return createHash49("sha256").update(canonical).digest("hex").slice(0, 16);
717466
717365
  }
717467
717366
  function projectDir(root) {
717468
717367
  return join172(PROJECTS_DIR, projectKey(root));
@@ -717753,7 +717652,7 @@ var init_disk_task_output = __esm({
717753
717652
  });
717754
717653
 
717755
717654
  // packages/cli/src/api/http.ts
717756
- import { createHash as createHash49 } from "node:crypto";
717655
+ import { createHash as createHash50 } from "node:crypto";
717757
717656
  function problemDetails(opts) {
717758
717657
  const p2 = {
717759
717658
  type: opts.type ?? "about:blank",
@@ -717816,7 +717715,7 @@ function paginated(items, page2, total) {
717816
717715
  }
717817
717716
  function computeEtag(payload) {
717818
717717
  const json = typeof payload === "string" ? payload : JSON.stringify(payload);
717819
- const hash = createHash49("sha1").update(json).digest("hex").slice(0, 16);
717718
+ const hash = createHash50("sha1").update(json).digest("hex").slice(0, 16);
717820
717719
  return `W/"${hash}"`;
717821
717720
  }
717822
717721
  function checkNotModified(req3, res, etag) {
@@ -735979,7 +735878,8 @@ function getOpenApiSpec() {
735979
735878
  tags: ["Context"],
735980
735879
  parameters: [
735981
735880
  { name: "id", in: "path", required: true, schema: { type: "string" }, description: "Dump id, or latest" },
735982
- { name: "repo", in: "query", required: false, schema: { type: "string" } }
735881
+ { name: "repo", in: "query", required: false, schema: { type: "string" } },
735882
+ { name: "agent_type", in: "query", required: false, schema: { type: "string", enum: ["main", "sub-agent", "internal", "adversary", "auxiliary"] }, description: "When id is latest, fetch the latest dump for this agent type" }
735983
735883
  ],
735984
735884
  responses: { 200: { description: "Full context-window dump" }, 404: { description: "Dump not found" } }
735985
735885
  }
@@ -737226,7 +737126,7 @@ import {
737226
737126
  closeSync as closeSync6
737227
737127
  } from "node:fs";
737228
737128
  import { randomBytes as randomBytes29, randomUUID as randomUUID21, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
737229
- import { createHash as createHash50 } from "node:crypto";
737129
+ import { createHash as createHash51 } from "node:crypto";
737230
737130
  function memoryDbPaths3(baseDir = process.cwd()) {
737231
737131
  const dir = join183(baseDir, ".omnius");
737232
737132
  return {
@@ -745395,7 +745295,7 @@ function listScheduledTasks() {
745395
745295
  );
745396
745296
  const enabled2 = typeof t2?.enabled === "boolean" ? t2.enabled : true;
745397
745297
  const realId = typeof t2?.id === "string" && t2.id ? t2.id : null;
745398
- const fallbackId = createHash50("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
745298
+ const fallbackId = createHash51("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
745399
745299
  const uid = realId || fallbackId;
745400
745300
  const key = `${uid}`;
745401
745301
  if (seen.has(key)) return;
@@ -745533,8 +745433,8 @@ function deleteScheduledById(id2) {
745533
745433
  if (typeof entry?.id === "string" && entry.id && !candidates.includes(entry.id))
745534
745434
  candidates.push(entry.id);
745535
745435
  try {
745536
- const { createHash: createHash51 } = require4("node:crypto");
745537
- const fallback = createHash51("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
745436
+ const { createHash: createHash53 } = require4("node:crypto");
745437
+ const fallback = createHash53("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
745538
745438
  if (!candidates.includes(fallback)) candidates.push(fallback);
745539
745439
  } catch {
745540
745440
  }
@@ -747771,6 +747671,7 @@ import { cwd } from "node:process";
747771
747671
  import { resolve as resolve78, join as join185, dirname as dirname56, extname as extname22, relative as relative22, sep as sep7 } from "node:path";
747772
747672
  import { createRequire as createRequire9 } from "node:module";
747773
747673
  import { fileURLToPath as fileURLToPath24 } from "node:url";
747674
+ import { createHash as createHash52 } from "node:crypto";
747774
747675
  import {
747775
747676
  readFileSync as readFileSync142,
747776
747677
  writeFileSync as writeFileSync94,
@@ -748697,6 +748598,37 @@ function getRuntimeToolProfilePolicy(repoRoot) {
748697
748598
  function truncateSubAgentViewText(s2, n2) {
748698
748599
  return s2.length > n2 ? `${s2.slice(0, n2)}…` : s2;
748699
748600
  }
748601
+ function childAgentTaskHash(task) {
748602
+ return createHash52("sha256").update(task).digest("hex").slice(0, 12);
748603
+ }
748604
+ function stripAnsiForParentContext(value2) {
748605
+ return value2.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, "");
748606
+ }
748607
+ function sanitizeChildAgentParentContextText(value2, options2 = {}) {
748608
+ const maxLines = options2.maxLines ?? CHILD_AGENT_PARENT_CONTEXT_MAX_LINES;
748609
+ const maxChars = options2.maxChars ?? CHILD_AGENT_PARENT_CONTEXT_MAX_CHARS;
748610
+ const noAnsi = stripAnsiForParentContext(value2).replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/<think>[\s\S]*$/gi, "");
748611
+ const sanitized = sanitizeRestorePromptForModel(noAnsi);
748612
+ const lines = sanitized.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).filter((line) => !/SHELL TRANSCRIPT/i.test(line)).filter((line) => !/^Task:\s/i.test(line)).filter((line) => !/^Last output:\s*$/i.test(line)).slice(-maxLines);
748613
+ const joined = lines.join("\n");
748614
+ return joined.length > maxChars ? `${joined.slice(0, Math.max(0, maxChars - 14)).trimEnd()}...[truncated]` : joined;
748615
+ }
748616
+ function formatChildAgentParentGuidance(input) {
748617
+ const status = input.exitCode === 0 ? "completed" : "failed";
748618
+ const summary = sanitizeChildAgentParentContextText(input.output);
748619
+ const taskPreview = sanitizeChildAgentParentContextText(input.task, {
748620
+ maxLines: 2,
748621
+ maxChars: 220
748622
+ });
748623
+ return [
748624
+ `[child_agent_result] kind=${input.kind} id=${input.id} status=${status} exit_code=${input.exitCode ?? "unknown"} task_sha256=${childAgentTaskHash(input.task)}`,
748625
+ taskPreview ? `task_preview:
748626
+ ${taskPreview}` : null,
748627
+ summary ? `result_preview:
748628
+ ${summary}` : "result_preview: unavailable",
748629
+ `full_output_available_via=${input.kind === "full sub-agent" ? "full_sub_agent" : "sub_agent"} id=${input.id}`
748630
+ ].filter((line) => Boolean(line)).join("\n");
748631
+ }
748700
748632
  function subAgentDynamicBlockId(agentId, event, kind) {
748701
748633
  const safeAgent = agentId.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 48);
748702
748634
  const safeTs = String(event.timestamp || Date.now()).replace(
@@ -749072,11 +749004,17 @@ ${task}` : task;
749072
749004
  `sub_agent: ${cleanedLabelTask.slice(0, 80)}`,
749073
749005
  promise
749074
749006
  );
749007
+ const taskPreview = sanitizeChildAgentParentContextText(task, {
749008
+ maxLines: 2,
749009
+ maxChars: 220
749010
+ });
749075
749011
  return {
749076
749012
  success: true,
749077
749013
  output: `${compatibilityPrefix}Sub-agent started in background: ${taskId}
749078
- Task: ${task}
749079
- Use task_status(task_id="${taskId}") or task_output(task_id="${taskId}") to check progress.`
749014
+ task_sha256=${childAgentTaskHash(task)}
749015
+ ` + (taskPreview ? `task_preview:
749016
+ ${taskPreview}
749017
+ ` : "") + `Use task_status(task_id="${taskId}") or task_output(task_id="${taskId}") to check progress.`
749080
749018
  };
749081
749019
  }
749082
749020
  if (onViewStatus) onViewStatus(agentId, "running");
@@ -750448,16 +750386,18 @@ ${content}
750448
750386
  onComplete: (id2, task2, exitCode, output) => {
750449
750387
  registry2.unregisterAgent(id2);
750450
750388
  statusBar.unregisterAgentView(id2);
750451
- const summary = output.split("\n").filter((l2) => l2.trim()).slice(-5).join("\n");
750452
- const status = exitCode === 0 ? "COMPLETED" : "FAILED";
750453
- _activeRunnerRef?.injectUserMessage(
750454
- `[Sub-agent ${id2} ${status}]
750455
- Task: ${task2.slice(0, 100)}
750456
- Exit code: ${exitCode}
750457
- Last output:
750458
- ${summary}
750459
- Review its full output via sub_agent(action='output', id='${id2}')`
750460
- );
750389
+ const guidance = formatChildAgentParentGuidance({
750390
+ kind: "sub-agent",
750391
+ id: id2,
750392
+ task: task2,
750393
+ exitCode,
750394
+ output
750395
+ });
750396
+ if (_activeRunnerRef?.injectRuntimeGuidance) {
750397
+ _activeRunnerRef.injectRuntimeGuidance(guidance);
750398
+ } else {
750399
+ _activeRunnerRef?.injectUserMessage(guidance);
750400
+ }
750461
750401
  }
750462
750402
  });
750463
750403
  }
@@ -752477,16 +752417,18 @@ async function startInteractive(config, repoPath2) {
752477
752417
  onComplete: (id2, task, exitCode, output) => {
752478
752418
  registry2.unregisterAgent(id2);
752479
752419
  statusBar.unregisterAgentView(id2);
752480
- const summary = output.split("\n").filter((l2) => l2.trim()).slice(-5).join("\n");
752481
- const status = exitCode === 0 ? "COMPLETED" : "FAILED";
752482
- _activeRunnerRef?.injectUserMessage(
752483
- `[Full sub-agent ${id2} ${status}]
752484
- Task: ${task.slice(0, 100)}
752485
- Exit code: ${exitCode}
752486
- Last output:
752487
- ${summary}
752488
- Review its full output via full_sub_agent(action='output', id='${id2}')`
752489
- );
752420
+ const guidance = formatChildAgentParentGuidance({
752421
+ kind: "full sub-agent",
752422
+ id: id2,
752423
+ task,
752424
+ exitCode,
752425
+ output
752426
+ });
752427
+ if (_activeRunnerRef?.injectRuntimeGuidance) {
752428
+ _activeRunnerRef.injectRuntimeGuidance(guidance);
752429
+ } else {
752430
+ _activeRunnerRef?.injectUserMessage(guidance);
752431
+ }
752490
752432
  }
752491
752433
  });
752492
752434
  };
@@ -752517,16 +752459,18 @@ Review its full output via full_sub_agent(action='output', id='${id2}')`
752517
752459
  onComplete: (id2, task, exitCode, output) => {
752518
752460
  registry2.unregisterAgent(id2);
752519
752461
  statusBar.unregisterAgentView(id2);
752520
- const summary = output.split("\n").filter((l2) => l2.trim()).slice(-5).join("\n");
752521
- const status = exitCode === 0 ? "COMPLETED" : "FAILED";
752522
- _activeRunnerRef?.injectUserMessage(
752523
- `[Sub-agent ${id2} ${status}]
752524
- Task: ${task.slice(0, 100)}
752525
- Exit code: ${exitCode}
752526
- Last output:
752527
- ${summary}
752528
- Review its full output via sub_agent(action='output', id='${id2}')`
752529
- );
752462
+ const guidance = formatChildAgentParentGuidance({
752463
+ kind: "sub-agent",
752464
+ id: id2,
752465
+ task,
752466
+ exitCode,
752467
+ output
752468
+ });
752469
+ if (_activeRunnerRef?.injectRuntimeGuidance) {
752470
+ _activeRunnerRef.injectRuntimeGuidance(guidance);
752471
+ } else {
752472
+ _activeRunnerRef?.injectUserMessage(guidance);
752473
+ }
752530
752474
  }
752531
752475
  });
752532
752476
  };
@@ -757966,13 +757910,13 @@ ${taskInput}`;
757966
757910
  writeContent(() => renderError(errMsg));
757967
757911
  if (failureStore) {
757968
757912
  try {
757969
- const { createHash: createHash51 } = await import("node:crypto");
757913
+ const { createHash: createHash53 } = await import("node:crypto");
757970
757914
  failureStore.insert({
757971
757915
  taskId: "",
757972
757916
  sessionId: `${Date.now()}`,
757973
757917
  repoRoot,
757974
757918
  failureType: "runtime-error",
757975
- fingerprint: createHash51("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
757919
+ fingerprint: createHash53("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
757976
757920
  filePath: null,
757977
757921
  errorMessage: errMsg.slice(0, 500),
757978
757922
  context: null,
@@ -758731,7 +758675,7 @@ Rules:
758731
758675
  process.exit(1);
758732
758676
  }
758733
758677
  }
758734
- var NEXUS_DIRECTORY_ORIGIN3, NEXUS_AGENT_DIRECTORY_URL, localOllamaModelCache, localOllamaProbeInFlight, NEXUS_SPONSORS_URL3, ADVERSARY_COLOR, _generativeProgressSink, _liveMediaStatusSink, _liveMediaAudioCount, _liveMediaVideoCount, _interactiveSessionActive, _interactiveSessionReason, _voiceChatSession2, taskManager, _apiCallbacks, _shellToolRef, _replToolRef, _fullSubAgentToolRef, _agentToolRef, _sendMessageToolRef, _agentLifecycleMgr, _activeRunnerRef, _parentRunnerForArchive, _wireSubAgentCallbacks, _wireAgentToolCallbacks, _wireSubAgentToolCallbacks, _autoUpdatedThisSession, _mcpManager, _pluginManager, _mcpTools, subAgentPendingToolCalls, subAgentViewBlockSeq, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
758678
+ var NEXUS_DIRECTORY_ORIGIN3, NEXUS_AGENT_DIRECTORY_URL, localOllamaModelCache, localOllamaProbeInFlight, NEXUS_SPONSORS_URL3, ADVERSARY_COLOR, _generativeProgressSink, _liveMediaStatusSink, _liveMediaAudioCount, _liveMediaVideoCount, _interactiveSessionActive, _interactiveSessionReason, _voiceChatSession2, taskManager, _apiCallbacks, _shellToolRef, _replToolRef, _fullSubAgentToolRef, _agentToolRef, _sendMessageToolRef, _agentLifecycleMgr, _activeRunnerRef, _parentRunnerForArchive, _wireSubAgentCallbacks, _wireAgentToolCallbacks, _wireSubAgentToolCallbacks, _autoUpdatedThisSession, _mcpManager, _pluginManager, _mcpTools, subAgentPendingToolCalls, subAgentViewBlockSeq, CHILD_AGENT_PARENT_CONTEXT_MAX_LINES, CHILD_AGENT_PARENT_CONTEXT_MAX_CHARS, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
758735
758679
  var init_interactive = __esm({
758736
758680
  "packages/cli/src/tui/interactive.ts"() {
758737
758681
  init_memory_maintenance();
@@ -758835,6 +758779,8 @@ var init_interactive = __esm({
758835
758779
  _mcpTools = [];
758836
758780
  subAgentPendingToolCalls = /* @__PURE__ */ new Map();
758837
758781
  subAgentViewBlockSeq = 0;
758782
+ CHILD_AGENT_PARENT_CONTEXT_MAX_LINES = 5;
758783
+ CHILD_AGENT_PARENT_CONTEXT_MAX_CHARS = 900;
758838
758784
  SELF_IMPROVE_INTERVAL = 5;
758839
758785
  _tasksSinceImprove = 0;
758840
758786
  }