omnius 1.0.270 → 1.0.271

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
@@ -546546,7 +546546,10 @@ var init_agent_tool = __esm({
546546
546546
  lines.push(prompt);
546547
546547
  return lines.join("\n");
546548
546548
  })();
546549
- if (isolation === "worktree") {
546549
+ const fullDefault = process.env["OMNIUS_FULL_SUBAGENT_DEFAULT"] !== "0";
546550
+ const workCapableType = subagentType === "general" || subagentType === "coordinator";
546551
+ const routeToSubprocess = isolation === "worktree" || fullDefault && runInBackground && workCapableType;
546552
+ if (routeToSubprocess) {
546550
546553
  this.callbacks.onViewRegister?.(agentId, label);
546551
546554
  const spawn35 = this.callbacks.spawnSubprocess({
546552
546555
  id: agentId,
@@ -555351,6 +555354,31 @@ var init_textSanitize = __esm({
555351
555354
  }
555352
555355
  });
555353
555356
 
555357
+ // packages/orchestrator/dist/permissionRuleset.js
555358
+ function checkDoomLoop(context2) {
555359
+ const history = context2.toolCallHistory;
555360
+ if (!history || history.length < 3)
555361
+ return null;
555362
+ const lastCall = history[history.length - 1];
555363
+ const recent = history.slice(-4);
555364
+ let identicalCount = 1;
555365
+ for (let i2 = history.length - 2; i2 >= Math.max(0, history.length - 4); i2--) {
555366
+ const prev = history[i2];
555367
+ if (prev.tool === lastCall.tool && JSON.stringify(prev.args) === JSON.stringify(lastCall.args)) {
555368
+ identicalCount++;
555369
+ }
555370
+ }
555371
+ if (identicalCount >= 3) {
555372
+ return "ask";
555373
+ }
555374
+ return null;
555375
+ }
555376
+ var init_permissionRuleset = __esm({
555377
+ "packages/orchestrator/dist/permissionRuleset.js"() {
555378
+ "use strict";
555379
+ }
555380
+ });
555381
+
555354
555382
  // packages/orchestrator/dist/completionContract.js
555355
555383
  function normalizeText(value2, max = 500) {
555356
555384
  const text2 = String(value2 ?? "").trim().replace(/\s+/g, " ");
@@ -565337,6 +565365,7 @@ var init_agenticRunner = __esm({
565337
565365
  "packages/orchestrator/dist/agenticRunner.js"() {
565338
565366
  "use strict";
565339
565367
  init_textSanitize();
565368
+ init_permissionRuleset();
565340
565369
  init_completionLedger();
565341
565370
  init_dist6();
565342
565371
  init_ollama_pool();
@@ -567832,10 +567861,12 @@ ${body}`;
567832
567861
  }
567833
567862
  const prior = seen.get(fp);
567834
567863
  if (prior) {
567864
+ const priorContent = typeof messages2[prior.idx]?.content === "string" ? messages2[prior.idx].content : "";
567865
+ const priorFailed = ERROR_MARKERS.test(priorContent);
567835
567866
  pending2.push({
567836
567867
  idx: prior.idx,
567837
567868
  reason: "dedupe",
567838
- replacement: `${DEDUPE_PREFIX} ${scanTurn} — duplicate ${name10}() call]`
567869
+ replacement: priorFailed ? `${DEDUPE_PREFIX} ${scanTurn} — duplicate ${name10}() call; the earlier call FAILED (same error as the retained copy below). Do not retry identically.]` : `${DEDUPE_PREFIX} ${scanTurn} — duplicate ${name10}() call]`
567839
567870
  });
567840
567871
  seen.set(fp, { turn: scanTurn, idx: resultIdx });
567841
567872
  continue;
@@ -567847,10 +567878,11 @@ ${body}`;
567847
567878
  if (priorResource && priorResource.idx !== resultIdx) {
567848
567879
  const priorContent = typeof messages2[priorResource.idx]?.content === "string" ? messages2[priorResource.idx].content : "";
567849
567880
  if (!priorContent.startsWith(PRUNE_PREFIX) && !priorContent.startsWith(DEDUPE_PREFIX) && !priorContent.startsWith(FILE_AGED_PREFIX)) {
567881
+ const priorResFailed = ERROR_MARKERS.test(priorContent);
567850
567882
  pending2.push({
567851
567883
  idx: priorResource.idx,
567852
567884
  reason: "dedupe",
567853
- replacement: `${DEDUPE_PREFIX} ${scanTurn} — semantic duplicate ${name10}() (same resource: ${rkey})]`
567885
+ replacement: priorResFailed ? `${DEDUPE_PREFIX} ${scanTurn} — semantic duplicate ${name10}() (same resource: ${rkey}); the earlier call FAILED. Do not retry identically.]` : `${DEDUPE_PREFIX} ${scanTurn} — semantic duplicate ${name10}() (same resource: ${rkey})]`
567854
567886
  });
567855
567887
  }
567856
567888
  }
@@ -572790,6 +572822,44 @@ Corrective action: try a different approach first: read relevant files, adjust a
572790
572822
  timestampMs: Date.now()
572791
572823
  });
572792
572824
  const _toolLogTailIdx = toolCallLog.length - 1;
572825
+ if (tc.name !== "task_complete") {
572826
+ const doomHistory = toolCallLog.slice(-5).map((e2) => ({ tool: e2.name, args: e2.argsKey }));
572827
+ doomHistory.push({
572828
+ tool: tc.name,
572829
+ args: this._buildExactArgsKey(tc.arguments ?? {})
572830
+ });
572831
+ const doom = checkDoomLoop({
572832
+ permission: tc.name,
572833
+ target: "",
572834
+ toolCallHistory: doomHistory
572835
+ });
572836
+ if (doom === "ask" && cohort && cohort.failure >= 3 && cohort.success === 0) {
572837
+ const stopMsg = `[blocked: doom-loop] '${tc.name}' has been called with identical arguments 3+ times and has failed every time. This exact call was NOT executed. Stop repeating it. Choose ONE: (a) change the arguments or approach, (b) read/inspect to understand why it fails, or (c) if genuinely blocked, call task_complete and state the blocker plainly.`;
572838
+ this.emit({
572839
+ type: "tool_call",
572840
+ toolName: tc.name,
572841
+ toolArgs: tc.arguments,
572842
+ turn,
572843
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
572844
+ });
572845
+ const lastLog = toolCallLog[_toolLogTailIdx];
572846
+ if (lastLog) {
572847
+ lastLog.success = false;
572848
+ lastLog.mutated = false;
572849
+ lastLog.mutatedFiles = [];
572850
+ lastLog.outputPreview = stopMsg.slice(0, 100);
572851
+ }
572852
+ this.emit({
572853
+ type: "tool_result",
572854
+ toolName: tc.name,
572855
+ success: false,
572856
+ content: stopMsg.slice(0, 200),
572857
+ turn,
572858
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
572859
+ });
572860
+ return { tc, output: stopMsg, success: false };
572861
+ }
572862
+ }
572793
572863
  if (editFeedbackRequiredBeforeMoreEdits && this._isProjectEditTool(tc.name)) {
572794
572864
  this.emit({
572795
572865
  type: "tool_call",
@@ -573971,8 +574041,23 @@ Respond with EXACTLY this structure before your next tool call:
573971
574041
  }
573972
574042
  }
573973
574043
  const isFileMutation = realFileMutation;
573974
- if (isFileMutation && dedupHitCount.size > 0) {
573975
- dedupHitCount.clear();
574044
+ if (isFileMutation) {
574045
+ if (realMutationPaths.length > 0) {
574046
+ for (const mp of realMutationPaths) {
574047
+ if (!mp)
574048
+ continue;
574049
+ for (const key of Array.from(dedupHitCount.keys())) {
574050
+ if (key.includes(mp))
574051
+ dedupHitCount.delete(key);
574052
+ }
574053
+ for (const key of Array.from(recentToolResults.keys())) {
574054
+ if (key.includes(mp))
574055
+ recentToolResults.delete(key);
574056
+ }
574057
+ }
574058
+ } else if (dedupHitCount.size > 0) {
574059
+ dedupHitCount.clear();
574060
+ }
573976
574061
  }
573977
574062
  if (isFileMutation && recentToolResults.size > 0) {
573978
574063
  for (const key of Array.from(recentToolResults.keys())) {
@@ -602335,7 +602420,7 @@ var init_call_agent = __esm({
602335
602420
  }
602336
602421
  /** Initialize the runner with appropriate tools for the access tier */
602337
602422
  async init() {
602338
- const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey);
602423
+ const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey, false);
602339
602424
  this.backend = backend;
602340
602425
  const feed = getActivityFeed();
602341
602426
  const systemPrompt = this.buildSystemPrompt();
@@ -705646,7 +705731,13 @@ Review its full output via sub_agent(action='output', id='${id}')`
705646
705731
  backend = new OllamaAgenticBackend(
705647
705732
  config.backendUrl,
705648
705733
  opts.model,
705649
- config.apiKey
705734
+ config.apiKey,
705735
+ // Sub-agents: force thinking OFF explicitly. Thinking models
705736
+ // interleave <think> blocks that corrupt tool-call parsing for
705737
+ // Qwen/Ollama. Relying on the constructor default is fragile
705738
+ // (breaks if OMNIUS_ENABLE_THINKING=1 is inherited); pass false
705739
+ // so sub-agent tool loops are always clean.
705740
+ false
705650
705741
  );
705651
705742
  }
705652
705743
  const subTier = getModelTier(opts.model);
@@ -705683,6 +705774,10 @@ Review its full output via sub_agent(action='output', id='${id}')`
705683
705774
  `Sub-agent ${subAgentId}`,
705684
705775
  "sub"
705685
705776
  );
705777
+ subRunner.onEvent((event) => {
705778
+ const line = formatSubAgentEventForView(event);
705779
+ if (line) statusBar.writeToAgentView(subAgentId, line);
705780
+ });
705686
705781
  subRunner.registerTool(
705687
705782
  createTaskCompleteTool(subTier, repoRoot, true)
705688
705783
  );
@@ -705725,11 +705820,21 @@ ${result.summary}`
705725
705820
  };
705726
705821
  },
705727
705822
  spawnSubprocess: (opts) => {
705728
- const entry = spawnFullSubAgent(opts.task, {
705729
- model: opts.model,
705730
- backendUrl: config.backendUrl,
705731
- workingDir: opts.workingDir
705732
- });
705823
+ const entry = spawnFullSubAgent(
705824
+ opts.task,
705825
+ {
705826
+ model: opts.model,
705827
+ backendUrl: config.backendUrl,
705828
+ workingDir: opts.workingDir
705829
+ },
705830
+ // Stream the full sub-agent's stdout into its toolbar view so the
705831
+ // clickable tab shows live output instead of staying empty.
705832
+ (text2) => statusBar.writeToAgentView(opts.id, text2),
705833
+ (id, exitCode) => statusBar.updateAgentViewStatus(
705834
+ opts.id,
705835
+ exitCode === 0 ? "completed" : "failed"
705836
+ )
705837
+ );
705733
705838
  return { id: entry.id, pid: entry.pid ?? 0 };
705734
705839
  },
705735
705840
  trackTask: (id, promise) => {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.270",
3
+ "version": "1.0.271",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.270",
9
+ "version": "1.0.271",
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.270",
3
+ "version": "1.0.271",
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",