omnius 1.0.194 → 1.0.195

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
@@ -552139,6 +552139,14 @@ function normalizeProviderToolMessage(msg, model) {
552139
552139
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0
552140
552140
  };
552141
552141
  }
552142
+ function isGenerationToolName(toolName) {
552143
+ return /^(generate_image|generate_audio|generate_video|generate_model|generate_tts|create_audio_file)$/.test(toolName);
552144
+ }
552145
+ function isGenerationArtifactSuccess(toolName, output) {
552146
+ if (!isGenerationToolName(toolName))
552147
+ return false;
552148
+ return /(?:Image generated|Music generated|Sound generated|Video generated|3D model generated|CAD generated|Model generated|TTS generated|Created [A-Z]+ file|Created|Saved to|Output saved to):?\s+/i.test(output);
552149
+ }
552142
552150
  function inferEpisodeModality(toolName) {
552143
552151
  if (VISUAL_TOOLS.has(toolName))
552144
552152
  return "visual";
@@ -553638,6 +553646,8 @@ ${result.output ?? ""}`;
553638
553646
  * no todo list, returns an empty array to allow task completion.
553639
553647
  */
553640
553648
  getOpenTodoItems() {
553649
+ if (this.options.disableTodoCompletionGuard)
553650
+ return [];
553641
553651
  const todos = this.readSessionTodos();
553642
553652
  if (!todos || todos.length === 0)
553643
553653
  return [];
@@ -557803,7 +557813,7 @@ ${_staleSamples.join("\n")}` : ``,
557803
557813
  const userMsg = this.pendingUserMessages.shift();
557804
557814
  await this.appendInjectedUserMessage(userMsg, messages2, turn);
557805
557815
  }
557806
- {
557816
+ if (!this.options.disableTodoPlanningNudges) {
557807
557817
  const maybeReminder = this.getTodoReminderContent(turn);
557808
557818
  if (maybeReminder) {
557809
557819
  messages2.push({ role: "user", content: maybeReminder });
@@ -557815,7 +557825,7 @@ ${_staleSamples.join("\n")}` : ``,
557815
557825
  }
557816
557826
  }
557817
557827
  const turnTier = this.options.modelTier ?? "large";
557818
- if (turn === 0 && (turnTier === "small" || turnTier === "medium")) {
557828
+ if (turn === 0 && !this.options.disableTodoPlanningNudges && (turnTier === "small" || turnTier === "medium")) {
557819
557829
  const goal = this._taskState.goal || "";
557820
557830
  const wordCount2 = goal.split(/\s+/).length;
557821
557831
  const hasMultipleActions = /\band\b.*\band\b|then.*then|also.*also/i.test(goal);
@@ -558927,6 +558937,9 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
558927
558937
  mode: "step_repetition",
558928
558938
  rationale: `force_progress_block on ${tc.name} after ${criticDecision.hitNumber} identical calls`
558929
558939
  });
558940
+ const generationCompletionHint = isGenerationArtifactSuccess(tc.name, criticDecision.cachedResult) ? `
558941
+
558942
+ [GENERATION ALREADY COMPLETE] This exact ${tc.name} call already succeeded. Do not call it again. Use the cached artifact/path above; if delivery is needed, send it, otherwise call task_complete.` : "";
558930
558943
  const header = criticDecision.compacted ? `[RE-SERVED FROM CACHE — the original result was compacted from context. Here is the data again. Do not retry this exact call.]
558931
558944
 
558932
558945
  ` : `[SKIPPED DUPLICATE — exact ${tc.name} call not re-run. The cached result below is from the prior successful call. Do not retry this exact call.]
@@ -558941,7 +558954,7 @@ ${truncatedCache}`);
558941
558954
  tc,
558942
558955
  output: `${criticDecision.blockMessage}
558943
558956
 
558944
- ${header}${truncatedCache}`,
558957
+ ${header}${truncatedCache}${generationCompletionHint}`,
558945
558958
  success: true
558946
558959
  };
558947
558960
  }
@@ -558959,6 +558972,9 @@ ${header}${truncatedCache}`,
558959
558972
  turn,
558960
558973
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
558961
558974
  });
558975
+ const generationCompletionHint = isGenerationArtifactSuccess(tc.name, criticDecision.cachedResult) ? `
558976
+
558977
+ [GENERATION ALREADY COMPLETE] This exact ${tc.name} call already succeeded. Do not call it again. Use the cached artifact/path above; if delivery is needed, send it, otherwise call task_complete.` : "";
558962
558978
  const header = criticDecision.compacted ? `[RE-SERVED FROM CACHE — the original result was compacted from context. Here is the data again. No need to call this tool again.]
558963
558979
 
558964
558980
  ` : `[DUPLICATE CALL #${criticDecision.hitNumber} — you already called ${tc.name} with these exact arguments. The result is identical. Do NOT call this again. Use the data you already have to make progress. One more identical call will trigger a hard progress block.]
@@ -558966,7 +558982,7 @@ ${header}${truncatedCache}`,
558966
558982
  `;
558967
558983
  const truncatedCache = criticDecision.cachedResult.length > 500 ? criticDecision.cachedResult.slice(0, 500) + `
558968
558984
  ... [${criticDecision.cachedResult.length - 500} chars omitted — same as before]` : criticDecision.cachedResult;
558969
- const dedupOutput = header + truncatedCache;
558985
+ const dedupOutput = header + truncatedCache + generationCompletionHint;
558970
558986
  markSyntheticToolLog(dedupOutput);
558971
558987
  this.emit({
558972
558988
  type: "tool_result",
@@ -560160,6 +560176,9 @@ Do NOT retry ${tc.name} with similar arguments.`);
560160
560176
  } else if (result.success && tc.name !== "task_complete") {
560161
560177
  sameToolFailStreak = 0;
560162
560178
  sameToolFailName = null;
560179
+ if (isGenerationArtifactSuccess(tc.name, result.output ?? "")) {
560180
+ this.pendingUserMessages.push(`[GENERATION COMPLETE] ${tc.name} succeeded. Do not call the same generation tool again for the same request. Use the artifact/path from the tool result; if delivery is needed, send it, otherwise call task_complete.`);
560181
+ }
560163
560182
  }
560164
560183
  if (filePath && (tc.name === "file_read" || tc.name === "file_write" || tc.name === "file_edit" || tc.name === "batch_edit" || tc.name === "file_patch")) {
560165
560184
  const isModify = tc.name !== "file_read";
@@ -634226,6 +634245,7 @@ Telegram response contract:
634226
634245
  - Do not summarize the fact that you answered; the visible assistant text must be the answer itself.
634227
634246
  - If you delegated long-running work, include the sub-agent id/status and what the admin should expect next.
634228
634247
  - Do not narrate retry strategy ("let me try one more approach", "actually", "wait, let me try") in assistant text. If you are stuck, send a single concise blocker sentence as the reply instead of streaming deliberation.
634248
+ - Treat todo_write as optional scratch state in Telegram runs. Do not create or maintain todos for simple Q&A, capability checks, or single artifact-generation requests.
634229
634249
  `.trim();
634230
634250
  TELEGRAM_EXTERNAL_ACQUISITION_CONTRACT = `
634231
634251
  External acquisition contract:
@@ -634412,10 +634432,6 @@ Telegram link integrity contract:
634412
634432
  TELEGRAM_ALLOWED_UPDATES = ["message", "guest_message", "callback_query", "poll", "message_reaction", "message_reaction_count"];
634413
634433
  TELEGRAM_DEFAULT_LONG_POLL_TIMEOUT_SECONDS = 50;
634414
634434
  TELEGRAM_DEFAULT_ROUTER_MODEL_CANDIDATES = [
634415
- "qwen3:0.6b",
634416
- "qwen3:1.7b",
634417
- "qwen3:4b",
634418
- "qwen3:8b",
634419
634435
  "qwen2.5:3b",
634420
634436
  "qwen2.5:7b",
634421
634437
  "llama3.2:1b",
@@ -634423,7 +634439,11 @@ Telegram link integrity contract:
634423
634439
  "gemma3:1b",
634424
634440
  "gemma3:4b",
634425
634441
  "phi3:mini",
634426
- "phi4-mini:latest"
634442
+ "phi4-mini:latest",
634443
+ "qwen3:0.6b",
634444
+ "qwen3:1.7b",
634445
+ "qwen3:4b",
634446
+ "qwen3:8b"
634427
634447
  ];
634428
634448
  TELEGRAM_PUBLIC_TOOL_QUOTAS = {
634429
634449
  web: { limit: 20, windowMs: 60 * 6e4 },
@@ -639374,6 +639394,19 @@ ${retryText}`,
639374
639394
  const candidates = raw ? raw.split(/[,\s]+/).map((part) => part.trim()).filter(Boolean) : TELEGRAM_DEFAULT_ROUTER_MODEL_CANDIDATES;
639375
639395
  return Array.from(new Set(candidates));
639376
639396
  }
639397
+ telegramRouterAllowThinkHeavyAutoModels() {
639398
+ const raw = (process.env["OMNIUS_TG_ROUTER_ALLOW_THINK_MODELS"] ?? "").trim().toLowerCase();
639399
+ return raw === "1" || raw === "true" || raw === "on";
639400
+ }
639401
+ telegramRouterModelLooksThinkHeavy(name10) {
639402
+ return /\b(?:qwen3|qwq|deepseek-r1|r1-|reasoning)\b/i.test(name10);
639403
+ }
639404
+ orderTelegramRouterCandidates(candidates) {
639405
+ if (this.telegramRouterAllowThinkHeavyAutoModels()) return candidates;
639406
+ const stable = candidates.filter((candidate) => !this.telegramRouterModelLooksThinkHeavy(candidate));
639407
+ const thinkHeavy = candidates.filter((candidate) => this.telegramRouterModelLooksThinkHeavy(candidate));
639408
+ return [...stable, ...thinkHeavy];
639409
+ }
639377
639410
  normalizeOllamaModelNameForMatch(name10) {
639378
639411
  return name10.trim().toLowerCase().replace(/:latest$/, "");
639379
639412
  }
@@ -639404,7 +639437,7 @@ ${retryText}`,
639404
639437
  source: "main"
639405
639438
  };
639406
639439
  }
639407
- const candidates = this.telegramRouterCandidateModels();
639440
+ const candidates = this.orderTelegramRouterCandidates(this.telegramRouterCandidateModels());
639408
639441
  const cacheKey = `${config.backendUrl}
639409
639442
  ${config.model}
639410
639443
  ${candidates.join(",")}`;
@@ -639432,7 +639465,7 @@ ${candidates.join(",")}`;
639432
639465
  atMs: now,
639433
639466
  model: selected,
639434
639467
  source: "auto-small",
639435
- detail: "selected first installed OMNIUS_TG_ROUTER_MODEL_CANDIDATES entry from Ollama /api/tags"
639468
+ detail: "selected first installed Telegram router candidate from Ollama /api/tags; think-heavy models are tried last unless OMNIUS_TG_ROUTER_ALLOW_THINK_MODELS=1"
639436
639469
  };
639437
639470
  this.telegramRouterModelCache = resolved;
639438
639471
  return {
@@ -640594,7 +640627,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
640594
640627
  return result.result?.message_id ?? null;
640595
640628
  } catch (err) {
640596
640629
  const errStr = err instanceof Error ? err.message : String(err);
640597
- if (this.shouldLogTelegramSendFailure(errStr)) {
640630
+ if (process.env["OMNIUS_TELEGRAM_DEBUG_SEND_FAILURES"] === "1" && this.shouldLogTelegramSendFailure(errStr)) {
640598
640631
  this.tuiWrite(() => renderWarning(`Failed to send Telegram live message: ${errStr}`));
640599
640632
  }
640600
640633
  this.updateTelegramTextDeliveryCapability(chatId, {
@@ -642020,6 +642053,8 @@ ${conversationStream}`
642020
642053
  compactionThreshold: this.telegramFallbackCompactionThreshold(modelTier),
642021
642054
  contextWindowSize,
642022
642055
  modelTier,
642056
+ disableTodoCompletionGuard: true,
642057
+ disableTodoPlanningNudges: true,
642023
642058
  streamEnabled: true,
642024
642059
  dynamicContext: sessionContext.context,
642025
642060
  captureContextFrame: true,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.194",
3
+ "version": "1.0.195",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.194",
9
+ "version": "1.0.195",
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.194",
3
+ "version": "1.0.195",
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",