omnius 1.0.431 → 1.0.432

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
@@ -1699,12 +1699,12 @@ var init_model_broker = __esm({
1699
1699
  // packages/execution/dist/broker-mediated-backend.js
1700
1700
  function wrapWithBroker(backend, options2) {
1701
1701
  const broker = getModelBroker();
1702
- const clamp10 = options2.clampNumCtx !== false;
1702
+ const clamp11 = options2.clampNumCtx !== false;
1703
1703
  const wrapped = Object.create(backend);
1704
1704
  wrapped.chatCompletion = async (request) => {
1705
1705
  const model = backend.model || request.model || "unknown";
1706
1706
  let effectiveRequest = request;
1707
- if (clamp10) {
1707
+ if (clamp11) {
1708
1708
  const trainCtx = await broker.getNctxTrain(model).catch(() => null);
1709
1709
  const requestedNumCtx = request.numCtx;
1710
1710
  if (trainCtx && trainCtx > 0) {
@@ -1738,7 +1738,7 @@ function wrapWithBroker(backend, options2) {
1738
1738
  wrapped.chatCompletionStream = async function* (request) {
1739
1739
  const model = backend.model || request.model || "unknown";
1740
1740
  let effectiveRequest = request;
1741
- if (clamp10) {
1741
+ if (clamp11) {
1742
1742
  const trainCtx = await broker.getNctxTrain(model).catch(() => null);
1743
1743
  const requestedNumCtx = request.numCtx;
1744
1744
  if (trainCtx && trainCtx > 0) {
@@ -37242,11 +37242,11 @@ function deleteCustomToolDefinition(name10, scope, repoRoot) {
37242
37242
  const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
37243
37243
  const filePath = join35(dir, `${name10}.json`);
37244
37244
  if (existsSync33(filePath)) {
37245
- const { unlinkSync: unlinkSync37 } = __require("node:fs");
37246
- unlinkSync37(filePath);
37245
+ const { unlinkSync: unlinkSync38 } = __require("node:fs");
37246
+ unlinkSync38(filePath);
37247
37247
  const docsPath = toolDocsPath(name10, scope, repoRoot);
37248
37248
  if (existsSync33(docsPath))
37249
- unlinkSync37(docsPath);
37249
+ unlinkSync38(docsPath);
37250
37250
  if (scope === "project" && repoRoot)
37251
37251
  writeCustomToolRegistry(repoRoot);
37252
37252
  return true;
@@ -96067,13 +96067,13 @@ var require_singleton = __commonJS({
96067
96067
  Object.defineProperty(exports, "__esModule", { value: true });
96068
96068
  var injectable_1 = require_injectable();
96069
96069
  var dependency_container_1 = require_dependency_container();
96070
- function singleton() {
96070
+ function singleton2() {
96071
96071
  return function(target) {
96072
96072
  injectable_1.default()(target);
96073
96073
  dependency_container_1.instance.registerSingleton(target);
96074
96074
  };
96075
96075
  }
96076
- exports.default = singleton;
96076
+ exports.default = singleton2;
96077
96077
  }
96078
96078
  });
96079
96079
 
@@ -554463,10 +554463,10 @@ function collectSnapshot(workingDir) {
554463
554463
  const freeRAM = freemem2();
554464
554464
  let load1 = 0, load5 = 0, load15 = 0;
554465
554465
  try {
554466
- const loadavg4 = __require("node:os").loadavg();
554467
- load1 = loadavg4[0];
554468
- load5 = loadavg4[1];
554469
- load15 = loadavg4[2];
554466
+ const loadavg5 = __require("node:os").loadavg();
554467
+ load1 = loadavg5[0];
554468
+ load5 = loadavg5[1];
554469
+ load15 = loadavg5[2];
554470
554470
  } catch {
554471
554471
  }
554472
554472
  let gpu = void 0;
@@ -564504,16 +564504,16 @@ function recommendMaxParallelFromVram(minFreeMB) {
564504
564504
  return 1;
564505
564505
  }
564506
564506
  async function getHardwareSnapshot() {
564507
- const { totalmem: totalmem10, freemem: freemem9, cpus: cpus6 } = await import("node:os");
564507
+ const { totalmem: totalmem11, freemem: freemem10, cpus: cpus7 } = await import("node:os");
564508
564508
  const gpus = await detectGpus();
564509
564509
  const diskPath = discoverSystemOllamaModelStore() ?? homedir33();
564510
564510
  const disk = snapshotDisk(diskPath);
564511
564511
  const network = snapshotNetwork();
564512
564512
  return {
564513
564513
  gpus,
564514
- cpuCores: cpus6().length,
564515
- ramTotalMB: Math.round(totalmem10() / (1024 * 1024)),
564516
- ramFreeMB: Math.round(freemem9() / (1024 * 1024)),
564514
+ cpuCores: cpus7().length,
564515
+ ramTotalMB: Math.round(totalmem11() / (1024 * 1024)),
564516
+ ramFreeMB: Math.round(freemem10() / (1024 * 1024)),
564517
564517
  disk,
564518
564518
  network,
564519
564519
  takenAtMs: Date.now()
@@ -578990,7 +578990,7 @@ ${context2 ?? ""}`;
578990
578990
  }
578991
578991
  }
578992
578992
  _applyTaskAffectFromResult(result, events) {
578993
- const clamp10 = (n2) => Math.max(0, Math.min(1, n2));
578993
+ const clamp11 = (n2) => Math.max(0, Math.min(1, n2));
578994
578994
  let uncertainty = this._taskAffectState.uncertainty * 0.94;
578995
578995
  let frustration = this._taskAffectState.frustration * 0.94;
578996
578996
  let confidence2 = this._taskAffectState.confidence * 0.94;
@@ -579023,11 +579023,11 @@ ${context2 ?? ""}`;
579023
579023
  }
579024
579024
  const level = frustration >= 0.72 || uncertainty >= 0.78 ? 4 : frustration >= 0.52 || uncertainty >= 0.58 ? 3 : frustration >= 0.32 || uncertainty >= 0.38 ? 2 : frustration >= 0.18 || uncertainty >= 0.22 ? 1 : 0;
579025
579025
  this._taskAffectState = {
579026
- uncertainty: clamp10(uncertainty),
579027
- frustration: clamp10(frustration),
579028
- confidence: clamp10(confidence2),
579029
- novelty: clamp10(novelty),
579030
- momentum: clamp10(momentum),
579026
+ uncertainty: clamp11(uncertainty),
579027
+ frustration: clamp11(frustration),
579028
+ confidence: clamp11(confidence2),
579029
+ novelty: clamp11(novelty),
579030
+ momentum: clamp11(momentum),
579031
579031
  adversaryLevel: level,
579032
579032
  lastUpdatedIso: (/* @__PURE__ */ new Date()).toISOString()
579033
579033
  };
@@ -593827,7 +593827,7 @@ ${result}`
593827
593827
  const buffer2 = Buffer.from(rawBase64, "base64");
593828
593828
  let resizedBase64 = null;
593829
593829
  try {
593830
- const { writeFileSync: writeFileSync95, readFileSync: readFileSync140, unlinkSync: unlinkSync37 } = await import("node:fs");
593830
+ const { writeFileSync: writeFileSync95, readFileSync: readFileSync140, unlinkSync: unlinkSync38 } = await import("node:fs");
593831
593831
  const { join: join188 } = await import("node:path");
593832
593832
  const { tmpdir: tmpdir26 } = await import("node:os");
593833
593833
  const tmpIn = join188(tmpdir26(), `omnius_img_in_${Date.now()}.png`);
@@ -593845,11 +593845,11 @@ ${result}`
593845
593845
  const resizedBuf = readFileSync140(tmpOut);
593846
593846
  resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
593847
593847
  try {
593848
- unlinkSync37(tmpIn);
593848
+ unlinkSync38(tmpIn);
593849
593849
  } catch {
593850
593850
  }
593851
593851
  try {
593852
- unlinkSync37(tmpOut);
593852
+ unlinkSync38(tmpOut);
593853
593853
  } catch {
593854
593854
  }
593855
593855
  } catch {
@@ -604342,13 +604342,36 @@ transcribe-cli error: ${transcribeCliError}` : "";
604342
604342
 
604343
604343
  // packages/cli/src/tui/camera-streamer.ts
604344
604344
  import { spawn as spawn30 } from "node:child_process";
604345
- import { existsSync as existsSync111, mkdirSync as mkdirSync69, statSync as statSync43 } from "node:fs";
604345
+ import { existsSync as existsSync111, mkdirSync as mkdirSync69, statSync as statSync43, unlinkSync as unlinkSync20 } from "node:fs";
604346
604346
  import { join as join127 } from "node:path";
604347
604347
  function streamFps() {
604348
604348
  const raw = Number(process.env["OMNIUS_LIVE_STREAM_FPS"] ?? "");
604349
604349
  if (Number.isFinite(raw) && raw > 0) return Math.max(1, Math.min(30, Math.round(raw)));
604350
604350
  return 8;
604351
604351
  }
604352
+ function parseResolution(value2) {
604353
+ const raw = String(value2 ?? "").trim().toLowerCase();
604354
+ if (!raw || raw === "native" || raw === "auto") return null;
604355
+ const alias = {
604356
+ "480p": "640x480",
604357
+ "720p": "1280x720",
604358
+ "1080p": "1920x1080",
604359
+ "1440p": "2560x1440",
604360
+ "4k": "3840x2160",
604361
+ "2160p": "3840x2160"
604362
+ };
604363
+ const normalized = alias[raw] ?? raw;
604364
+ const match = normalized.match(/^(\d{3,5})x(\d{3,5})$/);
604365
+ if (!match) return null;
604366
+ const width = Number(match[1]);
604367
+ const height = Number(match[2]);
604368
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;
604369
+ return { label: `${width}x${height}`, width, height };
604370
+ }
604371
+ function scaleFilter(resolution) {
604372
+ if (!resolution) return null;
604373
+ return `scale=w='min(${resolution.width}\\,iw)':h='min(${resolution.height}\\,ih)':force_original_aspect_ratio=decrease`;
604374
+ }
604352
604375
  function rotateFilter(rotation) {
604353
604376
  switch ((rotation % 360 + 360) % 360) {
604354
604377
  case 90:
@@ -604368,7 +604391,7 @@ var MAX_ATTEMPT, FAST_EXIT_MS, RESTART_DELAY_MS, MAX_CONSECUTIVE_FAILURES, Camer
604368
604391
  var init_camera_streamer = __esm({
604369
604392
  "packages/cli/src/tui/camera-streamer.ts"() {
604370
604393
  "use strict";
604371
- MAX_ATTEMPT = 2;
604394
+ MAX_ATTEMPT = 4;
604372
604395
  FAST_EXIT_MS = 3e3;
604373
604396
  RESTART_DELAY_MS = 1500;
604374
604397
  MAX_CONSECUTIVE_FAILURES = 10;
@@ -604403,7 +604426,7 @@ var init_camera_streamer = __esm({
604403
604426
  * Only v4l2 device paths are streamable; other backends (OSC/WiFi cams)
604404
604427
  * keep the one-shot capture path.
604405
604428
  */
604406
- sync(sources, rotationFor) {
604429
+ sync(sources, rotationFor, resolutionFor) {
604407
604430
  const wanted = new Set(sources.filter((source) => source.startsWith("/dev/video")));
604408
604431
  for (const [source, stream] of this.streams) {
604409
604432
  if (!wanted.has(source)) {
@@ -604413,20 +604436,21 @@ var init_camera_streamer = __esm({
604413
604436
  }
604414
604437
  for (const source of wanted) {
604415
604438
  const rotation = rotationFor(source);
604439
+ const resolution = resolutionFor(source);
604416
604440
  const existing = this.streams.get(source);
604417
- if (existing && existing.rotation === rotation && !existing.stopped) continue;
604441
+ if (existing && existing.rotation === rotation && existing.resolution === resolution && !existing.stopped) continue;
604418
604442
  if (existing) {
604419
604443
  this.stopStream(existing);
604420
604444
  this.streams.delete(source);
604421
604445
  }
604422
- this.startStream(source, rotation);
604446
+ this.startStream(source, rotation, resolution);
604423
604447
  }
604424
604448
  }
604425
604449
  stopAll() {
604426
604450
  for (const stream of this.streams.values()) this.stopStream(stream);
604427
604451
  this.streams.clear();
604428
604452
  }
604429
- startStream(source, rotation) {
604453
+ startStream(source, rotation, resolution) {
604430
604454
  try {
604431
604455
  mkdirSync69(this.streamDir, { recursive: true });
604432
604456
  } catch {
@@ -604435,6 +604459,7 @@ var init_camera_streamer = __esm({
604435
604459
  source,
604436
604460
  framePath: join127(this.streamDir, `${slugForSource(source)}.jpg`),
604437
604461
  rotation,
604462
+ resolution,
604438
604463
  process: null,
604439
604464
  attempt: 0,
604440
604465
  consecutiveFailures: 0,
@@ -604449,13 +604474,17 @@ var init_camera_streamer = __esm({
604449
604474
  spawnStream(stream) {
604450
604475
  if (stream.stopped) return;
604451
604476
  const fps = streamFps();
604477
+ const resolution = parseResolution(stream.resolution);
604452
604478
  const filters = [`fps=${fps}`];
604479
+ const scale = scaleFilter(resolution);
604480
+ if (scale) filters.push(scale);
604453
604481
  const rotate = rotateFilter(stream.rotation);
604454
604482
  if (rotate) filters.push(rotate);
604455
604483
  const args = ["-hide_banner", "-loglevel", "error", "-f", "v4l2"];
604456
- if (stream.attempt === 0) args.push("-input_format", "mjpeg");
604484
+ if (stream.attempt === 0 || stream.attempt === 2) args.push("-input_format", "mjpeg");
604485
+ if (resolution && stream.attempt <= 1) args.push("-video_size", resolution.label);
604457
604486
  args.push("-i", stream.source, "-vf", filters.join(","), "-q:v", "6", "-f", "image2", "-update", "1");
604458
- if (stream.attempt <= 1) args.push("-atomic_writing", "1");
604487
+ if (stream.attempt <= 3) args.push("-atomic_writing", "1");
604459
604488
  args.push("-y", stream.framePath);
604460
604489
  const child = spawn30(process.env["OMNIUS_FFMPEG"] || "ffmpeg", args, {
604461
604490
  stdio: ["ignore", "ignore", "pipe"]
@@ -604498,12 +604527,24 @@ var init_camera_streamer = __esm({
604498
604527
  stream.restartTimer = null;
604499
604528
  }
604500
604529
  if (stream.process) {
604530
+ const child = stream.process;
604501
604531
  try {
604502
- stream.process.kill("SIGTERM");
604532
+ child.kill("SIGTERM");
604503
604533
  } catch {
604504
604534
  }
604535
+ const killTimer = setTimeout(() => {
604536
+ try {
604537
+ if (!child.killed) child.kill("SIGKILL");
604538
+ } catch {
604539
+ }
604540
+ }, 1500);
604541
+ killTimer.unref?.();
604505
604542
  stream.process = null;
604506
604543
  }
604544
+ try {
604545
+ if (existsSync111(stream.framePath)) unlinkSync20(stream.framePath);
604546
+ } catch {
604547
+ }
604507
604548
  }
604508
604549
  };
604509
604550
  }
@@ -604719,9 +604760,230 @@ var init_live_vlm = __esm({
604719
604760
  }
604720
604761
  });
604721
604762
 
604763
+ // packages/cli/src/tui/live-resource-arbiter.ts
604764
+ import { cpus as cpus3, freemem as freemem4, loadavg, totalmem as totalmem5 } from "node:os";
604765
+ function getLiveResourceArbiter() {
604766
+ if (!singleton) singleton = new LiveResourceArbiter();
604767
+ return singleton;
604768
+ }
604769
+ function formatLiveResourceBudgetLines(width = 100) {
604770
+ const snap = getLiveResourceArbiter().snapshot();
604771
+ const inner = Math.max(24, width - 2);
604772
+ const memoryColor = pressureColor(snap.memoryPressure, snap.target);
604773
+ const totalGB = snap.totalMemMB / 1024;
604774
+ const usedGB = snap.usedMemMB / 1024;
604775
+ const freeGB = snap.freeMemMB / 1024;
604776
+ const deferMs = Math.max(0, snap.deferUntil - Date.now());
604777
+ const status = deferMs > 0 ? colorText("deferring vision", 208) : colorText("vision allowed", 82);
604778
+ const leaseText = snap.leases.length > 0 ? snap.leases.slice(0, 3).map((lease) => `${lease.owner} p${lease.priority} ${Math.ceil(lease.expiresInMs / 1e3)}s`).join("; ") : "none";
604779
+ return [
604780
+ colorText(" resource budget", 45),
604781
+ `├─ memory: ${memoryColor(`${usedGB.toFixed(1)}/${totalGB.toFixed(1)}GB used`)} free=${freeGB.toFixed(1)}GB target<=${Math.round(snap.target * 100)}%`,
604782
+ `├─ pressure: ${pressureColor(snap.pressure, snap.target)(`${Math.round(snap.pressure * 100)}%`)} pid=${Math.round(snap.pid * 100)}% cpuLoad=${snap.cpuLoad1m.toFixed(2)} budget=${snap.budget} ${status}`,
604783
+ `└─ leases: ${truncateAnsi(leaseText, inner - 12)}`
604784
+ ];
604785
+ }
604786
+ function readBudget() {
604787
+ const raw = String(process.env["OMNIUS_LIVE_RESOURCE_BUDGET"] ?? "").trim().toLowerCase();
604788
+ if (raw === "low" || raw === "conserve" || raw === "conservative" || raw === "battery") return "conserve";
604789
+ if (raw === "high" || raw === "generous") return "high";
604790
+ if (raw === "aggressive" || raw === "max" || raw === "unlimited") return "aggressive";
604791
+ return "balanced";
604792
+ }
604793
+ function budgetTarget(budget) {
604794
+ const override = Number(process.env["OMNIUS_LIVE_RESOURCE_TARGET"] ?? "");
604795
+ if (Number.isFinite(override) && override > 0 && override < 1) return override;
604796
+ if (budget === "conserve") return 0.55;
604797
+ if (budget === "high") return 0.82;
604798
+ if (budget === "aggressive") return 0.92;
604799
+ return 0.7;
604800
+ }
604801
+ function numberEnv(name10, fallback) {
604802
+ const value2 = Number(process.env[name10] ?? "");
604803
+ return Number.isFinite(value2) ? value2 : fallback;
604804
+ }
604805
+ function clamp8(value2, min, max) {
604806
+ return Math.max(min, Math.min(max, value2));
604807
+ }
604808
+ function pressureColor(pressure, target) {
604809
+ if (pressure <= target) return (text2) => colorText(text2, 82);
604810
+ if (pressure <= target + 0.12) return (text2) => colorText(text2, 220);
604811
+ return (text2) => colorText(text2, 196);
604812
+ }
604813
+ function colorText(text2, color) {
604814
+ return `\x1B[38;5;${color}m${text2}\x1B[0m`;
604815
+ }
604816
+ function truncateAnsi(text2, max) {
604817
+ const plain = text2.replace(/\x1b\[[0-9;]*m/g, "");
604818
+ if (plain.length <= max) return text2;
604819
+ return `${plain.slice(0, Math.max(0, max - 3))}...`;
604820
+ }
604821
+ var LiveResourceArbiter, singleton;
604822
+ var init_live_resource_arbiter = __esm({
604823
+ "packages/cli/src/tui/live-resource-arbiter.ts"() {
604824
+ "use strict";
604825
+ LiveResourceArbiter = class {
604826
+ leases = /* @__PURE__ */ new Map();
604827
+ seq = 0;
604828
+ integral = 0;
604829
+ lastError = 0;
604830
+ lastAt = 0;
604831
+ pidDeferUntil = 0;
604832
+ lastPid = 0;
604833
+ lastPressure = 0;
604834
+ claim(args) {
604835
+ const now2 = Date.now();
604836
+ this.cleanup(now2);
604837
+ const id2 = `${now2}-${++this.seq}-${args.owner.replace(/[^a-z0-9_.:-]+/gi, "_")}`;
604838
+ const record = {
604839
+ id: id2,
604840
+ owner: args.owner,
604841
+ priority: clamp8(args.priority, 0, 100),
604842
+ reason: args.reason,
604843
+ suppress: args.suppress?.length ? args.suppress : ["vision"],
604844
+ createdAt: now2,
604845
+ expiresAt: now2 + Math.max(250, args.ttlMs)
604846
+ };
604847
+ this.leases.set(id2, record);
604848
+ return {
604849
+ id: id2,
604850
+ owner: record.owner,
604851
+ priority: record.priority,
604852
+ get expiresAt() {
604853
+ return record.expiresAt;
604854
+ },
604855
+ release: () => {
604856
+ this.leases.delete(id2);
604857
+ },
604858
+ extend: (ttlMs, reason) => {
604859
+ const current = this.leases.get(id2);
604860
+ if (!current) return;
604861
+ current.expiresAt = Math.max(current.expiresAt, Date.now() + Math.max(250, ttlMs));
604862
+ if (reason) current.reason = reason;
604863
+ }
604864
+ };
604865
+ }
604866
+ shouldDefer(kind, options2 = {}) {
604867
+ const now2 = Date.now();
604868
+ this.cleanup(now2);
604869
+ const budget = readBudget();
604870
+ if (String(process.env["OMNIUS_LIVE_RESOURCE_ARBITER"] ?? "").toLowerCase() === "off") {
604871
+ return this.decision(false, "", now2, 0, budget);
604872
+ }
604873
+ const minPriority = clamp8(options2.minPriority ?? 50, 0, 100);
604874
+ const token = kind.toLowerCase();
604875
+ let strongest = null;
604876
+ for (const lease of this.leases.values()) {
604877
+ if (lease.priority < minPriority) continue;
604878
+ if (!lease.suppress.some((entry) => entry === "*" || token.includes(entry.toLowerCase()))) continue;
604879
+ if (!strongest || lease.priority > strongest.priority || lease.expiresAt > strongest.expiresAt) strongest = lease;
604880
+ }
604881
+ if (strongest) {
604882
+ return this.decision(
604883
+ true,
604884
+ `live resource priority ${strongest.priority} from ${strongest.owner}: ${strongest.reason}`,
604885
+ strongest.expiresAt,
604886
+ strongest.priority,
604887
+ budget
604888
+ );
604889
+ }
604890
+ const pid = this.samplePid(now2, budget);
604891
+ if (pid.deferUntil > now2) {
604892
+ return this.decision(
604893
+ true,
604894
+ `resource PID pressure budget=${budget} pressure=${pid.pressure.toFixed(2)} target=${pid.target.toFixed(2)} output=${pid.output.toFixed(2)}`,
604895
+ pid.deferUntil,
604896
+ 45,
604897
+ budget
604898
+ );
604899
+ }
604900
+ return this.decision(false, "", now2, 0, budget);
604901
+ }
604902
+ snapshot(now2 = Date.now()) {
604903
+ this.cleanup(now2);
604904
+ const budget = readBudget();
604905
+ const pid = this.samplePid(now2, budget);
604906
+ const total = Math.max(1, totalmem5());
604907
+ const free = Math.max(0, freemem4());
604908
+ const cpuCount = Math.max(1, cpus3().length);
604909
+ const cpuLoad1m = loadavg()[0] ?? 0;
604910
+ return {
604911
+ budget,
604912
+ totalMemMB: Math.round(total / 1024 / 1024),
604913
+ freeMemMB: Math.round(free / 1024 / 1024),
604914
+ usedMemMB: Math.round((total - free) / 1024 / 1024),
604915
+ memoryPressure: clamp8(1 - free / total, 0, 1),
604916
+ cpuLoad1m,
604917
+ cpuPressure: clamp8(cpuLoad1m / cpuCount, 0, 2) / 2,
604918
+ pressure: pid.pressure,
604919
+ target: pid.target,
604920
+ pid: pid.output,
604921
+ deferUntil: pid.deferUntil,
604922
+ leases: [...this.leases.values()].sort((a2, b) => b.priority - a2.priority).map((lease) => ({
604923
+ owner: lease.owner,
604924
+ priority: lease.priority,
604925
+ reason: lease.reason,
604926
+ expiresInMs: Math.max(0, lease.expiresAt - now2)
604927
+ }))
604928
+ };
604929
+ }
604930
+ releaseOwnerPrefix(prefix) {
604931
+ for (const [id2, lease] of this.leases) {
604932
+ if (lease.owner.startsWith(prefix)) this.leases.delete(id2);
604933
+ }
604934
+ }
604935
+ decision(defer, reason, until, priority, budget) {
604936
+ return {
604937
+ defer,
604938
+ reason,
604939
+ until,
604940
+ priority,
604941
+ budget,
604942
+ pressure: this.lastPressure,
604943
+ pid: this.lastPid
604944
+ };
604945
+ }
604946
+ cleanup(now2) {
604947
+ for (const [id2, lease] of this.leases) {
604948
+ if (lease.expiresAt <= now2) this.leases.delete(id2);
604949
+ }
604950
+ }
604951
+ samplePid(now2, budget) {
604952
+ const target = budgetTarget(budget);
604953
+ const cpuCount = Math.max(1, cpus3().length);
604954
+ const cpuPressure = clamp8((loadavg()[0] ?? 0) / cpuCount, 0, 2) / 2;
604955
+ const total = Math.max(1, totalmem5());
604956
+ const free = Math.max(0, freemem4());
604957
+ const memoryPressure = clamp8(1 - free / total, 0, 1);
604958
+ const pressure = clamp8(Math.max(memoryPressure, cpuPressure * 0.65 + memoryPressure * 0.35), 0, 1);
604959
+ const dt = this.lastAt > 0 ? clamp8((now2 - this.lastAt) / 1e3, 0.1, 10) : 1;
604960
+ const error = pressure - target;
604961
+ this.integral = clamp8(this.integral + error * dt, -2, 2);
604962
+ const derivative = (error - this.lastError) / dt;
604963
+ const kp = numberEnv("OMNIUS_LIVE_PID_KP", 0.9);
604964
+ const ki = numberEnv("OMNIUS_LIVE_PID_KI", 0.18);
604965
+ const kd = numberEnv("OMNIUS_LIVE_PID_KD", 0.12);
604966
+ const output = clamp8(kp * error + ki * this.integral + kd * derivative, 0, 1);
604967
+ this.lastAt = now2;
604968
+ this.lastError = error;
604969
+ this.lastPressure = pressure;
604970
+ this.lastPid = output;
604971
+ if (output > 0.08) {
604972
+ const maxMs = numberEnv("OMNIUS_LIVE_PID_MAX_DEFER_MS", 3e4);
604973
+ this.pidDeferUntil = Math.max(this.pidDeferUntil, now2 + clamp8(750 + output * maxMs, 1e3, maxMs));
604974
+ } else if (pressure < target - 0.08) {
604975
+ this.pidDeferUntil = Math.min(this.pidDeferUntil, now2);
604976
+ }
604977
+ return { output, pressure, target, deferUntil: this.pidDeferUntil };
604978
+ }
604979
+ };
604980
+ singleton = null;
604981
+ }
604982
+ });
604983
+
604722
604984
  // packages/cli/src/tui/live-sensors.ts
604723
604985
  import { existsSync as existsSync113, mkdirSync as mkdirSync70, readFileSync as readFileSync91, writeFileSync as writeFileSync58 } from "node:fs";
604724
- import { arch as arch3, freemem as freemem4 } from "node:os";
604986
+ import { arch as arch3, freemem as freemem5 } from "node:os";
604725
604987
  import { basename as basename23, join as join128, relative as relative11 } from "node:path";
604726
604988
  function liveDir(repoRoot) {
604727
604989
  return join128(repoRoot, ".omnius", "live");
@@ -604873,6 +605135,52 @@ function describeCameraOrientation(orientation) {
604873
605135
  if (!orientation) return "upright/no correction (default)";
604874
605136
  return `${formatCameraRotation(orientation.rotation)} (${orientation.source}${orientation.confidence !== void 0 ? ` confidence=${orientation.confidence.toFixed(2)}` : ""}, updated=${nowIso3(orientation.updatedAt)})`;
604875
605137
  }
605138
+ function normalizeLiveCameraResolution(value2) {
605139
+ const raw = String(value2 ?? "").trim().toLowerCase();
605140
+ if (!raw || raw === "default" || raw === "1080" || raw === "1080p") return "1920x1080";
605141
+ if (raw === "native" || raw === "auto" || raw === "max") return "native";
605142
+ if (raw === "480" || raw === "480p" || raw === "vga") return "640x480";
605143
+ if (raw === "720" || raw === "720p" || raw === "hd") return "1280x720";
605144
+ if (raw === "1440" || raw === "1440p" || raw === "2k") return "2560x1440";
605145
+ if (raw === "2160" || raw === "2160p" || raw === "4k" || raw === "uhd") return "3840x2160";
605146
+ if (["640x480", "1280x720", "1920x1080", "2560x1440", "3840x2160"].includes(raw)) return raw;
605147
+ throw new Error(`Unsupported live camera resolution: ${String(value2)}. Use native, 480p, 720p, 1080p, 1440p, 4k, or WxH.`);
605148
+ }
605149
+ function formatLiveCameraResolution(value2) {
605150
+ const res = value2 ?? DEFAULT_CAMERA_RESOLUTION;
605151
+ if (res === "native") return "native";
605152
+ if (res === "640x480") return "480p (640x480)";
605153
+ if (res === "1280x720") return "720p (1280x720)";
605154
+ if (res === "1920x1080") return "1080p (1920x1080)";
605155
+ if (res === "2560x1440") return "1440p (2560x1440)";
605156
+ if (res === "3840x2160") return "4K (3840x2160)";
605157
+ return res;
605158
+ }
605159
+ function liveCameraResolutionSize(value2) {
605160
+ const res = value2 ?? DEFAULT_CAMERA_RESOLUTION;
605161
+ if (res === "native") return null;
605162
+ const [widthRaw, heightRaw] = res.split("x");
605163
+ const width = Number(widthRaw);
605164
+ const height = Number(heightRaw);
605165
+ return Number.isFinite(width) && Number.isFinite(height) ? { width, height } : null;
605166
+ }
605167
+ function sanitizeCameraStreams(value2) {
605168
+ if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return {};
605169
+ const out = {};
605170
+ for (const [device, raw] of Object.entries(value2)) {
605171
+ if (!device || typeof raw !== "object" || raw === null || Array.isArray(raw)) continue;
605172
+ const entry = raw;
605173
+ try {
605174
+ out[device] = {
605175
+ enabled: entry["enabled"] !== false,
605176
+ resolution: normalizeLiveCameraResolution(entry["resolution"] ?? DEFAULT_CAMERA_RESOLUTION)
605177
+ };
605178
+ } catch {
605179
+ out[device] = { enabled: entry["enabled"] !== false, resolution: DEFAULT_CAMERA_RESOLUTION };
605180
+ }
605181
+ }
605182
+ return out;
605183
+ }
604876
605184
  function chooseCameraOrientationFromScores(scores) {
604877
605185
  const sorted = [...scores].filter((score) => Number.isFinite(score.score)).sort((a2, b) => b.score - a2.score);
604878
605186
  const best = sorted[0];
@@ -605632,6 +605940,13 @@ function formatLiveDashboardFromSnapshot(snapshot, opts = {}) {
605632
605940
  const horizontal = "─".repeat(Math.max(0, width - 2));
605633
605941
  const lines = [`╭${horizontal}╮`];
605634
605942
  lines.push(`│${truncateCell(` ${title}`, width - 2)}│`);
605943
+ lines.push(`├${horizontal}┤`);
605944
+ for (const budgetLine of formatLiveResourceBudgetLines(width - 2)) {
605945
+ lines.push(`│${truncateAnsiCell(budgetLine, width - 2)}│`);
605946
+ }
605947
+ const enabledStreams = Object.entries(snapshot.config.cameraStreams ?? {}).filter(([, stream]) => stream.enabled !== false);
605948
+ const selectedResolution = snapshot.config.selectedCamera ? formatLiveCameraResolution(snapshot.config.cameraStreams?.[snapshot.config.selectedCamera]?.resolution) : "none";
605949
+ lines.push(`│${truncateCell(` systems: camera-streams=${enabledStreams.length}/${snapshot.devices.video.length} selected-res=${selectedResolution} yolo=${snapshot.config.inferEnabled ? "on" : "off"} clip=${snapshot.config.clipEnabled ? "on" : "off"} asr=${snapshot.config.asrEnabled ? "on" : "off"} sounds=${snapshot.config.audioAnalysisEnabled ? "on" : "off"}`, width - 2)}│`);
605635
605950
  if (cameras.length === 0) {
605636
605951
  lines.push(`│${truncateCell(" no camera frames captured yet", width - 2)}│`);
605637
605952
  }
@@ -605958,6 +606273,7 @@ function loadLiveSensorConfig(repoRoot) {
605958
606273
  ...DEFAULT_CONFIG7,
605959
606274
  ...parsed,
605960
606275
  cameraOrientation: sanitizeCameraOrientation(parsed.cameraOrientation),
606276
+ cameraStreams: sanitizeCameraStreams(parsed.cameraStreams),
605961
606277
  videoIntervalMs: Math.max(MIN_VIDEO_INTERVAL_MS, Number(parsed.videoIntervalMs ?? DEFAULT_CONFIG7.videoIntervalMs)),
605962
606278
  audioIntervalMs: Math.max(MIN_AUDIO_INTERVAL_MS, Number(parsed.audioIntervalMs ?? DEFAULT_CONFIG7.audioIntervalMs))
605963
606279
  };
@@ -605997,7 +606313,9 @@ function formatLiveSensorContextFromSnapshot(snapshot, opts = {}) {
605997
606313
  lines.push(`Streams: video=${snapshot.config.videoEnabled ? "on" : "off"} infer=${snapshot.config.inferEnabled ? "on" : "off"} clip=${snapshot.config.clipEnabled ? "on" : "off"} audio=${snapshot.config.audioEnabled ? "on" : "off"} asr=${snapshot.config.asrEnabled ? "on" : "off"} sounds=${snapshot.config.audioAnalysisEnabled ? "on" : "off"} output-monitor=${snapshot.config.audioOutputEnabled ? "on" : "off"}`);
605998
606314
  if (snapshot.config.selectedCamera) {
605999
606315
  const orientation = snapshot.config.cameraOrientation?.[snapshot.config.selectedCamera];
606316
+ const stream = snapshot.config.cameraStreams?.[snapshot.config.selectedCamera];
606000
606317
  lines.push(`Selected camera: ${snapshot.config.selectedCamera}`);
606318
+ lines.push(`Selected camera stream: ${stream?.enabled !== false ? "enabled" : "disabled"} ${formatLiveCameraResolution(stream?.resolution)}`);
606001
606319
  lines.push(`Camera orientation correction: ${describeCameraOrientation(orientation)}`);
606002
606320
  }
606003
606321
  const cameraSnapshots = Object.values(snapshot.cameras ?? (snapshot.video ? { [snapshot.video.source]: snapshot.video } : {})).sort((a2, b) => {
@@ -606454,6 +606772,7 @@ function formatLiveStatus(snapshot) {
606454
606772
  const lines = [
606455
606773
  `Live streams: video=${cfg.videoEnabled ? "on" : "off"} infer=${cfg.inferEnabled ? "on" : "off"} clip=${cfg.clipEnabled ? "on" : "off"} audio=${cfg.audioEnabled ? "on" : "off"} asr=${cfg.asrEnabled ? "on" : "off"} sounds=${cfg.audioAnalysisEnabled ? "on" : "off"} output=${cfg.audioOutputEnabled ? "on" : "off"}`,
606456
606774
  `Camera: ${cfg.selectedCamera || "none"}`,
606775
+ `Camera stream: ${cfg.selectedCamera ? `${cfg.cameraStreams?.[cfg.selectedCamera]?.enabled !== false ? "enabled" : "disabled"} ${formatLiveCameraResolution(cfg.cameraStreams?.[cfg.selectedCamera]?.resolution)}` : "none"}`,
606457
606776
  `Camera orientation: ${cfg.selectedCamera ? describeCameraOrientation(cfg.cameraOrientation?.[cfg.selectedCamera]) : "none"}`,
606458
606777
  `Audio input: ${cfg.selectedAudioInput || "none"}`,
606459
606778
  `Audio output: ${cfg.selectedAudioOutput || "none"}`,
@@ -606467,7 +606786,7 @@ function formatLiveStatus(snapshot) {
606467
606786
  }
606468
606787
  return lines.join("\n");
606469
606788
  }
606470
- var MIN_VIDEO_INTERVAL_MS, LOW_LATENCY_VIDEO_INTERVAL_MS, MIN_AUDIO_INTERVAL_MS, LOW_LATENCY_AUDIO_INTERVAL_MS, AUDIO_ACTIVITY_INTERVAL_MS, AUDIO_ACTIVITY_SAMPLE_SEC, DEFAULT_CONFIG7, managers, DASHBOARD_ANSI_STICKY_PATTERN, _liveDashboardMaximizedCamera, LiveSensorManager;
606789
+ var MIN_VIDEO_INTERVAL_MS, LOW_LATENCY_VIDEO_INTERVAL_MS, MIN_AUDIO_INTERVAL_MS, LOW_LATENCY_AUDIO_INTERVAL_MS, AUDIO_ACTIVITY_INTERVAL_MS, AUDIO_ACTIVITY_SAMPLE_SEC, DEFAULT_CAMERA_RESOLUTION, DEFAULT_CONFIG7, managers, DASHBOARD_ANSI_STICKY_PATTERN, _liveDashboardMaximizedCamera, LiveSensorManager;
606471
606790
  var init_live_sensors = __esm({
606472
606791
  "packages/cli/src/tui/live-sensors.ts"() {
606473
606792
  "use strict";
@@ -606477,12 +606796,14 @@ var init_live_sensors = __esm({
606477
606796
  init_listen();
606478
606797
  init_camera_streamer();
606479
606798
  init_live_vlm();
606799
+ init_live_resource_arbiter();
606480
606800
  MIN_VIDEO_INTERVAL_MS = 250;
606481
606801
  LOW_LATENCY_VIDEO_INTERVAL_MS = 250;
606482
606802
  MIN_AUDIO_INTERVAL_MS = 1500;
606483
606803
  LOW_LATENCY_AUDIO_INTERVAL_MS = 2e3;
606484
606804
  AUDIO_ACTIVITY_INTERVAL_MS = 200;
606485
606805
  AUDIO_ACTIVITY_SAMPLE_SEC = 0.2;
606806
+ DEFAULT_CAMERA_RESOLUTION = "1920x1080";
606486
606807
  DEFAULT_CONFIG7 = {
606487
606808
  videoEnabled: false,
606488
606809
  audioEnabled: false,
@@ -606492,6 +606813,7 @@ var init_live_sensors = __esm({
606492
606813
  asrEnabled: false,
606493
606814
  audioAnalysisEnabled: false,
606494
606815
  cameraOrientation: {},
606816
+ cameraStreams: {},
606495
606817
  videoIntervalMs: 1e3,
606496
606818
  audioIntervalMs: 6e3
606497
606819
  };
@@ -606528,6 +606850,7 @@ var init_live_sensors = __esm({
606528
606850
  lastStreamPersistAt = 0;
606529
606851
  videoGeneration = 0;
606530
606852
  liveGpuYieldUntil = 0;
606853
+ resourceArbiter = getLiveResourceArbiter();
606531
606854
  videoInFlight = false;
606532
606855
  audioInFlight = false;
606533
606856
  audioActivityInFlight = false;
@@ -606672,12 +606995,85 @@ var init_live_sensors = __esm({
606672
606995
  if (!clean5 || ordered.includes(clean5)) return;
606673
606996
  const device = this.devices.video.find((entry) => entry.id === clean5);
606674
606997
  if (device && /metadata\/non-capture/i.test(device.detail ?? "")) return;
606998
+ if (!this.isCameraStreamEnabled(clean5)) return;
606675
606999
  ordered.push(clean5);
606676
607000
  };
606677
607001
  add3(this.config.selectedCamera);
606678
607002
  for (const device of this.devices.video) add3(device.id);
606679
- if (ordered.length === 0) add3(firstDeviceId(this.devices.video));
606680
- return ordered.slice(0, 4);
607003
+ const hasExplicitStreamConfig = Object.keys(this.config.cameraStreams ?? {}).length > 0;
607004
+ if (ordered.length === 0 && !hasExplicitStreamConfig) {
607005
+ const fallback = this.config.selectedCamera || firstDeviceId(this.devices.video);
607006
+ if (fallback) {
607007
+ this.config = {
607008
+ ...this.config,
607009
+ selectedCamera: fallback,
607010
+ cameraStreams: {
607011
+ ...this.config.cameraStreams ?? {},
607012
+ [fallback]: {
607013
+ enabled: true,
607014
+ resolution: this.config.cameraStreams?.[fallback]?.resolution ?? DEFAULT_CAMERA_RESOLUTION
607015
+ }
607016
+ }
607017
+ };
607018
+ add3(fallback);
607019
+ }
607020
+ }
607021
+ const maxStreams = Math.max(1, Math.min(8, Number(process.env["OMNIUS_LIVE_MAX_CAMERA_STREAMS"] ?? 4) || 4));
607022
+ return ordered.slice(0, maxStreams);
607023
+ }
607024
+ isCameraStreamEnabled(device = this.config.selectedCamera) {
607025
+ const target = device || this.config.selectedCamera;
607026
+ if (!target) return false;
607027
+ const configured = this.config.cameraStreams?.[target];
607028
+ if (configured) return configured.enabled !== false;
607029
+ return target === this.config.selectedCamera;
607030
+ }
607031
+ getCameraStreamResolution(device = this.config.selectedCamera) {
607032
+ const target = device || this.config.selectedCamera;
607033
+ return target ? this.config.cameraStreams?.[target]?.resolution ?? DEFAULT_CAMERA_RESOLUTION : DEFAULT_CAMERA_RESOLUTION;
607034
+ }
607035
+ setCameraStreamEnabled(device, enabled2) {
607036
+ const target = device || this.config.selectedCamera;
607037
+ if (!target) return null;
607038
+ const current = this.config.cameraStreams?.[target];
607039
+ const next = {
607040
+ enabled: enabled2,
607041
+ resolution: current?.resolution ?? DEFAULT_CAMERA_RESOLUTION
607042
+ };
607043
+ this.config = {
607044
+ ...this.config,
607045
+ selectedCamera: enabled2 ? target : this.config.selectedCamera,
607046
+ cameraStreams: {
607047
+ ...this.config.cameraStreams ?? {},
607048
+ [target]: next
607049
+ }
607050
+ };
607051
+ this.videoGeneration++;
607052
+ this.lastStreamFrameMtime.delete(target);
607053
+ this.persist();
607054
+ this.ensureLoops();
607055
+ return next;
607056
+ }
607057
+ setCameraStreamResolution(device, resolution) {
607058
+ const target = device || this.config.selectedCamera;
607059
+ if (!target) return null;
607060
+ const current = this.config.cameraStreams?.[target];
607061
+ const next = {
607062
+ enabled: current?.enabled ?? target === this.config.selectedCamera,
607063
+ resolution: normalizeLiveCameraResolution(resolution)
607064
+ };
607065
+ this.config = {
607066
+ ...this.config,
607067
+ cameraStreams: {
607068
+ ...this.config.cameraStreams ?? {},
607069
+ [target]: next
607070
+ }
607071
+ };
607072
+ this.videoGeneration++;
607073
+ this.lastStreamFrameMtime.delete(target);
607074
+ this.persist();
607075
+ this.ensureLoops();
607076
+ return next;
606681
607077
  }
606682
607078
  getCameraOrientation(device = this.config.selectedCamera) {
606683
607079
  return device ? this.config.cameraOrientation?.[device] : void 0;
@@ -606748,6 +607144,14 @@ var init_live_sensors = __esm({
606748
607144
  return isJetsonUnifiedMemoryHost() ? "yield" : "balanced";
606749
607145
  }
606750
607146
  async shouldYieldLiveGpuVideo(kind) {
607147
+ const resourceDecision = this.resourceArbiter.shouldDefer(`vision:${kind}`, { minPriority: 45 });
607148
+ if (resourceDecision.defer) {
607149
+ return {
607150
+ yield: true,
607151
+ reason: resourceDecision.reason,
607152
+ until: resourceDecision.until
607153
+ };
607154
+ }
606751
607155
  const policy = this.liveVideoGpuPolicy();
606752
607156
  if (policy === "aggressive") return { yield: false, reason: "" };
606753
607157
  if (policy === "yield") {
@@ -606771,7 +607175,7 @@ var init_live_sensors = __esm({
606771
607175
  };
606772
607176
  }
606773
607177
  } catch {
606774
- if (isJetsonUnifiedMemoryHost() || freemem4() < 6 * 1024 * 1024 * 1024) {
607178
+ if (isJetsonUnifiedMemoryHost() || freemem5() < 6 * 1024 * 1024 * 1024) {
606775
607179
  return { yield: true, reason: `live video ${kind} yielded: memory pressure unknown` };
606776
607180
  }
606777
607181
  }
@@ -606782,7 +607186,7 @@ var init_live_sensors = __esm({
606782
607186
  if (!decision2.yield) return false;
606783
607187
  const now2 = Date.now();
606784
607188
  if (now2 >= this.liveGpuYieldUntil) {
606785
- this.liveGpuYieldUntil = now2 + 15e3;
607189
+ this.liveGpuYieldUntil = Math.max(decision2.until ?? 0, now2 + 15e3);
606786
607190
  void this.liveVlm.unloadModel().catch(() => false);
606787
607191
  this.emitFeedbackThrottled(`live-video-gpu-yield:${kind}`, {
606788
607192
  kind: "status",
@@ -606790,6 +607194,8 @@ var init_live_sensors = __esm({
606790
607194
  observedAt: now2,
606791
607195
  message: `${decision2.reason}. Camera capture/ASCII preview stays active; GPU video inference is skipped. Set OMNIUS_LIVE_VIDEO_GPU_POLICY=aggressive to override.`
606792
607196
  }, 3e4);
607197
+ } else if (decision2.until) {
607198
+ this.liveGpuYieldUntil = Math.max(this.liveGpuYieldUntil, decision2.until);
606793
607199
  }
606794
607200
  return true;
606795
607201
  }
@@ -606814,10 +607220,12 @@ var init_live_sensors = __esm({
606814
607220
  }
606815
607221
  if (!framePath) {
606816
607222
  if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
607223
+ const captureSize = liveCameraResolutionSize(this.getCameraStreamResolution(target));
606817
607224
  const captured = await new CameraCaptureTool().execute({
606818
607225
  action: "capture",
606819
607226
  device: target,
606820
- rotate_degrees: 0
607227
+ rotate_degrees: 0,
607228
+ ...captureSize ? { width: captureSize.width, height: captureSize.height } : {}
606821
607229
  });
606822
607230
  if (!this.isVideoWorkCurrent(generation)) return "Video context is disabled.";
606823
607231
  if (!captured.success) {
@@ -606892,11 +607300,25 @@ var init_live_sensors = __esm({
606892
607300
  errors
606893
607301
  };
606894
607302
  if (!this.config.selectedCamera) this.config.selectedCamera = firstDeviceId(video);
607303
+ this.config.cameraStreams = this.reconcileCameraStreams(video);
606895
607304
  if (!this.config.selectedAudioInput) this.config.selectedAudioInput = preferredLiveAudioInputId(inputs.devices);
606896
607305
  if (!this.config.selectedAudioOutput) this.config.selectedAudioOutput = firstDeviceId(outputs.devices);
606897
607306
  this.persist();
606898
607307
  return this.devices;
606899
607308
  }
607309
+ reconcileCameraStreams(video) {
607310
+ const current = this.config.cameraStreams ?? {};
607311
+ const selected = this.config.selectedCamera || firstDeviceId(video);
607312
+ const next = {};
607313
+ for (const device of video) {
607314
+ if (!device.id || /metadata\/non-capture/i.test(device.detail ?? "")) continue;
607315
+ next[device.id] = {
607316
+ enabled: current[device.id]?.enabled ?? device.id === selected,
607317
+ resolution: current[device.id]?.resolution ?? DEFAULT_CAMERA_RESOLUTION
607318
+ };
607319
+ }
607320
+ return next;
607321
+ }
606900
607322
  configure(patch) {
606901
607323
  const wasVideoEnabled = this.config.videoEnabled;
606902
607324
  this.config = {
@@ -606905,6 +607327,17 @@ var init_live_sensors = __esm({
606905
607327
  videoIntervalMs: Math.max(MIN_VIDEO_INTERVAL_MS, Number(patch.videoIntervalMs ?? this.config.videoIntervalMs)),
606906
607328
  audioIntervalMs: Math.max(MIN_AUDIO_INTERVAL_MS, Number(patch.audioIntervalMs ?? this.config.audioIntervalMs))
606907
607329
  };
607330
+ this.config.cameraStreams = sanitizeCameraStreams(this.config.cameraStreams);
607331
+ if (patch.selectedCamera) {
607332
+ const selected = String(patch.selectedCamera);
607333
+ this.config.cameraStreams = {
607334
+ ...this.config.cameraStreams ?? {},
607335
+ [selected]: {
607336
+ enabled: true,
607337
+ resolution: this.config.cameraStreams?.[selected]?.resolution ?? DEFAULT_CAMERA_RESOLUTION
607338
+ }
607339
+ };
607340
+ }
606908
607341
  if (wasVideoEnabled && !this.config.videoEnabled) {
606909
607342
  this.videoGeneration++;
606910
607343
  this.lastStreamFrameMtime.clear();
@@ -606929,6 +607362,33 @@ var init_live_sensors = __esm({
606929
607362
  asrEnabled: false,
606930
607363
  audioAnalysisEnabled: false
606931
607364
  });
607365
+ this.cleanupLiveResources();
607366
+ }
607367
+ cleanupLiveResources() {
607368
+ this.clearLoopTimers();
607369
+ this.videoGeneration++;
607370
+ this.cameraStreamers?.stopAll();
607371
+ this.cameraStreamers = null;
607372
+ this.lastStreamFrameMtime.clear();
607373
+ this.lastVlmAt.clear();
607374
+ this.lastClipAt.clear();
607375
+ this.lastInferenceAt.clear();
607376
+ this.autoOrientationInFlight.clear();
607377
+ this.liveSpeechInFlight.clear();
607378
+ this.resourceArbiter.releaseOwnerPrefix("live-");
607379
+ void this.liveVlm.unloadModel().catch(() => false);
607380
+ this.snapshot = {
607381
+ version: 1,
607382
+ repoRoot: this.repoRoot,
607383
+ config: this.config,
607384
+ devices: this.devices,
607385
+ events: [],
607386
+ people: [],
607387
+ cameras: {}
607388
+ };
607389
+ this.persist();
607390
+ this.emitStatus();
607391
+ this.emitDashboard();
606932
607392
  }
606933
607393
  startRunMode(options2 = {}) {
606934
607394
  this.agentActionEnabled = Boolean(options2.agent);
@@ -607039,10 +607499,12 @@ var init_live_sensors = __esm({
607039
607499
  };
607040
607500
  }
607041
607501
  }
607502
+ const captureSize = liveCameraResolutionSize(this.getCameraStreamResolution(source));
607042
607503
  const result = await new CameraCaptureTool().execute({
607043
607504
  action: "capture",
607044
607505
  device: source,
607045
- rotate_degrees: rotation
607506
+ rotate_degrees: rotation,
607507
+ ...captureSize ? { width: captureSize.width, height: captureSize.height } : {}
607046
607508
  });
607047
607509
  if (!this.isVideoWorkCurrent(generation)) return { ok: false, message: "Video context is disabled." };
607048
607510
  if (!result.success) {
@@ -607447,6 +607909,8 @@ ${output}`).join("\n\n");
607447
607909
  async sampleAudioNow() {
607448
607910
  if (this.audioInFlight) return "Audio sampler is already running.";
607449
607911
  this.audioInFlight = true;
607912
+ let asrLease = null;
607913
+ let keepAsrLease = false;
607450
607914
  try {
607451
607915
  const input = this.resolveAudioInput();
607452
607916
  if (this.isLiveAudioMutedForTts()) {
@@ -607497,6 +607961,13 @@ ${output}`).join("\n\n");
607497
607961
  audioErrors.push(`No live input signal detected from selected input ${capture.device}; keeping the explicit selection.`);
607498
607962
  }
607499
607963
  if (this.config.asrEnabled) {
607964
+ asrLease = this.resourceArbiter.claim({
607965
+ owner: "live-asr",
607966
+ priority: 88,
607967
+ ttlMs: 18e3,
607968
+ reason: "live audio ASR capture/transcription",
607969
+ suppress: ["vision"]
607970
+ });
607500
607971
  try {
607501
607972
  const asr = await new TranscribeFileTool(this.repoRoot).execute({
607502
607973
  path: recordingPath,
@@ -607533,6 +608004,11 @@ ${output}`).join("\n\n");
607533
608004
  }
607534
608005
  if (transcript) {
607535
608006
  intake = await classifyLiveAudioIntake(transcript, this.intakeAgentConfig);
608007
+ keepAsrLease = true;
608008
+ asrLease?.extend(
608009
+ intake?.intendedForAgent ? 35e3 : 18e3,
608010
+ intake?.intendedForAgent ? "live ASR addressed Omnius; reserving compute for response inference" : "live ASR transcript accepted; briefly yielding vision"
608011
+ );
607536
608012
  }
607537
608013
  this.snapshot.audio = {
607538
608014
  updatedAt: Date.now(),
@@ -607600,6 +608076,7 @@ Sound analysis:
607600
608076
  ${analysis}` : ""
607601
608077
  ].filter(Boolean).join("\n");
607602
608078
  } finally {
608079
+ if (!keepAsrLease) asrLease?.release();
607603
608080
  this.audioInFlight = false;
607604
608081
  }
607605
608082
  }
@@ -607640,7 +608117,8 @@ ${analysis}` : ""
607640
608117
  }
607641
608118
  this.cameraStreamers.sync(
607642
608119
  this.activeVideoSources(),
607643
- (source) => this.getCameraOrientation(source)?.rotation ?? 0
608120
+ (source) => this.getCameraOrientation(source)?.rotation ?? 0,
608121
+ (source) => this.getCameraStreamResolution(source)
607644
608122
  );
607645
608123
  }
607646
608124
  previewTickIntervalMs() {
@@ -612442,6 +612920,8 @@ var init_command_registry = __esm({
612442
612920
  ["/live chat", "Start low-latency voicechat with live audio/video context and async agent review"],
612443
612921
  ["/livechat", "Alias for /live chat, used by the top live button"],
612444
612922
  ["/live camera <device>", "Select a camera and render an ASCII preview"],
612923
+ ["/live resolution [camera] 720p|1080p|1440p|4k|native", "Set per-camera live stream resolution (default 1080p)"],
612924
+ ["/live camera-on|camera-off [camera]", "Enable or disable an individual live camera stream"],
612445
612925
  ["/live rotate auto|cw|ccw|180|none [camera]", "Detect or set persistent camera orientation correction"],
612446
612926
  ["/live infer [now|on|off]", "Toggle or run camera object/location inference"],
612447
612927
  ["/live clip [on|off]", "Toggle CLIP visual-memory recognition on live frames"],
@@ -614330,7 +614810,7 @@ var init_syntax_highlight = __esm({
614330
614810
  });
614331
614811
 
614332
614812
  // packages/cli/src/tui/model-picker.ts
614333
- import { totalmem as totalmem5 } from "node:os";
614813
+ import { totalmem as totalmem6 } from "node:os";
614334
614814
  function isImageGenModel(name10, family) {
614335
614815
  return IMAGE_GEN_PATTERNS.some((p2) => p2.test(name10) || family && p2.test(family));
614336
614816
  }
@@ -614719,7 +615199,7 @@ async function queryModelContextSize(baseUrl2, modelName) {
614719
615199
  }
614720
615200
  }
614721
615201
  function estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2) {
614722
- const totalMemGB = totalmem5() / 1024 ** 3;
615202
+ const totalMemGB = totalmem6() / 1024 ** 3;
614723
615203
  const usableBytes = totalMemGB * 0.7 * 1024 ** 3;
614724
615204
  const maxTokens = Math.floor(usableBytes / kvBytesPerToken);
614725
615205
  let numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
@@ -619090,8 +619570,8 @@ import { spawn as spawn32, exec as exec3 } from "node:child_process";
619090
619570
  import { EventEmitter as EventEmitter8 } from "node:events";
619091
619571
  import { randomBytes as randomBytes22, timingSafeEqual } from "node:crypto";
619092
619572
  import { URL as URL2 } from "node:url";
619093
- import { loadavg, cpus as cpus3, totalmem as totalmem6, freemem as freemem5 } from "node:os";
619094
- import { existsSync as existsSync117, readFileSync as readFileSync95, writeFileSync as writeFileSync60, unlinkSync as unlinkSync20, mkdirSync as mkdirSync72, readdirSync as readdirSync38, statSync as statSync45, statfsSync as statfsSync7 } from "node:fs";
619573
+ import { loadavg as loadavg2, cpus as cpus4, totalmem as totalmem7, freemem as freemem6 } from "node:os";
619574
+ import { existsSync as existsSync117, readFileSync as readFileSync95, writeFileSync as writeFileSync60, unlinkSync as unlinkSync21, mkdirSync as mkdirSync72, readdirSync as readdirSync38, statSync as statSync45, statfsSync as statfsSync7 } from "node:fs";
619095
619575
  import { join as join132 } from "node:path";
619096
619576
  function cleanForwardHeaders(raw, targetHost) {
619097
619577
  const out = {};
@@ -619304,7 +619784,7 @@ function writeExposeState(stateDir, state) {
619304
619784
  }
619305
619785
  function removeExposeState(stateDir) {
619306
619786
  try {
619307
- unlinkSync20(join132(stateDir, STATE_FILE_NAME));
619787
+ unlinkSync21(join132(stateDir, STATE_FILE_NAME));
619308
619788
  } catch {
619309
619789
  }
619310
619790
  }
@@ -619348,10 +619828,10 @@ function parseRateLimitHeaders(headers) {
619348
619828
  };
619349
619829
  }
619350
619830
  async function collectSystemMetricsAsync() {
619351
- const [l1, l5, l15] = loadavg();
619352
- const cores = cpus3().length;
619353
- const totalMem = totalmem6();
619354
- const freeMem = freemem5();
619831
+ const [l1, l5, l15] = loadavg2();
619832
+ const cores = cpus4().length;
619833
+ const totalMem = totalmem7();
619834
+ const freeMem = freemem6();
619355
619835
  const usedMem = totalMem - freeMem;
619356
619836
  let disk = {
619357
619837
  path: process.cwd(),
@@ -619442,7 +619922,7 @@ function writeP2PExposeState(stateDir, state) {
619442
619922
  }
619443
619923
  function removeP2PExposeState(stateDir) {
619444
619924
  try {
619445
- unlinkSync20(join132(stateDir, P2P_STATE_FILE_NAME));
619925
+ unlinkSync21(join132(stateDir, P2P_STATE_FILE_NAME));
619446
619926
  } catch {
619447
619927
  }
619448
619928
  }
@@ -622577,7 +623057,7 @@ ${activitySummary}
622577
623057
  });
622578
623058
 
622579
623059
  // packages/cli/src/api/profiles.ts
622580
- import { existsSync as existsSync119, readFileSync as readFileSync97, writeFileSync as writeFileSync62, mkdirSync as mkdirSync74, readdirSync as readdirSync39, unlinkSync as unlinkSync21 } from "node:fs";
623060
+ import { existsSync as existsSync119, readFileSync as readFileSync97, writeFileSync as writeFileSync62, mkdirSync as mkdirSync74, readdirSync as readdirSync39, unlinkSync as unlinkSync22 } from "node:fs";
622581
623061
  import { join as join134 } from "node:path";
622582
623062
  import { homedir as homedir41 } from "node:os";
622583
623063
  import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes25, scryptSync as scryptSync3 } from "node:crypto";
@@ -622681,7 +623161,7 @@ function deleteProfile(name10, scope = "global", projectDir2) {
622681
623161
  const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
622682
623162
  const filePath = join134(dir, `${sanitized}.json`);
622683
623163
  if (existsSync119(filePath)) {
622684
- unlinkSync21(filePath);
623164
+ unlinkSync22(filePath);
622685
623165
  return true;
622686
623166
  }
622687
623167
  return false;
@@ -622959,7 +623439,7 @@ __export(omnius_directory_exports, {
622959
623439
  writeIndexMeta: () => writeIndexMeta,
622960
623440
  writeTaskHandoff: () => writeTaskHandoff2
622961
623441
  });
622962
- import { appendFileSync as appendFileSync13, cpSync as cpSync2, existsSync as existsSync120, mkdirSync as mkdirSync75, readFileSync as readFileSync98, writeFileSync as writeFileSync63, readdirSync as readdirSync40, statSync as statSync46, unlinkSync as unlinkSync22, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync11, watch as fsWatch2 } from "node:fs";
623442
+ import { appendFileSync as appendFileSync13, cpSync as cpSync2, existsSync as existsSync120, mkdirSync as mkdirSync75, readFileSync as readFileSync98, writeFileSync as writeFileSync63, readdirSync as readdirSync40, statSync as statSync46, unlinkSync as unlinkSync23, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync11, watch as fsWatch2 } from "node:fs";
622963
623443
  import { join as join135, relative as relative13, basename as basename25, dirname as dirname40, resolve as resolve57 } from "node:path";
622964
623444
  import { homedir as homedir42 } from "node:os";
622965
623445
  import { createHash as createHash37 } from "node:crypto";
@@ -623350,7 +623830,7 @@ function loadPendingTask(repoRoot) {
623350
623830
  if (!existsSync120(filePath)) return null;
623351
623831
  const data = JSON.parse(readFileSync98(filePath, "utf-8"));
623352
623832
  try {
623353
- unlinkSync22(filePath);
623833
+ unlinkSync23(filePath);
623354
623834
  } catch {
623355
623835
  }
623356
623836
  return data;
@@ -623369,7 +623849,7 @@ function writeTaskHandoff2(repoRoot, handoff) {
623369
623849
  } catch {
623370
623850
  writeFileSync63(filePath, JSON.stringify(handoff, null, 2) + "\n", "utf-8");
623371
623851
  try {
623372
- unlinkSync22(tempPath);
623852
+ unlinkSync23(tempPath);
623373
623853
  } catch {
623374
623854
  }
623375
623855
  }
@@ -623395,7 +623875,7 @@ function clearTaskHandoff(repoRoot) {
623395
623875
  const filePath = join135(repoRoot, OMNIUS_DIR, "context", HANDOFF_FILE);
623396
623876
  try {
623397
623877
  if (existsSync120(filePath)) {
623398
- unlinkSync22(filePath);
623878
+ unlinkSync23(filePath);
623399
623879
  }
623400
623880
  } catch {
623401
623881
  }
@@ -623469,13 +623949,13 @@ function acquireLock(lockPath) {
623469
623949
  const lockAge = Date.now() - lock.acquiredAt;
623470
623950
  if (lockAge > LOCK_TIMEOUT_MS) {
623471
623951
  try {
623472
- unlinkSync22(lockPath);
623952
+ unlinkSync23(lockPath);
623473
623953
  } catch {
623474
623954
  }
623475
623955
  }
623476
623956
  } catch {
623477
623957
  try {
623478
- unlinkSync22(lockPath);
623958
+ unlinkSync23(lockPath);
623479
623959
  } catch {
623480
623960
  }
623481
623961
  }
@@ -623493,7 +623973,7 @@ function releaseLock(lockPath) {
623493
623973
  const lockContent = readFileSync98(lockPath, "utf-8");
623494
623974
  const lock = JSON.parse(lockContent);
623495
623975
  if (lock.pid === process.pid) {
623496
- unlinkSync22(lockPath);
623976
+ unlinkSync23(lockPath);
623497
623977
  }
623498
623978
  }
623499
623979
  } catch {
@@ -623679,7 +624159,7 @@ function saveSessionContext(repoRoot, entry) {
623679
624159
  } catch {
623680
624160
  writeFileSync63(filePath, JSON.stringify(ctx3, null, 2) + "\n", "utf-8");
623681
624161
  try {
623682
- unlinkSync22(tempFilePath);
624162
+ unlinkSync23(tempFilePath);
623683
624163
  } catch {
623684
624164
  }
623685
624165
  }
@@ -624062,7 +624542,7 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
624062
624542
  if (index.length > 50) {
624063
624543
  const removed = index.shift();
624064
624544
  try {
624065
- unlinkSync22(join135(sessDir, `${removed.id}.jsonl`));
624545
+ unlinkSync23(join135(sessDir, `${removed.id}.jsonl`));
624066
624546
  } catch {
624067
624547
  }
624068
624548
  }
@@ -624092,7 +624572,7 @@ function deleteSession(repoRoot, sessionId) {
624092
624572
  const indexPath = join135(sessDir, SESSIONS_INDEX);
624093
624573
  try {
624094
624574
  const contentPath = join135(sessDir, `${sessionId}.jsonl`);
624095
- if (existsSync120(contentPath)) unlinkSync22(contentPath);
624575
+ if (existsSync120(contentPath)) unlinkSync23(contentPath);
624096
624576
  if (existsSync120(indexPath)) {
624097
624577
  let index = JSON.parse(readFileSync98(indexPath, "utf-8"));
624098
624578
  index = index.filter((s2) => s2.id !== sessionId);
@@ -624430,7 +624910,7 @@ function firstMeaningfulLine(transcript) {
624430
624910
  }
624431
624911
  return "";
624432
624912
  }
624433
- function clamp8(value2, max) {
624913
+ function clamp9(value2, max) {
624434
624914
  const v = value2.replace(/\s+/g, " ").trim();
624435
624915
  return v.length > max ? v.slice(0, max - 1).trimEnd() + "…" : v;
624436
624916
  }
@@ -624438,8 +624918,8 @@ function deterministicSummary(transcript) {
624438
624918
  const first2 = firstMeaningfulLine(transcript);
624439
624919
  if (!first2) return { title: "Untitled session", summary: "Empty session." };
624440
624920
  const cleaned = first2.replace(TUI_MARKER_PREFIX, "").replace(/^[>›$#\s]+/, "").trim();
624441
- const title = clamp8(cleaned, TITLE_MAX);
624442
- return { title: title || "Untitled session", summary: clamp8(cleaned || first2, SUMMARY_MAX) };
624921
+ const title = clamp9(cleaned, TITLE_MAX);
624922
+ return { title: title || "Untitled session", summary: clamp9(cleaned || first2, SUMMARY_MAX) };
624443
624923
  }
624444
624924
  function parseSummaryReply(content) {
624445
624925
  if (!content) return null;
@@ -624491,8 +624971,8 @@ async function generateSessionSummary(args) {
624491
624971
  const parsed = parseSummaryReply(content);
624492
624972
  if (!parsed) return fallback;
624493
624973
  return {
624494
- title: clamp8(parsed.title, TITLE_MAX) || fallback.title,
624495
- summary: clamp8(parsed.summary, SUMMARY_MAX) || fallback.summary
624974
+ title: clamp9(parsed.title, TITLE_MAX) || fallback.title,
624975
+ summary: clamp9(parsed.summary, SUMMARY_MAX) || fallback.summary
624496
624976
  };
624497
624977
  } catch {
624498
624978
  return fallback;
@@ -625522,7 +626002,7 @@ __export(system_metrics_exports, {
625522
626002
  getInstantSnapshot: () => getInstantSnapshot,
625523
626003
  instantaneousCpuPct: () => instantaneousCpuPct
625524
626004
  });
625525
- import { loadavg as loadavg2, cpus as cpus4, totalmem as totalmem7, freemem as freemem6, platform as platform4 } from "node:os";
626005
+ import { loadavg as loadavg3, cpus as cpus5, totalmem as totalmem8, freemem as freemem7, platform as platform4 } from "node:os";
625526
626006
  import { exec as exec4 } from "node:child_process";
625527
626007
  import { readFile as readFile24 } from "node:fs/promises";
625528
626008
  function formatRate(bytesPerSec) {
@@ -625691,7 +626171,7 @@ function getInstantSnapshot() {
625691
626171
  function readCpuTimes() {
625692
626172
  let idle = 0;
625693
626173
  let total = 0;
625694
- for (const cpu of cpus4()) {
626174
+ for (const cpu of cpus5()) {
625695
626175
  const t2 = cpu.times;
625696
626176
  idle += t2.idle;
625697
626177
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -625710,13 +626190,13 @@ function instantaneousCpuPct() {
625710
626190
  return Math.max(0, Math.min(100, Math.round(usage * 100)));
625711
626191
  }
625712
626192
  function collectCpuRam() {
625713
- const cores = cpus4().length;
625714
- const cpuModel = cpus4()[0]?.model ?? "";
625715
- const totalMem = totalmem7();
625716
- const usedMem = totalMem - freemem6();
626193
+ const cores = cpus5().length;
626194
+ const cpuModel = cpus5()[0]?.model ?? "";
626195
+ const totalMem = totalmem8();
626196
+ const usedMem = totalMem - freemem7();
625717
626197
  let cpuUtil = instantaneousCpuPct();
625718
626198
  if (cpuUtil < 0) {
625719
- const [l1] = loadavg2();
626199
+ const [l1] = loadavg3();
625720
626200
  cpuUtil = Math.max(0, Math.min(100, Math.round(l1 / cores * 100)));
625721
626201
  }
625722
626202
  return {
@@ -633132,7 +633612,7 @@ import { spawn as spawn34, exec as exec5 } from "node:child_process";
633132
633612
  import { promisify as promisify7 } from "node:util";
633133
633613
  import { existsSync as existsSync126, writeFileSync as writeFileSync66, readFileSync as readFileSync104, appendFileSync as appendFileSync14, mkdirSync as mkdirSync78, chmodSync as chmodSync3 } from "node:fs";
633134
633614
  import { delimiter as pathDelimiter, join as join141 } from "node:path";
633135
- import { freemem as freemem7, homedir as homedir46, platform as platform5, totalmem as totalmem8 } from "node:os";
633615
+ import { freemem as freemem8, homedir as homedir46, platform as platform5, totalmem as totalmem9 } from "node:os";
633136
633616
  function wrapText2(value2, width) {
633137
633617
  const words = value2.split(/\s+/).filter(Boolean);
633138
633618
  const lines = [];
@@ -633245,8 +633725,8 @@ function parseRocmSmi(stdout) {
633245
633725
  return { total, free: Math.max(0, total - used), name: name10 ? `AMD ${name10}` : "AMD GPU" };
633246
633726
  }
633247
633727
  function detectSystemSpecs() {
633248
- let totalRamGB = totalmem8() / 1024 ** 3;
633249
- let availableRamGB = freemem7() / 1024 ** 3;
633728
+ let totalRamGB = totalmem9() / 1024 ** 3;
633729
+ let availableRamGB = freemem8() / 1024 ** 3;
633250
633730
  let gpuVramGB = 0;
633251
633731
  let availableVramGB = 0;
633252
633732
  const gpuName = "";
@@ -640027,7 +640507,7 @@ var init_audio_waveform = __esm({
640027
640507
  });
640028
640508
 
640029
640509
  // packages/cli/src/tui/neovim-mode.ts
640030
- import { existsSync as existsSync132, unlinkSync as unlinkSync24 } from "node:fs";
640510
+ import { existsSync as existsSync132, unlinkSync as unlinkSync25 } from "node:fs";
640031
640511
  import { tmpdir as tmpdir22 } from "node:os";
640032
640512
  import { join as join145 } from "node:path";
640033
640513
  function isNeovimActive() {
@@ -640076,7 +640556,7 @@ async function startNeovimMode(opts) {
640076
640556
  }
640077
640557
  const socketPath = join145(tmpdir22(), `omnius-nvim-${process.pid}-${Date.now()}.sock`);
640078
640558
  try {
640079
- if (existsSync132(socketPath)) unlinkSync24(socketPath);
640559
+ if (existsSync132(socketPath)) unlinkSync25(socketPath);
640080
640560
  } catch {
640081
640561
  }
640082
640562
  const ptyCols = opts.cols;
@@ -640465,7 +640945,7 @@ function doCleanup(state) {
640465
640945
  state.pty = null;
640466
640946
  }
640467
640947
  try {
640468
- if (existsSync132(state.socketPath)) unlinkSync24(state.socketPath);
640948
+ if (existsSync132(state.socketPath)) unlinkSync25(state.socketPath);
640469
640949
  } catch {
640470
640950
  }
640471
640951
  if (state.stdinHandler) {
@@ -640540,7 +641020,7 @@ __export(daemon_exports, {
640540
641020
  stopDaemon: () => stopDaemon
640541
641021
  });
640542
641022
  import { spawn as spawn35 } from "node:child_process";
640543
- import { existsSync as existsSync133, readFileSync as readFileSync108, writeFileSync as writeFileSync67, mkdirSync as mkdirSync79, unlinkSync as unlinkSync25, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
641023
+ import { existsSync as existsSync133, readFileSync as readFileSync108, writeFileSync as writeFileSync67, mkdirSync as mkdirSync79, unlinkSync as unlinkSync26, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
640544
641024
  import { join as join146 } from "node:path";
640545
641025
  import { homedir as homedir48 } from "node:os";
640546
641026
  import { fileURLToPath as fileURLToPath20 } from "node:url";
@@ -640616,7 +641096,7 @@ function getDaemonPid() {
640616
641096
  return pid;
640617
641097
  } catch {
640618
641098
  try {
640619
- unlinkSync25(PID_FILE2);
641099
+ unlinkSync26(PID_FILE2);
640620
641100
  } catch {
640621
641101
  }
640622
641102
  return null;
@@ -640732,13 +641212,13 @@ function stopDaemon() {
640732
641212
  }
640733
641213
  process.kill(pid, "SIGTERM");
640734
641214
  try {
640735
- unlinkSync25(PID_FILE2);
641215
+ unlinkSync26(PID_FILE2);
640736
641216
  } catch {
640737
641217
  }
640738
641218
  return true;
640739
641219
  } catch {
640740
641220
  try {
640741
- unlinkSync25(PID_FILE2);
641221
+ unlinkSync26(PID_FILE2);
640742
641222
  } catch {
640743
641223
  }
640744
641224
  return false;
@@ -640769,7 +641249,7 @@ async function forceKillDaemon(port) {
640769
641249
  } catch {
640770
641250
  }
640771
641251
  try {
640772
- unlinkSync25(PID_FILE2);
641252
+ unlinkSync26(PID_FILE2);
640773
641253
  } catch {
640774
641254
  }
640775
641255
  }
@@ -640824,7 +641304,7 @@ async function ensureDaemon() {
640824
641304
  } catch {
640825
641305
  }
640826
641306
  try {
640827
- unlinkSync25(PID_FILE2);
641307
+ unlinkSync26(PID_FILE2);
640828
641308
  } catch {
640829
641309
  }
640830
641310
  }
@@ -640841,7 +641321,7 @@ async function ensureDaemon() {
640841
641321
  } catch {
640842
641322
  }
640843
641323
  try {
640844
- unlinkSync25(PID_FILE2);
641324
+ unlinkSync26(PID_FILE2);
640845
641325
  } catch {
640846
641326
  }
640847
641327
  return false;
@@ -641304,7 +641784,7 @@ import {
641304
641784
  mkdirSync as mkdirSync80,
641305
641785
  chmodSync as chmodSync4,
641306
641786
  existsSync as existsSync136,
641307
- unlinkSync as unlinkSync26,
641787
+ unlinkSync as unlinkSync27,
641308
641788
  readdirSync as readdirSync44
641309
641789
  } from "node:fs";
641310
641790
  import { join as join149 } from "node:path";
@@ -641499,12 +641979,12 @@ function saveJobs(jobs) {
641499
641979
  const tmp = path12 + ".tmp";
641500
641980
  writeFileSync68(tmp, content, "utf-8");
641501
641981
  try {
641502
- unlinkSync26(path12);
641982
+ unlinkSync27(path12);
641503
641983
  } catch {
641504
641984
  }
641505
641985
  writeFileSync68(path12, content, "utf-8");
641506
641986
  try {
641507
- unlinkSync26(tmp);
641987
+ unlinkSync27(tmp);
641508
641988
  } catch {
641509
641989
  }
641510
641990
  secureFile(path12);
@@ -641853,7 +642333,7 @@ import {
641853
642333
  openSync as openSync5,
641854
642334
  closeSync as closeSync5,
641855
642335
  writeFileSync as writeFileSync69,
641856
- unlinkSync as unlinkSync27,
642336
+ unlinkSync as unlinkSync28,
641857
642337
  readFileSync as readFileSync110
641858
642338
  } from "node:fs";
641859
642339
  import { join as join150 } from "node:path";
@@ -641878,7 +642358,7 @@ function acquireTickLock() {
641878
642358
  if (age < 3e5) return false;
641879
642359
  }
641880
642360
  try {
641881
- unlinkSync27(lockPath);
642361
+ unlinkSync28(lockPath);
641882
642362
  } catch {
641883
642363
  }
641884
642364
  }
@@ -641895,7 +642375,7 @@ function acquireTickLock() {
641895
642375
  }
641896
642376
  function releaseTickLock() {
641897
642377
  try {
641898
- unlinkSync27(lockFilePath());
642378
+ unlinkSync28(lockFilePath());
641899
642379
  } catch {
641900
642380
  }
641901
642381
  }
@@ -643608,7 +644088,7 @@ import {
643608
644088
  mkdirSync as mkdirSync83,
643609
644089
  writeFileSync as writeFileSync71,
643610
644090
  readFileSync as readFileSync112,
643611
- unlinkSync as unlinkSync28,
644091
+ unlinkSync as unlinkSync29,
643612
644092
  readdirSync as readdirSync45,
643613
644093
  statSync as statSync52,
643614
644094
  copyFileSync as copyFileSync6,
@@ -645246,7 +645726,7 @@ except Exception as exc:
645246
645726
  const p2 = join152(luxttsCloneRefsDir(), filename);
645247
645727
  if (!existsSync139(p2)) return false;
645248
645728
  try {
645249
- unlinkSync28(p2);
645729
+ unlinkSync29(p2);
645250
645730
  const meta = this.loadCloneMeta();
645251
645731
  delete meta[filename];
645252
645732
  this.saveCloneMeta(meta);
@@ -645621,7 +646101,7 @@ except Exception as exc:
645621
646101
  }
645622
646102
  if (prefetchedWav) {
645623
646103
  try {
645624
- unlinkSync28(prefetchedWav.path);
646104
+ unlinkSync29(prefetchedWav.path);
645625
646105
  } catch {
645626
646106
  }
645627
646107
  }
@@ -645715,7 +646195,7 @@ except Exception as exc:
645715
646195
  this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
645716
646196
  await this.playWav(wavPath);
645717
646197
  try {
645718
- unlinkSync28(wavPath);
646198
+ unlinkSync29(wavPath);
645719
646199
  } catch {
645720
646200
  }
645721
646201
  }
@@ -646261,7 +646741,7 @@ except Exception as exc:
646261
646741
  if (!wavPath) return null;
646262
646742
  try {
646263
646743
  const data = readFileSync112(wavPath);
646264
- unlinkSync28(wavPath);
646744
+ unlinkSync29(wavPath);
646265
646745
  return data;
646266
646746
  } catch {
646267
646747
  return null;
@@ -646445,7 +646925,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
646445
646925
  }
646446
646926
  await this.playWav(wavPath);
646447
646927
  try {
646448
- unlinkSync28(wavPath);
646928
+ unlinkSync29(wavPath);
646449
646929
  } catch {
646450
646930
  }
646451
646931
  }
@@ -646489,7 +646969,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
646489
646969
  if (!existsSync139(wavPath)) return null;
646490
646970
  try {
646491
646971
  const data = readFileSync112(wavPath);
646492
- unlinkSync28(wavPath);
646972
+ unlinkSync29(wavPath);
646493
646973
  return data;
646494
646974
  } catch {
646495
646975
  return null;
@@ -647445,7 +647925,7 @@ if __name__ == '__main__':
647445
647925
  await this.playWav(wavPath);
647446
647926
  await this.sleep(150);
647447
647927
  try {
647448
- unlinkSync28(wavPath);
647928
+ unlinkSync29(wavPath);
647449
647929
  } catch {
647450
647930
  }
647451
647931
  }
@@ -647485,7 +647965,7 @@ if __name__ == '__main__':
647485
647965
  if (!existsSync139(wavPath)) return null;
647486
647966
  try {
647487
647967
  const data = readFileSync112(wavPath);
647488
- unlinkSync28(wavPath);
647968
+ unlinkSync29(wavPath);
647489
647969
  return data;
647490
647970
  } catch {
647491
647971
  return null;
@@ -647812,7 +648292,7 @@ if __name__ == "__main__":
647812
648292
  await this.playWav(wavPath);
647813
648293
  await this.sleep(150);
647814
648294
  try {
647815
- unlinkSync28(wavPath);
648295
+ unlinkSync29(wavPath);
647816
648296
  } catch {
647817
648297
  }
647818
648298
  }
@@ -647861,7 +648341,7 @@ if __name__ == "__main__":
647861
648341
  if (!existsSync139(wavPath)) return null;
647862
648342
  try {
647863
648343
  const data = readFileSync112(wavPath);
647864
- unlinkSync28(wavPath);
648344
+ unlinkSync29(wavPath);
647865
648345
  return data;
647866
648346
  } catch {
647867
648347
  return null;
@@ -658706,6 +659186,134 @@ async function chooseLiveDevice(ctx3, title, devices, activeKey) {
658706
659186
  if (!result.confirmed || !result.key) return null;
658707
659187
  return devices.find((device) => device.id === result.key) ?? null;
658708
659188
  }
659189
+ function liveCameraStreamSummary(manager, deviceId) {
659190
+ return `${manager.isCameraStreamEnabled(deviceId) ? liveEnabled(true) : liveEnabled(false)} · ${formatLiveCameraResolution(manager.getCameraStreamResolution(deviceId))} · ${formatCameraRotation(manager.getCameraRotation(deviceId))}`;
659191
+ }
659192
+ async function chooseLiveCameraResolution(ctx3, manager, deviceId) {
659193
+ const current = manager.getCameraStreamResolution(deviceId);
659194
+ const choices = ["640x480", "1280x720", "1920x1080", "2560x1440", "3840x2160", "native"];
659195
+ const result = await tuiSelect({
659196
+ items: choices.map((resolution) => ({
659197
+ key: resolution,
659198
+ label: formatLiveCameraResolution(resolution),
659199
+ detail: resolution === "native" ? "use camera native format; highest burden" : resolution === "1920x1080" ? "default balanced stream size" : "downscaled camera stream"
659200
+ })),
659201
+ title: `Camera Resolution — ${deviceId}`,
659202
+ activeKey: current,
659203
+ rl: ctx3.rl,
659204
+ availableRows: ctx3.availableContentRows?.()
659205
+ });
659206
+ if (!result.confirmed || !result.key) return null;
659207
+ return normalizeLiveCameraResolution(result.key);
659208
+ }
659209
+ async function showLiveCameraMenu(ctx3, manager, device) {
659210
+ while (true) {
659211
+ const selected = manager.getConfig().selectedCamera === device.id;
659212
+ const enabled2 = manager.isCameraStreamEnabled(device.id);
659213
+ const resolution = manager.getCameraStreamResolution(device.id);
659214
+ const items = [
659215
+ { key: "hdr:camera", label: selectColors.dim(`─── Camera ${device.id} ───`) },
659216
+ {
659217
+ key: "info:camera",
659218
+ label: selectColors.dim(` ${device.label}${device.detail ? ` · ${device.detail}` : ""}`)
659219
+ },
659220
+ {
659221
+ key: "select",
659222
+ label: selected ? "Selected Camera" : "Select Camera",
659223
+ detail: "make this the primary live camera"
659224
+ },
659225
+ {
659226
+ key: "toggle",
659227
+ label: enabled2 ? "Disable This Camera Stream" : "Enable This Camera Stream",
659228
+ detail: "disabled cameras stay available but do not consume ffmpeg/vision resources"
659229
+ },
659230
+ {
659231
+ key: "resolution",
659232
+ label: "Set Stream Resolution",
659233
+ detail: formatLiveCameraResolution(resolution)
659234
+ },
659235
+ {
659236
+ key: "preview",
659237
+ label: "Preview Camera",
659238
+ detail: "capture frame + ASCII preview"
659239
+ },
659240
+ {
659241
+ key: "infer",
659242
+ label: "Infer Camera Now",
659243
+ detail: "run bounded vision inference on this camera"
659244
+ },
659245
+ {
659246
+ key: "auto-orient",
659247
+ label: "Auto-Orient Camera",
659248
+ detail: "detect persistent rotation correction"
659249
+ },
659250
+ {
659251
+ key: "cycle-rotation",
659252
+ label: "Cycle Rotation",
659253
+ detail: formatCameraRotation(manager.getCameraRotation(device.id))
659254
+ },
659255
+ { key: "rotate-0", label: "Rotation: Upright", detail: "0 degrees" },
659256
+ { key: "rotate-90", label: "Rotation: Clockwise", detail: "90 degrees" },
659257
+ { key: "rotate-180", label: "Rotation: 180", detail: "upside down correction" },
659258
+ { key: "rotate-270", label: "Rotation: Counter-clockwise", detail: "270 degrees" }
659259
+ ];
659260
+ const result = await tuiSelect({
659261
+ items,
659262
+ title: `Live Camera — ${device.id}`,
659263
+ activeKey: selected ? "select" : enabled2 ? "toggle" : void 0,
659264
+ rl: ctx3.rl,
659265
+ availableRows: ctx3.availableContentRows?.(),
659266
+ skipKeys: liveSkipKeys(items)
659267
+ });
659268
+ if (!result.confirmed || !result.key) return;
659269
+ switch (result.key) {
659270
+ case "select":
659271
+ manager.configure({ selectedCamera: device.id, videoEnabled: true });
659272
+ manager.setCameraStreamEnabled(device.id, true);
659273
+ renderInfo(`Selected camera ${device.id}.`);
659274
+ continue;
659275
+ case "toggle":
659276
+ manager.setCameraStreamEnabled(device.id, !enabled2);
659277
+ renderInfo(`${!enabled2 ? "Enabled" : "Disabled"} camera stream ${device.id}.`);
659278
+ continue;
659279
+ case "resolution": {
659280
+ const next = await chooseLiveCameraResolution(ctx3, manager, device.id);
659281
+ if (next) {
659282
+ manager.setCameraStreamResolution(device.id, next);
659283
+ renderInfo(`Camera ${device.id} stream resolution set to ${formatLiveCameraResolution(next)}.`);
659284
+ }
659285
+ continue;
659286
+ }
659287
+ case "preview":
659288
+ renderLivePreview(await manager.previewCamera(device.id));
659289
+ continue;
659290
+ case "infer":
659291
+ manager.setCameraStreamEnabled(device.id, true);
659292
+ renderInfo(await manager.sampleCameraNow(device.id, true, { forceInferenceNow: true }));
659293
+ continue;
659294
+ case "auto-orient":
659295
+ renderInfo("Detecting camera orientation...");
659296
+ renderInfo(await manager.autoOrientCamera(device.id));
659297
+ continue;
659298
+ case "cycle-rotation": {
659299
+ const orientation = manager.cycleCameraRotation(device.id);
659300
+ renderInfo(orientation ? `Camera rotation set to ${formatCameraRotation(orientation.rotation)} for ${device.id}.` : "No camera selected.");
659301
+ continue;
659302
+ }
659303
+ case "rotate-0":
659304
+ case "rotate-90":
659305
+ case "rotate-180":
659306
+ case "rotate-270": {
659307
+ const rotation = normalizeLiveCameraRotation(result.key.replace("rotate-", ""));
659308
+ const orientation = manager.setCameraRotation(device.id, rotation, "manual", `/live camera menu ${result.key}`);
659309
+ renderInfo(orientation ? `Camera rotation set to ${formatCameraRotation(orientation.rotation)} for ${device.id}.` : "No camera selected.");
659310
+ continue;
659311
+ }
659312
+ default:
659313
+ return;
659314
+ }
659315
+ }
659316
+ }
658709
659317
  async function handleLiveCommand(ctx3, arg) {
658710
659318
  const manager = getLiveSensorManager(ctx3.repoRoot);
658711
659319
  attachLiveSinks(ctx3, manager);
@@ -658777,6 +659385,40 @@ async function handleLiveCommand(ctx3, arg) {
658777
659385
  }
658778
659386
  return;
658779
659387
  }
659388
+ if (sub2 === "resolution" || sub2 === "res" || sub2 === "size") {
659389
+ await ensureLiveInventory(manager);
659390
+ const tokens = parts.slice(1);
659391
+ const rawResolution = tokens.pop();
659392
+ if (!rawResolution) {
659393
+ renderWarning("Usage: /live resolution [camera] 720p|1080p|1440p|4k|native");
659394
+ return;
659395
+ }
659396
+ const device = tokens.join(" ") || manager.getConfig().selectedCamera;
659397
+ if (!device) {
659398
+ renderWarning("No camera selected. Use /live camera <device> first.");
659399
+ return;
659400
+ }
659401
+ try {
659402
+ const resolution = normalizeLiveCameraResolution(rawResolution);
659403
+ manager.setCameraStreamResolution(device, resolution);
659404
+ renderInfo(`Camera ${device} stream resolution set to ${formatLiveCameraResolution(resolution)}.`);
659405
+ } catch (err) {
659406
+ renderWarning(err instanceof Error ? err.message : String(err));
659407
+ }
659408
+ return;
659409
+ }
659410
+ if (sub2 === "camera-on" || sub2 === "camera-off" || sub2 === "camera-enable" || sub2 === "camera-disable") {
659411
+ await ensureLiveInventory(manager);
659412
+ const device = value2 || manager.getConfig().selectedCamera;
659413
+ if (!device) {
659414
+ renderWarning("No camera selected. Use /live camera <device> first.");
659415
+ return;
659416
+ }
659417
+ const enabled2 = sub2 === "camera-on" || sub2 === "camera-enable";
659418
+ manager.setCameraStreamEnabled(device, enabled2);
659419
+ renderInfo(`${enabled2 ? "Enabled" : "Disabled"} camera stream ${device}.`);
659420
+ return;
659421
+ }
658780
659422
  if (sub2 === "video") {
658781
659423
  const cfg = manager.getConfig();
658782
659424
  manager.configure({ videoEnabled: setBool(value2, !cfg.videoEnabled) });
@@ -658902,6 +659544,11 @@ async function showLiveMenu(ctx3, manager) {
658902
659544
  label: "Select Camera",
658903
659545
  detail: `${devices.video.length} device(s)`
658904
659546
  },
659547
+ ...devices.video.map((device, index) => ({
659548
+ key: `camera-device:${index}`,
659549
+ label: `Camera: ${device.id}`,
659550
+ detail: `${liveCameraStreamSummary(manager, device.id)} — ${device.label}${device.detail ? ` — ${device.detail}` : ""}`
659551
+ })),
658905
659552
  {
658906
659553
  key: "preview-camera",
658907
659554
  label: "View Selected Camera",
@@ -658996,6 +659643,12 @@ async function showLiveMenu(ctx3, manager) {
658996
659643
  }
658997
659644
  });
658998
659645
  if (!result.confirmed || !result.key) return;
659646
+ if (result.key.startsWith("camera-device:")) {
659647
+ const index = Number(result.key.slice("camera-device:".length));
659648
+ const device = devices.video[index];
659649
+ if (device) await showLiveCameraMenu(ctx3, manager, device);
659650
+ continue;
659651
+ }
658999
659652
  switch (result.key) {
659000
659653
  case "toggle-video":
659001
659654
  manager.configure({ videoEnabled: !cfg.videoEnabled });
@@ -663849,15 +664502,15 @@ function refreshLocalGpuMetricsIfStale() {
663849
664502
  });
663850
664503
  }
663851
664504
  function getLocalSystemMetrics() {
663852
- const cpus6 = nodeOs.cpus();
664505
+ const cpus7 = nodeOs.cpus();
663853
664506
  const loads = nodeOs.loadavg();
663854
664507
  const totalMem = nodeOs.totalmem();
663855
664508
  const freeMem = nodeOs.freemem();
663856
664509
  const usedMem = totalMem - freeMem;
663857
664510
  const result = {
663858
- cpuModel: cpus6[0]?.model?.trim() ?? "unknown",
663859
- cpuCores: cpus6.length,
663860
- cpuUtil: Math.min(100, Math.round(loads[0] / cpus6.length * 100)),
664511
+ cpuModel: cpus7[0]?.model?.trim() ?? "unknown",
664512
+ cpuCores: cpus7.length,
664513
+ cpuUtil: Math.min(100, Math.round(loads[0] / cpus7.length * 100)),
663861
664514
  memTotalGB: Math.round(totalMem / (1024 * 1024 * 1024) * 10) / 10,
663862
664515
  memUsedGB: Math.round(usedMem / (1024 * 1024 * 1024) * 10) / 10,
663863
664516
  memUtil: Math.round(usedMem / totalMem * 100),
@@ -665722,7 +666375,7 @@ import {
665722
666375
  writeFileSync as writeFileSync74,
665723
666376
  renameSync as renameSync13,
665724
666377
  mkdirSync as mkdirSync86,
665725
- unlinkSync as unlinkSync29,
666378
+ unlinkSync as unlinkSync30,
665726
666379
  appendFileSync as appendFileSync16
665727
666380
  } from "node:fs";
665728
666381
  import { join as join156, resolve as resolve64 } from "node:path";
@@ -665761,7 +666414,7 @@ function persistInFlight(j) {
665761
666414
  function deleteInFlightFile(id2) {
665762
666415
  try {
665763
666416
  const p2 = inFlightPath(id2);
665764
- if (existsSync143(p2)) unlinkSync29(p2);
666417
+ if (existsSync143(p2)) unlinkSync30(p2);
665765
666418
  } catch {
665766
666419
  }
665767
666420
  }
@@ -666147,7 +666800,7 @@ function drainCheckins(sessionId) {
666147
666800
  try {
666148
666801
  const raw = readFileSync116(fp, "utf-8");
666149
666802
  try {
666150
- unlinkSync29(fp);
666803
+ unlinkSync30(fp);
666151
666804
  } catch {
666152
666805
  }
666153
666806
  if (!raw.trim()) return [];
@@ -666195,7 +666848,7 @@ function deleteSession2(id2) {
666195
666848
  try {
666196
666849
  const p2 = sessionPath(id2);
666197
666850
  if (existsSync143(p2)) {
666198
- unlinkSync29(p2);
666851
+ unlinkSync30(p2);
666199
666852
  removed = true;
666200
666853
  }
666201
666854
  } catch {
@@ -671827,7 +672480,7 @@ var init_bless_engine = __esm({
671827
672480
  });
671828
672481
 
671829
672482
  // packages/cli/src/tui/dmn-engine.ts
671830
- import { existsSync as existsSync150, readFileSync as readFileSync122, writeFileSync as writeFileSync79, mkdirSync as mkdirSync92, readdirSync as readdirSync53, unlinkSync as unlinkSync30 } from "node:fs";
672483
+ import { existsSync as existsSync150, readFileSync as readFileSync122, writeFileSync as writeFileSync79, mkdirSync as mkdirSync92, readdirSync as readdirSync53, unlinkSync as unlinkSync31 } from "node:fs";
671831
672484
  import { join as join163, basename as basename36 } from "node:path";
671832
672485
  import { exec as exec6 } from "node:child_process";
671833
672486
  import { promisify as promisify8 } from "node:util";
@@ -672764,7 +673417,7 @@ If decision is GO, selectedTask MUST be a fully-populated object (NEVER null)
672764
673417
  for (const file of files) {
672765
673418
  if (!keep.has(file)) {
672766
673419
  try {
672767
- unlinkSync30(join163(this.historyDir, file));
673420
+ unlinkSync31(join163(this.historyDir, file));
672768
673421
  } catch {
672769
673422
  }
672770
673423
  }
@@ -672842,7 +673495,7 @@ function appraiseEvent(event) {
672842
673495
  return null;
672843
673496
  }
672844
673497
  }
672845
- function clamp9(value2, min, max) {
673498
+ function clamp10(value2, min, max) {
672846
673499
  return Math.max(min, Math.min(max, value2));
672847
673500
  }
672848
673501
  var BASELINE_VALENCE, BASELINE_AROUSAL, DECAY_HALF_LIFE_MS, LABEL_UPDATE_INTERVAL_MS, DISTRESS_THRESHOLD, REFLECTION_COOLDOWN_MS, REFLECTION_MIN_EVENTS, LABEL_REGEN_THRESHOLD, EmotionEngine;
@@ -672981,8 +673634,8 @@ var init_emotion_engine = __esm({
672981
673634
  if (this.consecutiveFailures >= 2) {
672982
673635
  momentum = 1 + (this.consecutiveFailures - 1) * 0.25;
672983
673636
  }
672984
- this.state.valence = clamp9(this.state.valence + delta.valence * momentum, -1, 1);
672985
- this.state.arousal = clamp9(this.state.arousal + delta.arousal * momentum, 0, 1);
673637
+ this.state.valence = clamp10(this.state.valence + delta.valence * momentum, -1, 1);
673638
+ this.state.arousal = clamp10(this.state.arousal + delta.arousal * momentum, 0, 1);
672986
673639
  this.state.updatedAt = Date.now();
672987
673640
  const deterministicLabel = labelFromCoordinates(this.state.valence, this.state.arousal);
672988
673641
  this.state.label = deterministicLabel.label;
@@ -674567,7 +675220,7 @@ import {
674567
675220
  mkdirSync as mkdirSync93,
674568
675221
  readFileSync as readFileSync123,
674569
675222
  statSync as statSync55,
674570
- unlinkSync as unlinkSync31,
675223
+ unlinkSync as unlinkSync32,
674571
675224
  writeFileSync as writeFileSync80
674572
675225
  } from "node:fs";
674573
675226
  import { mkdir as mkdir22 } from "node:fs/promises";
@@ -674820,7 +675473,7 @@ function scopedTool(base3, root, mode) {
674820
675473
  }
674821
675474
  } else if (restoredEditPath) {
674822
675475
  try {
674823
- unlinkSync31(restoredEditPath);
675476
+ unlinkSync32(restoredEditPath);
674824
675477
  } catch {
674825
675478
  }
674826
675479
  }
@@ -674965,7 +675618,7 @@ function rememberCreated(root, absPath) {
674965
675618
  const previousPath = resolve66(root, previous.storedRel);
674966
675619
  if (isInside(resolve66(root), previousPath) && existsSync151(previousPath)) {
674967
675620
  try {
674968
- unlinkSync31(previousPath);
675621
+ unlinkSync32(previousPath);
674969
675622
  } catch {
674970
675623
  }
674971
675624
  }
@@ -674985,7 +675638,7 @@ function rememberCreated(root, absPath) {
674985
675638
  const storedAbs = join164(root, storedRel);
674986
675639
  writeFileSync80(storedAbs, Buffer.concat([prefix, encrypted]));
674987
675640
  try {
674988
- unlinkSync31(guarded.path.abs);
675641
+ unlinkSync32(guarded.path.abs);
674989
675642
  } catch {
674990
675643
  }
674991
675644
  manifest.objects = manifest.objects || {};
@@ -675063,7 +675716,7 @@ function materializeTelegramCreativeArtifactForSend(root, rawPath) {
675063
675716
  path: staged,
675064
675717
  cleanup: () => {
675065
675718
  try {
675066
- unlinkSync31(staged);
675719
+ unlinkSync32(staged);
675067
675720
  } catch {
675068
675721
  }
675069
675722
  }
@@ -676000,7 +676653,7 @@ import {
676000
676653
  readdirSync as readdirSync54,
676001
676654
  readFileSync as readFileSync124,
676002
676655
  writeFileSync as writeFileSync81,
676003
- unlinkSync as unlinkSync32
676656
+ unlinkSync as unlinkSync33
676004
676657
  } from "node:fs";
676005
676658
  import { join as join165 } from "node:path";
676006
676659
  import { createHash as createHash39 } from "node:crypto";
@@ -676738,7 +677391,7 @@ function pruneTelegramChannelDaydreams(repoRoot, sessionKey, keep = DAYDREAM_ART
676738
677391
  let removed = 0;
676739
677392
  for (const file of toRemove) {
676740
677393
  try {
676741
- unlinkSync32(join165(dir, file));
677394
+ unlinkSync33(join165(dir, file));
676742
677395
  removed++;
676743
677396
  } catch {
676744
677397
  }
@@ -678505,7 +679158,7 @@ __export(vision_ingress_exports, {
678505
679158
  resolveVisionModel: () => resolveVisionModel,
678506
679159
  runVisionIngress: () => runVisionIngress
678507
679160
  });
678508
- import { existsSync as existsSync153, readFileSync as readFileSync125, unlinkSync as unlinkSync33 } from "node:fs";
679161
+ import { existsSync as existsSync153, readFileSync as readFileSync125, unlinkSync as unlinkSync34 } from "node:fs";
678509
679162
  import { join as join166 } from "node:path";
678510
679163
  async function isTesseractAvailable() {
678511
679164
  try {
@@ -678563,7 +679216,7 @@ async function advancedOcr(imagePath) {
678563
679216
  const text2 = readFileSync125(txtFile, "utf-8").trim();
678564
679217
  if (text2.length > 0) results.push(text2);
678565
679218
  try {
678566
- unlinkSync33(txtFile);
679219
+ unlinkSync34(txtFile);
678567
679220
  } catch {
678568
679221
  }
678569
679222
  }
@@ -678742,7 +679395,7 @@ var init_vision_ingress = __esm({
678742
679395
  import {
678743
679396
  mkdirSync as mkdirSync95,
678744
679397
  existsSync as existsSync154,
678745
- unlinkSync as unlinkSync34,
679398
+ unlinkSync as unlinkSync35,
678746
679399
  readdirSync as readdirSync55,
678747
679400
  statSync as statSync56,
678748
679401
  readFileSync as readFileSync126,
@@ -689795,7 +690448,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`
689795
690448
  if (prior.pid !== process.pid) return;
689796
690449
  } catch {
689797
690450
  }
689798
- unlinkSync34(lockFile);
690451
+ unlinkSync35(lockFile);
689799
690452
  } catch {
689800
690453
  }
689801
690454
  }
@@ -696351,7 +697004,7 @@ ${text2}`.trim()
696351
697004
  for (const [key, entry] of this.mediaCache) {
696352
697005
  if (now2 - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
696353
697006
  try {
696354
- unlinkSync34(entry.localPath);
697007
+ unlinkSync35(entry.localPath);
696355
697008
  } catch {
696356
697009
  }
696357
697010
  this.mediaCache.delete(key);
@@ -697801,6 +698454,7 @@ var init_voicechat = __esm({
697801
698454
  "packages/cli/src/tui/voicechat.ts"() {
697802
698455
  "use strict";
697803
698456
  init_conversation_context();
698457
+ init_live_resource_arbiter();
697804
698458
  VAD_SILENCE_MS = 3e3;
697805
698459
  MAX_SEGMENT_MS = 6500;
697806
698460
  SUMMARY_INJECTION_INTERVAL = 4;
@@ -697856,6 +698510,7 @@ Rules:
697856
698510
  lastSignalScore = null;
697857
698511
  listenPausedForResponse = false;
697858
698512
  lastAgentSpeech = null;
698513
+ liveResourceLease = null;
697859
698514
  // Abort control for inference
697860
698515
  abortController = null;
697861
698516
  // Callbacks
@@ -697907,9 +698562,45 @@ Rules:
697907
698562
  if (this._state === next) return;
697908
698563
  const prev = this._state;
697909
698564
  this._state = next;
698565
+ this.updateLiveResourceLease(next);
697910
698566
  this.onStateChange(next);
697911
698567
  this.emit("stateChange", { from: prev, to: next });
697912
698568
  }
698569
+ updateLiveResourceLease(state) {
698570
+ if (state === "CAPTURING") {
698571
+ this.holdLiveResources("asr-capture", 92, 1e4, "voicechat ASR capture");
698572
+ return;
698573
+ }
698574
+ if (state === "TRANSCRIBING") {
698575
+ this.holdLiveResources("asr-final", 94, 18e3, "voicechat final ASR/transcript handoff");
698576
+ return;
698577
+ }
698578
+ if (state === "THINKING") {
698579
+ this.holdLiveResources("voice-llm", 100, 6e4, "voicechat live LLM inference");
698580
+ return;
698581
+ }
698582
+ if (state === "SPEAKING") {
698583
+ this.holdLiveResources("tts", 84, 24e3, "voicechat TTS playback/echo guard");
698584
+ return;
698585
+ }
698586
+ if (state === "IDLE" || state === "LISTENING") {
698587
+ this.releaseLiveResources();
698588
+ }
698589
+ }
698590
+ holdLiveResources(owner, priority, ttlMs, reason) {
698591
+ this.liveResourceLease?.release();
698592
+ this.liveResourceLease = getLiveResourceArbiter().claim({
698593
+ owner: `voicechat:${owner}`,
698594
+ priority,
698595
+ ttlMs,
698596
+ reason,
698597
+ suppress: ["vision"]
698598
+ });
698599
+ }
698600
+ releaseLiveResources() {
698601
+ this.liveResourceLease?.release();
698602
+ this.liveResourceLease = null;
698603
+ }
697913
698604
  // ---------------------------------------------------------------------------
697914
698605
  // Start / Stop
697915
698606
  // ---------------------------------------------------------------------------
@@ -698019,6 +698710,7 @@ Rules:
698019
698710
  await this.listen.stop();
698020
698711
  } catch {
698021
698712
  }
698713
+ this.releaseLiveResources();
698022
698714
  this.setState("IDLE");
698023
698715
  if (this.verbose) this.onStatus("VoiceChat ended");
698024
698716
  this.emit("stopped");
@@ -698037,6 +698729,12 @@ Rules:
698037
698729
  this.emit("voiceEchoFiltered", echo);
698038
698730
  return;
698039
698731
  }
698732
+ this.holdLiveResources(
698733
+ isFinal ? "asr-final" : "asr-capture",
698734
+ isFinal ? 94 : 92,
698735
+ isFinal ? 18e3 : 1e4,
698736
+ isFinal ? "voicechat final ASR incoming" : "voicechat partial ASR incoming"
698737
+ );
698040
698738
  if (this._state === "LISTENING") {
698041
698739
  this.setState("CAPTURING");
698042
698740
  this.resetCaptureState();
@@ -699957,7 +700655,7 @@ var init_access_policy = __esm({
699957
700655
 
699958
700656
  // packages/cli/src/api/project-preferences.ts
699959
700657
  import { createHash as createHash43 } from "node:crypto";
699960
- import { existsSync as existsSync156, mkdirSync as mkdirSync97, readFileSync as readFileSync128, renameSync as renameSync15, writeFileSync as writeFileSync84, unlinkSync as unlinkSync35 } from "node:fs";
700658
+ import { existsSync as existsSync156, mkdirSync as mkdirSync97, readFileSync as readFileSync128, renameSync as renameSync15, writeFileSync as writeFileSync84, unlinkSync as unlinkSync36 } from "node:fs";
699961
700659
  import { homedir as homedir57 } from "node:os";
699962
700660
  import { join as join169, resolve as resolve69 } from "node:path";
699963
700661
  import { randomUUID as randomUUID20 } from "node:crypto";
@@ -700018,7 +700716,7 @@ function writeProjectPreferences(root, partial) {
700018
700716
  } catch {
700019
700717
  }
700020
700718
  try {
700021
- unlinkSync35(tmp);
700719
+ unlinkSync36(tmp);
700022
700720
  } catch {
700023
700721
  }
700024
700722
  throw err;
@@ -700029,7 +700727,7 @@ function deleteProjectPreferences(root) {
700029
700727
  try {
700030
700728
  const file = prefsPath(root);
700031
700729
  if (!existsSync156(file)) return false;
700032
- unlinkSync35(file);
700730
+ unlinkSync36(file);
700033
700731
  return true;
700034
700732
  } catch {
700035
700733
  return false;
@@ -718980,7 +719678,7 @@ import {
718980
719678
  existsSync as existsSync168,
718981
719679
  watch as fsWatch4,
718982
719680
  renameSync as renameSync17,
718983
- unlinkSync as unlinkSync36,
719681
+ unlinkSync as unlinkSync37,
718984
719682
  statSync as statSync62,
718985
719683
  openSync as openSync6,
718986
719684
  readSync as readSync2,
@@ -720315,13 +721013,13 @@ function pruneOldJobs() {
720315
721013
  const ts = ageRef ? Date.parse(ageRef) : NaN;
720316
721014
  if (Number.isFinite(ts) && ts < cutoffMs) {
720317
721015
  try {
720318
- unlinkSync36(path12);
721016
+ unlinkSync37(path12);
720319
721017
  } catch {
720320
721018
  }
720321
721019
  const outFile = path12.replace(/\.json$/, ".output");
720322
721020
  if (existsSync168(outFile)) {
720323
721021
  try {
720324
- unlinkSync36(outFile);
721022
+ unlinkSync37(outFile);
720325
721023
  } catch {
720326
721024
  }
720327
721025
  }
@@ -720331,7 +721029,7 @@ function pruneOldJobs() {
720331
721029
  }
720332
721030
  } catch {
720333
721031
  try {
720334
- unlinkSync36(path12);
721032
+ unlinkSync37(path12);
720335
721033
  pruned++;
720336
721034
  } catch {
720337
721035
  }
@@ -720643,7 +721341,7 @@ function atomicJobWrite(dir, id2, job) {
720643
721341
  } catch {
720644
721342
  }
720645
721343
  try {
720646
- unlinkSync36(tmpPath);
721344
+ unlinkSync37(tmpPath);
720647
721345
  } catch {
720648
721346
  }
720649
721347
  }
@@ -724824,7 +725522,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
724824
725522
  return;
724825
725523
  }
724826
725524
  const { tmpdir: tmpdir26 } = await import("node:os");
724827
- const { writeFileSync: writeFileSync95, unlinkSync: unlinkSync37 } = await import("node:fs");
725525
+ const { writeFileSync: writeFileSync95, unlinkSync: unlinkSync38 } = await import("node:fs");
724828
725526
  const { join: pjoin } = await import("node:path");
724829
725527
  const tmpPath = pjoin(
724830
725528
  tmpdir26(),
@@ -724842,7 +725540,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
724842
725540
  });
724843
725541
  } finally {
724844
725542
  try {
724845
- unlinkSync37(tmpPath);
725543
+ unlinkSync38(tmpPath);
724846
725544
  } catch {
724847
725545
  }
724848
725546
  }
@@ -728085,8 +728783,8 @@ function startApiServer(options2 = {}) {
728085
728783
  job.startedAt ?? job.completedAt ?? 0
728086
728784
  ).getTime();
728087
728785
  if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
728088
- const { unlinkSync: unlinkSync37 } = require4("node:fs");
728089
- unlinkSync37(jobPath);
728786
+ const { unlinkSync: unlinkSync38 } = require4("node:fs");
728787
+ unlinkSync38(jobPath);
728090
728788
  }
728091
728789
  } catch {
728092
728790
  }
@@ -737290,11 +737988,21 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
737290
737988
  voiceEngine.synthesizeToPCM(text2).then((result) => {
737291
737989
  if (result && session?.isActive) {
737292
737990
  const { pcm, sampleRate } = result;
737991
+ const durationMs = pcm.length / 2 / sampleRate * 1e3;
737992
+ const ttsLease = getLiveResourceArbiter().claim({
737993
+ owner: `call-tts:${id2}`,
737994
+ priority: 84,
737995
+ ttlMs: Math.min(45e3, durationMs + 3e3),
737996
+ reason: "cloud call TTS playback/echo guard",
737997
+ suppress: ["vision"]
737998
+ });
737293
737999
  session.sendSpeakingStateToClient(id2, true);
737294
738000
  session.sendAudioToClient(id2, pcm, sampleRate);
737295
- const durationMs = pcm.length / 2 / sampleRate * 1e3;
737296
738001
  setTimeout(
737297
- () => session.sendSpeakingStateToClient(id2, false),
738002
+ () => {
738003
+ session.sendSpeakingStateToClient(id2, false);
738004
+ ttsLease.release();
738005
+ },
737298
738006
  durationMs
737299
738007
  );
737300
738008
  }
@@ -737340,6 +738048,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
737340
738048
  () => renderVoiceSessionTranscript("user", text2)
737341
738049
  );
737342
738050
  voiceSession?.sendTranscript("user", text2);
738051
+ getLiveResourceArbiter().claim({
738052
+ owner: "call-asr",
738053
+ priority: 92,
738054
+ ttlMs: 35e3,
738055
+ reason: "cloud call ASR accepted; reserving compute for call-agent inference",
738056
+ suppress: ["vision"]
738057
+ });
737343
738058
  for (const [clientId, agent] of callSubAgents) {
737344
738059
  agent.handleTranscript(text2);
737345
738060
  }
@@ -737406,10 +738121,20 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
737406
738121
  const session = voiceSession;
737407
738122
  voiceEngine.onPCMOutput = (pcm, sampleRate) => {
737408
738123
  if (session?.isActive) {
738124
+ const durationMs = pcm.length / 2 / sampleRate * 1e3;
738125
+ const ttsLease = getLiveResourceArbiter().claim({
738126
+ owner: "call-broadcast-tts",
738127
+ priority: 84,
738128
+ ttlMs: Math.min(45e3, durationMs + 3e3),
738129
+ reason: "cloud call broadcast TTS playback/echo guard",
738130
+ suppress: ["vision"]
738131
+ });
737409
738132
  session.sendSpeakingState(true);
737410
738133
  session.sendAudioToClients(pcm, sampleRate);
737411
- const durationMs = pcm.length / 2 / sampleRate * 1e3;
737412
- setTimeout(() => session.sendSpeakingState(false), durationMs);
738134
+ setTimeout(() => {
738135
+ session.sendSpeakingState(false);
738136
+ ttsLease.release();
738137
+ }, durationMs);
737413
738138
  }
737414
738139
  };
737415
738140
  }
@@ -740006,6 +740731,7 @@ var init_interactive = __esm({
740006
740731
  init_expose();
740007
740732
  init_p2p();
740008
740733
  init_call_agent();
740734
+ init_live_resource_arbiter();
740009
740735
  init_config();
740010
740736
  init_secret_redactor();
740011
740737
  init_profiles();