omnius 1.0.224 → 1.0.226

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
@@ -560040,6 +560040,15 @@ var init_agenticRunner = __esm({
560040
560040
  _fileWritesThisRun = 0;
560041
560041
  _backwardPassCyclesUsed = 0;
560042
560042
  _lastBackwardPassVerdict = null;
560043
+ // REG-54: completion-gate anti-collapse circuit breaker. The no-progress and
560044
+ // completion-provenance gates can hold task_complete indefinitely. When a
560045
+ // collapsed/weak model resubmits the same (or a similar) completion summary,
560046
+ // the gate rejects it every turn and the model re-emits the identical
560047
+ // task_complete forever — a mode-collapse loop. Unlike the backward-pass
560048
+ // critic (REG-47), these gates had no cycle bound. We track consecutive holds
560049
+ // of the same summary and fail open after a small threshold so the run
560050
+ // terminates instead of spinning. Reset whenever a completion is allowed.
560051
+ _completionHoldState = { count: 0, lastKey: "" };
560043
560052
  // ── WO-AM-01/04/10: Associative memory stores ──
560044
560053
  // Episode store: every tool call → persistent episode with importance + decay
560045
560054
  // Temporal KG: entities + relations with temporal validity (valid_from/valid_until)
@@ -564982,6 +564991,52 @@ TASK: ${scrubbedTask}` : scrubbedTask;
564982
564991
  });
564983
564992
  return true;
564984
564993
  };
564994
+ const completionHoldEscapeMax = (() => {
564995
+ const raw = Number(process.env["OMNIUS_COMPLETION_HOLD_MAX"]);
564996
+ return Number.isFinite(raw) && raw >= 1 ? Math.floor(raw) : 3;
564997
+ })();
564998
+ const holdTaskCompleteGates = (args, turn) => {
564999
+ const held = holdNoProgressTaskComplete(args, turn) || holdProvenanceTaskComplete(args, turn);
565000
+ if (!held) {
565001
+ this._completionHoldState.count = 0;
565002
+ this._completionHoldState.lastKey = "";
565003
+ return false;
565004
+ }
565005
+ const key = (extractTaskCompleteSummary(args) || "").trim().slice(0, 200);
565006
+ if (key && key === this._completionHoldState.lastKey) {
565007
+ this._completionHoldState.count += 1;
565008
+ } else {
565009
+ this._completionHoldState.lastKey = key;
565010
+ this._completionHoldState.count = 1;
565011
+ }
565012
+ if (this._completionHoldState.count >= completionHoldEscapeMax) {
565013
+ messages2.push({
565014
+ role: "system",
565015
+ content: `[COMPLETION GATE ESCAPE] task_complete was held ${this._completionHoldState.count} times for the same summary without new progress. The gate feedback above is not being acted on, so completion is now ALLOWED to avoid a stall/mode-collapse loop. If the summary lacks evidence, that limitation stands in the final result.`
565016
+ });
565017
+ this.emit({
565018
+ type: "status",
565019
+ content: `completion gates yielding after ${this._completionHoldState.count} repeated holds to prevent a mode-collapse loop`,
565020
+ turn,
565021
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
565022
+ });
565023
+ this.emit({
565024
+ type: "adversary_reaction",
565025
+ adversary: {
565026
+ class: "guidance",
565027
+ shortText: "Completion gate escape (anti-loop)",
565028
+ confidence: 0.9,
565029
+ details: `Same task_complete summary held ${this._completionHoldState.count}× — failing open to terminate the run.`
565030
+ },
565031
+ turn,
565032
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
565033
+ });
565034
+ this._completionHoldState.count = 0;
565035
+ this._completionHoldState.lastKey = "";
565036
+ return false;
565037
+ }
565038
+ return true;
565039
+ };
564985
565040
  const emitBackwardPassAdvisory = (feedback, turn) => {
564986
565041
  messages2.push({
564987
565042
  role: "system",
@@ -568543,7 +568598,7 @@ ${sr.result.output}`;
568543
568598
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
568544
568599
  });
568545
568600
  } else {
568546
- if (holdNoProgressTaskComplete(matchTc.arguments, turn) || holdProvenanceTaskComplete(matchTc.arguments, turn)) {
568601
+ if (holdTaskCompleteGates(matchTc.arguments, turn)) {
568547
568602
  continue;
568548
568603
  }
568549
568604
  const _bp1 = await this._runBackwardPassReview(turn);
@@ -568598,7 +568653,7 @@ ${sr.result.output}`;
568598
568653
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
568599
568654
  });
568600
568655
  } else {
568601
- if (holdNoProgressTaskComplete(r2.tc.arguments, turn) || holdProvenanceTaskComplete(r2.tc.arguments, turn)) {
568656
+ if (holdTaskCompleteGates(r2.tc.arguments, turn)) {
568602
568657
  continue;
568603
568658
  }
568604
568659
  const _bp2 = await this._runBackwardPassReview(turn);
@@ -568690,7 +568745,7 @@ ${sr.result.output}`;
568690
568745
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
568691
568746
  });
568692
568747
  } else {
568693
- if (holdNoProgressTaskComplete(r2.tc.arguments, turn) || holdProvenanceTaskComplete(r2.tc.arguments, turn)) {
568748
+ if (holdTaskCompleteGates(r2.tc.arguments, turn)) {
568694
568749
  continue;
568695
568750
  }
568696
568751
  const _bp3 = await this._runBackwardPassReview(turn);
@@ -568911,7 +568966,7 @@ Call task_complete(summary="...") NOW with whatever you have.`
568911
568966
  const adversaryAddedGuidance = this.pendingUserMessages.length > pendingBeforeAdversary;
568912
568967
  if (/task.?complete|all tests pass/i.test(content)) {
568913
568968
  const completionArgs = { summary: content };
568914
- if (holdNoProgressTaskComplete(completionArgs, turn) || holdProvenanceTaskComplete(completionArgs, turn)) {
568969
+ if (holdTaskCompleteGates(completionArgs, turn)) {
568915
568970
  continue;
568916
568971
  }
568917
568972
  completed = true;
@@ -569482,7 +569537,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
569482
569537
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
569483
569538
  });
569484
569539
  } else {
569485
- if (holdNoProgressTaskComplete(tc.arguments, turn) || holdProvenanceTaskComplete(tc.arguments, turn)) {
569540
+ if (holdTaskCompleteGates(tc.arguments, turn)) {
569486
569541
  continue;
569487
569542
  }
569488
569543
  const _bp4 = await this._runBackwardPassReview(turn);
@@ -569535,7 +569590,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
569535
569590
  });
569536
569591
  } else {
569537
569592
  const completionArgs = { summary: content };
569538
- if (holdNoProgressTaskComplete(completionArgs, turn) || holdProvenanceTaskComplete(completionArgs, turn)) {
569593
+ if (holdTaskCompleteGates(completionArgs, turn)) {
569539
569594
  continue;
569540
569595
  }
569541
569596
  completed = true;
@@ -637758,13 +637813,15 @@ var init_emotion_engine = __esm({
637758
637813
  const prompt = [
637759
637814
  "You are the agent's private reflection process deciding whether to contact the Telegram admin.",
637760
637815
  "",
637816
+ "CRITICAL ROLE BOUNDARY: You are NOT executing the task below and you must not try to. You have exactly two tools — telegram_admin_message and task_complete — and that is correct and complete for your role. You do not have, and do not need, file/shell/edit/code tools. Never report that you are 'blocked', that you 'lack tools', or ask for tool access — that is never your job and the main agent (which has the real tools) handles the work. The task is shown only as CONTEXT so you can judge whether the admin would want a message right now.",
637817
+ "",
637761
637818
  "If no message is useful, call task_complete with NO_MESSAGE.",
637762
637819
  "If a message is useful, call telegram_admin_message with the exact text to send, then call task_complete.",
637763
- "Send a message when the agent is blocked, needs a preference/secret/clarification, is about to make a risky choice, or has a high-value status update the admin should know now.",
637764
- "Do not send routine task-complete, success-streak, mood, or cheerleading updates.",
637765
- "If you message, write it naturally in first person, under 700 characters. Ask a direct question only when user input would change the next action.",
637820
+ "Send a message when the MAIN AGENT is genuinely blocked, needs a preference/secret/clarification from the admin, is about to make a risky choice, or has a high-value status update the admin should know now.",
637821
+ "Do not send routine task-complete, success-streak, mood, or cheerleading updates. Do not send messages about your own (the reflection process's) tools or capabilities.",
637822
+ "If you message, write it naturally in first person as the agent, under 700 characters. Ask a direct question only when admin input would change the next action.",
637766
637823
  "",
637767
- `Current task: ${this.currentTask || "(none recorded)"}`,
637824
+ `Task the MAIN AGENT is working on (context only — NOT for you to perform): ${this.currentTask || "(none recorded)"}`,
637768
637825
  `Last event: ${event.type}${event.toolName ? `:${event.toolName}` : ""}${event.success === false ? " failed" : event.success === true ? " succeeded" : ""}`,
637769
637826
  `Event content: ${String(event.content ?? "").slice(0, 500)}`,
637770
637827
  `Recent activity: ${this.describeRecentActivity() || "(none)"}`,
@@ -637783,8 +637840,20 @@ var init_emotion_engine = __esm({
637783
637840
  cleanReflectionMessage(raw) {
637784
637841
  const text = raw.replace(/^["'`]+|["'`]+$/g, "").trim();
637785
637842
  if (!text || /^NO_MESSAGE\.?$/i.test(text)) return "";
637843
+ if (this.isReflectionToolComplaint(text)) return "";
637786
637844
  return text.slice(0, 900);
637787
637845
  }
637846
+ /**
637847
+ * Detect reflection-process meta-complaints about its own (intentionally
637848
+ * minimal) tool surface. These are mode-collapse artifacts, not genuine
637849
+ * admin outreach, and must be suppressed.
637850
+ */
637851
+ isReflectionToolComplaint(text) {
637852
+ const t2 = text.toLowerCase();
637853
+ const mentionsTools = /\btask_complete\b/.test(t2) || /\btelegram_admin_message\b/.test(t2) || /\b(file_read|file_edit|file_write|shell|file_patch|batch_edit)\b/.test(t2) || /\btool ?set\b/.test(t2) || /\btools?\b/.test(t2);
637854
+ if (!mentionsTools) return false;
637855
+ return /\b(don'?t|do not|doesn'?t|did not|didn'?t|cannot|can'?t|unable to|no longer)\b[^.]*\b(have|access|use)\b/.test(t2) || /\b(provide|grant|give|need|require|request)\b[^.]*\b(access|tools?|tool ?set)\b/.test(t2) || /\bi (only )?have (only )?(access to )?(task_complete|telegram_admin_message)/.test(t2) || /\bblocked\b[^.]*\b(tools?|access)\b/.test(t2) || /\bonly (have|with) (reflection|admin|task_complete|telegram)/.test(t2);
637856
+ }
637788
637857
  /** Summarize recent tool activity into a brief phrase */
637789
637858
  describeRecentActivity() {
637790
637859
  if (this.recentTools.length === 0) return "";
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.224",
3
+ "version": "1.0.226",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.224",
9
+ "version": "1.0.226",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.224",
3
+ "version": "1.0.226",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",