omnius 1.0.405 → 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
@@ -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}`,
@@ -672519,7 +672796,7 @@ function buildTelegramReflectionExtractionPrompt(options2) {
672519
672796
  episodes || "none"
672520
672797
  ].join("\n");
672521
672798
  }
672522
- function parseJsonObject3(raw) {
672799
+ function parseJsonObject4(raw) {
672523
672800
  const text2 = raw.trim();
672524
672801
  if (!text2) return null;
672525
672802
  const fenced = text2.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
@@ -672533,7 +672810,7 @@ function parseJsonObject3(raw) {
672533
672810
  }
672534
672811
  }
672535
672812
  function parseTelegramReflectionExtraction(raw) {
672536
- const parsed = parseJsonObject3(raw);
672813
+ const parsed = parseJsonObject4(raw);
672537
672814
  if (!parsed) return null;
672538
672815
  const tags = Array.isArray(parsed.tags) ? parsed.tags.map((item) => {
672539
672816
  const obj = item;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.405",
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.405",
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.405",
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",