omnius 1.0.485 → 1.0.486

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
@@ -576193,6 +576193,7 @@ function normalizeCompletionStatus(value2) {
576193
576193
  function isEvidenceGatheringTool(toolName) {
576194
576194
  return [
576195
576195
  "file_read",
576196
+ "file_explore",
576196
576197
  "grep_search",
576197
576198
  "find_files",
576198
576199
  "list_directory",
@@ -576200,6 +576201,9 @@ function isEvidenceGatheringTool(toolName) {
576200
576201
  "todo_write"
576201
576202
  ].includes(toolName);
576202
576203
  }
576204
+ function isEvidenceLike(toolName, isReadLike) {
576205
+ return isReadLike || isEvidenceGatheringTool(toolName);
576206
+ }
576203
576207
  function isEditTool(toolName) {
576204
576208
  return ["file_write", "file_edit", "file_patch", "batch_edit"].includes(toolName);
576205
576209
  }
@@ -576541,7 +576545,7 @@ var init_focusSupervisor = __esm({
576541
576545
  return this.pass();
576542
576546
  }
576543
576547
  const strict = this.shouldStrictlyIntervene(input.context);
576544
- const sameTurnAsDirective = input.turn <= prior.createdTurn;
576548
+ const sameTurnAsDirective = prior.state === "verify_or_block" ? input.turn < prior.createdTurn : input.turn <= prior.createdTurn;
576545
576549
  const alreadyCountedThisTurn = this.lastIgnoredDirectiveTurn === input.turn;
576546
576550
  if (sameTurnAsDirective || alreadyCountedThisTurn) {
576547
576551
  if (strict) {
@@ -576692,10 +576696,14 @@ var init_focusSupervisor = __esm({
576692
576696
  this.clearSatisfiedDirective("requested edit already applied", input.turn);
576693
576697
  return;
576694
576698
  }
576695
- if (input.success && input.noop && input.isReadLike && (this.directive?.requiredNextAction === "use_cached_evidence" || this.directive?.requiredNextAction === "read_authoritative_target")) {
576699
+ if (input.success && input.noop && isEvidenceLike(input.toolName, input.isReadLike) && (this.directive?.requiredNextAction === "use_cached_evidence" || this.directive?.requiredNextAction === "read_authoritative_target")) {
576696
576700
  this.clearSatisfiedDirective(input.runtimeAuthored ? "cached authoritative evidence reused" : "authoritative evidence already available", input.turn);
576697
576701
  return;
576698
576702
  }
576703
+ if (input.success && isEvidenceLike(input.toolName, input.isReadLike) && this.directive?.requiredNextAction === "use_cached_evidence") {
576704
+ this.clearSatisfiedDirective(input.runtimeAuthored ? "cached evidence reused via successful read" : "alternative read action succeeded after cached evidence", input.turn);
576705
+ return;
576706
+ }
576699
576707
  if (input.toolName === "shell" && input.success) {
576700
576708
  if (this.convergenceBreaker) {
576701
576709
  const fam = actionFamily(input.toolName, input.args, this.familyCwd);
@@ -576704,7 +576712,7 @@ var init_focusSupervisor = __esm({
576704
576712
  }
576705
576713
  if (this.directive?.requiredNextAction === "run_verification") {
576706
576714
  this.clearSatisfiedDirective(input.runtimeAuthored ? "cached verification replay consumed" : "verification ran successfully", input.turn);
576707
- } else if (input.isReadLike && this.directive?.requiredNextAction === "read_authoritative_target") {
576715
+ } else if (isEvidenceLike(input.toolName, input.isReadLike) && this.directive?.requiredNextAction === "read_authoritative_target") {
576708
576716
  this.clearSatisfiedDirective("authoritative evidence read via shell", input.turn);
576709
576717
  } else if (!input.isReadLike && this.directive?.requiredNextAction === "use_cached_evidence") {
576710
576718
  this.clearSatisfiedDirective("distinct shell action executed after cached evidence", input.turn);
@@ -576831,8 +576839,9 @@ var init_focusSupervisor = __esm({
576831
576839
  markCompletionBlocked(input) {
576832
576840
  if (!this.enabled)
576833
576841
  return;
576842
+ const effectiveTurn = input.turn + 1;
576834
576843
  this.setDirective({
576835
- turn: input.turn,
576844
+ turn: effectiveTurn,
576836
576845
  state: "verify_or_block",
576837
576846
  reason: input.reason,
576838
576847
  requiredNextAction: this.resolveRequiredNextAction(input.requiredNextAction ?? "run_verification"),
@@ -576899,7 +576908,7 @@ var init_focusSupervisor = __esm({
576899
576908
  createdTurn: input.turn,
576900
576909
  ignoredCount: 0
576901
576910
  };
576902
- if (!stable) {
576911
+ if (!stable && (!existing || existing.state !== input.state || existing.requiredNextAction !== input.requiredNextAction)) {
576903
576912
  this.repeatedViolationCounts.clear();
576904
576913
  }
576905
576914
  this.directive = directive;
@@ -583716,6 +583725,8 @@ ${result.output ?? ""}`;
583716
583725
  if (this._completionIncompleteVerification)
583717
583726
  return true;
583718
583727
  const directive = this._focusSupervisor?.snapshot().directive;
583728
+ if (directive?.state === "forced_replan" && directive.requiredNextAction === "creative_pivot_or_research")
583729
+ return true;
583719
583730
  return directive?.state === "terminal_incomplete" || directive?.requiredNextAction === "report_incomplete" || directive?.requiredNextAction === "report_blocked";
583720
583731
  }
583721
583732
  /**
@@ -585603,7 +585614,13 @@ ${contentPreview}
585603
585614
  return true;
585604
585615
  if (/\b(?:cp|mv|rm|mkdir|rmdir|touch|truncate|ln|install|chmod|chown|chgrp|setfacl)\b/i.test(unquoted))
585605
585616
  return true;
585606
- if (/\b(?:udevadm|mount|umount|modprobe|insmod)\b/i.test(unquoted))
585617
+ if (/\b(?:udevadm|mount|umount|modprobe|insmod|kill|pkill|killall)\b/i.test(unquoted))
585618
+ return true;
585619
+ if (/\b(?:nohup|systemctl|service|chvt|renice)\b/i.test(unquoted))
585620
+ return true;
585621
+ if (/\bservice\s+(start|stop|restart|reload|reload-or-restart)\b/i.test(unquoted))
585622
+ return true;
585623
+ if (/\bsystemctl\s+(start|stop|restart|reload|daemon-reload|enable|disable|isolate|set-default)\b/i.test(unquoted))
585607
585624
  return true;
585608
585625
  if (/\b(?:python3?|node|ruby|deno|bun)\b[\s\S]{0,240}\b(?:writeFile|writeFileSync|openSync|mkdirSync|renameSync|unlinkSync|rmSync)\b/i.test(cmd))
585609
585626
  return true;
@@ -588781,6 +588798,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
588781
588798
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
588782
588799
  });
588783
588800
  };
588801
+ let executeSingle = async () => null;
588784
588802
  const turnCap = this.options.maxTurns && this.options.maxTurns > 0 ? this.options.maxTurns : Number.MAX_SAFE_INTEGER;
588785
588803
  for (let turn = 0; turn < turnCap; turn++) {
588786
588804
  clearTurnState(this._appState);
@@ -590813,7 +590831,7 @@ ${memoryLines.join("\n")}`
590813
590831
  });
590814
590832
  }
590815
590833
  let editFeedbackRequiredBeforeMoreEdits = null;
590816
- const executeSingle = async (tc) => {
590834
+ executeSingle = async (tc) => {
590817
590835
  if (this.aborted)
590818
590836
  return null;
590819
590837
  const actionReasonForAdvisory = this._toolActionReasonForCall(tc.name, tc.arguments ?? {});
@@ -591533,7 +591551,7 @@ Read the current file if needed, make a different concrete edit, or move to veri
591533
591551
  });
591534
591552
  }
591535
591553
  const _repeatGateMax = this._resolveRepeatGateMax();
591536
- const isFailedShellRepeat = tc.name === "shell" && typeof _existingFp?.result === "string" && _existingFp.result.includes("status: failure");
591554
+ const isFailedShellRepeat = tc.name === "shell" && typeof _existingFp?.result === "string" && _existingFp.result.includes("status: failure") && !shellLikelyMutatesFilesystem;
591537
591555
  const repeatGateEligible = isReadLike || tc.name === "memory_write" || isFailedShellRepeat;
591538
591556
  const suppressSuccessfulShellCacheGuidance = tc.name === "shell" && !isFailedShellRepeat;
591539
591557
  if (suppressSuccessfulShellCacheGuidance)
@@ -592676,7 +592694,8 @@ Respond with EXACTLY this structure before your next tool call:
592676
592694
  }
592677
592695
  const cacheableMemoryNoop = tc.name === "memory_write" && result.success && result.noop;
592678
592696
  const cacheableProjectWriteNoop = this._isProjectEditTool(tc.name) && result.success && !this._isRealProjectMutation(tc.name, result) && (result.noop === true || result.mutated === false);
592679
- if (isReadLike && result.success && result.runtimeAuthored !== true || tc.name === "shell" && result.runtimeAuthored !== true || cacheableMemoryNoop || cacheableProjectWriteNoop) {
592697
+ const cacheableShellResult = tc.name === "shell" && result.runtimeAuthored !== true && !shellLikelyMutatesFilesystem;
592698
+ if (isReadLike && result.success && result.runtimeAuthored !== true || cacheableShellResult || cacheableMemoryNoop || cacheableProjectWriteNoop) {
592680
592699
  recentToolResults.set(toolFingerprint, {
592681
592700
  result: tc.name === "shell" ? this._buildShellCacheResult(tc.arguments, result) : (
592682
592701
  // Read-like results are SERVED BACK to the model when the
@@ -594580,183 +594599,21 @@ ${this.options.maxTurns && this.options.maxTurns > 0 ? `You have ${this.options.
594580
594599
  for (const tc of msg.toolCalls) {
594581
594600
  if (this.aborted)
594582
594601
  break;
594583
- toolCallCount++;
594584
- const bfActionReason = this._toolActionReasonForCall(tc.name, tc.arguments ?? {});
594585
- const bfArgsKey = this._buildExactArgsKey(tc.arguments ?? {});
594586
- toolCallLog.push({ name: tc.name, argsKey: bfArgsKey });
594587
- this._toolLastUsedTurn.set(tc.name, turn);
594588
- if (this._contextTree) {
594589
- this._contextTree.observeToolCall(tc.name, bfArgsKey, turn);
594590
- const transition = this._contextTree.maybeTransition(turn);
594591
- if (transition) {
594592
- const phaseSlice = messages2.slice(this._phaseMessageStartIdx);
594593
- if (phaseSlice.length > 0) {
594594
- const fromNode = this._contextTree.getSnapshot().phases[transition.from];
594595
- if (fromNode) {
594596
- fromNode.messages = phaseSlice;
594597
- }
594598
- }
594599
- this.emit({
594600
- type: "status",
594601
- content: `Phase: ${transition.from} → ${transition.to} (brute-force cycle)`,
594602
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594603
- });
594604
- const summarizer = this.makePhaseSummarizer();
594605
- const contracted = this._contextTree.contractInactive(turn, summarizer ? (msgs) => summarizer(transition.from, msgs) : void 0);
594606
- if (contracted.length > 0) {
594607
- this.emit({
594608
- type: "status",
594609
- content: `Phase contraction: ${contracted.join(", ")} → contracted (${summarizer ? "LLM-summarized" : "stub-summarized"}, anchors retained, brute-force)`,
594610
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594611
- });
594612
- }
594613
- this._phaseMessageStartIdx = messages2.length;
594614
- this._taskState.phase = transition.to;
594615
- this._taskState.phaseSince = turn;
594616
- }
594617
- }
594618
- this.emit({
594619
- type: "tool_call",
594620
- toolName: tc.name,
594621
- toolArgs: tc.arguments,
594622
- turn,
594623
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594624
- });
594625
- const _decomp2BFBlock = this._maybeDecomp2Block(tc, turn);
594626
- if (_decomp2BFBlock) {
594627
- this.emit({
594628
- type: "tool_result",
594629
- toolName: tc.name,
594630
- content: _decomp2BFBlock.slice(0, 200),
594631
- success: false,
594632
- turn,
594633
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594634
- });
594635
- messages2.push(this.buildToolMessage(_decomp2BFBlock, tc.id, tc.name));
594602
+ const r2 = await executeSingle(tc);
594603
+ if (!r2)
594636
594604
  continue;
594637
- }
594638
- const resolvedTool = this.lookupRegisteredTool(tc.name);
594639
- const tool = resolvedTool?.tool;
594640
- let result;
594641
- if (!tool) {
594642
- result = {
594643
- success: false,
594644
- output: "",
594645
- error: this.unknownToolError(tc.name)
594646
- };
594647
- } else {
594648
- try {
594649
- result = await tool.execute(tc.arguments);
594650
- result = this.applyRegisteredToolResultTriage(result, resolvedTool?.name ?? tc.name, tool);
594651
- } catch (err) {
594652
- result = {
594653
- success: false,
594654
- output: "",
594655
- error: err instanceof Error ? err.message : String(err)
594656
- };
594657
- }
594658
- }
594659
- if (!result.success && tc.name === "shell" && /\[PERMISSION_ERROR\]/.test(result.error ?? "")) {
594660
- this.emit({
594661
- type: "sudo_request",
594662
- content: `Command requires elevated privileges: ${tc.arguments.command?.slice(0, 100) ?? ""}`,
594663
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594664
- });
594665
- const pw2 = await this.waitForSudoPassword(12e4);
594666
- if (pw2 && tool) {
594667
- try {
594668
- result = await tool.execute(tc.arguments);
594669
- result = this.applyRegisteredToolResultTriage(result, resolvedTool?.name ?? tc.name, tool);
594670
- } catch (err) {
594671
- result = {
594672
- success: false,
594673
- output: "",
594674
- error: err instanceof Error ? err.message : String(err)
594675
- };
594676
- }
594677
- }
594678
- }
594679
- const { toolOutputMaxChars: maxLen2 } = this.contextLimits();
594680
- let output;
594681
- const modelContent2 = result.llmContent ?? result.output;
594682
- const isAlreadyTriaged = modelContent2.startsWith(TRIAGE_ENVELOPE_MARKER) && modelContent2.includes(TRIAGE_SAVED_PATH_MARKER);
594683
- if (!result.success) {
594684
- output = `Error: ${result.error || "unknown error"}
594685
- ${modelContent2}`;
594686
- } else if (isAlreadyTriaged) {
594687
- output = modelContent2;
594688
- } else if (modelContent2.length > maxLen2) {
594689
- const handleId = this.quickHash(tc.name + String(tc.arguments?.["path"] ?? "") + String(turn));
594690
- const lineCount = (result.output.match(/\n/g) || []).length + 1;
594691
- const preview = result.output.slice(0, 500).replace(/\n/g, " ");
594692
- this._memexArchive.set(handleId, {
594693
- id: handleId,
594694
- toolName: tc.name,
594695
- summary: `${tc.name} output (${lineCount} lines, ${result.output.length} chars)`,
594696
- fullContent: result.output,
594697
- turn,
594698
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594605
+ messages2.push(this.buildModelFacingToolMessage(r2.output, r2.tc.id, r2.tc.name, r2.tc.arguments, r2.success));
594606
+ if (r2.systemGuidance) {
594607
+ messages2.push({
594608
+ role: "system",
594609
+ content: r2.systemGuidance
594699
594610
  });
594700
- output = `[${tc.name} succeeded — output externalized: ${result.output.length} chars, ${lineCount} lines]
594701
- Handle: ${handleId}
594702
- Preview: ${preview}...
594703
- Full content available via: repl_exec(code="data = retrieve('${handleId}')") or memex_retrieve(id="${handleId}")`;
594704
- } else {
594705
- output = modelContent2;
594706
594611
  }
594707
- const bfRealFileMutation = this._isRealProjectMutation(tc.name, result);
594708
- const bfRealMutationPaths = bfRealFileMutation ? this._extractToolTargetPaths(tc.name, tc.arguments, result) : [];
594709
- const bfLogEntry = toolCallLog[toolCallLog.length - 1];
594710
- if (bfLogEntry) {
594711
- bfLogEntry.success = result.success;
594712
- bfLogEntry.mutated = bfRealFileMutation;
594713
- bfLogEntry.mutatedFiles = bfRealMutationPaths;
594714
- bfLogEntry.outputPreview = this._toolEvidencePreview(result, output, 1200, tc.name);
594715
- }
594716
- this.emit({
594717
- type: "tool_result",
594718
- toolName: tc.name,
594719
- content: this.toolResultEventContent(tc.name, output || result.output || result.error || ""),
594720
- success: result.success,
594721
- turn,
594722
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
594723
- });
594724
- this._trackDecomp2(tc, result, turn);
594725
- this._recordCompletionToolEvidenceFromResult({
594726
- toolName: tc.name,
594727
- argsKey: bfArgsKey,
594728
- args: tc.arguments,
594729
- actionReason: bfActionReason,
594730
- result,
594731
- outputPreview: this._toolEvidencePreview(result, output, 1200, tc.name),
594732
- realFileMutation: bfRealFileMutation,
594733
- realMutationPaths: bfRealMutationPaths
594734
- });
594735
- const enoentTools2 = /* @__PURE__ */ new Set([
594736
- "file_read",
594737
- "list_directory",
594738
- "find_files"
594739
- ]);
594740
- if (!result.success && enoentTools2.has(tc.name) && /ENOENT|no such file|does not exist|not found/i.test(result.error ?? result.output)) {
594741
- this._consecutiveEnoent++;
594742
- if (this._consecutiveEnoent >= 2) {
594743
- const failedPath2 = String(tc.arguments?.["path"] ?? tc.arguments?.["file"] ?? "unknown");
594744
- this.enqueueRuntimeGuidance(`[SYSTEM] ${this._consecutiveEnoent} consecutive file-not-found errors (last: "${failedPath2}"). You are repeating failed paths. CHANGE YOUR APPROACH:
594745
- 1. Call list_directory(".") to see what exists at the project root
594746
- 2. Entries in a directory listing are RELATIVE to that directory. If you listed "parent/" and saw "child", the full path is "parent/child" — NOT ".child" or just "child"
594747
- 3. If an entry is a directory (marked "d"), use list_directory on it, NOT file_read
594748
- 4. Use the FULL relative paths shown in list_directory output — they are copy-paste ready`);
594749
- }
594750
- } else {
594751
- this._consecutiveEnoent = 0;
594752
- }
594753
- const toolMsg = this.buildModelFacingToolMessage(output, tc.id, tc.name, tc.arguments, result.success);
594754
- messages2.push(toolMsg);
594755
- if (tc.name === "task_complete") {
594756
- if (!result.success) {
594612
+ if (r2.tc.name === "task_complete") {
594613
+ if (!r2.success) {
594757
594614
  messages2.push({
594758
594615
  role: "system",
594759
- content: this.buildTaskCompleteToolFailureGuard(output)
594616
+ content: this.buildTaskCompleteToolFailureGuard(r2.output)
594760
594617
  });
594761
594618
  this.emit({
594762
594619
  type: "status",
@@ -594765,7 +594622,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
594765
594622
  });
594766
594623
  continue;
594767
594624
  }
594768
- const taskCompleteArgs = tc.arguments;
594625
+ const taskCompleteArgs = r2.tc.arguments;
594769
594626
  const open2 = this.getOpenTodoItems();
594770
594627
  if (open2.length > 0 && !this._shouldBypassTodoCompletionGuardForTaskComplete(taskCompleteArgs)) {
594771
594628
  const guard = this.buildTodoCompletionGuard(open2);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.485",
3
+ "version": "1.0.486",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.485",
9
+ "version": "1.0.486",
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.485",
3
+ "version": "1.0.486",
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",