omnius 1.0.616 → 1.0.618

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
@@ -602265,18 +602265,34 @@ function getAsrEngine(engineId) {
602265
602265
  function getAsrModel(engineId, modelId) {
602266
602266
  return getAsrEngine(engineId)?.models.find((model) => model.id === modelId.trim().toLowerCase());
602267
602267
  }
602268
- function resolveAsrSelection(input) {
602269
- const engineId = normalizeAsrEngineId(input?.engineId || "openai-whisper");
602268
+ function findAsrEnginesForModel(modelId) {
602269
+ const wanted = String(modelId || "").trim().toLowerCase();
602270
+ if (!wanted)
602271
+ return [];
602272
+ return ASR_ENGINES.filter((engine) => engine.models.some((model) => model.id === wanted));
602273
+ }
602274
+ function getAsrEngineUnavailableReason(engineId) {
602270
602275
  const engine = getAsrEngine(engineId);
602271
- if (!engine)
602276
+ return engine?.availability === "disabled" ? engine.unavailableReason ?? `ASR engine ${engine.id} is disabled.` : void 0;
602277
+ }
602278
+ function resolveAsrSelection(input, options2 = {}) {
602279
+ const requestedEngineId = normalizeAsrEngineId(input?.engineId || "openai-whisper");
602280
+ const requestedEngine = getAsrEngine(requestedEngineId);
602281
+ if (!requestedEngine)
602272
602282
  throw new Error(`Unknown ASR engine: ${input?.engineId || ""}`);
602273
- const modelId = String(input?.modelId || engine.models[0]?.id || "").trim().toLowerCase();
602274
- if (!getAsrModel(engineId, modelId)) {
602275
- throw new Error(`Unknown ASR model ${modelId || "(empty)"} for engine ${engineId}`);
602283
+ const modelId = String(input?.modelId || requestedEngine.models[0]?.id || "").trim().toLowerCase();
602284
+ if (getAsrModel(requestedEngineId, modelId)) {
602285
+ return { engineId: requestedEngineId, modelId };
602286
+ }
602287
+ const owners = findAsrEnginesForModel(modelId);
602288
+ if (options2.inferEngineFromModel && owners.length === 1) {
602289
+ return { engineId: owners[0].id, modelId };
602276
602290
  }
602277
- return { engineId, modelId };
602291
+ const known = requestedEngine.models.map((model) => model.id).join(", ");
602292
+ const hint = owners.length === 1 ? ` That model belongs to engine ${owners[0].id}; send engineId with it.` : owners.length > 1 ? ` That model id is shared by engines ${owners.map((engine) => engine.id).join(", ")}; send engineId to disambiguate.` : "";
602293
+ throw new Error(`Unknown ASR model ${modelId || "(empty)"} for engine ${requestedEngineId}.${hint} Known models for ${requestedEngineId}: ${known}.`);
602278
602294
  }
602279
- var VIBEVOICE_ASR_MODEL_REVISION, VIBEVOICE_ASR_SOURCE_REVISION, VIBEVOICE_ASR_QWEN_TOKENIZER_REVISION, VIBEVOICE_ASR_WEIGHTS_BYTES, whisperCapabilities, WHISPER_MODEL_IDS, whisperModels, ASR_ENGINES, ENGINE_ALIASES;
602295
+ var VIBEVOICE_ASR_MODEL_REVISION, VIBEVOICE_ASR_SOURCE_REVISION, VIBEVOICE_ASR_QWEN_TOKENIZER_REVISION, VIBEVOICE_ASR_WEIGHTS_BYTES, NEMOTRON_DISABLED_REASON, whisperCapabilities, WHISPER_MODEL_IDS, whisperModels, ASR_ENGINES, ENGINE_ALIASES;
602280
602296
  var init_registry2 = __esm({
602281
602297
  "packages/execution/dist/asr/registry.js"() {
602282
602298
  "use strict";
@@ -602284,6 +602300,7 @@ var init_registry2 = __esm({
602284
602300
  VIBEVOICE_ASR_SOURCE_REVISION = "94da20d98b2fa7688e9cbfaf7692ddb4954f7600";
602285
602301
  VIBEVOICE_ASR_QWEN_TOKENIZER_REVISION = "d149729398750b98c0af14eb82c78cfe92750796";
602286
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.";
602287
602304
  whisperCapabilities = Object.freeze({
602288
602305
  file: true,
602289
602306
  pcmStream: true,
@@ -602324,6 +602341,8 @@ var init_registry2 = __esm({
602324
602341
  provider: "NVIDIA",
602325
602342
  runtime: "python",
602326
602343
  setupMode: "managed",
602344
+ availability: "disabled",
602345
+ unavailableReason: NEMOTRON_DISABLED_REASON,
602327
602346
  models: [
602328
602347
  {
602329
602348
  id: "nemotron-speech-streaming-en-0.6b",
@@ -603250,7 +603269,7 @@ print(json.dumps({"ok": False, "error": "No whisper backend available"}))
603250
603269
  backend: "nemotron",
603251
603270
  text: "",
603252
603271
  latencyMs: Math.round(performance.now() - t0),
603253
- error: "Nemotron is catalogued but its legacy self-installing worker is disabled until it is migrated to the managed fail-closed runtime."
603272
+ error: NEMOTRON_DISABLED_REASON
603254
603273
  };
603255
603274
  }
603256
603275
  };
@@ -611906,6 +611925,7 @@ __export(dist_exports2, {
611906
611925
  ModelBroker: () => ModelBroker,
611907
611926
  ModelGenerateTool: () => ModelGenerateTool,
611908
611927
  MultimodalMemoryTool: () => MultimodalMemoryTool,
611928
+ NEMOTRON_DISABLED_REASON: () => NEMOTRON_DISABLED_REASON,
611909
611929
  NetworkEgressPolicyError: () => NetworkEgressPolicyError,
611910
611930
  NexusTool: () => NexusTool,
611911
611931
  NotebookEditTool: () => NotebookEditTool,
@@ -612115,6 +612135,7 @@ __export(dist_exports2, {
612115
612135
  failureClassCounts: () => failureClassCounts,
612116
612136
  fetchHuggingFaceModelInfo: () => fetchHuggingFaceModelInfo,
612117
612137
  fetchWithNetworkEgressPolicy: () => fetchWithNetworkEgressPolicy,
612138
+ findAsrEnginesForModel: () => findAsrEnginesForModel,
612118
612139
  findNonGatedAudioFallback: () => findNonGatedAudioFallback,
612119
612140
  findNonGatedImageFallback: () => findNonGatedImageFallback,
612120
612141
  findNonGatedVideoFallback: () => findNonGatedVideoFallback,
@@ -612134,6 +612155,7 @@ __export(dist_exports2, {
612134
612155
  getAllConstraints: () => getAllConstraints,
612135
612156
  getAllFullSubAgents: () => getAllFullSubAgents,
612136
612157
  getAsrEngine: () => getAsrEngine,
612158
+ getAsrEngineUnavailableReason: () => getAsrEngineUnavailableReason,
612137
612159
  getAsrModel: () => getAsrModel,
612138
612160
  getAudioGenerationPreset: () => getAudioGenerationPreset,
612139
612161
  getCodeGraphDB: () => getCodeGraphDB,
@@ -679176,6 +679198,8 @@ __export(daemon_exports, {
679176
679198
  getDaemonStatus: () => getDaemonStatus,
679177
679199
  getLocalCliVersion: () => getLocalCliVersion,
679178
679200
  isDaemonRunning: () => isDaemonRunning,
679201
+ managedDaemonServiceOwnsPort: () => managedDaemonServiceOwnsPort,
679202
+ pidIsInManagedDaemonUnit: () => pidIsInManagedDaemonUnit,
679179
679203
  quiesceDaemonForUpdate: () => quiesceDaemonForUpdate,
679180
679204
  reclaimOwnedDaemonListener: () => reclaimOwnedDaemonListener,
679181
679205
  recoverDaemonVersionBoundedly: () => recoverDaemonVersionBoundedly,
@@ -679420,6 +679444,27 @@ async function managedDaemonServiceMatchesPort(port) {
679420
679444
  if (environment === null) return false;
679421
679445
  return daemonServiceMatchesPort(port, environment);
679422
679446
  }
679447
+ function pidIsInManagedDaemonUnit(pid, readCgroup = defaultReadProcCgroup) {
679448
+ const cgroup = readCgroup(pid);
679449
+ return cgroup === null ? false : cgroup.includes("omnius-daemon.service");
679450
+ }
679451
+ function defaultReadProcCgroup(pid) {
679452
+ try {
679453
+ return readFileSync95(`/proc/${pid}/cgroup`, "utf8");
679454
+ } catch {
679455
+ return null;
679456
+ }
679457
+ }
679458
+ async function managedDaemonServiceOwnsPort(port, dependencies = {
679459
+ holderPids: (value2) => portHolderPids(value2),
679460
+ pidInUnit: (pid) => pidIsInManagedDaemonUnit(pid)
679461
+ }) {
679462
+ const holders = await dependencies.holderPids(port);
679463
+ if (holders === null) return false;
679464
+ const uniqueHolders = [...new Set(holders.filter((pid) => pid > 0 && pid !== process.pid))];
679465
+ if (uniqueHolders.length === 0) return true;
679466
+ return uniqueHolders.every((pid) => dependencies.pidInUnit(pid));
679467
+ }
679423
679468
  async function managedDaemonServicePort() {
679424
679469
  if (!await hasManagedDaemonService()) return null;
679425
679470
  const environment = await readUserSystemctl([
@@ -679696,6 +679741,11 @@ async function restartDaemon(port, expectedVersion) {
679696
679741
  const p2 = port ?? getDaemonPort();
679697
679742
  const managed = await managedDaemonServiceMatchesPort(p2);
679698
679743
  if (managed) {
679744
+ if (!await managedDaemonServiceOwnsPort(p2)) {
679745
+ const reclaimed = await reclaimOwnedDaemonListener(p2);
679746
+ if (!reclaimed.ok) return false;
679747
+ await reclaimStaleDaemonEndpointClaim(p2);
679748
+ }
679699
679749
  const restarted = await runUserSystemctl(["restart", "omnius-daemon.service"]);
679700
679750
  if (restarted.ok && (await waitForDaemonReady(p2, expectedVersion)).ok) return true;
679701
679751
  const repaired = await repairManagedDaemonUnit(p2);
@@ -679881,7 +679931,7 @@ async function stopDaemonAtPort(port = getDaemonPort()) {
679881
679931
  async function quiesceDaemonForUpdate(port = getDaemonPort()) {
679882
679932
  if (await managedDaemonServiceMatchesPort(port)) {
679883
679933
  const stopped = await runUserSystemctl(["stop", "omnius-daemon.service"]);
679884
- return stopped.ok && await waitForDaemonStopped(port);
679934
+ if (stopped.ok && await waitForDaemonStopped(port)) return true;
679885
679935
  }
679886
679936
  if (!await isDaemonRunning(port)) {
679887
679937
  return daemonPortIsFree(port);
@@ -680001,6 +680051,13 @@ async function ensureDaemonVersion(expectedVersion = getLocalCliVersion(), port
680001
680051
  return finish(false, "failed", null, 0, process.platform === "linux");
680002
680052
  }
680003
680053
  getDaemonPid();
680054
+ if (await managedDaemonServiceMatchesPort(port)) {
680055
+ const started = await runUserSystemctl(["start", "omnius-daemon.service"]);
680056
+ if (started.ok) {
680057
+ const ready2 = await waitForDaemonReady(port, expectedVersion);
680058
+ if (ready2.ok) return finish(true, "started", ready2.observedVersion);
680059
+ }
680060
+ }
680004
680061
  const pid = await startDaemon(port);
680005
680062
  if (!pid) {
680006
680063
  for (let i2 = 0; i2 < 20; i2++) {
@@ -683735,11 +683792,8 @@ var init_listen = __esm({
683735
683792
  throw error;
683736
683793
  }
683737
683794
  }
683738
- if (selection.engineId === "nemotron-streaming") {
683739
- throw new Error(
683740
- "Nemotron is catalogued but its legacy self-installing worker is disabled until it is migrated to the managed fail-closed runtime."
683741
- );
683742
- }
683795
+ const unavailableReason = getAsrEngineUnavailableReason(selection.engineId);
683796
+ if (unavailableReason) throw new Error(unavailableReason);
683743
683797
  const whisperModel2 = selection.modelId;
683744
683798
  if (wasActive) await this.stop();
683745
683799
  if (previous.engineId === "vibevoice-transformers") await stopVibeVoiceAsr();
@@ -751155,17 +751209,12 @@ async function handleUpdate(subcommand, ctx3) {
751155
751209
  daemonUpgrade = await ensureDaemonVersion2(expectedDaemonVersion);
751156
751210
  }
751157
751211
  }
751158
- if (!daemonUpgrade.ok) {
751159
- installOverlay.stop("Update installed, but daemon upgrade was not verified");
751160
- await new Promise((r2) => setTimeout(r2, 1200));
751161
- installOverlay.dismiss();
751162
- renderError(
751163
- `Updated CLI to ${expectedDaemonVersion}, but the shared daemon still reports ${daemonUpgrade.observedVersion ?? "unavailable"} after ${daemonUpgrade.recoveryAttempts} verified recovery round(s). A privileged owner was ${daemonUpgrade.requiresPrivilegedMigration ? "not safely migratable" : "not detected"}; no arbitrary port holder was terminated.`
751164
- );
751165
- return;
751212
+ const daemonUpgradeFailure = daemonUpgrade.ok ? null : `The shared daemon still reports ${daemonUpgrade.observedVersion ?? "unavailable"} after ${daemonUpgrade.recoveryAttempts} verified recovery round(s). A privileged owner was ${daemonUpgrade.requiresPrivilegedMigration ? "not safely migratable" : "not detected"}; no arbitrary port holder was terminated. Restarting this session on ${expectedDaemonVersion} anyway — run /daemon restart to retry the daemon.`;
751213
+ if (daemonUpgradeFailure) {
751214
+ renderWarning(daemonUpgradeFailure);
751166
751215
  }
751167
751216
  installOverlay.setStatus(
751168
- daemonUpgrade.action === "restarted" ? `Daemon upgraded to ${expectedDaemonVersion}` : `Daemon verified at ${expectedDaemonVersion}`
751217
+ !daemonUpgrade.ok ? `Daemon still at ${daemonUpgrade.observedVersion ?? "unknown"} — restarting client anyway` : daemonUpgrade.action === "restarted" ? `Daemon upgraded to ${expectedDaemonVersion}` : `Daemon verified at ${expectedDaemonVersion}`
751169
751218
  );
751170
751219
  ctx3.contextSave?.();
751171
751220
  const hadActiveTask = ctx3.savePendingTaskState?.() ?? false;
@@ -805719,7 +805768,7 @@ async function loadAsrEngines() {
805719
805768
  _asrSelection = data.selection || null;
805720
805769
  engineSelect.innerHTML = _asrEngines.map(engine =>
805721
805770
  '<option value="' + escAttr(engine.id) + '"' + (engine.id === _asrSelection?.engineId ? ' selected' : '') + '>' +
805722
- escHtml(engine.label) + '</option>'
805771
+ escHtml(engine.label) + (engine.availability === 'disabled' ? ' (unavailable)' : '') + '</option>'
805723
805772
  ).join('');
805724
805773
  renderAsrModelSelect();
805725
805774
  } catch (error) {
@@ -805749,13 +805798,23 @@ window.renderAsrModelSelect = renderAsrModelSelect;
805749
805798
  function renderAsrStatus(engine, error) {
805750
805799
  const host = document.getElementById('voice-asr-status');
805751
805800
  const setupButton = document.getElementById('voice-asr-setup-btn');
805801
+ const activateButton = document.getElementById('voice-asr-activate-btn');
805752
805802
  if (!host) return;
805753
805803
  if (error || !engine) {
805754
805804
  host.style.borderLeftColor = 'var(--color-error)';
805755
805805
  host.textContent = error || 'No ASR engine selected';
805756
805806
  if (setupButton) setupButton.style.display = 'none';
805807
+ if (activateButton) activateButton.disabled = false;
805757
805808
  return;
805758
805809
  }
805810
+ if (engine.availability === 'disabled') {
805811
+ host.style.borderLeftColor = 'var(--color-error)';
805812
+ host.textContent = 'unavailable · ' + (engine.unavailableReason || 'this engine cannot be activated');
805813
+ if (setupButton) setupButton.style.display = 'none';
805814
+ if (activateButton) activateButton.disabled = true;
805815
+ return;
805816
+ }
805817
+ if (activateButton) activateButton.disabled = false;
805759
805818
  const readiness = engine.readiness || {};
805760
805819
  const model = (engine.models || []).find(item => item.id === document.getElementById('voice-asr-model-select')?.value) || engine.models?.[0];
805761
805820
  const caps = model?.capabilities || {};
@@ -805787,6 +805846,11 @@ async function activateSelectedAsr() {
805787
805846
  const engineId = document.getElementById('voice-asr-engine-select')?.value;
805788
805847
  const modelId = document.getElementById('voice-asr-model-select')?.value;
805789
805848
  if (!engineId || !modelId) return;
805849
+ const engine = selectedAsrEngine();
805850
+ if (engine?.availability === 'disabled') {
805851
+ alert('ASR engine unavailable: ' + (engine.unavailableReason || engine.id));
805852
+ return;
805853
+ }
805790
805854
  const button = document.getElementById('voice-asr-activate-btn');
805791
805855
  if (button) { button.disabled = true; button.textContent = 'activating…'; }
805792
805856
  try {
@@ -816715,13 +816779,21 @@ data: ${JSON.stringify(data)}
816715
816779
  const vibe = getVibeVoiceAsrReadiness();
816716
816780
  const engines = listAsrEngines().map((engine) => {
816717
816781
  const selected = engine.id === listen.currentEngine;
816718
- const readiness = engine.id === "vibevoice-transformers" ? vibe : {
816782
+ const unavailableReason = getAsrEngineUnavailableReason(engine.id);
816783
+ const readiness = unavailableReason ? {
816784
+ installed: false,
816785
+ weightsReady: false,
816786
+ active: false,
816787
+ lastError: unavailableReason
816788
+ } : engine.id === "vibevoice-transformers" ? vibe : {
816719
816789
  installed: true,
816720
816790
  weightsReady: true,
816721
816791
  active: selected && listen.isActive
816722
816792
  };
816723
816793
  return {
816724
816794
  ...engine,
816795
+ availability: unavailableReason ? "disabled" : "available",
816796
+ unavailableReason,
816725
816797
  selected,
816726
816798
  readiness,
816727
816799
  models: engine.models.map((model) => ({
@@ -816787,16 +816859,39 @@ data: ${JSON.stringify(data)}
816787
816859
  if ((pathname === "/v1/asr/selection" || pathname === "/v1/asr/activate" || pathname === "/v1/voice/asr-models/switch") && (method === "POST" || method === "PATCH")) {
816788
816860
  const body = await parseJsonBody(req3);
816789
816861
  const current = getDaemonListenEngine();
816862
+ const explicitEngineId = body?.engineId ?? body?.engine;
816790
816863
  let selection;
816791
816864
  try {
816792
- selection = resolveAsrSelection({
816793
- engineId: body?.engineId ?? body?.engine ?? current.currentEngine,
816794
- modelId: body?.modelId ?? body?.model
816795
- });
816865
+ selection = resolveAsrSelection(
816866
+ {
816867
+ engineId: explicitEngineId ?? current.currentEngine,
816868
+ modelId: body?.modelId ?? body?.model
816869
+ },
816870
+ { inferEngineFromModel: !explicitEngineId }
816871
+ );
816796
816872
  } catch (err) {
816797
816873
  jsonResponse(res, 400, {
816798
816874
  error: "invalid_asr_selection",
816799
- message: err instanceof Error ? err.message : String(err)
816875
+ message: err instanceof Error ? err.message : String(err),
816876
+ requested: {
816877
+ engineId: explicitEngineId ?? current.currentEngine,
816878
+ engineInferred: !explicitEngineId,
816879
+ modelId: body?.modelId ?? body?.model ?? null
816880
+ },
816881
+ engines: listAsrEngines().map((engine) => ({
816882
+ engineId: engine.id,
816883
+ models: engine.models.map((model) => model.id)
816884
+ }))
816885
+ });
816886
+ return;
816887
+ }
816888
+ const unavailableReason = getAsrEngineUnavailableReason(selection.engineId);
816889
+ if (unavailableReason) {
816890
+ jsonResponse(res, 409, {
816891
+ error: "asr_engine_unavailable",
816892
+ message: unavailableReason,
816893
+ requested: selection,
816894
+ state: getRuntimeStatus()
816800
816895
  });
816801
816896
  return;
816802
816897
  }
@@ -828025,6 +828120,14 @@ This is an independent background session started from /background.`
828025
828120
  }, 1500);
828026
828121
  return;
828027
828122
  }
828123
+ setTimeout(() => {
828124
+ if (statusBar.isActive)
828125
+ writeContent(
828126
+ () => renderWarning(
828127
+ `Shared daemon on port ${apiPort} reports ${daemon.observedVersion ?? "unavailable"}, expected ${daemon.expectedVersion}. Run /daemon restart to retry it.`
828128
+ )
828129
+ );
828130
+ }, 1500);
828028
828131
  const { startApiServer: startApiServer2 } = await Promise.resolve().then(() => (init_serve(), serve_exports));
828029
828132
  const apiServer = startApiServer2({
828030
828133
  port: apiPort,
@@ -829502,10 +829605,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
829502
829605
  },
829503
829606
  async listenSetModel(model) {
829504
829607
  const engine = getListenEngine();
829505
- const result = await engine.activateSelection({
829506
- engineId: "openai-whisper",
829507
- modelId: model
829508
- });
829608
+ const engineId = getAsrModel(engine.currentEngine, model) ? engine.currentEngine : "openai-whisper";
829609
+ const result = await engine.activateSelection({ engineId, modelId: model });
829509
829610
  return result.message;
829510
829611
  },
829511
829612
  asrGetSelection() {
@@ -833244,11 +833345,13 @@ async function coerceForSettings(key, value2) {
833244
833345
  return normalized3;
833245
833346
  }
833246
833347
  if (key === "asrModel") {
833247
- const { getAsrModel: getAsrModel2, normalizeAsrEngineId: normalizeAsrEngineId2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports2));
833348
+ const { findAsrEnginesForModel: findAsrEnginesForModel2, getAsrModel: getAsrModel2, normalizeAsrEngineId: normalizeAsrEngineId2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports2));
833248
833349
  const engine = normalizeAsrEngineId2(loadGlobalSettings().asrEngine || "openai-whisper");
833249
833350
  const normalized3 = value2.trim().toLowerCase();
833250
833351
  if (!getAsrModel2(engine, normalized3)) {
833251
- throw new Error(`Invalid ASR model "${value2}" for ${engine}`);
833352
+ const owners = findAsrEnginesForModel2(normalized3).map((spec) => spec.id);
833353
+ const hint = owners.length ? ` It belongs to ${owners.join(", ")}; run "omnius config set asrEngine ${owners[0]}" first.` : "";
833354
+ throw new Error(`Invalid ASR model "${value2}" for ${engine}.${hint}`);
833252
833355
  }
833253
833356
  return normalized3;
833254
833357
  }
@@ -293353,6 +293353,7 @@ var MM_INDEX = join9(MM_DIR, "index.json");
293353
293353
  // packages/execution/dist/asr/registry.js
293354
293354
  var VIBEVOICE_ASR_MODEL_REVISION = "d0c9efdb8d614685062c04425d91e01b6f37d944";
293355
293355
  var VIBEVOICE_ASR_WEIGHTS_BYTES = 17348198410;
293356
+ var NEMOTRON_DISABLED_REASON = "Nemotron is catalogued but its legacy self-installing worker is disabled until it is migrated to the managed fail-closed runtime.";
293356
293357
  var whisperCapabilities = Object.freeze({
293357
293358
  file: true,
293358
293359
  pcmStream: true,
@@ -293410,6 +293411,8 @@ var ASR_ENGINES = Object.freeze([
293410
293411
  provider: "NVIDIA",
293411
293412
  runtime: "python",
293412
293413
  setupMode: "managed",
293414
+ availability: "disabled",
293415
+ unavailableReason: NEMOTRON_DISABLED_REASON,
293413
293416
  models: [
293414
293417
  {
293415
293418
  id: "nemotron-speech-streaming-en-0.6b",
@@ -293761,6 +293764,27 @@ async function managedDaemonServiceMatchesPort(port) {
293761
293764
  if (environment === null) return false;
293762
293765
  return daemonServiceMatchesPort(port, environment);
293763
293766
  }
293767
+ function pidIsInManagedDaemonUnit(pid, readCgroup = defaultReadProcCgroup) {
293768
+ const cgroup = readCgroup(pid);
293769
+ return cgroup === null ? false : cgroup.includes("omnius-daemon.service");
293770
+ }
293771
+ function defaultReadProcCgroup(pid) {
293772
+ try {
293773
+ return readFileSync4(`/proc/${pid}/cgroup`, "utf8");
293774
+ } catch {
293775
+ return null;
293776
+ }
293777
+ }
293778
+ async function managedDaemonServiceOwnsPort(port, dependencies = {
293779
+ holderPids: (value) => portHolderPids(value),
293780
+ pidInUnit: (pid) => pidIsInManagedDaemonUnit(pid)
293781
+ }) {
293782
+ const holders = await dependencies.holderPids(port);
293783
+ if (holders === null) return false;
293784
+ const uniqueHolders = [...new Set(holders.filter((pid) => pid > 0 && pid !== process.pid))];
293785
+ if (uniqueHolders.length === 0) return true;
293786
+ return uniqueHolders.every((pid) => dependencies.pidInUnit(pid));
293787
+ }
293764
293788
  function systemdQuote(value) {
293765
293789
  return /[\s"\\]/.test(value) ? `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"` : value;
293766
293790
  }
@@ -293982,6 +294006,11 @@ async function restartDaemon(port, expectedVersion) {
293982
294006
  const p = port ?? getDaemonPort();
293983
294007
  const managed = await managedDaemonServiceMatchesPort(p);
293984
294008
  if (managed) {
294009
+ if (!await managedDaemonServiceOwnsPort(p)) {
294010
+ const reclaimed = await reclaimOwnedDaemonListener(p);
294011
+ if (!reclaimed.ok) return false;
294012
+ await reclaimStaleDaemonEndpointClaim(p);
294013
+ }
293985
294014
  const restarted = await runUserSystemctl(["restart", "omnius-daemon.service"]);
293986
294015
  if (restarted.ok && (await waitForDaemonReady(p, expectedVersion)).ok) return true;
293987
294016
  const repaired = await repairManagedDaemonUnit(p);
@@ -294127,7 +294156,7 @@ async function stopDaemonAtPort(port = getDaemonPort()) {
294127
294156
  async function quiesceDaemonForUpdate(port = getDaemonPort()) {
294128
294157
  if (await managedDaemonServiceMatchesPort(port)) {
294129
294158
  const stopped = await runUserSystemctl(["stop", "omnius-daemon.service"]);
294130
- return stopped.ok && await waitForDaemonStopped(port);
294159
+ if (stopped.ok && await waitForDaemonStopped(port)) return true;
294131
294160
  }
294132
294161
  if (!await isDaemonRunning(port)) {
294133
294162
  return daemonPortIsFree(port);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.616",
3
+ "version": "1.0.618",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.616",
9
+ "version": "1.0.618",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
@@ -1745,9 +1745,9 @@
1745
1745
  }
1746
1746
  },
1747
1747
  "node_modules/@noble/ciphers": {
1748
- "version": "2.2.0",
1749
- "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.2.0.tgz",
1750
- "integrity": "sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA==",
1748
+ "version": "2.3.0",
1749
+ "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.3.0.tgz",
1750
+ "integrity": "sha512-Clu/xdfgVTf9o7ngLOURaxePwR0j8sjclKEtVij10/jGulwFsPWCvvRgG/XjUVf8Nei+jLG6uwyXzUTGY1DQrw==",
1751
1751
  "license": "MIT",
1752
1752
  "engines": {
1753
1753
  "node": ">= 20.19.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.616",
3
+ "version": "1.0.618",
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/library.js",