omnius 1.0.445 → 1.0.447

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
@@ -573841,6 +573841,7 @@ function recordDebugToolEvent(input) {
573841
573841
  ...input.focusSupervisor ? { focusSupervisor: input.focusSupervisor } : {},
573842
573842
  ...input.focusDecision ? { focusDecision: input.focusDecision } : {},
573843
573843
  ...input.repeatShortCircuit !== void 0 ? { repeatShortCircuit: input.repeatShortCircuit } : {},
573844
+ ...input.runtimeAuthored !== void 0 ? { runtimeAuthored: input.runtimeAuthored } : {},
573844
573845
  ...input.runtimeGuidance ? { runtimeGuidancePreview: trim(input.runtimeGuidance, 1200) } : {},
573845
573846
  diagnoses,
573846
573847
  summary: summarizeToolEvent(input.toolName, input.success, diagnoses, command),
@@ -574413,6 +574414,11 @@ function resolveFocusSupervisorMode(configured, envValue = process.env["OMNIUS_F
574413
574414
  }
574414
574415
  function violatesDirective(directive, input) {
574415
574416
  if (input.toolName === "task_complete") {
574417
+ const summary = String(input.args?.["summary"] ?? input.args?.["message"] ?? input.args?.["reason"] ?? "");
574418
+ const reportsConcreteBlocker = /\b(blocked|blocker|incomplete|unable|cannot|can't|failed|failure|stopped|cached failure|no safe progress|unrecoverable)\b/i.test(summary);
574419
+ if (reportsConcreteBlocker && (directive.requiredNextAction === "read_authoritative_target" || directive.requiredNextAction === "report_blocked" || directive.requiredNextAction === "report_incomplete")) {
574420
+ return false;
574421
+ }
574416
574422
  return directive.requiredNextAction !== "report_blocked" && directive.requiredNextAction !== "report_incomplete" && directive.requiredNextAction !== "use_cached_evidence";
574417
574423
  }
574418
574424
  if (input.toolName === "ask_user")
@@ -574463,6 +574469,21 @@ function isEditTool(toolName) {
574463
574469
  function isReportTool(toolName) {
574464
574470
  return toolName === "task_complete" || toolName === "ask_user";
574465
574471
  }
574472
+ function compactCachedEvidence(text2) {
574473
+ const value2 = text2 || "";
574474
+ const lineCount = value2 ? value2.split("\n").length : 0;
574475
+ const sha = value2.match(/sha256=([a-f0-9]{8,64})/i)?.[1];
574476
+ const header = value2.match(/\[FILE CONTEXT \|[^\]]+\]/)?.[0];
574477
+ const preview = value2.split("\n").map((line) => line.trim()).find((line) => line.length > 0 && !line.startsWith("[trust_tier:") && line !== "---") ?? "";
574478
+ return [
574479
+ "Cached evidence is already available in the active context/tool cache; full payload omitted from this block to avoid context bloat.",
574480
+ `cached_size=${lineCount} lines, ${value2.length} chars`,
574481
+ sha ? `cached_sha256=${sha.slice(0, 16)}` : "",
574482
+ header ? `cached_header=${header.slice(0, 220)}` : "",
574483
+ preview && preview !== header ? `cached_preview=${preview.slice(0, 220)}` : "",
574484
+ "Use the cached evidence now, or request a distinct offset/limit/query if genuinely needed."
574485
+ ].filter(Boolean).join("\n");
574486
+ }
574466
574487
  function actionFamily(toolName, args) {
574467
574488
  if (isEditTool(toolName)) {
574468
574489
  const path12 = primaryPath(args);
@@ -574606,6 +574627,7 @@ var init_focusSupervisor = __esm({
574606
574627
  lastContext = null;
574607
574628
  failureFamilies = /* @__PURE__ */ new Map();
574608
574629
  ignoredDirectiveStreak = 0;
574630
+ lastIgnoredDirectiveTurn = null;
574609
574631
  constructor(options2 = {}) {
574610
574632
  this.mode = options2.mode ?? "auto";
574611
574633
  this.modelTier = options2.modelTier ?? "large";
@@ -574653,9 +574675,25 @@ var init_focusSupervisor = __esm({
574653
574675
  const family = actionFamily(input.toolName, input.args);
574654
574676
  const prior = this.directive;
574655
574677
  if (prior && violatesDirective(prior, input)) {
574678
+ const strict = this.shouldStrictlyIntervene(input.context);
574679
+ const sameTurnAsDirective = input.turn <= prior.createdTurn;
574680
+ const alreadyCountedThisTurn = this.lastIgnoredDirectiveTurn === input.turn;
574681
+ if (sameTurnAsDirective || alreadyCountedThisTurn) {
574682
+ if (strict) {
574683
+ const reason = sameTurnAsDirective ? `queued tool call was emitted in the same turn that created directive ${prior.id}; it could not have observed the directive` : `another tool call in turn ${input.turn} already counted against directive ${prior.id}`;
574684
+ return this.block(prior, [
574685
+ "[FOCUS SUPERVISOR BLOCK]",
574686
+ `${reason}.`,
574687
+ `Required next action: ${prior.requiredNextAction}.`,
574688
+ `Blocked action family: ${family}.`,
574689
+ "This block is not counted as a new ignored directive."
574690
+ ].join("\n"), false);
574691
+ }
574692
+ return this.pass();
574693
+ }
574656
574694
  prior.ignoredCount++;
574657
574695
  this.ignoredDirectiveStreak++;
574658
- const strict = this.shouldStrictlyIntervene(input.context);
574696
+ this.lastIgnoredDirectiveTurn = input.turn;
574659
574697
  if (strict && prior.ignoredCount >= 1) {
574660
574698
  const terminal = this.ignoredDirectiveStreak >= TERMINAL_INCOMPLETE_IGNORE_THRESHOLD;
574661
574699
  const ignoredManyTimes = this.ignoredDirectiveStreak >= 3;
@@ -574669,6 +574707,7 @@ var init_focusSupervisor = __esm({
574669
574707
  family
574670
574708
  ])
574671
574709
  });
574710
+ this.lastIgnoredDirectiveTurn = input.turn;
574672
574711
  return this.block(directive, [
574673
574712
  `[FOCUS SUPERVISOR BLOCK] The previous directive was ignored: ${prior.reason}`,
574674
574713
  `Required next action: ${directive.requiredNextAction}.`,
@@ -574708,7 +574747,7 @@ var init_focusSupervisor = __esm({
574708
574747
  `This ${input.toolName} action family has already produced evidence and should not be re-executed unchanged.`,
574709
574748
  `Required next action: ${directive.requiredNextAction}.`,
574710
574749
  "",
574711
- input.cachedResult.slice(0, 8e3)
574750
+ compactCachedEvidence(input.cachedResult)
574712
574751
  ].join("\n"), !input.cachedResultFailed);
574713
574752
  }
574714
574753
  return this.inject(directive, `[FOCUS SUPERVISOR] ${directive.reason}. Required next action: ${directive.requiredNextAction}.`);
@@ -574736,6 +574775,11 @@ var init_focusSupervisor = __esm({
574736
574775
  this.clearSatisfiedDirective("mutation landed", input.turn);
574737
574776
  return;
574738
574777
  }
574778
+ if (input.runtimeAuthored) {
574779
+ this.lastDecision = "runtime_authored_not_satisfied";
574780
+ this.lastReason = "runtime-authored control result did not execute the requested tool";
574781
+ return;
574782
+ }
574739
574783
  if (input.toolName === "todo_write" && input.success) {
574740
574784
  if (input.noop) {
574741
574785
  this.lastDecision = "todo_noop_not_satisfied";
@@ -574745,6 +574789,11 @@ var init_focusSupervisor = __esm({
574745
574789
  this.clearSatisfiedDirective("todo plan updated", input.turn);
574746
574790
  return;
574747
574791
  }
574792
+ if (input.success && input.noop) {
574793
+ this.lastDecision = "noop_not_satisfied";
574794
+ this.lastReason = "cached/no-op tool result did not perform the required recovery action";
574795
+ return;
574796
+ }
574748
574797
  if (input.toolName === "file_read" && input.success) {
574749
574798
  if (this.directive?.requiredNextAction === "read_authoritative_target" || this.directive?.requiredNextAction === "use_cached_evidence") {
574750
574799
  this.clearSatisfiedDirective("authoritative evidence refreshed", input.turn);
@@ -574848,6 +574897,8 @@ var init_focusSupervisor = __esm({
574848
574897
  this.directive = directive;
574849
574898
  this.state = directive.state;
574850
574899
  this.lastReason = directive.reason;
574900
+ if (!stable)
574901
+ this.lastIgnoredDirectiveTurn = null;
574851
574902
  return directive;
574852
574903
  }
574853
574904
  clearSatisfiedDirective(reason, _turn) {
@@ -574858,6 +574909,7 @@ var init_focusSupervisor = __esm({
574858
574909
  this.directive = null;
574859
574910
  this.state = "observe";
574860
574911
  this.ignoredDirectiveStreak = 0;
574912
+ this.lastIgnoredDirectiveTurn = null;
574861
574913
  }
574862
574914
  pass() {
574863
574915
  return { kind: "pass", state: this.state, ...this.directive ? { directive: this.directive } : {} };
@@ -578352,7 +578404,11 @@ ${parts.join("\n")}
578352
578404
  if (!card)
578353
578405
  return false;
578354
578406
  const editTools = /* @__PURE__ */ new Set(["file_write", "file_edit", "batch_edit", "file_patch"]);
578355
- return card.evidence.some((e2) => typeof e2.tool === "string" && editTools.has(e2.tool));
578407
+ return card.evidence.some((e2) => {
578408
+ if (typeof e2.tool === "string" && editTools.has(e2.tool))
578409
+ return true;
578410
+ return e2.tool === "shell" && /filesystem mutation/i.test(e2.summary ?? "");
578411
+ });
578356
578412
  }
578357
578413
  _workboardHasVerificationEvidence(card) {
578358
578414
  if (!card)
@@ -578463,11 +578519,14 @@ ${parts.join("\n")}
578463
578519
  lines.push("not_progress=repeat unchanged todo_write; repeat broad discovery already represented in this frame; keep discovery active after a real mutation");
578464
578520
  return lines.join("\n");
578465
578521
  }
578466
- _workboardTargetCardId(snapshot, toolName, result) {
578522
+ _workboardTargetCardId(snapshot, toolName, result, meta = {}) {
578467
578523
  const byId = new Map(snapshot.cards.map((card) => [card.id, card]));
578468
578524
  if (this._isProjectEditTool(toolName) && this._isRealProjectMutation(toolName, result)) {
578469
578525
  return byId.has("implement-repair") ? "implement-repair" : null;
578470
578526
  }
578527
+ if (toolName === "shell" && meta.shellFilesystemMutation === true) {
578528
+ return byId.has("implement-repair") ? "implement-repair" : null;
578529
+ }
578471
578530
  if (toolName === "shell" || toolName === "background_run") {
578472
578531
  const implementation2 = byId.get("implement-repair");
578473
578532
  const target = this._workboardHasEditEvidence(implementation2) ? "integrate-and-run" : "discover-current-state";
@@ -578484,11 +578543,11 @@ ${parts.join("\n")}
578484
578543
  this._workboard = refreshed;
578485
578544
  return refreshed;
578486
578545
  }
578487
- _advanceWorkboardForTool(snapshot, toolName, result, actor) {
578546
+ _advanceWorkboardForTool(snapshot, toolName, result, actor, meta = {}) {
578488
578547
  const dir = this._workboardDir();
578489
578548
  let current = snapshot;
578490
578549
  const byId = () => new Map(current.cards.map((card) => [card.id, card]));
578491
- const editMutation = this._isProjectEditTool(toolName) && this._isRealProjectMutation(toolName, result);
578550
+ const editMutation = this._isProjectEditTool(toolName) && this._isRealProjectMutation(toolName, result) || toolName === "shell" && result?.success === true && meta.shellFilesystemMutation === true;
578492
578551
  try {
578493
578552
  if (editMutation) {
578494
578553
  let cards = byId();
@@ -578550,18 +578609,22 @@ ${parts.join("\n")}
578550
578609
  * Matches by card assignee when the card is in progress.
578551
578610
  * Non-fatal: failures to attach evidence are silently caught.
578552
578611
  */
578553
- recordWorkboardToolCall(toolName, args, success, output, result) {
578612
+ recordWorkboardToolCall(toolName, args, success, output, result, meta = {}) {
578554
578613
  const board = this._workboard ?? this.getOrCreateWorkboard();
578555
578614
  if (!board)
578556
578615
  return;
578557
578616
  if (toolName === "task_complete" || toolName === "workboard_create")
578558
578617
  return;
578618
+ if (meta.repeatShortCircuit || result?.runtimeAuthored)
578619
+ return;
578620
+ if (meta.focusDecisionKind === "block_tool_call")
578621
+ return;
578559
578622
  if (result?.success === true && this._isProjectEditTool(toolName) && !this._isRealProjectMutation(toolName, result)) {
578560
578623
  return;
578561
578624
  }
578562
578625
  const dir = this._workboardDir();
578563
578626
  try {
578564
- const evidenceSummary = `${toolName} ${success ? "ok" : "fail"}`;
578627
+ const evidenceSummary = toolName === "shell" && meta.shellFilesystemMutation ? `shell filesystem mutation ${success ? "ok" : "fail"}` : `${toolName} ${success ? "ok" : "fail"}`;
578565
578628
  const rawEvidenceOutput = typeof output === "string" && output.length > 0 ? output : result?.output || result?.error || "";
578566
578629
  const evidenceContent = rawEvidenceOutput.slice(0, 1e3);
578567
578630
  const evidence = {
@@ -578573,8 +578636,8 @@ ${parts.join("\n")}
578573
578636
  ref: typeof args["path"] === "string" ? args["path"]?.slice(0, 200) : void 0
578574
578637
  };
578575
578638
  const actor = this.options.subAgent ? "sub-agent" : "agent";
578576
- const advanced = this._advanceWorkboardForTool(board, toolName, result, actor);
578577
- const targetCardId = this._workboardTargetCardId(advanced, toolName, result);
578639
+ const advanced = this._advanceWorkboardForTool(board, toolName, result, actor, meta);
578640
+ const targetCardId = this._workboardTargetCardId(advanced, toolName, result, meta);
578578
578641
  if (!targetCardId)
578579
578642
  return;
578580
578643
  const targetCard = advanced.cards.find((card) => card.id === targetCardId);
@@ -582405,6 +582468,32 @@ ${sections.join("\n")}` : sections.join("\n");
582405
582468
  `Do NOT repeat this exact call. If you believe state changed, perform the concrete change first, then retry with distinct evidence.`
582406
582469
  ].join("\n");
582407
582470
  }
582471
+ _buildRepeatCachedEvidenceNotice(toolName, args, hits, cachedResult) {
582472
+ const argPreview = JSON.stringify(args ?? {}).slice(0, 200);
582473
+ const target = this.extractPrimaryToolPath(args) || argPreview;
582474
+ const summary = this._summarizeCachedToolResult(cachedResult);
582475
+ return [
582476
+ "[REPEAT GATE - cached evidence not re-sent]",
582477
+ `Exact repeat #${hits} of ${toolName}(${argPreview}).`,
582478
+ `target=${target}`,
582479
+ "This call was not executed again, and the cached payload was not re-emitted because repeating it bloats the model context.",
582480
+ summary,
582481
+ "",
582482
+ "Required next action: use the active evidence frame/tool cache and take a concrete next step: edit/write, run verification, update todos with changed state, or task_complete with evidence.",
582483
+ "If you need different information, use a distinct offset/limit/query. For broad multi-file discovery, use file_explore, grep_search, fanout_explore, or full_sub_agent instead of repeating this call."
582484
+ ].join("\n");
582485
+ }
582486
+ _summarizeCachedToolResult(output) {
582487
+ const text2 = output || "";
582488
+ const lineCount = text2 ? text2.split("\n").length : 0;
582489
+ const sha = text2.match(/sha256=([a-f0-9]{8,64})/i)?.[1];
582490
+ const header = text2.match(/\[FILE CONTEXT \|[^\]]+\]/)?.[0];
582491
+ return [
582492
+ `cached_size=${lineCount} lines, ${text2.length} chars`,
582493
+ sha ? `cached_sha256=${sha.slice(0, 16)}` : "",
582494
+ header ? `cached_header=${header.slice(0, 220)}` : ""
582495
+ ].filter(Boolean).join("\n");
582496
+ }
582408
582497
  _renderKnowledgeBlock(recentToolResults) {
582409
582498
  if (recentToolResults.size === 0)
582410
582499
  return null;
@@ -587744,12 +587833,11 @@ Read the current file if needed, make a different concrete edit, or move to veri
587744
587833
  if (repeatGateEligible && _existingFp !== void 0 && _repeatGateMax > 0) {
587745
587834
  if (criticDecision.hitNumber >= _repeatGateMax) {
587746
587835
  if (isReadLike) {
587747
- const cachedResult = this.sanitizeCachedToolResult(tc.name, _existingFp.result);
587748
587836
  repeatShortCircuit = {
587749
587837
  success: true,
587750
- output: `[STOP RE-READING — you have requested this exact read ${criticDecision.hitNumber}× and you ALREADY HAVE its full content, shown again below. Do NOT read it again. Act on it: edit the file, run a verification, or call task_complete. If a previous edit failed with "old_string not found", your old_string did not match the file — copy it EXACTLY (including indentation) from the content below.]
587751
-
587752
- ` + cachedResult
587838
+ output: this._buildRepeatCachedEvidenceNotice(tc.name, tc.arguments ?? {}, criticDecision.hitNumber, this.sanitizeCachedToolResult(tc.name, _existingFp.result)),
587839
+ runtimeAuthored: true,
587840
+ noop: true
587753
587841
  };
587754
587842
  } else if (isFailedShellRepeat) {
587755
587843
  repeatShortCircuit = {
@@ -587776,7 +587864,9 @@ ${cachedResult}`,
587776
587864
  runtimeAuthored: true
587777
587865
  } : {
587778
587866
  success: true,
587779
- output: cachedResult
587867
+ output: this._buildRepeatCachedEvidenceNotice(tc.name, tc.arguments ?? {}, criticDecision.hitNumber, cachedResult),
587868
+ runtimeAuthored: true,
587869
+ noop: true
587780
587870
  };
587781
587871
  }
587782
587872
  }
@@ -587823,7 +587913,8 @@ ${cachedResult}`,
587823
587913
  success: focusDecision.success,
587824
587914
  output: focusDecision.message,
587825
587915
  error: focusDecision.success ? void 0 : focusDecision.message,
587826
- runtimeAuthored: true
587916
+ runtimeAuthored: true,
587917
+ noop: true
587827
587918
  };
587828
587919
  }
587829
587920
  }
@@ -589125,7 +589216,7 @@ Respond with EXACTLY this structure before your next tool call:
589125
589216
  }
589126
589217
  }
589127
589218
  }
589128
- if (criticGuidance) {
589219
+ if (criticGuidance && !repeatShortCircuit) {
589129
589220
  output += `
589130
589221
 
589131
589222
  ${criticGuidance}`;
@@ -589181,7 +589272,6 @@ Evidence: ${evidencePreview}`.slice(0, 500);
589181
589272
  turn,
589182
589273
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
589183
589274
  });
589184
- this.recordWorkboardToolCall(tc.name, tc.arguments, result.success, result.output || result.error || output, result);
589185
589275
  this._taskState.toolCallCount++;
589186
589276
  if (realFileMutation) {
589187
589277
  this._lastFileWriteTurn = turn;
@@ -589311,7 +589401,8 @@ Evidence: ${evidencePreview}`.slice(0, 500);
589311
589401
  error: result.error ?? "",
589312
589402
  mutated: realFileMutation || shellFilesystemMutation,
589313
589403
  isReadLike,
589314
- noop: tc.name === "todo_write" ? this._isTodoWriteNoopResult(result) : result.noop
589404
+ noop: tc.name === "todo_write" ? this._isTodoWriteNoopResult(result) : result.noop,
589405
+ runtimeAuthored: result.runtimeAuthored === true
589315
589406
  });
589316
589407
  const focusSnapshotAfter = this._focusSupervisor?.snapshot();
589317
589408
  focusAfterToolResult = focusSnapshotAfter ?? void 0;
@@ -589354,10 +589445,16 @@ Evidence: ${evidencePreview}`.slice(0, 500);
589354
589445
  requiredNextAction: focusDecision.directive.requiredNextAction
589355
589446
  },
589356
589447
  repeatShortCircuit: Boolean(repeatShortCircuit),
589448
+ runtimeAuthored: result.runtimeAuthored === true,
589357
589449
  runtimeGuidance: runtimeSystemGuidance
589358
589450
  });
589359
589451
  } catch {
589360
589452
  }
589453
+ this.recordWorkboardToolCall(tc.name, tc.arguments, result.success, result.output || result.error || output, result, {
589454
+ repeatShortCircuit: Boolean(repeatShortCircuit),
589455
+ focusDecisionKind: focusDecision?.kind,
589456
+ shellFilesystemMutation
589457
+ });
589361
589458
  if (tc.name === "todo_write" && !this._isTodoWriteNoopResult(result)) {
589362
589459
  this._lastTodoWriteTurn = turn;
589363
589460
  }
@@ -591824,7 +591921,7 @@ ${marker}` : marker);
591824
591921
  ].filter(Boolean).join("\n"));
591825
591922
  }
591826
591923
  shouldBypassDiscoveryCompaction(output) {
591827
- return output.includes("[IMAGE_BASE64:") || output.includes("[BRANCH-EXTRACT]") || output.includes("[STOP RE-READING") || output.includes("[Tool output truncated") || output.includes(TRIAGE_ENVELOPE_MARKER);
591924
+ return output.includes("[IMAGE_BASE64:") || output.includes("[BRANCH-EXTRACT]") || output.includes("[REPEAT GATE - cached evidence not re-sent]") || output.includes("[Tool output truncated") || output.includes(TRIAGE_ENVELOPE_MARKER);
591828
591925
  }
591829
591926
  countTextLines(text2) {
591830
591927
  if (!text2)
@@ -609750,7 +609847,7 @@ var init_live_sensors = __esm({
609750
609847
  inferEnabled: true,
609751
609848
  clipEnabled: true,
609752
609849
  audioEnabled: true,
609753
- asrEnabled: true,
609850
+ asrEnabled: options2.asr ?? true,
609754
609851
  audioAnalysisEnabled: true,
609755
609852
  videoIntervalMs: options2.lowLatency === false ? this.config.videoIntervalMs : Math.min(this.config.videoIntervalMs, LOW_LATENCY_VIDEO_INTERVAL_MS),
609756
609853
  audioIntervalMs: options2.lowLatency === false ? this.config.audioIntervalMs : Math.min(this.config.audioIntervalMs, LOW_LATENCY_AUDIO_INTERVAL_MS)
@@ -610334,7 +610431,7 @@ ${output}`).join("\n\n");
610334
610431
  transcript = cleanPreview(liveAsr.lastPartialTranscript, 1600);
610335
610432
  asrBackend = [liveAsr.backend, liveAsr.model, "streaming-partial"].filter(Boolean).join(" ");
610336
610433
  } else if (liveAsr.phase === "idle") {
610337
- audioErrors.push("Streaming ASR is not running. Start /live run or /listen to enable CUDA Whisper streaming.");
610434
+ audioErrors.push("Streaming ASR is not active yet; live sound analysis is continuing without a fresh transcript.");
610338
610435
  } else if (liveAsr.lastStatus) {
610339
610436
  audioErrors.push(`Streaming ASR status: ${liveAsr.lastStatus}`);
610340
610437
  }
@@ -661536,11 +661633,24 @@ function attachLiveSinks(ctx3, manager, agentEnabled = false, speechEnabledOverr
661536
661633
  }
661537
661634
  }
661538
661635
  async function ensureLiveStreamingAsr(ctx3, manager, force = false) {
661539
- if (!force && !manager.getConfig().asrEnabled) return;
661540
- if (!ctx3.listenStart) return;
661541
- ctx3.listenSetMode?.("auto");
661542
- const msg = await ctx3.listenStart("live");
661543
- if (!/already active/i.test(msg)) renderInfo(`Live ASR: ${msg}`);
661636
+ if (!force && !manager.getConfig().asrEnabled) return Boolean(ctx3.listenIsActive?.());
661637
+ if (!ctx3.listenStart) {
661638
+ renderWarning("Live ASR auto-start is unavailable in this command context; live audio analysis will continue without transcript intake.");
661639
+ return false;
661640
+ }
661641
+ try {
661642
+ ctx3.listenSetMode?.("auto");
661643
+ const msg = await ctx3.listenStart("live");
661644
+ const active = Boolean(ctx3.listenIsActive?.()) || /already active|listening with|already listening/i.test(msg);
661645
+ if (!/already active/i.test(msg)) {
661646
+ const render2 = active ? renderInfo : renderWarning;
661647
+ render2(`${active ? "Live ASR" : "Live ASR startup"}: ${msg}`);
661648
+ }
661649
+ return active;
661650
+ } catch (err) {
661651
+ renderWarning(`Live ASR startup failed: ${err instanceof Error ? err.message : String(err)}`);
661652
+ return false;
661653
+ }
661544
661654
  }
661545
661655
  async function releaseLiveStreamingAsr(ctx3) {
661546
661656
  try {
@@ -661797,8 +661907,8 @@ async function handleLiveCommand(ctx3, arg) {
661797
661907
  renderWarning("Live PFC agent review is unavailable in this context; starting visual/audio feedback only.");
661798
661908
  }
661799
661909
  await ensureLiveInventory(manager);
661800
- await ensureLiveStreamingAsr(ctx3, manager, true);
661801
- renderInfo(manager.startRunMode({ agent: effectiveAgent, lowLatency: true, speech: effectiveAgent && Boolean(ctx3.voiceSpeak) }));
661910
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
661911
+ renderInfo(manager.startRunMode({ agent: effectiveAgent, lowLatency: true, speech: effectiveAgent && Boolean(ctx3.voiceSpeak), asr: asrStarted }));
661802
661912
  return;
661803
661913
  }
661804
661914
  if (sub2 === "chat" || sub2 === "voicechat" || sub2 === "voice") {
@@ -661899,12 +662009,14 @@ async function handleLiveCommand(ctx3, arg) {
661899
662009
  if (sub2 === "asr") {
661900
662010
  const cfg = manager.getConfig();
661901
662011
  const enabled2 = setBool(value2, !cfg.asrEnabled);
661902
- manager.configure({
661903
- audioEnabled: true,
661904
- asrEnabled: enabled2
661905
- });
661906
- if (enabled2) await ensureLiveStreamingAsr(ctx3, manager);
661907
- else await releaseLiveStreamingAsr(ctx3);
662012
+ if (enabled2) {
662013
+ manager.configure({ audioEnabled: true, asrEnabled: false });
662014
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662015
+ manager.configure({ asrEnabled: asrStarted });
662016
+ } else {
662017
+ manager.configure({ audioEnabled: true, asrEnabled: false });
662018
+ await releaseLiveStreamingAsr(ctx3);
662019
+ }
661908
662020
  renderInfo(formatLiveStatus(manager.getSnapshot()));
661909
662021
  return;
661910
662022
  }
@@ -661957,8 +662069,9 @@ async function handleLiveCommand(ctx3, arg) {
661957
662069
  }
661958
662070
  if (sub2 === "sample" || sub2 === "hear") {
661959
662071
  await ensureLiveInventory(manager);
661960
- manager.configure({ audioEnabled: true, asrEnabled: true, audioAnalysisEnabled: true });
661961
- await ensureLiveStreamingAsr(ctx3, manager, true);
662072
+ manager.configure({ audioEnabled: true, asrEnabled: false, audioAnalysisEnabled: false });
662073
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662074
+ manager.configure({ asrEnabled: asrStarted, audioAnalysisEnabled: true });
661962
662075
  renderInfo("Sampling live audio...");
661963
662076
  renderInfo(await manager.sampleAudioNow());
661964
662077
  return;
@@ -662194,8 +662307,8 @@ async function showLiveMenu(ctx3, manager) {
662194
662307
  await ensureLiveInventory(manager);
662195
662308
  if (!manager.isRunning()) {
662196
662309
  attachLiveSinks(ctx3, manager, false);
662197
- await ensureLiveStreamingAsr(ctx3, manager, true);
662198
- renderInfo(manager.startRunMode({ agent: false, lowLatency: true, speech: false }));
662310
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662311
+ renderInfo(manager.startRunMode({ agent: false, lowLatency: true, speech: false, asr: asrStarted }));
662199
662312
  }
662200
662313
  while (true) {
662201
662314
  await refreshLiveResourceModelSnapshot().catch(() => void 0);
@@ -662353,19 +662466,21 @@ async function showLiveMenu(ctx3, manager) {
662353
662466
  case "toggle-video":
662354
662467
  manager.configure({ videoEnabled: !cfg.videoEnabled });
662355
662468
  continue;
662356
- case "run-live":
662469
+ case "run-live": {
662357
662470
  attachLiveSinks(ctx3, manager, false);
662358
- await ensureLiveStreamingAsr(ctx3, manager, true);
662359
- renderInfo(manager.startRunMode({ agent: false, lowLatency: true, speech: false }));
662471
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662472
+ renderInfo(manager.startRunMode({ agent: false, lowLatency: true, speech: false, asr: asrStarted }));
662360
662473
  continue;
662361
- case "run-agent":
662474
+ }
662475
+ case "run-agent": {
662362
662476
  attachLiveSinks(ctx3, manager, true);
662363
662477
  if (!ctx3.startBackgroundPrompt) {
662364
662478
  renderWarning("Live PFC agent review is unavailable in this context; starting visual/audio feedback only.");
662365
662479
  }
662366
- await ensureLiveStreamingAsr(ctx3, manager, true);
662367
- renderInfo(manager.startRunMode({ agent: Boolean(ctx3.startBackgroundPrompt), lowLatency: true, speech: Boolean(ctx3.startBackgroundPrompt && ctx3.voiceSpeak) }));
662480
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662481
+ renderInfo(manager.startRunMode({ agent: Boolean(ctx3.startBackgroundPrompt), lowLatency: true, speech: Boolean(ctx3.startBackgroundPrompt && ctx3.voiceSpeak), asr: asrStarted }));
662368
662482
  continue;
662483
+ }
662369
662484
  case "run-chat":
662370
662485
  await startLiveVoicechat(ctx3, manager);
662371
662486
  continue;
@@ -662382,9 +662497,14 @@ async function showLiveMenu(ctx3, manager) {
662382
662497
  manager.configure({ videoEnabled: true, clipEnabled: !cfg.clipEnabled });
662383
662498
  continue;
662384
662499
  case "toggle-asr":
662385
- manager.configure({ audioEnabled: true, asrEnabled: !cfg.asrEnabled });
662386
- if (!cfg.asrEnabled) await ensureLiveStreamingAsr(ctx3, manager);
662387
- else await releaseLiveStreamingAsr(ctx3);
662500
+ if (!cfg.asrEnabled) {
662501
+ manager.configure({ audioEnabled: true, asrEnabled: false });
662502
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662503
+ manager.configure({ asrEnabled: asrStarted });
662504
+ } else {
662505
+ manager.configure({ audioEnabled: true, asrEnabled: false });
662506
+ await releaseLiveStreamingAsr(ctx3);
662507
+ }
662388
662508
  continue;
662389
662509
  case "toggle-sounds":
662390
662510
  manager.configure({ audioEnabled: true, audioAnalysisEnabled: !cfg.audioAnalysisEnabled });
@@ -662432,12 +662552,14 @@ Previewing microphone activity...`);
662432
662552
  renderInfo("Sampling camera inference...");
662433
662553
  renderInfo(await manager.sampleVideoNow(true));
662434
662554
  continue;
662435
- case "sample-audio":
662436
- manager.configure({ audioEnabled: true, asrEnabled: true, audioAnalysisEnabled: true });
662437
- await ensureLiveStreamingAsr(ctx3, manager, true);
662555
+ case "sample-audio": {
662556
+ manager.configure({ audioEnabled: true, asrEnabled: false, audioAnalysisEnabled: false });
662557
+ const asrStarted = await ensureLiveStreamingAsr(ctx3, manager, true);
662558
+ manager.configure({ asrEnabled: asrStarted, audioAnalysisEnabled: true });
662438
662559
  renderInfo("Sampling live audio...");
662439
662560
  renderInfo(await manager.sampleAudioNow());
662440
662561
  continue;
662562
+ }
662441
662563
  case "listen-mode":
662442
662564
  if (ctx3.listenToggle) {
662443
662565
  ctx3.listenSetMode?.("auto");
@@ -702421,6 +702543,25 @@ function buildSyntheticContext(config, repoRoot) {
702421
702543
  renderError(`voice model ${TUI_ONLY_HINT}`);
702422
702544
  return "";
702423
702545
  },
702546
+ listenStart: async (owner = "live") => {
702547
+ const engine = getDaemonListenEngine();
702548
+ const available = await engine.isAvailable();
702549
+ if (!available) {
702550
+ return "ASR runtime unavailable. Omnius attempted managed Whisper setup; check ~/.omnius/runtimes/asr and CUDA PyTorch.";
702551
+ }
702552
+ engine.setMode("auto");
702553
+ return engine.acquire(owner);
702554
+ },
702555
+ listenRelease: async (owner = "live") => {
702556
+ const engine = getDaemonListenEngine();
702557
+ return engine.release(owner);
702558
+ },
702559
+ listenIsActive: () => getDaemonListenEngine().isActive,
702560
+ listenSetMode: (mode) => {
702561
+ const engine = getDaemonListenEngine();
702562
+ engine.setMode(mode);
702563
+ return mode === "auto" ? "Auto mode: transcriptions auto-submit after 3s silence" : "Manual mode: press Enter to submit transcriptions (auto-submit off)";
702564
+ },
702424
702565
  getColors: () => colorsEnabled,
702425
702566
  setColors: (enabled2) => {
702426
702567
  colorsEnabled = enabled2;
@@ -738713,13 +738854,14 @@ This is an independent background session started from /background.`
738713
738854
  headerBtnQueue = command;
738714
738855
  return;
738715
738856
  }
738716
- const commandToRun = command === "live" ? isLiveSensorActiveForRepo(repoRoot) ? "live stop" : "live run" : command;
738857
+ const normalizedHeaderCommand = command.replace(/^\/+/, "");
738858
+ const commandToRun = normalizedHeaderCommand === "live" ? isLiveSensorActiveForRepo(repoRoot) ? "live stop" : "live run" : command;
738717
738859
  if (headerBtnActive && headerBtnActive !== command) {
738718
738860
  headerBtnQueue = command;
738719
738861
  return;
738720
738862
  }
738721
738863
  if (headerBtnActive === command) {
738722
- if (command === "live") headerBtnQueue = command;
738864
+ if (normalizedHeaderCommand === "live") headerBtnQueue = command;
738723
738865
  return;
738724
738866
  }
738725
738867
  headerBtnActive = command;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.445",
3
+ "version": "1.0.447",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.445",
9
+ "version": "1.0.447",
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.445",
3
+ "version": "1.0.447",
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",