omnius 1.0.354 → 1.0.356

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
@@ -567216,10 +567216,13 @@ function adversarySystemPrompt() {
567216
567216
  " • simulation / mock / placeholder ≠ real.",
567217
567217
  " • partial progress ≠ done.",
567218
567218
  "Mixed results are the norm: do NOT let one success excuse an unproven completion claim.",
567219
+ " • a repeating IDENTICAL error while the agent keeps editing the same target = a FAILING",
567220
+ " APPROACH: the change itself is wrong (an unsupported token / wrong API / missing",
567221
+ ' prerequisite), not a value to retry. Class "failing_approach".',
567219
567222
  "",
567220
567223
  "Given the agent's latest message and recent tool outcomes, decide whether the claim is proven.",
567221
567224
  "Respond with ONLY a JSON object, no prose, no code fences:",
567222
- '{"class":"false_success|unproven_claim|weak_evidence|false_failure|repeated_action|ok",',
567225
+ '{"class":"false_success|unproven_claim|weak_evidence|false_failure|repeated_action|failing_approach|ok",',
567223
567226
  ' "shortText":"<=12 word headline",',
567224
567227
  ' "confidence":0.0-1.0, // how strongly the claim is NOT proven',
567225
567228
  ' "details":"2-4 sentence skeptical critique citing the specific gap",',
@@ -567250,6 +567253,26 @@ ${ls2.alreadyHave.slice(0, 900)}` : `(No cached result available for the repeate
567250
567253
  "Return ONLY the JSON object."
567251
567254
  ].join("\n");
567252
567255
  }
567256
+ if (obs.failingApproach) {
567257
+ const fa = obs.failingApproach;
567258
+ const target = fa.churnTarget ? `${fa.churnTarget} (edited ${fa.churnWrites ?? "several"}× recently)` : "the same target";
567259
+ return [
567260
+ `The agent is in a FAILING APPROACH: the SAME error has recurred ${fa.count}× while it keeps changing ${target}.`,
567261
+ `The recurring error:`,
567262
+ ` ${fa.sample.slice(0, 400)}`,
567263
+ "",
567264
+ "A repeating identical error means the CHANGE ITSELF is wrong — an unsupported attribute/option, a wrong API/signature, or a missing prerequisite — NOT a value the agent hasn't guessed yet.",
567265
+ "",
567266
+ "Agent's latest message:",
567267
+ obs.assistantText.slice(0, 900) || "(empty)",
567268
+ "",
567269
+ "Recent tool outcomes:",
567270
+ outcomes || " (none)",
567271
+ "",
567272
+ `Reason about THIS specific error. Identify the EXACT token it rejects (attribute/symbol/flag/path) and the root cause. Return class "failing_approach" with a "demand" that names the ONE authoritative source to verify the correct contract (the defining file / schema / API doc) and the supported alternative to use — or, if the feature is genuinely unsupported, to REMOVE it. If the error is actually transient or unrelated, class "ok".`,
567273
+ "Return ONLY the JSON object."
567274
+ ].join("\n");
567275
+ }
567253
567276
  return [
567254
567277
  obs.claimsCompletion ? "The agent is asserting COMPLETION this turn." : "The agent produced a progress/success-flavored claim this turn.",
567255
567278
  "",
@@ -567286,6 +567309,7 @@ function parseAdversaryCritique(raw) {
567286
567309
  "unproven_claim",
567287
567310
  "weak_evidence",
567288
567311
  "false_failure",
567312
+ "failing_approach",
567289
567313
  "ok"
567290
567314
  ];
567291
567315
  const klass = valid.includes(cls) ? cls : "unproven_claim";
@@ -567337,13 +567361,15 @@ var init_adversaryStream = __esm({
567337
567361
  return true;
567338
567362
  if (obs.loopSignal)
567339
567363
  return true;
567364
+ if (obs.failingApproach)
567365
+ return true;
567340
567366
  return SUCCESS_LANGUAGE.test(obs.assistantText);
567341
567367
  }
567342
567368
  /** Ingest an observation. Replaces any prior un-audited pending observation. */
567343
567369
  observe(obs) {
567344
567370
  if (!this.shouldAudit(obs))
567345
567371
  return;
567346
- const loopKey = obs.loopSignal ? `loop:${obs.loopSignal.tool}:${obs.loopSignal.target}:${obs.loopSignal.count}` : "";
567372
+ const loopKey = obs.loopSignal ? `loop:${obs.loopSignal.tool}:${obs.loopSignal.target}:${obs.loopSignal.count}` : obs.failingApproach ? `fail:${obs.failingApproach.count}:${obs.failingApproach.sample.slice(0, 60)}` : "";
567347
567373
  const sig = `${obs.turn}:${loopKey}:${obs.assistantText.slice(0, 200)}`;
567348
567374
  if (sig === this.lastAuditedSignature)
567349
567375
  return;
@@ -570895,25 +570921,24 @@ Your hypotheses MUST address this specific error, not generic causes.
570895
570921
  return best && best.count >= 3 ? best : null;
570896
570922
  }
570897
570923
  /**
570898
- * Backend adapter for AUXILIARY inference (adversary critiques, branch
570899
- * extraction) — tool-less, think-off, JSON-shaped calls. The main backend's
570900
- * chatCompletion routes to Ollama's /v1/chat/completions, where qwen3-family
570901
- * models IGNORE think:false and /no_think and (with no tools to anchor
570902
- * output) emit a reasoning-only response that gets stripped to EMPTY. The
570903
- * native /api/chat path honors think:false. This adapter prefers it and sets
570904
- * a responseFormat so the native path enforces JSON mode. Falls back to
570905
- * chatCompletion for non-Ollama backends.
570924
+ * Backend adapter for AUXILIARY inference (adversary critiques, resolution
570925
+ * gate, branch extraction) — tool-less, think-off, JSON-shaped calls. Uses the
570926
+ * SAME inference backend the main agent loop uses — whatever provider the user
570927
+ * selected and only ensures a JSON responseFormat for these structured
570928
+ * calls. Provider-specific quirks (e.g. Ollama /v1 + qwen3 returning an empty
570929
+ * reasoning-only response for tool-less think-off calls) are recovered INSIDE
570930
+ * the backend's own chatCompletion (empty-recovery native /api/chat
570931
+ * fallback), so no caller here is Ollama-aware.
570906
570932
  */
570907
570933
  _auxInferenceBackend() {
570908
570934
  const b = this.backend;
570909
- const useNative = typeof b.nativeOllamaChatCompletion === "function";
570910
570935
  return {
570911
570936
  chatCompletion: (req3) => {
570912
570937
  const r2 = {
570913
570938
  ...req3,
570914
570939
  responseFormat: req3.responseFormat ?? { type: "json_object" }
570915
570940
  };
570916
- return useNative ? b.nativeOllamaChatCompletion(r2) : b.chatCompletion(r2);
570941
+ return b.chatCompletion(r2);
570917
570942
  }
570918
570943
  };
570919
570944
  }
@@ -570963,7 +570988,15 @@ Your hypotheses MUST address this specific error, not generic causes.
570963
570988
  * (optionally corroborated by the error-cluster tracker), self-cooldown 8
570964
570989
  * turns. OMNIUS_DISABLE_FAILING_APPROACH=1 disables.
570965
570990
  */
570966
- _detectFailingApproach(turn) {
570991
+ /**
570992
+ * Detect a FAILING APPROACH (same error recurring ≥N× while churning the same
570993
+ * target) and return the STRUCTURED signal. The runtime routes this signal
570994
+ * through the generative AdversaryStream (real per-case inference) rather than
570995
+ * emitting a canned directive; `_failingApproachDirective` builds the templated
570996
+ * fallback used ONLY when the adversary is disabled. Sets the cooldown so a
570997
+ * detection (via either path) does not re-fire immediately.
570998
+ */
570999
+ _detectFailingApproachSignal(turn) {
570967
571000
  if (process.env["OMNIUS_DISABLE_FAILING_APPROACH"] === "1")
570968
571001
  return null;
570969
571002
  if (turn <= this._failingApproachCooldownUntil)
@@ -570971,7 +571004,7 @@ Your hypotheses MUST address this specific error, not generic causes.
570971
571004
  const recurring = this._recurringFailureSignature(turn);
570972
571005
  if (!recurring)
570973
571006
  return null;
570974
- let churnPath = null;
571007
+ let churnPath;
570975
571008
  let churnWrites = 0;
570976
571009
  const wf = this._worldFacts;
570977
571010
  if (wf) {
@@ -570985,11 +571018,25 @@ Your hypotheses MUST address this specific error, not generic causes.
570985
571018
  }
570986
571019
  }
570987
571020
  this._failingApproachCooldownUntil = turn + 8;
570988
- const target = churnPath ? `${churnPath} (edited ${churnWrites}× recently)` : "the same target";
571021
+ return {
571022
+ count: recurring.count,
571023
+ sample: recurring.sample,
571024
+ churnTarget: churnPath,
571025
+ churnWrites: churnWrites || void 0
571026
+ };
571027
+ }
571028
+ /**
571029
+ * Deterministic templated directive built from a failing-approach signal.
571030
+ * Used ONLY as a fallback when the generative adversary is disabled
571031
+ * (disableAdversaryCritic). Normally the signal is routed through real
571032
+ * inference so the wording is reasoned per-case, not canned.
571033
+ */
571034
+ _failingApproachDirective(fa) {
571035
+ const target = fa.churnTarget ? `${fa.churnTarget} (edited ${fa.churnWrites ?? "several"}× recently)` : "the same target";
570989
571036
  return [
570990
571037
  `[FAILING APPROACH DETECTED — stop retrying variants]`,
570991
- `The SAME error has recurred ${recurring.count}× in your recent attempts while you keep changing ${target}:`,
570992
- ` ${recurring.sample}`,
571038
+ `The SAME error has recurred ${fa.count}× in your recent attempts while you keep changing ${target}:`,
571039
+ ` ${fa.sample}`,
570993
571040
  ``,
570994
571041
  `Trying another variant of the same change is not converging. A repeating error means the CHANGE ITSELF is wrong — an unsupported attribute/option, a wrong API or signature, or a missing prerequisite — not that you haven't hit the right value yet.`,
570995
571042
  `MANDATORY before your next edit:`,
@@ -571000,6 +571047,11 @@ Your hypotheses MUST address this specific error, not generic causes.
571000
571047
  `Do NOT re-apply another variant of the rejected change.`
571001
571048
  ].join("\n");
571002
571049
  }
571050
+ /** Back-compat wrapper: structured detection → templated directive. */
571051
+ _detectFailingApproach(turn) {
571052
+ const fa = this._detectFailingApproachSignal(turn);
571053
+ return fa ? this._failingApproachDirective(fa) : null;
571054
+ }
571003
571055
  /**
571004
571056
  * REG-61 sliding-window first-edit / sustained-edit nudge.
571005
571057
  *
@@ -576114,25 +576166,52 @@ TASK: ${scrubbedTask}` : scrubbedTask;
576114
576166
  }
576115
576167
  this._runReg61Check(turn, toolCallLog, messages2);
576116
576168
  if (turn > stagnationCooldownUntilTurn) {
576117
- const failingApproach = this._detectFailingApproach(turn);
576118
- if (failingApproach) {
576119
- messages2.push({ role: "system", content: failingApproach });
576169
+ const faSignal = this._detectFailingApproachSignal(turn);
576170
+ if (faSignal) {
576120
576171
  stagnationCooldownUntilTurn = turn + 4;
576121
- this.emit({
576122
- type: "adversary_reaction",
576123
- adversary: {
576124
- class: "guidance",
576125
- shortText: "Failing approach — same error recurring; diagnose root cause",
576126
- confidence: 0.9,
576127
- details: failingApproach
576128
- },
576129
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
576130
- });
576131
- this.emit({
576132
- type: "status",
576133
- content: `FAILING-APPROACH detected at turn ${turn} — injected root-cause directive`,
576134
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
576135
- });
576172
+ if (this._adversaryStream) {
576173
+ this._adversaryStream.observe({
576174
+ turn,
576175
+ assistantText: "",
576176
+ recentToolOutcomes: this._adversaryToolOutcomes.slice(-8).map((o2) => ({
576177
+ tool: o2.tool,
576178
+ succeeded: o2.succeeded,
576179
+ preview: o2.preview
576180
+ })),
576181
+ claimsCompletion: false,
576182
+ failingApproach: {
576183
+ count: faSignal.count,
576184
+ sample: faSignal.sample,
576185
+ churnTarget: faSignal.churnTarget,
576186
+ churnWrites: faSignal.churnWrites
576187
+ }
576188
+ });
576189
+ void this._adversaryStream.tick().catch(() => {
576190
+ });
576191
+ this.emit({
576192
+ type: "status",
576193
+ content: `FAILING-APPROACH detected at turn ${turn} — routed to adversary inference`,
576194
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
576195
+ });
576196
+ } else {
576197
+ const directive = this._failingApproachDirective(faSignal);
576198
+ messages2.push({ role: "system", content: directive });
576199
+ this.emit({
576200
+ type: "adversary_reaction",
576201
+ adversary: {
576202
+ class: "guidance",
576203
+ shortText: "Failing approach — same error recurring; diagnose root cause",
576204
+ confidence: 0.9,
576205
+ details: directive
576206
+ },
576207
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
576208
+ });
576209
+ this.emit({
576210
+ type: "status",
576211
+ content: `FAILING-APPROACH detected at turn ${turn} — injected root-cause directive (deterministic fallback; adversary disabled)`,
576212
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
576213
+ });
576214
+ }
576136
576215
  }
576137
576216
  }
576138
576217
  const REG58_NO_WRITE_BUDGET = 30;
@@ -585983,6 +586062,15 @@ ${description}`
585983
586062
  const justSuppressed = this._thinkSuppressed && this._thinkFailStreak === _OllamaAgenticBackend._thinkFailThreshold;
585984
586063
  const shouldRetryThinkGuard = outcome !== null && effectiveThink === true && (justSuppressed || outcome === "empty_after_strip" || outcome === "unclosed_think");
585985
586064
  if (shouldRetryThinkGuard || shouldRecoverFromEmpty) {
586065
+ if (shouldRecoverFromEmpty) {
586066
+ try {
586067
+ const _native = await this.nativeOllamaChatCompletion(request);
586068
+ const _nText = String(_native.choices?.[0]?.message?.content ?? "");
586069
+ if (_nText.trim().length >= 2)
586070
+ return _native;
586071
+ } catch {
586072
+ }
586073
+ }
585986
586074
  const retryMessages = injectNoThinkDirective(requestMessages);
585987
586075
  const retryBody = {
585988
586076
  model: this.model,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.354",
3
+ "version": "1.0.356",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.354",
9
+ "version": "1.0.356",
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.354",
3
+ "version": "1.0.356",
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",