omnius 1.0.618 → 1.0.619

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
@@ -204044,7 +204044,7 @@ var require_snapshot_recorder = __commonJS({
204044
204044
  "../node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
204045
204045
  "use strict";
204046
204046
  var { writeFile: writeFile27, readFile: readFile27, mkdir: mkdir24 } = __require("node:fs/promises");
204047
- var { dirname: dirname67, resolve: resolve88 } = __require("node:path");
204047
+ var { dirname: dirname68, resolve: resolve88 } = __require("node:path");
204048
204048
  var { setTimeout: setTimeout3, clearTimeout: clearTimeout3 } = __require("node:timers");
204049
204049
  var { InvalidArgumentError, UndiciError } = require_errors2();
204050
204050
  var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -204275,7 +204275,7 @@ var require_snapshot_recorder = __commonJS({
204275
204275
  throw new InvalidArgumentError("Snapshot path is required");
204276
204276
  }
204277
204277
  const resolvedPath = resolve88(path16);
204278
- await mkdir24(dirname67(resolvedPath), { recursive: true });
204278
+ await mkdir24(dirname68(resolvedPath), { recursive: true });
204279
204279
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
204280
204280
  hash: hash2,
204281
204281
  snapshot
@@ -317937,15 +317937,15 @@ var init_ls = __esm({
317937
317937
  });
317938
317938
 
317939
317939
  // ../node_modules/@helia/unixfs/dist/src/commands/mkdir.js
317940
- async function mkdir6(parentCid, dirname67, blockstore, options2 = {}) {
317941
- if (dirname67.includes("/")) {
317940
+ async function mkdir6(parentCid, dirname68, blockstore, options2 = {}) {
317941
+ if (dirname68.includes("/")) {
317942
317942
  throw new InvalidParametersError4("Path must not have slashes");
317943
317943
  }
317944
317944
  const entry = await exporter2(parentCid, blockstore, options2);
317945
317945
  if (entry.type !== "directory") {
317946
317946
  throw new NotADirectoryError(`${parentCid.toString()} was not a UnixFS directory`);
317947
317947
  }
317948
- log16("creating %s", dirname67);
317948
+ log16("creating %s", dirname68);
317949
317949
  const metadata = new UnixFS({
317950
317950
  type: "directory",
317951
317951
  mode: options2.mode,
@@ -317961,9 +317961,9 @@ async function mkdir6(parentCid, dirname67, blockstore, options2 = {}) {
317961
317961
  await blockstore.put(emptyDirCid, buf);
317962
317962
  const [directory, pblink] = await Promise.all([
317963
317963
  cidToDirectory(parentCid, blockstore, options2),
317964
- cidToPBLink(emptyDirCid, dirname67, blockstore, options2)
317964
+ cidToPBLink(emptyDirCid, dirname68, blockstore, options2)
317965
317965
  ]);
317966
- log16("adding empty dir called %s to %c", dirname67, parentCid);
317966
+ log16("adding empty dir called %s to %c", dirname68, parentCid);
317967
317967
  const result = await addLink(directory, pblink, blockstore, {
317968
317968
  ...options2,
317969
317969
  allowOverwriting: options2.force
@@ -318462,8 +318462,8 @@ var init_unixfs2 = __esm({
318462
318462
  async *ls(cid, options2 = {}) {
318463
318463
  yield* ls(cid, this.components.blockstore, options2);
318464
318464
  }
318465
- async mkdir(cid, dirname67, options2 = {}) {
318466
- return mkdir6(cid, dirname67, this.components.blockstore, options2);
318465
+ async mkdir(cid, dirname68, options2 = {}) {
318466
+ return mkdir6(cid, dirname68, this.components.blockstore, options2);
318467
318467
  }
318468
318468
  async rm(cid, path16, options2 = {}) {
318469
318469
  return rm3(cid, path16, this.components.blockstore, options2);
@@ -566258,7 +566258,7 @@ var require_path_browserify = __commonJS({
566258
566258
  _makeLong: function _makeLong(path16) {
566259
566259
  return path16;
566260
566260
  },
566261
- dirname: function dirname67(path16) {
566261
+ dirname: function dirname68(path16) {
566262
566262
  assertPath(path16);
566263
566263
  if (path16.length === 0) return ".";
566264
566264
  var code8 = path16.charCodeAt(0);
@@ -602245,9 +602245,9 @@ function whisperModel(engineId, id2, label) {
602245
602245
  languages: ["multilingual"],
602246
602246
  capabilities: whisperCapabilities,
602247
602247
  resources: {
602248
- cpuSupported: engineId === "transcribe-cli",
602248
+ cpuSupported: false,
602249
602249
  architectures: ["x64", "arm64"],
602250
- notes: engineId === "transcribe-cli" ? ["Managed transcribe-cli runtime; implementation may use faster-whisper or ONNX."] : ["CUDA is required by Omnius unless an explicit local override is configured."]
602250
+ notes: ["CUDA is required by Omnius unless an explicit local override is configured."]
602251
602251
  }
602252
602252
  };
602253
602253
  }
@@ -602300,7 +602300,7 @@ var init_registry2 = __esm({
602300
602300
  VIBEVOICE_ASR_SOURCE_REVISION = "94da20d98b2fa7688e9cbfaf7692ddb4954f7600";
602301
602301
  VIBEVOICE_ASR_QWEN_TOKENIZER_REVISION = "d149729398750b98c0af14eb82c78cfe92750796";
602302
602302
  VIBEVOICE_ASR_WEIGHTS_BYTES = 17348198410;
602303
- NEMOTRON_DISABLED_REASON = "Nemotron is catalogued but its legacy self-installing worker is disabled until it is migrated to the managed fail-closed runtime.";
602303
+ NEMOTRON_DISABLED_REASON = "Nemotron is unavailable because its managed CUDA runtime could not be activated.";
602304
602304
  whisperCapabilities = Object.freeze({
602305
602305
  file: true,
602306
602306
  pcmStream: true,
@@ -602325,15 +602325,6 @@ var init_registry2 = __esm({
602325
602325
  setupMode: "managed",
602326
602326
  models: whisperModels("openai-whisper")
602327
602327
  },
602328
- {
602329
- id: "transcribe-cli",
602330
- label: "transcribe-cli",
602331
- detail: "Managed faster-whisper/ONNX bridge for live and file transcription",
602332
- provider: "transcribe-cli",
602333
- runtime: "node",
602334
- setupMode: "managed",
602335
- models: whisperModels("transcribe-cli")
602336
- },
602337
602328
  {
602338
602329
  id: "nemotron-streaming",
602339
602330
  label: "NVIDIA Nemotron Speech Streaming",
@@ -602341,8 +602332,6 @@ var init_registry2 = __esm({
602341
602332
  provider: "NVIDIA",
602342
602333
  runtime: "python",
602343
602334
  setupMode: "managed",
602344
- availability: "disabled",
602345
- unavailableReason: NEMOTRON_DISABLED_REASON,
602346
602335
  models: [
602347
602336
  {
602348
602337
  id: "nemotron-speech-streaming-en-0.6b",
@@ -602423,8 +602412,10 @@ var init_registry2 = __esm({
602423
602412
  ENGINE_ALIASES = {
602424
602413
  whisper: "openai-whisper",
602425
602414
  openai_whisper: "openai-whisper",
602426
- faster_whisper: "transcribe-cli",
602427
- transcribe_cli: "transcribe-cli",
602415
+ transcribe_cli: "openai-whisper",
602416
+ transcribe_cli_runtime: "openai-whisper",
602417
+ "transcribe-cli": "openai-whisper",
602418
+ faster_whisper: "openai-whisper",
602428
602419
  nemotron: "nemotron-streaming",
602429
602420
  vibevoice: "vibevoice-transformers",
602430
602421
  vibevoice_asr: "vibevoice-transformers"
@@ -633848,8 +633839,8 @@ var init_adversaryStream = __esm({
633848
633839
  return;
633849
633840
  try {
633850
633841
  const { writeFileSync: writeFileSync104, mkdirSync: mkdirSync120, existsSync: existsSync184 } = __require("node:fs");
633851
- const { dirname: dirname67 } = __require("node:path");
633852
- const dir = dirname67(this.persistPath);
633842
+ const { dirname: dirname68 } = __require("node:path");
633843
+ const dir = dirname68(this.persistPath);
633853
633844
  if (!existsSync184(dir))
633854
633845
  mkdirSync120(dir, { recursive: true });
633855
633846
  writeFileSync104(this.persistPath, JSON.stringify({ ledger: this.ledger }, null, 2));
@@ -682403,16 +682394,64 @@ var init_image_ascii_preview = __esm({
682403
682394
  var py_embed_exports = {};
682404
682395
  __export(py_embed_exports, {
682405
682396
  ensureEmbedDeps: () => ensureEmbedDeps,
682397
+ ensureManagedAsrModel: () => ensureManagedAsrModel,
682398
+ getManagedAsrReadiness: () => getManagedAsrReadiness,
682406
682399
  getVenvPython: () => getVenvPython,
682407
682400
  runEmbedAudio: () => runEmbedAudio,
682408
682401
  runEmbedImage: () => runEmbedImage,
682409
682402
  runEmbedText: () => runEmbedText,
682410
- runTranscribeFile: () => runTranscribeFile
682403
+ runTranscribeFile: () => runTranscribeFile,
682404
+ transcribeManagedNemotronFile: () => transcribeManagedNemotronFile
682411
682405
  });
682412
682406
  import { spawnSync as spawnSync9 } from "node:child_process";
682413
682407
  import { existsSync as existsSync122, mkdirSync as mkdirSync74, readFileSync as readFileSync99, writeFileSync as writeFileSync64 } from "node:fs";
682414
- import { join as join134 } from "node:path";
682408
+ import { dirname as dirname46, join as join134 } from "node:path";
682415
682409
  import { homedir as homedir41 } from "node:os";
682410
+ import { fileURLToPath as fileURLToPath21 } from "node:url";
682411
+ function managedAsrStateFile(engineId) {
682412
+ return join134(MANAGED_ASR_ROOT, engineId, "models.json");
682413
+ }
682414
+ function managedAsrModelDir(engineId) {
682415
+ return join134(MANAGED_ASR_MODEL_ROOT, engineId);
682416
+ }
682417
+ function readManagedAsrState(engineId) {
682418
+ try {
682419
+ return JSON.parse(readFileSync99(managedAsrStateFile(engineId), "utf8"));
682420
+ } catch {
682421
+ return {};
682422
+ }
682423
+ }
682424
+ function persistManagedAsrReadiness(readiness) {
682425
+ const root = join134(MANAGED_ASR_ROOT, readiness.engineId);
682426
+ mkdirSync74(root, { recursive: true });
682427
+ const state2 = readManagedAsrState(readiness.engineId);
682428
+ state2.models ??= {};
682429
+ state2.models[readiness.modelId] = {
682430
+ installed: readiness.installed,
682431
+ weightsReady: readiness.weightsReady,
682432
+ device: readiness.device,
682433
+ lastError: readiness.lastError,
682434
+ pulledAt: readiness.pulledAt
682435
+ };
682436
+ writeFileSync64(managedAsrStateFile(readiness.engineId), `${JSON.stringify(state2, null, 2)}
682437
+ `, "utf8");
682438
+ }
682439
+ function assertManagedAsrModel(engineId, modelId) {
682440
+ if (engineId === "openai-whisper" && WHISPER_MODEL_IDS2.has(modelId)) return;
682441
+ if (engineId === "nemotron-streaming" && modelId === NEMOTRON_MODEL_ID) return;
682442
+ throw new Error(`No managed CUDA runtime is registered for ASR model ${engineId}/${modelId}`);
682443
+ }
682444
+ function parseWorkerEvents(output2) {
682445
+ const events = [];
682446
+ for (const line of output2.split(/\r?\n/)) {
682447
+ try {
682448
+ const value2 = JSON.parse(line);
682449
+ if (value2 && typeof value2 === "object") events.push(value2);
682450
+ } catch {
682451
+ }
682452
+ }
682453
+ return events;
682454
+ }
682416
682455
  function getVenvDir() {
682417
682456
  return join134(homedir41(), ".omnius", "venv");
682418
682457
  }
@@ -682781,6 +682820,126 @@ ${log22.slice(-2e3)}` };
682781
682820
  }
682782
682821
  return { ok: ok3, log: log22 };
682783
682822
  }
682823
+ function getManagedAsrReadiness(engineId, modelId) {
682824
+ assertManagedAsrModel(engineId, modelId);
682825
+ const saved = readManagedAsrState(engineId).models?.[modelId];
682826
+ return {
682827
+ engineId,
682828
+ modelId,
682829
+ installed: Boolean(saved?.installed && existsSync122(getVenvPython())),
682830
+ weightsReady: Boolean(saved?.weightsReady),
682831
+ active: false,
682832
+ device: saved?.device,
682833
+ lastError: saved?.lastError,
682834
+ pulledAt: saved?.pulledAt
682835
+ };
682836
+ }
682837
+ function ensureManagedAsrModel(input) {
682838
+ const engineId = input.engineId.trim().toLowerCase();
682839
+ const modelId = input.modelId.trim().toLowerCase();
682840
+ assertManagedAsrModel(engineId, modelId);
682841
+ const deps = ensureEmbedDeps();
682842
+ if (!deps.ok) throw new Error(`ASR dependency setup failed: ${deps.log.slice(-2400)}`);
682843
+ const modelDir2 = managedAsrModelDir(engineId);
682844
+ mkdirSync74(modelDir2, { recursive: true });
682845
+ const env2 = {
682846
+ ...process.env,
682847
+ OMNIUS_ASR_MODEL_DIR: modelDir2,
682848
+ ...input.device ? { OMNIUS_ASR_CUDA_DEVICE: input.device } : {}
682849
+ };
682850
+ let device = "";
682851
+ let failure = "";
682852
+ if (engineId === "openai-whisper") {
682853
+ const code8 = [
682854
+ "import json, os, sys",
682855
+ "import torch, whisper",
682856
+ "allow_cpu=os.environ.get('OMNIUS_ASR_ALLOW_CPU','').strip().lower() in ('1','true','yes','on')",
682857
+ "if torch.cuda.is_available() and torch.cuda.device_count() > 0:",
682858
+ " index=int(os.environ.get('OMNIUS_ASR_CUDA_DEVICE','0') or '0')",
682859
+ " if index < 0 or index >= torch.cuda.device_count(): raise RuntimeError(f'CUDA device {index} is outside the visible device range')",
682860
+ " torch.cuda.set_device(index); device=f'cuda:{index}'",
682861
+ "elif allow_cpu: device='cpu'",
682862
+ `else: raise RuntimeError(f'CUDA-only ASR is enabled but torch cannot use CUDA (torch.version.cuda={getattr(torch.version, \\"cuda\\", None)}, device_count={torch.cuda.device_count()})')`,
682863
+ "model=whisper.load_model(sys.argv[1], device=device, download_root=sys.argv[2])",
682864
+ "print(json.dumps({'ok': True, 'device': device, 'cuda': device.startswith('cuda'), 'model': sys.argv[1]}))"
682865
+ ].join("\n");
682866
+ const pulled = spawnSync9(getVenvPython(), ["-c", code8, modelId, modelDir2], {
682867
+ encoding: "utf8",
682868
+ timeout: 12e5,
682869
+ env: env2
682870
+ });
682871
+ const events = parseWorkerEvents(`${pulled.stdout || ""}`);
682872
+ const ready = events.find((event) => event["ok"] === true);
682873
+ device = typeof ready?.["device"] === "string" ? ready["device"] : "";
682874
+ failure = `${pulled.stderr || ""}`.trim() || (pulled.error ? String(pulled.error) : "");
682875
+ if (pulled.status !== 0 || !ready || !device) {
682876
+ const message2 = failure || `Whisper model pull exited with status ${pulled.status ?? "unknown"}`;
682877
+ const readiness2 = { engineId, modelId, installed: true, weightsReady: false, active: false, lastError: message2 };
682878
+ persistManagedAsrReadiness(readiness2);
682879
+ throw new Error(message2);
682880
+ }
682881
+ } else {
682882
+ const script = locateScript("live-nemotron.py");
682883
+ const pulled = spawnSync9(getVenvPython(), [script, "--model", modelId, "--setup"], {
682884
+ encoding: "utf8",
682885
+ timeout: 12e5,
682886
+ env: env2
682887
+ });
682888
+ const events = parseWorkerEvents(`${pulled.stdout || ""}`);
682889
+ const ready = events.find((event) => event["type"] === "ready");
682890
+ const error = events.find((event) => event["type"] === "error");
682891
+ device = typeof ready?.["device"] === "string" ? ready["device"] : "";
682892
+ failure = String(error?.["message"] ?? (`${pulled.stderr || ""}`.trim() || pulled.error || ""));
682893
+ if (pulled.status !== 0 || !ready || !device) {
682894
+ const message2 = failure || `Nemotron model pull exited with status ${pulled.status ?? "unknown"}`;
682895
+ const readiness2 = { engineId, modelId, installed: true, weightsReady: false, active: false, lastError: message2 };
682896
+ persistManagedAsrReadiness(readiness2);
682897
+ throw new Error(message2);
682898
+ }
682899
+ }
682900
+ const readiness = {
682901
+ engineId,
682902
+ modelId,
682903
+ installed: true,
682904
+ weightsReady: true,
682905
+ active: false,
682906
+ device,
682907
+ pulledAt: (/* @__PURE__ */ new Date()).toISOString()
682908
+ };
682909
+ persistManagedAsrReadiness(readiness);
682910
+ return readiness;
682911
+ }
682912
+ function transcribeManagedNemotronFile(input) {
682913
+ const modelId = input.modelId.trim().toLowerCase();
682914
+ const existing = getManagedAsrReadiness("nemotron-streaming", modelId);
682915
+ if (!existing.weightsReady) ensureManagedAsrModel({ engineId: "nemotron-streaming", modelId, device: input.device });
682916
+ const result = spawnSync9(
682917
+ getVenvPython(),
682918
+ [locateScript("live-nemotron.py"), "--model", modelId, "--file", input.path],
682919
+ {
682920
+ encoding: "utf8",
682921
+ timeout: 12e5,
682922
+ env: {
682923
+ ...process.env,
682924
+ OMNIUS_ASR_MODEL_DIR: managedAsrModelDir("nemotron-streaming"),
682925
+ ...input.device ? { OMNIUS_ASR_CUDA_DEVICE: input.device } : {}
682926
+ }
682927
+ }
682928
+ );
682929
+ const events = parseWorkerEvents(`${result.stdout || ""}`);
682930
+ const transcript = [...events].reverse().find((event) => event["type"] === "transcript");
682931
+ const ready = events.find((event) => event["type"] === "ready");
682932
+ const error = events.find((event) => event["type"] === "error");
682933
+ if (result.status !== 0 || !transcript) {
682934
+ throw new Error(String(error?.["message"] ?? (`${result.stderr || ""}`.trim() || result.error || "Nemotron file transcription failed")));
682935
+ }
682936
+ return {
682937
+ text: String(transcript["text"] ?? ""),
682938
+ duration: Number.isFinite(Number(transcript["audioSeconds"])) ? Number(transcript["audioSeconds"]) : null,
682939
+ device: typeof ready?.["device"] === "string" ? ready["device"] : existing.device,
682940
+ warnings: []
682941
+ };
682942
+ }
682784
682943
  function runEmbedImage(input) {
682785
682944
  const py = getVenvPython();
682786
682945
  const script = locateScript("embed-image.py");
@@ -682827,20 +682986,23 @@ function runTranscribeFile(input) {
682827
682986
  }
682828
682987
  function locateScript(name10) {
682829
682988
  const candidates = [
682989
+ join134(MODULE_DIR, "..", "scripts", name10),
682830
682990
  join134(process.cwd(), "dist", "scripts", name10),
682831
682991
  join134(process.cwd(), name10),
682832
682992
  join134(process.cwd(), "scripts", name10)
682833
682993
  ];
682834
682994
  for (const c9 of candidates) if (existsSync122(c9)) return c9;
682835
682995
  const fallback = join134(process.cwd(), name10);
682836
- try {
682837
- writeFileSync64(fallback, 'print("missing script")\n');
682838
- } catch {
682839
- }
682840
682996
  return fallback;
682841
682997
  }
682998
+ var MODULE_DIR, MANAGED_ASR_ROOT, MANAGED_ASR_MODEL_ROOT, WHISPER_MODEL_IDS2, NEMOTRON_MODEL_ID;
682842
682999
  var init_py_embed = __esm({
682843
683000
  "packages/cli/src/api/py-embed.ts"() {
683001
+ MODULE_DIR = dirname46(fileURLToPath21(import.meta.url));
683002
+ MANAGED_ASR_ROOT = join134(homedir41(), ".omnius", "runtimes", "asr");
683003
+ MANAGED_ASR_MODEL_ROOT = join134(homedir41(), ".omnius", "models", "asr");
683004
+ WHISPER_MODEL_IDS2 = /* @__PURE__ */ new Set(["tiny", "base", "small", "medium", "large-v3"]);
683005
+ NEMOTRON_MODEL_ID = "nemotron-speech-streaming-en-0.6b";
682844
683006
  }
682845
683007
  });
682846
683008
 
@@ -682866,9 +683028,9 @@ import {
682866
683028
  writeFileSync as writeFileSync65,
682867
683029
  readdirSync as readdirSync37
682868
683030
  } from "node:fs";
682869
- import { join as join135, dirname as dirname46 } from "node:path";
683031
+ import { join as join135, dirname as dirname47 } from "node:path";
682870
683032
  import { homedir as homedir42 } from "node:os";
682871
- import { fileURLToPath as fileURLToPath21 } from "node:url";
683033
+ import { fileURLToPath as fileURLToPath22 } from "node:url";
682872
683034
  import { EventEmitter as EventEmitter6 } from "node:events";
682873
683035
  import { createInterface as createInterface3 } from "node:readline";
682874
683036
  function isAudioPath(path16) {
@@ -683121,7 +683283,7 @@ async function findMicCaptureCommand() {
683121
683283
  return null;
683122
683284
  }
683123
683285
  async function findTranscribeFileScript() {
683124
- const thisDir = dirname46(fileURLToPath21(import.meta.url));
683286
+ const thisDir = dirname47(fileURLToPath22(import.meta.url));
683125
683287
  const candidates = [
683126
683288
  join135(thisDir, "../../../../packages/execution/scripts/transcribe-file.py"),
683127
683289
  join135(thisDir, "../../../packages/execution/scripts/transcribe-file.py"),
@@ -683206,15 +683368,15 @@ async function transcribeFileViaWhisper(filePath, model) {
683206
683368
  }
683207
683369
  });
683208
683370
  }
683209
- async function findLiveWhisperScript() {
683210
- const thisDir = dirname46(fileURLToPath21(import.meta.url));
683371
+ async function findLiveAsrScript(scriptName) {
683372
+ const thisDir = dirname47(fileURLToPath22(import.meta.url));
683211
683373
  const candidates = [
683212
- join135(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
683213
- join135(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
683214
- join135(thisDir, "../../execution/scripts/live-whisper.py"),
683374
+ join135(thisDir, "../../../../packages/execution/scripts", scriptName),
683375
+ join135(thisDir, "../../../packages/execution/scripts", scriptName),
683376
+ join135(thisDir, "../../execution/scripts", scriptName),
683215
683377
  // npm install layout — scripts bundled alongside dist
683216
- join135(thisDir, "../scripts/live-whisper.py"),
683217
- join135(thisDir, "../../scripts/live-whisper.py")
683378
+ join135(thisDir, "../scripts", scriptName),
683379
+ join135(thisDir, "../../scripts", scriptName)
683218
683380
  ];
683219
683381
  for (const p2 of candidates) {
683220
683382
  if (existsSync123(p2)) return p2;
@@ -683222,8 +683384,8 @@ async function findLiveWhisperScript() {
683222
683384
  try {
683223
683385
  const globalRoot = (await execFileText5("npm", ["root", "-g"], { timeout: 5e3 })).trim();
683224
683386
  const candidates2 = [
683225
- join135(globalRoot, "omnius", "dist", "scripts", "live-whisper.py"),
683226
- join135(globalRoot, "omnius", "scripts", "live-whisper.py")
683387
+ join135(globalRoot, "omnius", "dist", "scripts", scriptName),
683388
+ join135(globalRoot, "omnius", "scripts", scriptName)
683227
683389
  ];
683228
683390
  for (const p2 of candidates2) {
683229
683391
  if (existsSync123(p2)) return p2;
@@ -683242,7 +683404,7 @@ async function findLiveWhisperScript() {
683242
683404
  "omnius",
683243
683405
  "dist",
683244
683406
  "scripts",
683245
- "live-whisper.py"
683407
+ scriptName
683246
683408
  );
683247
683409
  if (existsSync123(p2)) return p2;
683248
683410
  }
@@ -683251,6 +683413,12 @@ async function findLiveWhisperScript() {
683251
683413
  }
683252
683414
  return null;
683253
683415
  }
683416
+ async function findLiveWhisperScript() {
683417
+ return findLiveAsrScript("live-whisper.py");
683418
+ }
683419
+ async function findLiveNemotronScript() {
683420
+ return findLiveAsrScript("live-nemotron.py");
683421
+ }
683254
683422
  function defaultConsensusModel(primaryModel) {
683255
683423
  const model = primaryModel.trim().toLowerCase();
683256
683424
  if (model === "tiny") return "base";
@@ -683472,13 +683640,15 @@ var init_listen = __esm({
683472
683640
  196
683473
683641
  ];
683474
683642
  WhisperFallbackTranscriber = class extends EventEmitter6 {
683475
- constructor(model, scriptPath2) {
683643
+ constructor(model, scriptPath2, engineId = "openai-whisper") {
683476
683644
  super();
683477
683645
  this.model = model;
683478
683646
  this.scriptPath = scriptPath2;
683647
+ this.engineId = engineId;
683479
683648
  }
683480
683649
  model;
683481
683650
  scriptPath;
683651
+ engineId;
683482
683652
  process = null;
683483
683653
  _ready = false;
683484
683654
  registeredBrokerName = null;
@@ -683510,30 +683680,31 @@ var init_listen = __esm({
683510
683680
  }
683511
683681
  updateListenLiveState({
683512
683682
  phase: "loading-model",
683513
- backend: "openai-whisper",
683683
+ backend: this.engineId,
683514
683684
  model: this.model,
683515
- lastStatus: `loading whisper ${this.model} model...`
683685
+ lastStatus: `loading ${this.engineId} ${this.model} model...`
683516
683686
  });
683517
683687
  const consensusModel = resolveAsrConsensusModel(this.model);
683518
683688
  const consensusThreshold = String(process.env["OMNIUS_ASR_CONSENSUS_THRESHOLD"] ?? "0.45");
683519
683689
  const silenceMs = String(process.env["OMNIUS_ASR_SILENCE_MS"] ?? "3000");
683690
+ const workerArgs = this.engineId === "nemotron-streaming" ? [this.scriptPath, "--model", this.model] : [
683691
+ this.scriptPath,
683692
+ "--model",
683693
+ this.model,
683694
+ "--chunk-seconds",
683695
+ "3",
683696
+ "--window-seconds",
683697
+ "10",
683698
+ "--consensus-model",
683699
+ consensusModel,
683700
+ "--consensus-threshold",
683701
+ consensusThreshold,
683702
+ "--silence-ms",
683703
+ silenceMs
683704
+ ];
683520
683705
  this.process = spawn33(
683521
683706
  pyPath,
683522
- [
683523
- this.scriptPath,
683524
- "--model",
683525
- this.model,
683526
- "--chunk-seconds",
683527
- "3",
683528
- "--window-seconds",
683529
- "10",
683530
- "--consensus-model",
683531
- consensusModel,
683532
- "--consensus-threshold",
683533
- consensusThreshold,
683534
- "--silence-ms",
683535
- silenceMs
683536
- ],
683707
+ workerArgs,
683537
683708
  {
683538
683709
  stdio: ["pipe", "pipe", "pipe"],
683539
683710
  env: { ...process.env }
@@ -683559,7 +683730,7 @@ var init_listen = __esm({
683559
683730
  case "ready":
683560
683731
  this._ready = true;
683561
683732
  clearTimeout(timeout2);
683562
- updateListenLiveState({ phase: "ready", lastStatus: "whisper model loaded" });
683733
+ updateListenLiveState({ phase: "ready", lastStatus: `${this.engineId} model loaded` });
683563
683734
  this.registerBrokerModel(evt);
683564
683735
  this.emit("ready");
683565
683736
  resolve88();
@@ -683589,7 +683760,7 @@ var init_listen = __esm({
683589
683760
  const speech = evt.speech === true;
683590
683761
  const now2 = Date.now();
683591
683762
  if (process.env["OMNIUS_ASR_VERBOSE_VAD"] === "1" && (speech !== this.lastVadSpeech || now2 - this.lastVisibleVadAt > 1e4)) {
683592
- this.emit("status", `Whisper VAD: ${speech ? "speech" : "silence"}`);
683763
+ this.emit("status", `${this.engineId} VAD: ${speech ? "speech" : "silence"}`);
683593
683764
  this.lastVisibleVadAt = now2;
683594
683765
  }
683595
683766
  this.lastVadSpeech = speech;
@@ -683656,11 +683827,11 @@ var init_listen = __esm({
683656
683827
  const gpuIndexMatch = device.match(/^cuda:(\d+)/);
683657
683828
  const gpuIndex = gpuIndexMatch ? Number(gpuIndexMatch[1]) : null;
683658
683829
  const consensus = typeof evt["consensusModel"] === "string" && String(evt["consensusModel"]).trim() ? String(evt["consensusModel"]).trim() : "";
683659
- const name10 = `whisper:${this.model}${consensus ? `+${consensus}` : ""}`;
683830
+ const name10 = `${this.engineId}:${this.model}${consensus ? `+${consensus}` : ""}`;
683660
683831
  const vramMB = Math.max(0, Math.round(Number(evt["vramUsedMB"] ?? 0)));
683661
683832
  try {
683662
683833
  getModelBroker().registerLoaded({
683663
- key: `whisper-cli:${name10}`,
683834
+ key: `asr-worker:${name10}`,
683664
683835
  name: name10,
683665
683836
  domain: "asr",
683666
683837
  host: "whisper-cli",
@@ -683707,7 +683878,7 @@ var init_listen = __esm({
683707
683878
  // Medium by default (EGG lineage): with utterance-chunked capture the
683708
683879
  // per-utterance compute fits, and accuracy jumps over base.
683709
683880
  model: config?.model ?? "medium",
683710
- engineId: config?.engineId ?? "openai-whisper",
683881
+ engineId: normalizeAsrEngineId(config?.engineId ?? "openai-whisper"),
683711
683882
  modelId: config?.modelId ?? config?.model ?? "medium",
683712
683883
  mode: config?.mode ?? "confirm",
683713
683884
  silenceTimeoutMs: config?.silenceTimeoutMs ?? 3e3
@@ -683794,6 +683965,14 @@ var init_listen = __esm({
683794
683965
  }
683795
683966
  const unavailableReason = getAsrEngineUnavailableReason(selection.engineId);
683796
683967
  if (unavailableReason) throw new Error(unavailableReason);
683968
+ if (options2.setup && (selection.engineId === "openai-whisper" || selection.engineId === "nemotron-streaming")) {
683969
+ const managed = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
683970
+ managed.ensureManagedAsrModel({
683971
+ engineId: selection.engineId,
683972
+ modelId: selection.modelId,
683973
+ device: options2.device
683974
+ });
683975
+ }
683797
683976
  const whisperModel2 = selection.modelId;
683798
683977
  if (wasActive) await this.stop();
683799
683978
  if (previous.engineId === "vibevoice-transformers") await stopVibeVoiceAsr();
@@ -683939,7 +684118,7 @@ var init_listen = __esm({
683939
684118
  const req3 = createRequire12(import.meta.url);
683940
684119
  const loaded = req3("transcribe-cli");
683941
684120
  try {
683942
- transcribeCliPackageDirs.add(dirname46(req3.resolve("transcribe-cli/package.json")));
684121
+ transcribeCliPackageDirs.add(dirname47(req3.resolve("transcribe-cli/package.json")));
683943
684122
  } catch {
683944
684123
  }
683945
684124
  return loaded;
@@ -683986,9 +684165,7 @@ var init_listen = __esm({
683986
684165
  if (this.config.engineId === "vibevoice-transformers") {
683987
684166
  return "VibeVoice ASR does not support incremental PCM streaming. Use file/completed-utterance transcription or select Whisper.";
683988
684167
  }
683989
- if (this.config.engineId === "nemotron-streaming") {
683990
- return "Nemotron live activation is unavailable until its managed CUDA runtime passes the hardware gate.";
683991
- }
684168
+ const isNemotron = this.config.engineId === "nemotron-streaming";
683992
684169
  this.micWaterfall = [];
683993
684170
  updateListenLiveState({
683994
684171
  phase: "bootstrapping",
@@ -684005,17 +684182,17 @@ var init_listen = __esm({
684005
684182
  updateListenLiveState({ phase: "error", lastStatus: "no mic capture tool (arecord/sox/ffmpeg)" });
684006
684183
  return "No microphone capture tool found. Install arecord (Linux), sox (macOS), or ffmpeg.";
684007
684184
  }
684008
- const consensusEnabled = asrConsensusEnabled(this.config.model);
684009
- const useTranscribeCli = this.config.engineId === "transcribe-cli" || liveAsrUseTranscribeCli() && !consensusEnabled;
684185
+ const consensusEnabled = !isNemotron && asrConsensusEnabled(this.config.model);
684186
+ const useTranscribeCli = !isNemotron && liveAsrUseTranscribeCli() && !consensusEnabled;
684010
684187
  const preferWhisperFallback = !useTranscribeCli;
684011
684188
  if (preferWhisperFallback) {
684012
684189
  this.emit(
684013
684190
  "info",
684014
- consensusEnabled ? "ASR consensus enabled — using live-whisper.py with CUDA-only Whisper guard." : "Using live-whisper.py with CUDA-only Whisper guard."
684191
+ consensusEnabled ? "ASR consensus enabled — using live-whisper.py with CUDA-only Whisper guard." : isNemotron ? "Using managed Nemotron worker with CUDA-only guard." : "Using live-whisper.py with CUDA-only Whisper guard."
684015
684192
  );
684016
684193
  updateListenLiveState({
684017
- backend: "openai-whisper",
684018
- lastStatus: consensusEnabled ? "starting consensus Whisper backend..." : "starting CUDA Whisper backend..."
684194
+ backend: this.config.engineId,
684195
+ lastStatus: consensusEnabled ? "starting consensus Whisper backend..." : isNemotron ? "starting CUDA Nemotron backend..." : "starting CUDA Whisper backend..."
684019
684196
  });
684020
684197
  }
684021
684198
  let tc = useTranscribeCli ? await this.loadTranscribeCli() : null;
@@ -684043,7 +684220,7 @@ var init_listen = __esm({
684043
684220
  let tcUpToDate = false;
684044
684221
  try {
684045
684222
  const tcPkgPath = join135(
684046
- dirname46(__require.resolve?.("transcribe-cli/package.json") || ""),
684223
+ dirname47(__require.resolve?.("transcribe-cli/package.json") || ""),
684047
684224
  "package.json"
684048
684225
  );
684049
684226
  if (existsSync123(tcPkgPath)) {
@@ -684141,15 +684318,16 @@ var init_listen = __esm({
684141
684318
  }
684142
684319
  }
684143
684320
  if (!this.liveTranscriber) {
684144
- const scriptPath2 = await findLiveWhisperScript();
684321
+ const scriptPath2 = isNemotron ? await findLiveNemotronScript() : await findLiveWhisperScript();
684145
684322
  if (!scriptPath2) {
684146
684323
  const hint = transcribeCliError ? ` transcribe-cli error: ${transcribeCliError}` : "";
684147
- return `No transcription backend available.${hint} live-whisper.py not found.`;
684324
+ return `No transcription backend available.${hint} ${isNemotron ? "live-nemotron.py" : "live-whisper.py"} not found.`;
684148
684325
  }
684149
684326
  try {
684150
684327
  const fallback = new WhisperFallbackTranscriber(
684151
684328
  this.config.model,
684152
- scriptPath2
684329
+ scriptPath2,
684330
+ isNemotron ? "nemotron-streaming" : "openai-whisper"
684153
684331
  );
684154
684332
  usedFallback = true;
684155
684333
  fallback.on("status", (msg) => {
@@ -684188,7 +684366,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
684188
684366
  this.emit("started");
684189
684367
  this.emit("recording", true);
684190
684368
  const modeDesc = this.config.mode === "auto" ? `auto (${this.config.silenceTimeoutMs / 1e3}s timeout)` : "confirm (press Enter to submit)";
684191
- const backend = usedFallback ? "openai-whisper" : "transcribe-cli";
684369
+ const backend = usedFallback ? this.config.engineId : "transcribe-cli";
684192
684370
  updateListenLiveState({
684193
684371
  phase: "listening",
684194
684372
  backend,
@@ -684299,6 +684477,18 @@ transcribe-cli error: ${transcribeCliError}` : "";
684299
684477
  * Caller is responsible for calling .stop() when done.
684300
684478
  */
684301
684479
  async createCallTranscriber() {
684480
+ if (this.config.engineId === "vibevoice-transformers") return null;
684481
+ if (this.config.engineId === "nemotron-streaming") {
684482
+ const scriptPath3 = await findLiveNemotronScript();
684483
+ if (!scriptPath3) return null;
684484
+ try {
684485
+ const fallback = new WhisperFallbackTranscriber(this.config.model, scriptPath3, "nemotron-streaming");
684486
+ await fallback.start();
684487
+ return fallback;
684488
+ } catch {
684489
+ return null;
684490
+ }
684491
+ }
684302
684492
  const requireConsensus = asrConsensusEnabled(this.config.model);
684303
684493
  const useTranscribeCli = liveAsrUseTranscribeCli() && !requireConsensus;
684304
684494
  let tc = useTranscribeCli ? await this.loadTranscribeCli() : null;
@@ -684391,15 +684581,36 @@ transcribe-cli error: ${transcribeCliError}` : "";
684391
684581
  };
684392
684582
  }
684393
684583
  if (this.config.engineId === "nemotron-streaming") {
684394
- throw new Error("Nemotron file transcription is disabled until its managed runtime passes the hardware gate");
684584
+ const managed = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
684585
+ const result = managed.transcribeManagedNemotronFile({
684586
+ path: filePath,
684587
+ modelId: this.config.modelId,
684588
+ device: options2.device
684589
+ });
684590
+ if (outputDir2) {
684591
+ const { basename: basename47 } = await import("node:path");
684592
+ const transcriptDir = join135(outputDir2, ".omnius", "transcripts");
684593
+ mkdirSync75(transcriptDir, { recursive: true });
684594
+ writeFileSync65(join135(transcriptDir, `${basename47(filePath)}.txt`), result.text, "utf-8");
684595
+ }
684596
+ return {
684597
+ text: result.text,
684598
+ duration: result.duration,
684599
+ speakers: [],
684600
+ engineId: "nemotron-streaming",
684601
+ modelId: this.config.modelId,
684602
+ warnings: result.warnings,
684603
+ segments: []
684604
+ };
684395
684605
  }
684396
- let tc = this.config.engineId === "transcribe-cli" ? await this.loadTranscribeCli() : null;
684397
- if (this.config.engineId === "transcribe-cli" && !tc && _bgInstallPromise) {
684606
+ const useTranscribeCli = liveAsrUseTranscribeCli();
684607
+ let tc = useTranscribeCli ? await this.loadTranscribeCli() : null;
684608
+ if (useTranscribeCli && !tc && _bgInstallPromise) {
684398
684609
  await _bgInstallPromise;
684399
684610
  this.transcribeCliAvailable = null;
684400
684611
  tc = await this.loadTranscribeCli();
684401
684612
  }
684402
- if (this.config.engineId === "transcribe-cli" && !tc) {
684613
+ if (useTranscribeCli && !tc) {
684403
684614
  try {
684404
684615
  await ensureManagedTranscribeCliNode();
684405
684616
  this.transcribeCliAvailable = null;
@@ -703296,7 +703507,7 @@ var init_types3 = __esm({
703296
703507
  // packages/cli/src/tui/p2p/secret-vault.ts
703297
703508
  import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes23, scryptSync as scryptSync2, createHash as createHash55 } from "node:crypto";
703298
703509
  import { readFileSync as readFileSync106, writeFileSync as writeFileSync69, existsSync as existsSync130, mkdirSync as mkdirSync80 } from "node:fs";
703299
- import { dirname as dirname47 } from "node:path";
703510
+ import { dirname as dirname48 } from "node:path";
703300
703511
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
703301
703512
  var init_secret_vault = __esm({
703302
703513
  "packages/cli/src/tui/p2p/secret-vault.ts"() {
@@ -703502,7 +703713,7 @@ var init_secret_vault = __esm({
703502
703713
  const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
703503
703714
  const tag = cipher.getAuthTag();
703504
703715
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
703505
- const dir = dirname47(this.storePath);
703716
+ const dir = dirname48(this.storePath);
703506
703717
  if (!existsSync130(dir)) mkdirSync80(dir, { recursive: true });
703507
703718
  writeFileSync69(this.storePath, blob, { mode: 384 });
703508
703719
  }
@@ -705177,7 +705388,7 @@ __export(omnius_directory_exports, {
705177
705388
  writeTaskHandoff: () => writeTaskHandoff2
705178
705389
  });
705179
705390
  import { appendFileSync as appendFileSync15, cpSync as cpSync2, existsSync as existsSync132, mkdirSync as mkdirSync82, readFileSync as readFileSync108, writeFileSync as writeFileSync71, readdirSync as readdirSync41, statSync as statSync52, unlinkSync as unlinkSync28, openSync as openSync9, closeSync as closeSync9, renameSync as renameSync19, watch as fsWatch3 } from "node:fs";
705180
- import { join as join143, relative as relative18, basename as basename27, dirname as dirname48, resolve as resolve67 } from "node:path";
705391
+ import { join as join143, relative as relative18, basename as basename27, dirname as dirname49, resolve as resolve67 } from "node:path";
705181
705392
  import { homedir as homedir45 } from "node:os";
705182
705393
  import { createHash as createHash58 } from "node:crypto";
705183
705394
  function isGitRoot(dir) {
@@ -705242,7 +705453,7 @@ function ensureOmniusIgnored(repoRoot) {
705242
705453
  if (!gitRoot) return;
705243
705454
  const gitignorePath = findNearestExistingGitignore(repoRoot, gitRoot);
705244
705455
  if (!gitignorePath) return;
705245
- const gitignoreDir = dirname48(gitignorePath);
705456
+ const gitignoreDir = dirname49(gitignorePath);
705246
705457
  const relDir = relative18(gitignoreDir || ".", repoRoot).replace(/\\/g, "/");
705247
705458
  const ignorePattern = relDir && relDir !== "." ? `${relDir}/.omnius/` : ".omnius/";
705248
705459
  const content = readFileSync108(gitignorePath, "utf-8");
@@ -705825,7 +706036,7 @@ function pruneContextLedger(ledgerPath) {
705825
706036
  const lines = readFileSync108(ledgerPath, "utf-8").split(/\r?\n/).filter((line) => line.trim().length > 0);
705826
706037
  if (lines.length <= MAX_CONTEXT_LEDGER_LINES) return;
705827
706038
  const kept = lines.slice(-MAX_CONTEXT_LEDGER_LINES);
705828
- const archiveDir = join143(dirname48(ledgerPath), "archive");
706039
+ const archiveDir = join143(dirname49(ledgerPath), "archive");
705829
706040
  mkdirSync82(archiveDir, { recursive: true });
705830
706041
  const archivePath = join143(
705831
706042
  archiveDir,
@@ -707573,8 +707784,8 @@ var init_render2 = __esm({
707573
707784
 
707574
707785
  // packages/prompts/dist/promptLoader.js
707575
707786
  import { readFileSync as readFileSync111, existsSync as existsSync135 } from "node:fs";
707576
- import { join as join145, dirname as dirname49 } from "node:path";
707577
- import { fileURLToPath as fileURLToPath22 } from "node:url";
707787
+ import { join as join145, dirname as dirname50 } from "node:path";
707788
+ import { fileURLToPath as fileURLToPath23 } from "node:url";
707578
707789
  function resolvePromptsDir(baseDir, promptPath = "code.md") {
707579
707790
  const devPath2 = join145(baseDir, "..", "templates");
707580
707791
  const publishedPath2 = join145(baseDir, "..", "prompts", "templates");
@@ -707602,8 +707813,8 @@ var __filename4, __dirname5, PROMPTS_DIR2, cache6;
707602
707813
  var init_promptLoader2 = __esm({
707603
707814
  "packages/prompts/dist/promptLoader.js"() {
707604
707815
  "use strict";
707605
- __filename4 = fileURLToPath22(import.meta.url);
707606
- __dirname5 = dirname49(__filename4);
707816
+ __filename4 = fileURLToPath23(import.meta.url);
707817
+ __dirname5 = dirname50(__filename4);
707607
707818
  PROMPTS_DIR2 = resolvePromptsDir(__dirname5);
707608
707819
  cache6 = /* @__PURE__ */ new Map();
707609
707820
  }
@@ -707717,8 +707928,8 @@ var init_task_templates = __esm({
707717
707928
  });
707718
707929
 
707719
707930
  // packages/prompts/dist/index.js
707720
- import { join as join146, dirname as dirname50 } from "node:path";
707721
- import { fileURLToPath as fileURLToPath23 } from "node:url";
707931
+ import { join as join146, dirname as dirname51 } from "node:path";
707932
+ import { fileURLToPath as fileURLToPath24 } from "node:url";
707722
707933
  var _dir, _packageRoot;
707723
707934
  var init_dist9 = __esm({
707724
707935
  "packages/prompts/dist/index.js"() {
@@ -707727,7 +707938,7 @@ var init_dist9 = __esm({
707727
707938
  init_render2();
707728
707939
  init_task_templates();
707729
707940
  init_render2();
707730
- _dir = dirname50(fileURLToPath23(import.meta.url));
707941
+ _dir = dirname51(fileURLToPath24(import.meta.url));
707731
707942
  _packageRoot = join146(_dir, "..");
707732
707943
  }
707733
707944
  });
@@ -709125,7 +709336,7 @@ var init_braille_spinner = __esm({
709125
709336
 
709126
709337
  // packages/cli/src/tui/project-context.ts
709127
709338
  import { existsSync as existsSync137, readFileSync as readFileSync113, readdirSync as readdirSync42, mkdirSync as mkdirSync84, statSync as statSync54, writeFileSync as writeFileSync73 } from "node:fs";
709128
- import { dirname as dirname51, join as join148, basename as basename29, resolve as resolve69 } from "node:path";
709339
+ import { dirname as dirname52, join as join148, basename as basename29, resolve as resolve69 } from "node:path";
709129
709340
  import { homedir as homedir48 } from "node:os";
709130
709341
  function projectContextUrlSpanAt(text2, index) {
709131
709342
  PROJECT_CONTEXT_URL_RE.lastIndex = 0;
@@ -709199,7 +709410,7 @@ function findGitDir(repoRoot) {
709199
709410
  }
709200
709411
  return gitPath;
709201
709412
  }
709202
- const parent = dirname51(dir);
709413
+ const parent = dirname52(dir);
709203
709414
  if (parent === dir) return null;
709204
709415
  dir = parent;
709205
709416
  }
@@ -710850,7 +711061,7 @@ __export(status_bar_exports, {
710850
711061
  stripSubAgentPrefix: () => stripSubAgentPrefix,
710851
711062
  unlockFooterRedraws: () => unlockFooterRedraws
710852
711063
  });
710853
- import { basename as basename30, dirname as dirname52 } from "node:path";
711064
+ import { basename as basename30, dirname as dirname53 } from "node:path";
710854
711065
  import { readFile as readFileAsync } from "node:fs/promises";
710855
711066
  function headerButtonGlyphFg() {
710856
711067
  const a2 = tuiAccent();
@@ -715153,7 +715364,7 @@ ${CONTENT_BG_SEQ}`);
715153
715364
  if (limit <= 6) return value2.slice(-limit);
715154
715365
  const marker = "...";
715155
715366
  const leaf = basename30(value2);
715156
- const parentLeaf = basename30(dirname52(value2));
715367
+ const parentLeaf = basename30(dirname53(value2));
715157
715368
  const suffix = parentLeaf && parentLeaf !== "." && parentLeaf !== leaf ? `${parentLeaf}/${leaf}` : leaf;
715158
715369
  if (suffix.length + marker.length + 1 <= limit) {
715159
715370
  return `${marker}/${suffix}`;
@@ -717314,10 +717525,10 @@ __export(personaplex_exports, {
717314
717525
  stopPersonaPlex: () => stopPersonaPlex
717315
717526
  });
717316
717527
  import { existsSync as existsSync138, writeFileSync as writeFileSync74, readFileSync as readFileSync114, mkdirSync as mkdirSync85, copyFileSync as copyFileSync5, readdirSync as readdirSync43, statSync as statSync55 } from "node:fs";
717317
- import { join as join149, dirname as dirname53 } from "node:path";
717528
+ import { join as join149, dirname as dirname54 } from "node:path";
717318
717529
  import { homedir as homedir49 } from "node:os";
717319
717530
  import { spawn as spawn37 } from "node:child_process";
717320
- import { fileURLToPath as fileURLToPath24 } from "node:url";
717531
+ import { fileURLToPath as fileURLToPath25 } from "node:url";
717321
717532
  function personaplexPythonEnv(extra = {}) {
717322
717533
  const env2 = { ...process.env, ...extra };
717323
717534
  applyMediaCudaDeviceFilterToEnv(env2, "voice");
@@ -718124,7 +718335,7 @@ function getShippedVoicesDir() {
718124
718335
  // repo root
718125
718336
  ];
718126
718337
  try {
718127
- const modDir = dirname53(fileURLToPath24(import.meta.url));
718338
+ const modDir = dirname54(fileURLToPath25(import.meta.url));
718128
718339
  candidates.push(join149(modDir, "..", "voices", "personaplex"));
718129
718340
  candidates.push(join149(modDir, "..", "..", "..", "voices", "personaplex"));
718130
718341
  candidates.push(join149(modDir, "..", "..", "..", "..", "voices", "personaplex"));
@@ -719507,7 +719718,7 @@ async function runOptionalDepsSetup(rl) {
719507
719718
  };
719508
719719
  process.stdout.write(` ${c3.bold("Optional dependencies")}
719509
719720
  `);
719510
- process.stdout.write(` ${c3.dim("These add features (vision/OCR, voice tunnel, live transcription). You can install them now or later via the in-TUI commands.")}
719721
+ process.stdout.write(` ${c3.dim("These add features (vision/OCR, voice tunnel). You can install them now or later via the in-TUI commands.")}
719511
719722
 
719512
719723
  `);
719513
719724
  const askVision = await ask(rl, ` ${c3.bold("Install vision / OCR deps?")} (Y/n) `);
@@ -719554,31 +719765,6 @@ async function runOptionalDepsSetup(rl) {
719554
719765
  } else {
719555
719766
  process.stdout.write(` ${c3.dim("Skipped cloudflared.")}
719556
719767
 
719557
- `);
719558
- }
719559
- const askTranscribe = await ask(rl, ` ${c3.bold("Install transcribe-cli for live transcription?")} (Y/n) `);
719560
- if (askTranscribe.toLowerCase() !== "n") {
719561
- process.stdout.write(` ${c3.cyan("●")} Installing managed transcribe-cli runtime...
719562
- `);
719563
- try {
719564
- const ok3 = await ensureTranscribeCliBackground();
719565
- if (ok3) {
719566
- process.stdout.write(` ${c3.green("✔")} Transcribe-CLI installed.
719567
-
719568
- `);
719569
- } else {
719570
- process.stdout.write(` ${c3.cyan("⚠")} transcribe-cli install did not complete — live transcription will be unavailable.
719571
-
719572
- `);
719573
- }
719574
- } catch (err) {
719575
- process.stdout.write(` ${c3.cyan("⚠")} transcribe-cli install hit an error: ${err instanceof Error ? err.message : String(err)}
719576
-
719577
- `);
719578
- }
719579
- } else {
719580
- process.stdout.write(` ${c3.dim("Skipped transcribe-cli.")}
719581
-
719582
719768
  `);
719583
719769
  }
719584
719770
  }
@@ -721206,7 +721392,6 @@ var init_setup = __esm({
721206
721392
  init_config();
721207
721393
  init_dist6();
721208
721394
  init_tui_select();
721209
- init_listen();
721210
721395
  init_ollama_gpu_policy();
721211
721396
  execAsync2 = promisify8(exec5);
721212
721397
  OMNIUS_FIRST_RUN_BANNER = [
@@ -725729,7 +725914,7 @@ import {
725729
725914
  renameSync as renameSync20,
725730
725915
  unlinkSync as unlinkSync31
725731
725916
  } from "node:fs";
725732
- import { dirname as dirname54, join as join155 } from "node:path";
725917
+ import { dirname as dirname55, join as join155 } from "node:path";
725733
725918
  import { homedir as homedir52 } from "node:os";
725734
725919
  import { randomBytes as randomBytes26 } from "node:crypto";
725735
725920
  function configHome() {
@@ -725745,7 +725930,7 @@ function bootstrapApiKeyFile() {
725745
725930
  return fromEnv || join155(configHome(), "api.key");
725746
725931
  }
725747
725932
  function ensureDirFor(file) {
725748
- const dir = dirname54(file);
725933
+ const dir = dirname55(file);
725749
725934
  if (!existsSync146(dir)) mkdirSync87(dir, { recursive: true });
725750
725935
  }
725751
725936
  function atomicWritePrivateFile(file, content) {
@@ -728710,10 +728895,10 @@ import {
728710
728895
  statSync as statSync59,
728711
728896
  writeFileSync as writeFileSync80
728712
728897
  } from "node:fs";
728713
- import { dirname as dirname55, join as join160, resolve as resolve72 } from "node:path";
728898
+ import { dirname as dirname56, join as join160, resolve as resolve72 } from "node:path";
728714
728899
  import { platform as platform8 } from "node:os";
728715
728900
  import { spawn as spawn39, spawnSync as spawnSync10 } from "node:child_process";
728716
- import { fileURLToPath as fileURLToPath25 } from "node:url";
728901
+ import { fileURLToPath as fileURLToPath26 } from "node:url";
728717
728902
  function normalizeVoiceboxModelId(value2) {
728718
728903
  const normalized3 = String(value2 || "").trim().toLowerCase().replace(/-/g, "_");
728719
728904
  return MODEL_ALIASES[normalized3] ?? normalized3;
@@ -728848,7 +729033,7 @@ async function runCommand(command, args, options2 = {}) {
728848
729033
  });
728849
729034
  }
728850
729035
  function packageAssetPath(...segments) {
728851
- const moduleDir = dirname55(fileURLToPath25(import.meta.url));
729036
+ const moduleDir = dirname56(fileURLToPath26(import.meta.url));
728852
729037
  const candidates = [
728853
729038
  join160(moduleDir, "..", "assets", ...segments),
728854
729039
  join160(moduleDir, "..", "..", "assets", ...segments)
@@ -729218,7 +729403,7 @@ function writeProfileMap(value2) {
729218
729403
  if (Buffer.byteLength(serialized) > PROFILE_MAP_MAX_BYTES) {
729219
729404
  throw new Error("Voicebox profile map exceeded its bounded storage limit");
729220
729405
  }
729221
- mkdirSync91(dirname55(profileMapPath()), { recursive: true });
729406
+ mkdirSync91(dirname56(profileMapPath()), { recursive: true });
729222
729407
  const temporary = `${profileMapPath()}.tmp-${process.pid}-${Date.now()}`;
729223
729408
  writeFileSync80(temporary, serialized, { mode: 384 });
729224
729409
  renameSync21(temporary, profileMapPath());
@@ -729606,13 +729791,13 @@ import {
729606
729791
  copyFileSync as copyFileSync6,
729607
729792
  rmSync as rmSync13
729608
729793
  } from "node:fs";
729609
- import { basename as basename32, join as join161, dirname as dirname56, resolve as resolve73 } from "node:path";
729794
+ import { basename as basename32, join as join161, dirname as dirname57, resolve as resolve73 } from "node:path";
729610
729795
  import { homedir as homedir55, tmpdir as tmpdir24, platform as platform9 } from "node:os";
729611
729796
  import {
729612
729797
  spawn as nodeSpawn
729613
729798
  } from "node:child_process";
729614
729799
  import { createRequire as createRequire8 } from "node:module";
729615
- import { fileURLToPath as fileURLToPath26 } from "node:url";
729800
+ import { fileURLToPath as fileURLToPath27 } from "node:url";
729616
729801
  function voicePythonEnv(extra = {}) {
729617
729802
  const { TRANSFORMERS_CACHE: _deprecatedCache, ...baseEnv } = process.env;
729618
729803
  const { TRANSFORMERS_CACHE: _extraDeprecatedCache, ...safeExtra } = extra;
@@ -729712,7 +729897,7 @@ function luxttsInferScript2() {
729712
729897
  return join161(voiceDir2(), "luxtts-infer.py");
729713
729898
  }
729714
729899
  function resolveBundledVoiceAsset(relativePath2) {
729715
- const moduleDir = dirname56(fileURLToPath26(import.meta.url));
729900
+ const moduleDir = dirname57(fileURLToPath27(import.meta.url));
729716
729901
  const candidates = [
729717
729902
  // npm bundle: publish/dist/index.js -> publish/assets
729718
729903
  join161(moduleDir, "..", "assets", relativePath2),
@@ -729813,7 +729998,7 @@ function consolidateVoiceDirs2() {
729813
729998
  const c9 = join161(dir, ".omnius", "voice");
729814
729999
  if (existsSync152(c9) && c9 !== globalVoice) candidates.add(c9);
729815
730000
  prev = dir;
729816
- dir = dirname56(dir);
730001
+ dir = dirname57(dir);
729817
730002
  }
729818
730003
  for (const root of COMMON_PROJECT_ROOTS) {
729819
730004
  const rootDir2 = join161(homedir55(), root);
@@ -730008,7 +730193,7 @@ function insertTagAfterOpeningClause(text2, tag) {
730008
730193
  function writeDetectTorchScript(targetPath) {
730009
730194
  if (existsSync152(targetPath)) return;
730010
730195
  try {
730011
- mkdirSync92(dirname56(targetPath), { recursive: true });
730196
+ mkdirSync92(dirname57(targetPath), { recursive: true });
730012
730197
  } catch {
730013
730198
  }
730014
730199
  const script = `#!/usr/bin/env python3
@@ -734566,7 +734751,7 @@ import {
734566
734751
  appendFileSync as appendFileSync17,
734567
734752
  writeSync as writeSync5
734568
734753
  } from "node:fs";
734569
- import { basename as basename33, dirname as dirname57, relative as relative20, join as join162 } from "node:path";
734754
+ import { basename as basename33, dirname as dirname58, relative as relative20, join as join162 } from "node:path";
734570
734755
  function omniusPinnedDependencyVersion(name10) {
734571
734756
  const spec = OMNIUS_PINNED_DEPENDENCY_SPECS[name10];
734572
734757
  if (!spec) return null;
@@ -748404,7 +748589,7 @@ async function collectSponsorMediaStream(args) {
748404
748589
  }
748405
748590
  const safeName3 = basename33(artifact.filename).replace(/[^\w.-]/g, "_") || `artifact${defaultExtensionForMime(artifact.mime)}`;
748406
748591
  const outputPath3 = join162(args.outputRoot, safeName3);
748407
- mkdirSync93(dirname57(outputPath3), { recursive: true });
748592
+ mkdirSync93(dirname58(outputPath3), { recursive: true });
748408
748593
  writeFileSync82(outputPath3, bytes2);
748409
748594
  return { ok: true, path: outputPath3, metadata };
748410
748595
  }
@@ -748905,14 +749090,14 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
748905
749090
  if (models.length > 0) {
748906
749091
  try {
748907
749092
  const { writeFileSync: writeFileSync104, mkdirSync: mkdirSync120 } = await import("node:fs");
748908
- const { join: join197, dirname: dirname67 } = await import("node:path");
749093
+ const { join: join197, dirname: dirname68 } = await import("node:path");
748909
749094
  const cachePath2 = join197(
748910
749095
  ctx3.repoRoot || process.cwd(),
748911
749096
  ".omnius",
748912
749097
  "nexus",
748913
749098
  "peer-models-cache.json"
748914
749099
  );
748915
- mkdirSync120(dirname67(cachePath2), { recursive: true });
749100
+ mkdirSync120(dirname68(cachePath2), { recursive: true });
748916
749101
  writeFileSync104(
748917
749102
  cachePath2,
748918
749103
  JSON.stringify(
@@ -748988,14 +749173,14 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
748988
749173
  );
748989
749174
  try {
748990
749175
  const { writeFileSync: writeFileSync104, mkdirSync: mkdirSync120 } = await import("node:fs");
748991
- const { join: join197, dirname: dirname67 } = await import("node:path");
749176
+ const { join: join197, dirname: dirname68 } = await import("node:path");
748992
749177
  const cachePath2 = join197(
748993
749178
  ctx3.repoRoot || process.cwd(),
748994
749179
  ".omnius",
748995
749180
  "nexus",
748996
749181
  "peer-models-cache.json"
748997
749182
  );
748998
- mkdirSync120(dirname67(cachePath2), { recursive: true });
749183
+ mkdirSync120(dirname68(cachePath2), { recursive: true });
748999
749184
  writeFileSync104(
749000
749185
  cachePath2,
749001
749186
  JSON.stringify(
@@ -750021,11 +750206,11 @@ async function handleUpdate(subcommand, ctx3) {
750021
750206
  let currentVersion = "0.0.0";
750022
750207
  try {
750023
750208
  const { createRequire: createRequire12 } = await import("node:module");
750024
- const { fileURLToPath: fileURLToPath32 } = await import("node:url");
750025
- const { dirname: dirname67, join: join197 } = await import("node:path");
750209
+ const { fileURLToPath: fileURLToPath33 } = await import("node:url");
750210
+ const { dirname: dirname68, join: join197 } = await import("node:path");
750026
750211
  const { existsSync: existsSync184 } = await import("node:fs");
750027
750212
  const req3 = createRequire12(import.meta.url);
750028
- const thisDir = dirname67(fileURLToPath32(import.meta.url));
750213
+ const thisDir = dirname68(fileURLToPath33(import.meta.url));
750029
750214
  const candidates = [
750030
750215
  join197(thisDir, "..", "package.json"),
750031
750216
  join197(thisDir, "..", "..", "package.json"),
@@ -751178,9 +751363,7 @@ async function handleUpdate(subcommand, ctx3) {
751178
751363
  } else {
751179
751364
  installOverlay.setStatus("cloudflared ready");
751180
751365
  }
751181
- installOverlay.setStatus("Checking managed transcribe-cli runtime...");
751182
- await ensureTranscribeCliBackground().catch(() => false);
751183
- installOverlay.setStatus("cloudflared/transcribe checks complete");
751366
+ installOverlay.setStatus("Cloudflared checks complete");
751184
751367
  }
751185
751368
  if (!primaryUpdated) {
751186
751369
  installOverlay.stop("Done — no restart needed");
@@ -751740,7 +751923,6 @@ var init_commands = __esm({
751740
751923
  init_typed_node_events();
751741
751924
  init_platforms();
751742
751925
  init_workspace_explorer();
751743
- init_listen();
751744
751926
  init_dist6();
751745
751927
  init_tui_select();
751746
751928
  init_usage_bars();
@@ -751784,10 +751966,10 @@ var init_commands = __esm({
751784
751966
  }
751785
751967
  try {
751786
751968
  const { createRequire: createRequire12 } = await import("node:module");
751787
- const { fileURLToPath: fileURLToPath32 } = await import("node:url");
751969
+ const { fileURLToPath: fileURLToPath33 } = await import("node:url");
751788
751970
  const { dirname: pathDirname, join: pathJoin } = await import("node:path");
751789
751971
  const localRequire = createRequire12(import.meta.url);
751790
- const here = pathDirname(fileURLToPath32(import.meta.url));
751972
+ const here = pathDirname(fileURLToPath33(import.meta.url));
751791
751973
  let version5 = "?";
751792
751974
  for (const up of ["..", "../..", "../../.."]) {
751793
751975
  try {
@@ -757468,8 +757650,8 @@ Call task_complete with the JSON array when done.`,
757468
757650
 
757469
757651
  // packages/cli/src/tui/promptLoader.ts
757470
757652
  import { readFileSync as readFileSync132, existsSync as existsSync161 } from "node:fs";
757471
- import { join as join170, dirname as dirname59 } from "node:path";
757472
- import { fileURLToPath as fileURLToPath27 } from "node:url";
757653
+ import { join as join170, dirname as dirname60 } from "node:path";
757654
+ import { fileURLToPath as fileURLToPath28 } from "node:url";
757473
757655
  function loadPrompt3(promptPath, vars) {
757474
757656
  let content = cache7.get(promptPath);
757475
757657
  if (content === void 0) {
@@ -757486,8 +757668,8 @@ function loadPrompt3(promptPath, vars) {
757486
757668
  var __filename5, __dirname6, devPath, publishedPath, PROMPTS_DIR3, cache7;
757487
757669
  var init_promptLoader3 = __esm({
757488
757670
  "packages/cli/src/tui/promptLoader.ts"() {
757489
- __filename5 = fileURLToPath27(import.meta.url);
757490
- __dirname6 = dirname59(__filename5);
757671
+ __filename5 = fileURLToPath28(import.meta.url);
757672
+ __dirname6 = dirname60(__filename5);
757491
757673
  devPath = join170(__dirname6, "..", "..", "prompts");
757492
757674
  publishedPath = join170(__dirname6, "..", "prompts");
757493
757675
  PROMPTS_DIR3 = existsSync161(devPath) ? devPath : publishedPath;
@@ -762703,7 +762885,7 @@ import {
762703
762885
  import { mkdir as mkdir23 } from "node:fs/promises";
762704
762886
  import {
762705
762887
  basename as basename41,
762706
- dirname as dirname60,
762888
+ dirname as dirname61,
762707
762889
  extname as extname21,
762708
762890
  isAbsolute as isAbsolute16,
762709
762891
  join as join174,
@@ -762924,7 +763106,7 @@ function scopedTool(base3, root, mode) {
762924
763106
  guarded.path.rel
762925
763107
  );
762926
763108
  if (!materialized.ok) return denied(materialized.error);
762927
- mkdirSync102(dirname60(guarded.path.abs), { recursive: true });
763109
+ mkdirSync102(dirname61(guarded.path.abs), { recursive: true });
762928
763110
  writeFileSync90(guarded.path.abs, readFileSync135(materialized.path));
762929
763111
  materialized.cleanup?.();
762930
763112
  restoredEditPath = guarded.path.abs;
@@ -763443,7 +763625,7 @@ var init_telegram_creative_tools = __esm({
763443
763625
  stage: "setup",
763444
763626
  message: "Preparing scoped TTS audio file"
763445
763627
  });
763446
- await mkdir23(dirname60(guarded.path.abs), { recursive: true });
763628
+ await mkdir23(dirname61(guarded.path.abs), { recursive: true });
763447
763629
  const tts = new TtsGenerateTool();
763448
763630
  this.emitProgress(start2, {
763449
763631
  stage: "load",
@@ -766872,7 +767054,7 @@ import {
766872
767054
  } from "node:fs";
766873
767055
  import {
766874
767056
  join as join177,
766875
- dirname as dirname61,
767057
+ dirname as dirname62,
766876
767058
  resolve as resolve79,
766877
767059
  basename as basename43,
766878
767060
  relative as relative22,
@@ -771215,7 +771397,7 @@ ${message2}`)
771215
771397
  appendTelegramIntakeJournal(sessionKey, entry) {
771216
771398
  const write2 = async () => {
771217
771399
  const path16 = this.telegramIntakePath(sessionKey);
771218
- await mkdirAsync(dirname61(path16), { recursive: true });
771400
+ await mkdirAsync(dirname62(path16), { recursive: true });
771219
771401
  await appendFileAsync(path16, `${JSON.stringify(entry)}
771220
771402
  `, "utf8");
771221
771403
  };
@@ -786963,15 +787145,14 @@ function getDaemonListenEngine() {
786963
787145
  const settings = loadGlobalSettings();
786964
787146
  const modelId = settings.asrModel?.trim() || "medium";
786965
787147
  const whisperModels2 = /* @__PURE__ */ new Set(["tiny", "base", "small", "medium", "large-v3"]);
787148
+ const persistedEngine = settings.asrEngine?.trim() ?? "openai-whisper";
787149
+ const engineId = normalizeAsrEngineId(persistedEngine);
786966
787150
  _listenEngine = getListenEngine({
786967
- engineId: settings.asrEngine?.trim() || "openai-whisper",
787151
+ engineId,
786968
787152
  modelId,
786969
787153
  ...whisperModels2.has(modelId) ? { model: modelId } : {}
786970
787154
  });
786971
787155
  }
786972
- if (_listenEngine.currentEngine === "transcribe-cli" && !_daemonAsrBootstrap) {
786973
- _daemonAsrBootstrap = ensureTranscribeCliBackground().catch(() => false);
786974
- }
786975
787156
  return _listenEngine;
786976
787157
  }
786977
787158
  function getVoiceBus() {
@@ -787219,7 +787400,7 @@ function _resetForTests() {
787219
787400
  _shutdownTimer = null;
787220
787401
  }
787221
787402
  }
787222
- var _voiceEngine, _listenEngine, _voiceChatSession, _bus, _state3, _loadedAt, _lastError, _clients2, _ttsSpeaking, _shutdownTimer, _daemonAsrBootstrap, _runtimeLoadPromise, IDLE_SHUTDOWN_MS, _wired;
787403
+ var _voiceEngine, _listenEngine, _voiceChatSession, _bus, _state3, _loadedAt, _lastError, _clients2, _ttsSpeaking, _shutdownTimer, _runtimeLoadPromise, IDLE_SHUTDOWN_MS, _wired;
787223
787404
  var init_voice_runtime = __esm({
787224
787405
  "packages/cli/src/api/voice-runtime.ts"() {
787225
787406
  init_voice();
@@ -787237,7 +787418,6 @@ var init_voice_runtime = __esm({
787237
787418
  _clients2 = /* @__PURE__ */ new Map();
787238
787419
  _ttsSpeaking = false;
787239
787420
  _shutdownTimer = null;
787240
- _daemonAsrBootstrap = null;
787241
787421
  _runtimeLoadPromise = null;
787242
787422
  IDLE_SHUTDOWN_MS = 6e4;
787243
787423
  _wired = false;
@@ -788687,7 +788867,7 @@ var init_audit_log = __esm({
788687
788867
  // packages/cli/src/api/disk-task-output.ts
788688
788868
  import { open } from "node:fs/promises";
788689
788869
  import { existsSync as existsSync171, mkdirSync as mkdirSync108, statSync as statSync66 } from "node:fs";
788690
- import { dirname as dirname62 } from "node:path";
788870
+ import { dirname as dirname63 } from "node:path";
788691
788871
  import * as fsConstants from "node:constants";
788692
788872
  var O_NOFOLLOW2, O_APPEND2, O_CREAT2, O_WRONLY2, OPEN_FLAGS_WRITE, OPEN_MODE, DiskTaskOutput;
788693
788873
  var init_disk_task_output = __esm({
@@ -788705,7 +788885,7 @@ var init_disk_task_output = __esm({
788705
788885
  fileSize = 0;
788706
788886
  constructor(outputPath3) {
788707
788887
  this.path = outputPath3;
788708
- mkdirSync108(dirname62(outputPath3), { recursive: true });
788888
+ mkdirSync108(dirname63(outputPath3), { recursive: true });
788709
788889
  }
788710
788890
  /** Queue content for async append. Non-blocking. */
788711
788891
  append(chunk) {
@@ -808764,7 +808944,7 @@ function getOpenApiSpec() {
808764
808944
  patch: {
808765
808945
  summary: "Persist and activate an exact ASR selection",
808766
808946
  tags: ["ASR"],
808767
- description: "Body: {engineId, modelId?, setup?, device?}. Selection is validated against the registry. VibeVoice activation is CUDA-only and fail-closed; setup=true installs the pinned runtime and exact weights before activation. Hardware evidence uses nvidia-smi on discrete Linux and NVIDIA's documented tegrastats plus a CUDA Torch property probe on Jetson/L4T.",
808947
+ description: "Body: {engineId, modelId?, setup?, device?}. Selection is validated against the registry. setup=true pulls the exact managed model and verifies CUDA placement before activation. Hardware evidence uses nvidia-smi on discrete Linux and NVIDIA's documented tegrastats plus a CUDA Torch property probe on Jetson/L4T.",
808768
808948
  responses: { 200: { description: "Exact selection activated" }, 400: { description: "Unknown engine or model" }, 409: { description: "Runtime unavailable or not installed" }, 500: { description: "Setup, hardware preflight, or activation failed" } }
808769
808949
  }
808770
808950
  },
@@ -808773,11 +808953,29 @@ function getOpenApiSpec() {
808773
808953
  post: {
808774
808954
  summary: "Install a managed ASR runtime and its pinned weights",
808775
808955
  tags: ["ASR"],
808776
- description: "Currently implemented for vibevoice-transformers. The exact microsoft/VibeVoice-ASR revision and tokenizer snapshot are stored under the unified Omnius ASR model/runtime directories; model weights are never bundled into npm.",
808956
+ description: "Body: {modelId?, device?}. Installs the managed runtime and pulls the requested model. Whisper and Nemotron loads validate their selected CUDA device; VibeVoice stores its pinned model and tokenizer snapshot under Omnius' ASR runtime directories.",
808777
808957
  parameters: [{ name: "engineId", in: "path", required: true, schema: { type: "string" } }],
808778
808958
  responses: { 200: { description: "Runtime and weights ready" }, 409: { description: "Engine has no managed setup adapter" }, 500: { description: "Setup failed" } }
808779
808959
  }
808780
808960
  },
808961
+ "/v1/asr/engines/{engineId}/models/{modelId}/pull": {
808962
+ post: {
808963
+ summary: "Pull one exact ASR model and validate its managed runtime",
808964
+ tags: ["ASR"],
808965
+ description: "Optional body: {device}. Downloads model weights into Omnius-managed storage and verifies CUDA placement for Whisper and Nemotron.",
808966
+ parameters: [{ name: "engineId", in: "path", required: true, schema: { type: "string" } }, { name: "modelId", in: "path", required: true, schema: { type: "string" } }],
808967
+ responses: { 200: { description: "Weights are ready" }, 500: { description: "Runtime, download, or CUDA validation failed" } }
808968
+ }
808969
+ },
808970
+ "/v1/asr/engines/{engineId}/models/{modelId}/deploy": {
808971
+ post: {
808972
+ summary: "Pull, select, and activate one exact ASR model",
808973
+ tags: ["ASR"],
808974
+ description: "Optional body: {device}. Persists the selection after the managed runtime and weights are ready.",
808975
+ parameters: [{ name: "engineId", in: "path", required: true, schema: { type: "string" } }, { name: "modelId", in: "path", required: true, schema: { type: "string" } }],
808976
+ responses: { 200: { description: "Model deployed and selected" }, 500: { description: "Deploy or CUDA validation failed" } }
808977
+ }
808978
+ },
808781
808979
  "/v1/voice/asr-models": { get: { summary: "Compatibility alias of GET /v1/asr/engines", tags: ["ASR"], responses: { 200: { description: "Canonical ASR registry plus legacy model projection" } } } },
808782
808980
  "/v1/voice/asr-models/switch": { post: { summary: "Compatibility alias of POST /v1/asr/activate", tags: ["ASR"], responses: { 200: { description: "Exact selection activated" }, 400: { description: "Unknown selection" }, 409: { description: "Runtime unavailable" }, 500: { description: "Activation failed" } } } },
808783
808981
  "/v1/voice/tts": {
@@ -809452,9 +809650,9 @@ var init_chat_followup = __esm({
809452
809650
  // packages/cli/src/docker.ts
809453
809651
  import { execSync as execSync38, spawn as spawn41 } from "node:child_process";
809454
809652
  import { existsSync as existsSync179, mkdirSync as mkdirSync114, writeFileSync as writeFileSync98 } from "node:fs";
809455
- import { join as join188, resolve as resolve82, dirname as dirname63 } from "node:path";
809653
+ import { join as join188, resolve as resolve82, dirname as dirname64 } from "node:path";
809456
809654
  import { homedir as homedir64 } from "node:os";
809457
- import { fileURLToPath as fileURLToPath28 } from "node:url";
809655
+ import { fileURLToPath as fileURLToPath29 } from "node:url";
809458
809656
  function getDockerDir() {
809459
809657
  try {
809460
809658
  if (typeof __dirname !== "undefined") {
@@ -809463,7 +809661,7 @@ function getDockerDir() {
809463
809661
  } catch {
809464
809662
  }
809465
809663
  try {
809466
- const thisDir = dirname63(fileURLToPath28(import.meta.url));
809664
+ const thisDir = dirname64(fileURLToPath29(import.meta.url));
809467
809665
  return join188(thisDir, "..", "..", "..", "docker");
809468
809666
  } catch {
809469
809667
  }
@@ -809929,8 +810127,8 @@ __export(serve_exports, {
809929
810127
  import * as http5 from "node:http";
809930
810128
  import * as https3 from "node:https";
809931
810129
  import { createRequire as createRequire9 } from "node:module";
809932
- import { fileURLToPath as fileURLToPath29 } from "node:url";
809933
- import { dirname as dirname64, join as join190, resolve as resolve83 } from "node:path";
810130
+ import { fileURLToPath as fileURLToPath30 } from "node:url";
810131
+ import { dirname as dirname65, join as join190, resolve as resolve83 } from "node:path";
809934
810132
  import { homedir as homedir65 } from "node:os";
809935
810133
  import { spawn as spawn42, execSync as execSync39 } from "node:child_process";
809936
810134
  import {
@@ -809959,7 +810157,7 @@ function memoryDbPaths3(baseDir = process.cwd()) {
809959
810157
  }
809960
810158
  function readServerPackageIdentity() {
809961
810159
  try {
809962
- const thisDir = dirname64(fileURLToPath29(import.meta.url));
810160
+ const thisDir = dirname65(fileURLToPath30(import.meta.url));
809963
810161
  const candidates = [
809964
810162
  join190(thisDir, "..", "package.json"),
809965
810163
  join190(thisDir, "..", "..", "package.json"),
@@ -813777,7 +813975,7 @@ async function handleV1Update(req3, res, requestId) {
813777
813975
  );
813778
813976
  const fs14 = require4("node:fs");
813779
813977
  const nodeBin = process.execPath;
813780
- const nodeDir = dirname64(nodeBin);
813978
+ const nodeDir = dirname65(nodeBin);
813781
813979
  const { execSync: es } = require4("node:child_process");
813782
813980
  const isWin2 = process.platform === "win32";
813783
813981
  let npmBin = "";
@@ -813792,7 +813990,7 @@ async function handleV1Update(req3, res, requestId) {
813792
813990
  const dir = join190(homedir65(), ".omnius");
813793
813991
  fs14.mkdirSync(dir, { recursive: true });
813794
813992
  const logFd = fs14.openSync(logPath3, "w");
813795
- const npmPrefix = dirname64(nodeDir);
813993
+ const npmPrefix = dirname65(nodeDir);
813796
813994
  let globalBinDir = "";
813797
813995
  try {
813798
813996
  if (isWin2) {
@@ -816780,16 +816978,13 @@ data: ${JSON.stringify(data)}
816780
816978
  const engines = listAsrEngines().map((engine) => {
816781
816979
  const selected = engine.id === listen.currentEngine;
816782
816980
  const unavailableReason = getAsrEngineUnavailableReason(engine.id);
816981
+ const selectedModel = selected ? listen.currentModel : engine.models[0]?.id;
816783
816982
  const readiness = unavailableReason ? {
816784
816983
  installed: false,
816785
816984
  weightsReady: false,
816786
816985
  active: false,
816787
816986
  lastError: unavailableReason
816788
- } : engine.id === "vibevoice-transformers" ? vibe : {
816789
- installed: true,
816790
- weightsReady: true,
816791
- active: selected && listen.isActive
816792
- };
816987
+ } : engine.id === "vibevoice-transformers" ? vibe : getManagedAsrReadiness(engine.id, selectedModel ?? engine.models[0].id);
816793
816988
  return {
816794
816989
  ...engine,
816795
816990
  availability: unavailableReason ? "disabled" : "available",
@@ -816798,6 +816993,7 @@ data: ${JSON.stringify(data)}
816798
816993
  readiness,
816799
816994
  models: engine.models.map((model) => ({
816800
816995
  ...model,
816996
+ readiness: engine.id === "vibevoice-transformers" ? vibe : getManagedAsrReadiness(engine.id, model.id),
816801
816997
  selected: selected && model.id === listen.currentModel,
816802
816998
  isActive: selected && model.id === listen.currentModel && readiness.active
816803
816999
  }))
@@ -816823,35 +817019,76 @@ data: ${JSON.stringify(data)}
816823
817019
  modelId: listen.currentModel
816824
817020
  },
816825
817021
  state: getRuntimeStatus(),
816826
- vibevoice: getVibeVoiceAsrReadiness()
817022
+ vibevoice: getVibeVoiceAsrReadiness(),
817023
+ runtimes: listAsrEngines().filter((engine) => engine.id === "openai-whisper" || engine.id === "nemotron-streaming").flatMap((engine) => engine.models.map((model) => getManagedAsrReadiness(engine.id, model.id)))
816827
817024
  });
816828
817025
  return;
816829
817026
  }
817027
+ const asrPullMatch = pathname.match(/^\/v1\/asr\/engines\/([^/]+)\/models\/([^/]+)\/pull$/);
817028
+ if (asrPullMatch && method === "POST") {
817029
+ const engineId = decodeURIComponent(asrPullMatch[1] || "");
817030
+ const modelId = decodeURIComponent(asrPullMatch[2] || "");
817031
+ const body = await parseJsonBody(req3);
817032
+ try {
817033
+ const selection = resolveAsrSelection({ engineId, modelId });
817034
+ const readiness = selection.engineId === "vibevoice-transformers" ? (await ensureVibeVoiceAsrSetup(), getVibeVoiceAsrReadiness()) : ensureManagedAsrModel({ ...selection, device: body?.device });
817035
+ jsonResponse(res, 200, { ok: true, action: "pull", selection, readiness });
817036
+ } catch (err) {
817037
+ jsonResponse(res, 500, {
817038
+ error: "asr_pull_failed",
817039
+ engineId,
817040
+ modelId,
817041
+ message: err instanceof Error ? err.message : String(err)
817042
+ });
817043
+ }
817044
+ return;
817045
+ }
817046
+ const asrDeployMatch = pathname.match(/^\/v1\/asr\/engines\/([^/]+)\/models\/([^/]+)\/deploy$/);
817047
+ if (asrDeployMatch && method === "POST") {
817048
+ const engineId = decodeURIComponent(asrDeployMatch[1] || "");
817049
+ const modelId = decodeURIComponent(asrDeployMatch[2] || "");
817050
+ const body = await parseJsonBody(req3);
817051
+ try {
817052
+ const selection = resolveAsrSelection({ engineId, modelId });
817053
+ const activated = await getDaemonListenEngine().activateSelection(selection, {
817054
+ setup: true,
817055
+ device: body?.device
817056
+ });
817057
+ saveGlobalSettings({ asrEngine: activated.selection.engineId, asrModel: activated.selection.modelId });
817058
+ jsonResponse(res, 200, { ok: true, action: "deploy", ...activated, state: getRuntimeStatus() });
817059
+ } catch (err) {
817060
+ jsonResponse(res, 500, {
817061
+ error: "asr_deploy_failed",
817062
+ engineId,
817063
+ modelId,
817064
+ message: err instanceof Error ? err.message : String(err)
817065
+ });
817066
+ }
817067
+ return;
817068
+ }
816830
817069
  const asrSetupMatch = pathname.match(/^\/v1\/asr\/engines\/([^/]+)\/setup$/);
816831
817070
  if (asrSetupMatch && method === "POST") {
816832
817071
  const engineId = decodeURIComponent(asrSetupMatch[1] || "");
816833
- if (engineId !== "vibevoice-transformers") {
816834
- jsonResponse(res, 409, {
816835
- error: "setup_not_managed_here",
817072
+ const body = await parseJsonBody(req3);
817073
+ try {
817074
+ const current = getDaemonListenEngine();
817075
+ const selection = resolveAsrSelection({
816836
817076
  engineId,
816837
- message: "Only the VibeVoice managed setup is exposed by this endpoint in this release."
817077
+ modelId: body?.modelId ?? body?.model ?? (current.currentEngine === engineId ? current.currentModel : void 0)
816838
817078
  });
816839
- return;
816840
- }
816841
- try {
816842
- await ensureVibeVoiceAsrSetup();
817079
+ const readiness = selection.engineId === "vibevoice-transformers" ? (await ensureVibeVoiceAsrSetup(), getVibeVoiceAsrReadiness()) : ensureManagedAsrModel({ ...selection, device: body?.device });
816843
817080
  jsonResponse(res, 200, {
816844
817081
  ok: true,
816845
- engineId,
816846
- readiness: getVibeVoiceAsrReadiness(),
816847
- plan: getVibeVoiceAsrSetupPlan()
817082
+ selection,
817083
+ readiness,
817084
+ ...selection.engineId === "vibevoice-transformers" ? { plan: getVibeVoiceAsrSetupPlan() } : {}
816848
817085
  });
816849
817086
  } catch (err) {
816850
817087
  jsonResponse(res, 500, {
816851
817088
  error: "asr_setup_failed",
816852
817089
  engineId,
816853
817090
  message: err instanceof Error ? err.message : String(err),
816854
- readiness: getVibeVoiceAsrReadiness()
817091
+ readiness: engineId === "vibevoice-transformers" ? getVibeVoiceAsrReadiness() : void 0
816855
817092
  });
816856
817093
  }
816857
817094
  return;
@@ -820961,6 +821198,7 @@ var init_serve = __esm({
820961
821198
  init_project_preferences();
820962
821199
  init_internal_output();
820963
821200
  init_voice_runtime();
821201
+ init_py_embed();
820964
821202
  init_voice();
820965
821203
  init_voicebox();
820966
821204
  init_audit_log();
@@ -821150,9 +821388,9 @@ var init_clipboard_media = __esm({
821150
821388
 
821151
821389
  // packages/cli/src/tui/interactive.ts
821152
821390
  import { cwd } from "node:process";
821153
- import { resolve as resolve84, join as join192, dirname as dirname65, extname as extname23, relative as relative23, sep as sep10 } from "node:path";
821391
+ import { resolve as resolve84, join as join192, dirname as dirname66, extname as extname23, relative as relative23, sep as sep10 } from "node:path";
821154
821392
  import { createRequire as createRequire10 } from "node:module";
821155
- import { fileURLToPath as fileURLToPath30 } from "node:url";
821393
+ import { fileURLToPath as fileURLToPath31 } from "node:url";
821156
821394
  import { createHash as createHash68 } from "node:crypto";
821157
821395
  import {
821158
821396
  readFileSync as readFileSync149,
@@ -821211,7 +821449,7 @@ function formatTimeAgo2(date) {
821211
821449
  function getVersion4() {
821212
821450
  try {
821213
821451
  const require5 = createRequire10(import.meta.url);
821214
- const thisDir = dirname65(fileURLToPath30(import.meta.url));
821452
+ const thisDir = dirname66(fileURLToPath31(import.meta.url));
821215
821453
  const candidates = [
821216
821454
  join192(thisDir, "..", "package.json"),
821217
821455
  join192(thisDir, "..", "..", "package.json"),
@@ -833541,7 +833779,7 @@ var init_config6 = __esm({
833541
833779
  // -- Voice & audio --
833542
833780
  voice: "Enable TTS voice feedback (true/false)",
833543
833781
  voiceModel: "TTS voice model id (built-in, LuxTTS clone, Supertonic, MisoTTS, or selected Voicebox model)",
833544
- asrEngine: "ASR engine id (openai-whisper, transcribe-cli, nemotron-streaming, vibevoice-transformers)",
833782
+ asrEngine: "ASR engine id (openai-whisper, nemotron-streaming, vibevoice-transformers)",
833545
833783
  asrModel: "Exact model id within the selected ASR engine",
833546
833784
  // -- Agent autonomy --
833547
833785
  commandsMode: "Agent slash-command access: auto (agent can invoke) or manual (user-only)",
@@ -833958,8 +834196,8 @@ init_updater();
833958
834196
  init_typed_node_events();
833959
834197
  init_dist5();
833960
834198
  import { parseArgs as nodeParseArgs2 } from "node:util";
833961
- import { fileURLToPath as fileURLToPath31 } from "node:url";
833962
- import { dirname as dirname66, join as join196 } from "node:path";
834199
+ import { fileURLToPath as fileURLToPath32 } from "node:url";
834200
+ import { dirname as dirname67, join as join196 } from "node:path";
833963
834201
  import { createRequire as createRequire11 } from "node:module";
833964
834202
 
833965
834203
  // packages/cli/src/cli.ts
@@ -834128,7 +834366,7 @@ init_output();
834128
834366
  function getVersion5() {
834129
834367
  try {
834130
834368
  const require5 = createRequire11(import.meta.url);
834131
- const pkgPath = join196(dirname66(fileURLToPath31(import.meta.url)), "..", "package.json");
834369
+ const pkgPath = join196(dirname67(fileURLToPath32(import.meta.url)), "..", "package.json");
834132
834370
  const pkg = require5(pkgPath);
834133
834371
  return pkg.version;
834134
834372
  } catch {