omnius 1.0.404 → 1.0.406

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
@@ -543187,14 +543187,14 @@ var init_camera_capture = __esm({
543187
543187
  };
543188
543188
  CameraCaptureTool = class {
543189
543189
  name = "camera_capture";
543190
- description = "Access system cameras to capture images. Supports USB/CSI webcams (v4l2), Dropbear-style multi-camera router topology, RealSense/depth capability metadata, AND Kandao QooCam 8K/Pro 360 cameras (auto-connects via WiFi). Actions: 'list' to enumerate all cameras, 'capture' to grab a JPEG frame, 'info' to query camera capabilities, 'router_config' to emit a camera/depth topology plan, and 'profiles' to list built-in profiles. Use this when you need to SEE the physical environment — take a photo, check what's on a desk, read a whiteboard, inspect hardware, or observe any real-world scene. The captured image can be analyzed with vision tools.";
543190
+ description = "Access system cameras to capture images. Supports USB/CSI webcams (v4l2), Dropbear-style multi-camera router topology, RealSense/depth capability metadata, AND Kandao QooCam 8K/Pro 360 cameras (auto-connects via WiFi). Defaults to 'capture' when no action is provided. Actions: 'list' to enumerate all cameras, 'capture' to grab a JPEG frame, 'info' to query camera capabilities, 'router_config' to emit a camera/depth topology plan, and 'profiles' to list built-in profiles. Use this when you need to SEE the physical environment — take a photo, check what's on a desk, read a whiteboard, inspect hardware, or observe any real-world scene. The captured image can be analyzed with vision tools.";
543191
543191
  parameters = {
543192
543192
  type: "object",
543193
543193
  properties: {
543194
543194
  action: {
543195
543195
  type: "string",
543196
543196
  enum: ["list", "capture", "info", "router_config", "topology", "profiles"],
543197
- description: "Action to perform: list cameras, capture frame, get camera info, emit router topology, or list camera profiles"
543197
+ description: "Action to perform. Defaults to capture. Use list to enumerate cameras, capture to grab a frame, info for camera capabilities, router_config/topology for a camera/depth plan, or profiles for built-in profiles."
543198
543198
  },
543199
543199
  device: {
543200
543200
  type: "string",
@@ -543226,10 +543226,10 @@ var init_camera_capture = __esm({
543226
543226
  description: "Return format for list/router_config/profiles. Default text."
543227
543227
  }
543228
543228
  },
543229
- required: ["action"]
543229
+ required: []
543230
543230
  };
543231
543231
  async execute(args) {
543232
- const action = args["action"];
543232
+ const action = typeof args["action"] === "string" && args["action"].trim() ? args["action"].trim().toLowerCase() : "capture";
543233
543233
  const start2 = performance.now();
543234
543234
  try {
543235
543235
  switch (action) {
@@ -543245,7 +543245,7 @@ var init_camera_capture = __esm({
543245
543245
  case "profiles":
543246
543246
  return this.listProfiles(args, start2);
543247
543247
  default:
543248
- return { success: false, output: "", error: `Unknown action: ${action}. Use list, capture, info, router_config, or profiles.`, durationMs: performance.now() - start2 };
543248
+ return { success: false, output: "", error: `Unknown action: ${action}. Use list, capture, info, router_config, topology, or profiles.`, durationMs: performance.now() - start2 };
543249
543249
  }
543250
543250
  } catch (err) {
543251
543251
  return { success: false, output: "", error: `camera_capture error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
@@ -555840,13 +555840,24 @@ var init_live_media_loop = __esm({
555840
555840
  for (const face of result.faces.slice(0, 8)) {
555841
555841
  try {
555842
555842
  const rec = await visualMemory.execute({
555843
- action: "recognize",
555843
+ action: "identify",
555844
555844
  image: face.crop_path,
555845
555845
  auto_setup: false,
555846
555846
  timeout_ms: 15e3,
555847
555847
  format: "json"
555848
555848
  });
555849
555849
  face.identity_candidates = rec.success ? String(rec.llmContent || rec.output || "").slice(0, 1200) : rec.error;
555850
+ if (rec.success) {
555851
+ try {
555852
+ const parsed = JSON.parse(String(rec.llmContent || rec.output || "{}"));
555853
+ const identified = parsed.faces?.find((candidate) => candidate.identified && candidate.name);
555854
+ if (identified?.name) {
555855
+ face.identity = identified.name;
555856
+ face.confidence = identified.confidence ?? face.confidence;
555857
+ }
555858
+ } catch {
555859
+ }
555860
+ }
555850
555861
  } catch (err) {
555851
555862
  face.identity_candidates = err instanceof Error ? err.message : String(err);
555852
555863
  }
@@ -601917,6 +601928,166 @@ function nowIso3(ms) {
601917
601928
  function cleanPreview(value2, maxChars) {
601918
601929
  return String(value2 ?? "").replace(/\r/g, "").split("\n").map((line) => line.trimEnd()).filter((line) => line.trim().length > 0).join("\n").slice(0, maxChars);
601919
601930
  }
601931
+ function boundedText(value2, maxChars) {
601932
+ return cleanPreview(value2, maxChars).replace(/\n{3,}/g, "\n\n");
601933
+ }
601934
+ function eventAge(now2, observedAt) {
601935
+ return `${Math.max(0, Math.round((now2 - observedAt) / 1e3))}s`;
601936
+ }
601937
+ function stableEventId(kind, source, observedAt, suffix) {
601938
+ const compact4 = suffix.replace(/[^a-z0-9_.:-]+/gi, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "event";
601939
+ return `${kind}:${source}:${Math.round(observedAt)}:${compact4}`;
601940
+ }
601941
+ function stablePersonId(source, observedAt, suffix) {
601942
+ const compact4 = suffix.replace(/[^a-z0-9_.:-]+/gi, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "person";
601943
+ return `person:${source}:${Math.round(observedAt)}:${compact4}`;
601944
+ }
601945
+ function mergeRecentById(existing, incoming, limit) {
601946
+ const merged = /* @__PURE__ */ new Map();
601947
+ for (const item of [...existing ?? [], ...incoming]) merged.set(item.id, item);
601948
+ return [...merged.values()].sort((a2, b) => b.observedAt - a2.observedAt).slice(0, limit);
601949
+ }
601950
+ function parseJsonObject3(value2) {
601951
+ if (typeof value2 !== "string" || !value2.trim()) return null;
601952
+ try {
601953
+ const parsed = JSON.parse(value2);
601954
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : null;
601955
+ } catch {
601956
+ return null;
601957
+ }
601958
+ }
601959
+ function parseLiveMediaPayload(value2) {
601960
+ const parsed = parseJsonObject3(value2);
601961
+ if (!parsed) return null;
601962
+ if (!Array.isArray(parsed["objects"]) && !Array.isArray(parsed["tracks"]) && !Array.isArray(parsed["faces"])) return null;
601963
+ return parsed;
601964
+ }
601965
+ function observedAtFromOffset(sampledAt, payload, offsetSec) {
601966
+ const duration = Math.max(0, Number(payload.duration_observed_sec ?? 0));
601967
+ const offset = Math.max(0, Number(offsetSec ?? duration));
601968
+ if (!duration) return sampledAt;
601969
+ return Math.round(sampledAt - Math.max(0, duration - offset) * 1e3);
601970
+ }
601971
+ function parseFaceIdentity(face) {
601972
+ if (typeof face.identity === "string" && face.identity.trim()) {
601973
+ return {
601974
+ status: "known",
601975
+ name: face.identity.trim(),
601976
+ confidence: typeof face.confidence === "number" ? face.confidence : void 0,
601977
+ evidence: "identity field from live media loop"
601978
+ };
601979
+ }
601980
+ const raw = face.identity_candidates;
601981
+ const parsed = typeof raw === "string" ? parseJsonObject3(raw) : typeof raw === "object" && raw !== null ? raw : null;
601982
+ const faces = Array.isArray(parsed?.["faces"]) ? parsed["faces"] : [];
601983
+ const identified = faces.find((candidate) => candidate["identified"] === true && typeof candidate["name"] === "string" && candidate["name"]);
601984
+ if (identified) {
601985
+ return {
601986
+ status: "known",
601987
+ name: String(identified["name"]).trim(),
601988
+ confidence: typeof identified["confidence"] === "number" ? identified["confidence"] : void 0,
601989
+ evidence: "visual_memory identify match"
601990
+ };
601991
+ }
601992
+ const best = faces.find((candidate) => typeof candidate["confidence"] === "number");
601993
+ return {
601994
+ status: "unknown",
601995
+ confidence: typeof best?.["confidence"] === "number" ? best["confidence"] : typeof face.confidence === "number" ? face.confidence : void 0,
601996
+ evidence: typeof raw === "string" && raw.trim() ? boundedText(raw, 500) : "no known visual-memory face match"
601997
+ };
601998
+ }
601999
+ function observationsFromLiveMediaPayload(payload, sampledAt, fallbackSource) {
602000
+ if (!payload) return { events: [], people: [] };
602001
+ const source = String(payload.source || fallbackSource || "camera");
602002
+ const events = [];
602003
+ const people = [];
602004
+ for (const track of (payload.tracks ?? []).slice(0, 16)) {
602005
+ const label = String(track.label || "object");
602006
+ const observedAt = observedAtFromOffset(sampledAt, payload, Number(track.last_seen_sec ?? track.first_seen_sec ?? 0));
602007
+ const trackId = track.track_id === void 0 || track.track_id === null ? "" : String(track.track_id);
602008
+ events.push({
602009
+ id: stableEventId("camera_track", source, observedAt, `${label}:${trackId}`),
602010
+ kind: "camera_track",
602011
+ observedAt,
602012
+ source,
602013
+ title: `Tracked ${label}`,
602014
+ summary: `track=${trackId || "none"} first=${Number(track.first_seen_sec ?? 0).toFixed(1)}s last=${Number(track.last_seen_sec ?? 0).toFixed(1)}s observations=${Number(track.observations ?? 0)} mean_conf=${Number(track.mean_confidence ?? 0).toFixed(2)}`,
602015
+ confidence: typeof track.mean_confidence === "number" ? track.mean_confidence : void 0,
602016
+ trackId
602017
+ });
602018
+ }
602019
+ for (const object of (payload.objects ?? []).slice(0, 24)) {
602020
+ const label = String(object.label || "object");
602021
+ const observedAt = observedAtFromOffset(sampledAt, payload, Number(object.timestamp_sec ?? 0));
602022
+ const trackId = object.track_id === void 0 || object.track_id === null ? "" : String(object.track_id);
602023
+ events.push({
602024
+ id: stableEventId("camera_object", source, observedAt, `${label}:${trackId}:${object.frame_index ?? ""}`),
602025
+ kind: "camera_object",
602026
+ observedAt,
602027
+ source,
602028
+ title: `Detected ${label}`,
602029
+ summary: `frame=${object.frame_index ?? "?"} t=${Number(object.timestamp_sec ?? 0).toFixed(1)}s conf=${Number(object.confidence ?? 0).toFixed(2)} track=${trackId || "none"} bbox=${JSON.stringify(object.bbox_xyxy ?? [])}`,
602030
+ confidence: typeof object.confidence === "number" ? object.confidence : void 0,
602031
+ trackId
602032
+ });
602033
+ }
602034
+ for (const face of (payload.faces ?? []).slice(0, 16)) {
602035
+ const observedAt = observedAtFromOffset(sampledAt, payload, Number(face.timestamp_sec ?? 0));
602036
+ const identity3 = parseFaceIdentity(face);
602037
+ const cropPath = typeof face.crop_path === "string" ? face.crop_path : void 0;
602038
+ events.push({
602039
+ id: stableEventId("camera_face", source, observedAt, cropPath || `${face.frame_index ?? ""}:${face.timestamp_sec ?? ""}`),
602040
+ kind: "camera_face",
602041
+ observedAt,
602042
+ source,
602043
+ title: identity3.status === "known" && identity3.name ? `Observed known face: ${identity3.name}` : "Observed unknown face",
602044
+ summary: `frame=${face.frame_index ?? "?"} t=${Number(face.timestamp_sec ?? 0).toFixed(1)}s conf=${Number(identity3.confidence ?? face.confidence ?? 0).toFixed(2)} crop=${cropPath ?? "none"} bbox=${JSON.stringify(face.bbox_xyxy ?? [])}`,
602045
+ confidence: identity3.confidence ?? face.confidence,
602046
+ evidencePath: cropPath
602047
+ });
602048
+ people.push({
602049
+ id: stablePersonId(source, observedAt, cropPath || `${face.frame_index ?? ""}:${face.timestamp_sec ?? ""}`),
602050
+ observedAt,
602051
+ source,
602052
+ status: identity3.status,
602053
+ name: identity3.name,
602054
+ confidence: identity3.confidence ?? face.confidence,
602055
+ cropPath,
602056
+ evidence: identity3.evidence
602057
+ });
602058
+ }
602059
+ const faceCount = people.length;
602060
+ if (faceCount === 0) {
602061
+ const personTracks = (payload.tracks ?? []).filter((track) => String(track.label || "").toLowerCase() === "person").slice(0, 8);
602062
+ for (const track of personTracks) {
602063
+ const observedAt = observedAtFromOffset(sampledAt, payload, Number(track.last_seen_sec ?? track.first_seen_sec ?? 0));
602064
+ const trackId = track.track_id === void 0 || track.track_id === null ? "" : String(track.track_id);
602065
+ people.push({
602066
+ id: stablePersonId(source, observedAt, `track:${trackId || track.label || "person"}`),
602067
+ observedAt,
602068
+ source,
602069
+ status: "unknown",
602070
+ confidence: typeof track.mean_confidence === "number" ? track.mean_confidence : void 0,
602071
+ trackId,
602072
+ evidence: "person-class object track; no face crop was available"
602073
+ });
602074
+ }
602075
+ }
602076
+ for (const hit of (payload.trigger_hits ?? []).slice(0, 8)) {
602077
+ const observedAt = sampledAt;
602078
+ const name10 = String(hit.triggerName || hit.matched || "visual trigger");
602079
+ events.push({
602080
+ id: stableEventId("visual_trigger", source, observedAt, name10),
602081
+ kind: "visual_trigger",
602082
+ observedAt,
602083
+ source,
602084
+ title: `Visual trigger: ${name10}`,
602085
+ summary: `matched=${String(hit.matched ?? "")} conf=${Number(hit.confidence ?? 0).toFixed(2)}`,
602086
+ confidence: typeof hit.confidence === "number" ? hit.confidence : void 0
602087
+ });
602088
+ }
602089
+ return { events, people };
602090
+ }
601920
602091
  function dedupeDevices(devices) {
601921
602092
  const seen = /* @__PURE__ */ new Set();
601922
602093
  const out = [];
@@ -602033,16 +602204,60 @@ function formatLiveSensorContextFromSnapshot(snapshot, opts = {}) {
602033
602204
  const activeAudio = snapshot.config.audioEnabled || snapshot.config.audioOutputEnabled || Boolean(snapshot.audio);
602034
602205
  if (!activeVideo && !activeAudio) return "";
602035
602206
  lines.push("<live-sensor-context>");
602207
+ lines.push("## LIVE SENSOR STATUS");
602036
602208
  lines.push("Live sensor context is operator-enabled ambient input. Treat it as current perceptual evidence for this turn; if it is stale, missing, or insufficient, use camera/audio tools to refresh before answering what you see or hear.");
602209
+ lines.push("Identity rule: never invent names for observed people. If a person is unknown and identity matters, ask the user or the person for their name, then store the association with visual_memory(action='enroll', image='<face crop>', name='<name>') when a face crop is available, or multimodal_memory(action='meet', person_name='<name>') when live voice/name context is available.");
602037
602210
  lines.push(`Snapshot file: ${liveSnapshotPath(snapshot.repoRoot)}`);
602038
602211
  lines.push(`Streams: video=${snapshot.config.videoEnabled ? "on" : "off"} infer=${snapshot.config.inferEnabled ? "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"}`);
602039
602212
  if (snapshot.config.selectedCamera) lines.push(`Selected camera: ${snapshot.config.selectedCamera}`);
602040
602213
  if (snapshot.config.selectedAudioInput) lines.push(`Selected audio input: ${snapshot.config.selectedAudioInput}`);
602041
602214
  if (snapshot.config.selectedAudioOutput) lines.push(`Selected audio output: ${snapshot.config.selectedAudioOutput}`);
602215
+ const cameraEvents = (snapshot.events ?? []).filter((event) => event.kind.startsWith("camera_") || event.kind === "visual_trigger").sort((a2, b) => b.observedAt - a2.observedAt).slice(0, 18);
602216
+ if (activeVideo) {
602217
+ lines.push("");
602218
+ lines.push("## LIVE CAMERA EVENTS");
602219
+ if (cameraEvents.length === 0) {
602220
+ lines.push("No structured camera events have been captured yet in this live session.");
602221
+ } else {
602222
+ for (const event of cameraEvents) {
602223
+ const stale = now2 - event.observedAt > maxAgeMs ? " STALE" : "";
602224
+ lines.push(`### ${event.title}`);
602225
+ lines.push(`timestamp: ${nowIso3(event.observedAt)} age=${eventAge(now2, event.observedAt)} source=${event.source} kind=${event.kind}${stale}`);
602226
+ if (event.confidence !== void 0) lines.push(`confidence: ${event.confidence.toFixed(2)}`);
602227
+ if (event.trackId) lines.push(`track_id: ${event.trackId}`);
602228
+ if (event.evidencePath) lines.push(`evidence: ${event.evidencePath}`);
602229
+ lines.push(`summary: ${boundedText(event.summary, 500)}`);
602230
+ }
602231
+ }
602232
+ const people = (snapshot.people ?? []).sort((a2, b) => b.observedAt - a2.observedAt).slice(0, 12);
602233
+ const known = people.filter((person) => person.status === "known");
602234
+ const unknown = people.filter((person) => person.status === "unknown");
602235
+ lines.push("");
602236
+ lines.push("## LIVE INDIVIDUALS");
602237
+ lines.push("Known individuals:");
602238
+ if (known.length === 0) {
602239
+ lines.push("- none currently recognized");
602240
+ } else {
602241
+ for (const person of known) {
602242
+ lines.push(`- ${person.name ?? "known individual"} @ ${nowIso3(person.observedAt)} age=${eventAge(now2, person.observedAt)} source=${person.source}${person.confidence !== void 0 ? ` confidence=${person.confidence.toFixed(2)}` : ""}${person.cropPath ? ` crop=${person.cropPath}` : ""}`);
602243
+ }
602244
+ }
602245
+ lines.push("Unknown individuals:");
602246
+ if (unknown.length === 0) {
602247
+ lines.push("- none currently visible");
602248
+ } else {
602249
+ for (const person of unknown) {
602250
+ lines.push(`- unknown person @ ${nowIso3(person.observedAt)} age=${eventAge(now2, person.observedAt)} source=${person.source}${person.confidence !== void 0 ? ` confidence=${person.confidence.toFixed(2)}` : ""}${person.cropPath ? ` crop=${person.cropPath}` : ""}${person.trackId ? ` track=${person.trackId}` : ""}`);
602251
+ if (person.evidence) lines.push(` evidence: ${boundedText(person.evidence, 360)}`);
602252
+ }
602253
+ }
602254
+ lines.push("Identity next step: when responding about an unknown individual, say they are unknown; ask for their name if appropriate. After the user/person provides a name, enroll the face crop with visual_memory or run multimodal_memory meet. Do not claim a name unless this section lists a known individual or a tool confirms it.");
602255
+ }
602042
602256
  if (snapshot.video) {
602043
602257
  const age = now2 - snapshot.video.updatedAt;
602044
602258
  lines.push("");
602045
- lines.push(`[video latest: ${nowIso3(snapshot.video.updatedAt)} age=${Math.max(0, Math.round(age / 1e3))}s source=${snapshot.video.source}${age > maxAgeMs ? " STALE" : ""}]`);
602259
+ lines.push("## LIVE CAMERA LATEST FRAME");
602260
+ lines.push(`timestamp: ${nowIso3(snapshot.video.updatedAt)} age=${Math.max(0, Math.round(age / 1e3))}s source=${snapshot.video.source}${age > maxAgeMs ? " STALE" : ""}`);
602046
602261
  if (snapshot.video.error) lines.push(`error: ${snapshot.video.error}`);
602047
602262
  if (snapshot.video.framePath) lines.push(`frame: ${snapshot.video.framePath}`);
602048
602263
  if (snapshot.video.asciiContext) lines.push(snapshot.video.asciiContext);
@@ -602052,9 +602267,22 @@ function formatLiveSensorContextFromSnapshot(snapshot, opts = {}) {
602052
602267
  }
602053
602268
  }
602054
602269
  if (snapshot.audio) {
602270
+ const audioEvents = (snapshot.events ?? []).filter((event) => event.kind === "audio_transcript" || event.kind === "audio_sound").sort((a2, b) => b.observedAt - a2.observedAt).slice(0, 8);
602271
+ if (audioEvents.length > 0) {
602272
+ lines.push("");
602273
+ lines.push("## LIVE AUDIO EVENTS");
602274
+ for (const event of audioEvents) {
602275
+ const stale = now2 - event.observedAt > maxAgeMs ? " STALE" : "";
602276
+ lines.push(`### ${event.title}`);
602277
+ lines.push(`timestamp: ${nowIso3(event.observedAt)} age=${eventAge(now2, event.observedAt)} source=${event.source} kind=${event.kind}${stale}`);
602278
+ if (event.evidencePath) lines.push(`evidence: ${event.evidencePath}`);
602279
+ lines.push(`summary: ${boundedText(event.summary, 700)}`);
602280
+ }
602281
+ }
602055
602282
  const age = now2 - snapshot.audio.updatedAt;
602056
602283
  lines.push("");
602057
- lines.push(`[audio latest: ${nowIso3(snapshot.audio.updatedAt)} age=${Math.max(0, Math.round(age / 1e3))}s${age > maxAgeMs ? " STALE" : ""}]`);
602284
+ lines.push("## LIVE AUDIO LATEST SAMPLE");
602285
+ lines.push(`timestamp: ${nowIso3(snapshot.audio.updatedAt)} age=${Math.max(0, Math.round(age / 1e3))}s${age > maxAgeMs ? " STALE" : ""}`);
602058
602286
  if (snapshot.audio.error) lines.push(`error: ${snapshot.audio.error}`);
602059
602287
  if (snapshot.audio.recordingPath) lines.push(`recording: ${snapshot.audio.recordingPath}`);
602060
602288
  if (snapshot.audio.transcript) {
@@ -602296,11 +602524,20 @@ var init_live_sensors = __esm({
602296
602524
  });
602297
602525
  if (!result.success) {
602298
602526
  const error = result.error || result.output || "camera capture failed";
602527
+ const observedAt2 = Date.now();
602299
602528
  this.snapshot.video = {
602300
- updatedAt: Date.now(),
602529
+ updatedAt: observedAt2,
602301
602530
  source,
602302
602531
  error
602303
602532
  };
602533
+ this.snapshot.events = mergeRecentById(this.snapshot.events, [{
602534
+ id: stableEventId("camera_error", source, observedAt2, error.slice(0, 80)),
602535
+ kind: "camera_error",
602536
+ observedAt: observedAt2,
602537
+ source,
602538
+ title: "Camera capture failed",
602539
+ summary: error
602540
+ }], 50);
602304
602541
  this.persist();
602305
602542
  return { ok: false, message: error };
602306
602543
  }
@@ -602309,13 +602546,23 @@ var init_live_sensors = __esm({
602309
602546
  const displayPath = relative11(this.repoRoot, framePath).startsWith("..") ? framePath : relative11(this.repoRoot, framePath);
602310
602547
  const preview = await buildImageAsciiPreview(framePath, { width: 72, height: 22 });
602311
602548
  const asciiContext = preview ? formatImageAsciiContext(preview, displayPath) : void 0;
602549
+ const observedAt = Date.now();
602312
602550
  this.snapshot.video = {
602313
- updatedAt: Date.now(),
602551
+ updatedAt: observedAt,
602314
602552
  source,
602315
602553
  framePath,
602316
602554
  displayPath,
602317
602555
  asciiContext
602318
602556
  };
602557
+ this.snapshot.events = mergeRecentById(this.snapshot.events, [{
602558
+ id: stableEventId("camera_frame", source, observedAt, framePath),
602559
+ kind: "camera_frame",
602560
+ observedAt,
602561
+ source,
602562
+ title: "Captured camera frame",
602563
+ summary: `frame=${framePath}${displayPath ? ` display=${displayPath}` : ""}`,
602564
+ evidencePath: framePath
602565
+ }], 50);
602319
602566
  this.persist();
602320
602567
  return {
602321
602568
  ok: true,
@@ -602346,12 +602593,18 @@ var init_live_sensors = __esm({
602346
602593
  audio_mode: "none",
602347
602594
  detect_objects: true,
602348
602595
  track_objects: true,
602349
- crop_faces: true
602596
+ crop_faces: true,
602597
+ recognize_faces: true
602350
602598
  });
602599
+ const sampledAt = Date.now();
602351
602600
  inference = result.success ? String(result.output || result.llmContent || "") : `Video inference failed: ${result.error || result.output || "unknown error"}`;
602601
+ const livePayload = result.success ? parseLiveMediaPayload(result.llmContent || result.output) : null;
602602
+ const observations = observationsFromLiveMediaPayload(livePayload, sampledAt, source);
602603
+ this.snapshot.events = mergeRecentById(this.snapshot.events, observations.events, 50);
602604
+ this.snapshot.people = mergeRecentById(this.snapshot.people, observations.people, 24);
602352
602605
  this.snapshot.video = {
602353
602606
  ...this.snapshot.video ?? { updatedAt: Date.now(), source },
602354
- updatedAt: Date.now(),
602607
+ updatedAt: sampledAt,
602355
602608
  source,
602356
602609
  inference,
602357
602610
  ...preview.ok ? {} : { error: preview.message }
@@ -602420,6 +602673,30 @@ ${inference}` : ""].filter(Boolean).join("\n");
602420
602673
  transcript,
602421
602674
  analysis
602422
602675
  };
602676
+ const audioEvents = [];
602677
+ if (transcript) {
602678
+ audioEvents.push({
602679
+ id: stableEventId("audio_transcript", input, this.snapshot.audio.updatedAt, recordingPath),
602680
+ kind: "audio_transcript",
602681
+ observedAt: this.snapshot.audio.updatedAt,
602682
+ source: input,
602683
+ title: "Live ASR transcript",
602684
+ summary: transcript,
602685
+ evidencePath: recordingPath
602686
+ });
602687
+ }
602688
+ if (analysis) {
602689
+ audioEvents.push({
602690
+ id: stableEventId("audio_sound", input, this.snapshot.audio.updatedAt, recordingPath),
602691
+ kind: "audio_sound",
602692
+ observedAt: this.snapshot.audio.updatedAt,
602693
+ source: input,
602694
+ title: "Live sound analysis",
602695
+ summary: analysis,
602696
+ evidencePath: recordingPath
602697
+ });
602698
+ }
602699
+ this.snapshot.events = mergeRecentById(this.snapshot.events, audioEvents, 50);
602423
602700
  this.persist();
602424
602701
  return [
602425
602702
  `Audio sample captured from ${input}: ${recordingPath}`,
@@ -622245,7 +622522,7 @@ function setTerminalTitle(task, version5) {
622245
622522
  process.stdout.write(data);
622246
622523
  }
622247
622524
  }
622248
- var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_BUTTON_GLYPH_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, HEADER_ACCENT_BOLD_FG, HEADER_TELEGRAM_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, SPONSOR_HEADER_LABEL_MAX, _termTitleWriter, StatusBar;
622525
+ var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_BUTTON_GLYPH_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, HEADER_ACCENT_BOLD_FG, HEADER_TELEGRAM_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, BOX_BJ, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, SPONSOR_HEADER_LABEL_MAX, _termTitleWriter, StatusBar;
622249
622526
  var init_status_bar = __esm({
622250
622527
  "packages/cli/src/tui/status-bar.ts"() {
622251
622528
  "use strict";
@@ -622437,6 +622714,7 @@ var init_status_bar = __esm({
622437
622714
  BOX_BR3 = "╯";
622438
622715
  BOX_H3 = "─";
622439
622716
  BOX_V3 = "│";
622717
+ BOX_BJ = "┴";
622440
622718
  _globalFooterLock = false;
622441
622719
  RESET4 = "\x1B[0m";
622442
622720
  CURSOR_BLINK_BLOCK = "\x1B[1 q";
@@ -622996,27 +623274,20 @@ var init_status_bar = __esm({
622996
623274
  return fg2;
622997
623275
  };
622998
623276
  const decorateMenuButton = (cmd, label) => {
622999
- return `${HEADER_BUTTON_GLYPH_FG}🭁\x1B[0m${HEADER_BUTTON_BG}${HEADER_BUTTON_FG}${label}\x1B[0m${PANEL_BG_SEQ}${HEADER_BUTTON_GLYPH_FG}🭝\x1B[0m${PANEL_BG_SEQ}`;
623277
+ return `${HEADER_BUTTON_GLYPH_FG}[\x1B[0m${HEADER_BUTTON_BG}${HEADER_BUTTON_FG}${label}\x1B[0m${PANEL_BG_SEQ}${HEADER_BUTTON_GLYPH_FG}]\x1B[0m${PANEL_BG_SEQ}`;
623000
623278
  };
623001
623279
  const decorateAgentButton = (content, color, active) => {
623002
623280
  const bg = `\x1B[48;5;${color}m`;
623003
623281
  const fg2 = `\x1B[38;5;${contrastTextColor(color)}m`;
623004
623282
  const weight = active ? "\x1B[1m" : "";
623005
- return `\x1B[38;5;${color}m🭁\x1B[0m${weight}${fg2}${bg}${content}\x1B[0m${PANEL_BG_SEQ}\x1B[38;5;${color}m🭝\x1B[0m${PANEL_BG_SEQ}`;
623283
+ return `\x1B[38;5;${color}m[\x1B[0m${weight}${fg2}${bg}${content}\x1B[0m${PANEL_BG_SEQ}\x1B[38;5;${color}m]\x1B[0m${PANEL_BG_SEQ}`;
623006
623284
  };
623007
623285
  const renderBtn = (cmd, label) => {
623008
623286
  const fg2 = buttonFg(cmd);
623009
- const left = _isWindows ? "" : "🛁";
623010
- const right = _isWindows ? "" : "🛂";
623011
- const leftW = _isWindows ? 0 : 2;
623012
- const rightW = _isWindows ? 0 : 2;
623013
- const btnW = label.length + leftW + rightW + 4;
623287
+ const btnW = label.length;
623014
623288
  const availW2 = getTermWidth() - identity3.width - 1;
623015
623289
  if (btnW > availW2) return linkify(cmd, `\x1B[38;5;${fg2}m${label}`);
623016
- return linkify(
623017
- cmd,
623018
- ` ${PANEL_BG_SEQ}\x1B[38;5;${tuiBg()}m${left}\x1B[0m ${PANEL_BG_SEQ}\x1B[38;5;${fg2}m${label}\x1B[0m ${PANEL_BG_SEQ}\x1B[38;5;${tuiBg()}m${right}\x1B[0m `
623019
- );
623290
+ return linkify(cmd, `${PANEL_BG_SEQ}\x1B[38;5;${fg2}m${label}\x1B[0m${PANEL_BG_SEQ}`);
623020
623291
  };
623021
623292
  const identity3 = this.buildHeaderIdentityRender();
623022
623293
  const modelLabel = this.summarizeHeaderModelName() || "model";
@@ -623335,8 +623606,17 @@ var init_status_bar = __esm({
623335
623606
  buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${RESET4}${PANEL_BG_SEQ}`;
623336
623607
  const scrollPct = this._contentScrollOffset > 0 ? `${Math.round(this._contentScrollOffset / this._contentMaxLines * 100)}%` : "live";
623337
623608
  if (this._headerExpanded) {
623609
+ const separatorCols = new Set(this.getHeaderBorderSeparatorColumns(w));
623338
623610
  const sepRow1 = hdrRow + 1;
623339
- buf += `\x1B[${sepRow1};1H${BOX_FG}├${"─".repeat(w - 2)}${BOX_FG}┤${RESET4}${PANEL_BG_SEQ}`;
623611
+ let expandedSep = `${BOX_FG}├${"─".repeat(w - 2)}${BOX_FG}┤${RESET4}${PANEL_BG_SEQ}`;
623612
+ if (separatorCols.size > 0) {
623613
+ const chars = Array.from(stripAnsi(expandedSep));
623614
+ for (const col of separatorCols) {
623615
+ if (col > 1 && col < w) chars[col - 1] = BOX_BJ;
623616
+ }
623617
+ expandedSep = `${BOX_FG}${chars.join("")}${RESET4}${PANEL_BG_SEQ}`;
623618
+ }
623619
+ buf += `\x1B[${sepRow1};1H${expandedSep}`;
623340
623620
  const subRow = hdrRow + 2;
623341
623621
  buf += `\x1B[${subRow};1H${PANEL_BG_SEQ}\x1B[2K`;
623342
623622
  buf += `${BOX_FG}│${RESET4}${PANEL_BG_SEQ}`;
@@ -623347,7 +623627,15 @@ var init_status_bar = __esm({
623347
623627
  buf += ` ${subAgents.substring(0, w - 4)}`;
623348
623628
  buf += `\x1B[${subRow};${w}H${BOX_FG}│${RESET4}${PANEL_BG_SEQ}`;
623349
623629
  const scrollRow = subRow + 1;
623350
- buf += `\x1B[${scrollRow};1H${BOX_FG}╰${"─".repeat(w - 2)}${BOX_FG}╯${RESET4}${PANEL_BG_SEQ}`;
623630
+ let expandedBottom = `${BOX_BL3}${BOX_H3.repeat(w - 2)}${BOX_BR3}`;
623631
+ if (separatorCols.size > 0) {
623632
+ const chars = Array.from(expandedBottom);
623633
+ for (const col of separatorCols) {
623634
+ if (col > 1 && col < w) chars[col - 1] = BOX_BJ;
623635
+ }
623636
+ expandedBottom = chars.join("");
623637
+ }
623638
+ buf += `\x1B[${scrollRow};1H${BOX_FG}${expandedBottom}${RESET4}${PANEL_BG_SEQ}`;
623351
623639
  } else {
623352
623640
  const scrollRow = hdrRow + 1;
623353
623641
  buf += `\x1B[${scrollRow};1H${PANEL_BG_SEQ}\x1B[2K`;
@@ -625777,10 +626065,6 @@ ${CONTENT_BG_SEQ}`);
625777
626065
  const pastel2 = (code8, s2) => `${PANEL_BG_SEQ}\x1B[38;5;${code8}m${s2}\x1B[0m${PANEL_BG_SEQ}`;
625778
626066
  const pipe3 = `${PANEL_BG_SEQ}${BOX_FG}│${RESET4}${PANEL_BG_SEQ}`;
625779
626067
  const pipeW = 1;
625780
- const BTN_L = _isWindows ? "" : "🛁";
625781
- const BTN_R = _isWindows ? "" : "🛂";
625782
- const BTN_L_W = _isWindows ? 0 : 2;
625783
- const BTN_R_W = _isWindows ? 0 : 2;
625784
626068
  const sections = [];
625785
626069
  const compactOrder = [];
625786
626070
  let modelSectionIdx = -1;
@@ -672512,7 +672796,7 @@ function buildTelegramReflectionExtractionPrompt(options2) {
672512
672796
  episodes || "none"
672513
672797
  ].join("\n");
672514
672798
  }
672515
- function parseJsonObject3(raw) {
672799
+ function parseJsonObject4(raw) {
672516
672800
  const text2 = raw.trim();
672517
672801
  if (!text2) return null;
672518
672802
  const fenced = text2.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
@@ -672526,7 +672810,7 @@ function parseJsonObject3(raw) {
672526
672810
  }
672527
672811
  }
672528
672812
  function parseTelegramReflectionExtraction(raw) {
672529
- const parsed = parseJsonObject3(raw);
672813
+ const parsed = parseJsonObject4(raw);
672530
672814
  if (!parsed) return null;
672531
672815
  const tags = Array.isArray(parsed.tags) ? parsed.tags.map((item) => {
672532
672816
  const obj = item;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.404",
3
+ "version": "1.0.406",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.404",
9
+ "version": "1.0.406",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.404",
3
+ "version": "1.0.406",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",