omnius 1.0.34 → 1.0.36

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
@@ -91213,7 +91213,7 @@ var require_auto = __commonJS({
91213
91213
  // ../node_modules/acme-client/src/client.js
91214
91214
  var require_client = __commonJS({
91215
91215
  "../node_modules/acme-client/src/client.js"(exports, module) {
91216
- var { createHash: createHash24 } = __require("crypto");
91216
+ var { createHash: createHash25 } = __require("crypto");
91217
91217
  var { getPemBodyAsB64u } = require_crypto();
91218
91218
  var { log: log22 } = require_logger();
91219
91219
  var HttpClient = require_http();
@@ -91524,14 +91524,14 @@ var require_client = __commonJS({
91524
91524
  */
91525
91525
  async getChallengeKeyAuthorization(challenge) {
91526
91526
  const jwk = this.http.getJwk();
91527
- const keysum = createHash24("sha256").update(JSON.stringify(jwk));
91527
+ const keysum = createHash25("sha256").update(JSON.stringify(jwk));
91528
91528
  const thumbprint = keysum.digest("base64url");
91529
91529
  const result = `${challenge.token}.${thumbprint}`;
91530
91530
  if (challenge.type === "http-01") {
91531
91531
  return result;
91532
91532
  }
91533
91533
  if (challenge.type === "dns-01") {
91534
- return createHash24("sha256").update(result).digest("base64url");
91534
+ return createHash25("sha256").update(result).digest("base64url");
91535
91535
  }
91536
91536
  if (challenge.type === "tls-alpn-01") {
91537
91537
  return result;
@@ -234211,7 +234211,7 @@ var require_websocket2 = __commonJS({
234211
234211
  var http6 = __require("http");
234212
234212
  var net5 = __require("net");
234213
234213
  var tls2 = __require("tls");
234214
- var { randomBytes: randomBytes26, createHash: createHash24 } = __require("crypto");
234214
+ var { randomBytes: randomBytes26, createHash: createHash25 } = __require("crypto");
234215
234215
  var { Duplex: Duplex3, Readable } = __require("stream");
234216
234216
  var { URL: URL3 } = __require("url");
234217
234217
  var PerMessageDeflate3 = require_permessage_deflate2();
@@ -234871,7 +234871,7 @@ var require_websocket2 = __commonJS({
234871
234871
  abortHandshake(websocket, socket, "Invalid Upgrade header");
234872
234872
  return;
234873
234873
  }
234874
- const digest3 = createHash24("sha1").update(key + GUID).digest("base64");
234874
+ const digest3 = createHash25("sha1").update(key + GUID).digest("base64");
234875
234875
  if (res.headers["sec-websocket-accept"] !== digest3) {
234876
234876
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
234877
234877
  return;
@@ -235238,7 +235238,7 @@ var require_websocket_server = __commonJS({
235238
235238
  var EventEmitter13 = __require("events");
235239
235239
  var http6 = __require("http");
235240
235240
  var { Duplex: Duplex3 } = __require("stream");
235241
- var { createHash: createHash24 } = __require("crypto");
235241
+ var { createHash: createHash25 } = __require("crypto");
235242
235242
  var extension3 = require_extension2();
235243
235243
  var PerMessageDeflate3 = require_permessage_deflate2();
235244
235244
  var subprotocol3 = require_subprotocol();
@@ -235539,7 +235539,7 @@ var require_websocket_server = __commonJS({
235539
235539
  );
235540
235540
  }
235541
235541
  if (this._state > RUNNING) return abortHandshake(socket, 503);
235542
- const digest3 = createHash24("sha1").update(key + GUID).digest("base64");
235542
+ const digest3 = createHash25("sha1").update(key + GUID).digest("base64");
235543
235543
  const headers = [
235544
235544
  "HTTP/1.1 101 Switching Protocols",
235545
235545
  "Upgrade: websocket",
@@ -248346,13 +248346,13 @@ Justification: ${justification || "(none provided)"}`,
248346
248346
  }
248347
248347
  const snapshot = JSON.stringify(this.selfState, null, 2);
248348
248348
  try {
248349
- const { createHash: createHash24 } = await import("node:crypto");
248349
+ const { createHash: createHash25 } = await import("node:crypto");
248350
248350
  const snapshotDir = join30(this.cwd, ".omnius", "identity", "snapshots");
248351
248351
  await mkdir6(snapshotDir, { recursive: true });
248352
248352
  const version4 = this.selfState.version;
248353
248353
  const snapshotPath = join30(snapshotDir, `v${version4}.json`);
248354
248354
  await writeFile11(snapshotPath, snapshot, "utf8");
248355
- const hash = createHash24("sha256").update(snapshot).digest("hex");
248355
+ const hash = createHash25("sha256").update(snapshot).digest("hex");
248356
248356
  await writeFile11(join30(this.cwd, ".omnius", "identity", "latest-hash.txt"), hash, "utf8");
248357
248357
  let ipfsCid = "";
248358
248358
  try {
@@ -248485,8 +248485,8 @@ New: ${newNarrative.slice(0, 200)}...`,
248485
248485
  }
248486
248486
  // ── Helpers ──────────────────────────────────────────────────────────────
248487
248487
  createDefaultState() {
248488
- const { createHash: createHash24 } = __require("node:crypto");
248489
- const machineId = createHash24("sha256").update(this.cwd).digest("hex").slice(0, 12);
248488
+ const { createHash: createHash25 } = __require("node:crypto");
248489
+ const machineId = createHash25("sha256").update(this.cwd).digest("hex").slice(0, 12);
248490
248490
  return {
248491
248491
  self_id: `omnius-${machineId}`,
248492
248492
  version: 1,
@@ -248568,9 +248568,9 @@ New: ${newNarrative.slice(0, 200)}...`,
248568
248568
  let cid;
248569
248569
  if (this.selfState.version > prevVersion) {
248570
248570
  try {
248571
- const { createHash: createHash24 } = await import("node:crypto");
248571
+ const { createHash: createHash25 } = await import("node:crypto");
248572
248572
  const stateJson = JSON.stringify(this.selfState);
248573
- const hash = createHash24("sha256").update(stateJson).digest("hex").slice(0, 32);
248573
+ const hash = createHash25("sha256").update(stateJson).digest("hex").slice(0, 32);
248574
248574
  const cidsPath = join30(this.cwd, ".omnius", "identity", "cids.json");
248575
248575
  const cidsData = { latest: "", hash, version: this.selfState.version };
248576
248576
  try {
@@ -249572,21 +249572,21 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
249572
249572
  utility += 0.15;
249573
249573
  if (/https?:\/\/|\/[a-z]+\/[a-z]+|npm |pip |git /i.test(lower))
249574
249574
  utility += 0.1;
249575
- let confidence = 0.5;
249575
+ let confidence2 = 0.5;
249576
249576
  if (source === "user")
249577
- confidence += 0.3;
249577
+ confidence2 += 0.3;
249578
249578
  else if (source === "trajectory-consolidation")
249579
- confidence += 0.15;
249579
+ confidence2 += 0.15;
249580
249580
  else if (source === "reflection")
249581
- confidence += 0.1;
249581
+ confidence2 += 0.1;
249582
249582
  else if (source === "llm-query")
249583
- confidence -= 0.1;
249583
+ confidence2 -= 0.1;
249584
249584
  if (/maybe|probably|might|possibly|I think|not sure|unclear/i.test(lower))
249585
- confidence -= 0.15;
249585
+ confidence2 -= 0.15;
249586
249586
  if (/always|never|must|confirmed|verified|tested|proven/i.test(lower))
249587
- confidence += 0.1;
249587
+ confidence2 += 0.1;
249588
249588
  if (sentences >= 3)
249589
- confidence += 0.05;
249589
+ confidence2 += 0.05;
249590
249590
  let identityRelevance = 0.2;
249591
249591
  if (type === "normative")
249592
249592
  identityRelevance += 0.5;
@@ -249607,7 +249607,7 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
249607
249607
  return {
249608
249608
  novelty: Math.max(0, Math.min(1, novelty)),
249609
249609
  utility: Math.max(0, Math.min(1, utility)),
249610
- confidence: Math.max(0, Math.min(1, confidence)),
249610
+ confidence: Math.max(0, Math.min(1, confidence2)),
249611
249611
  identityRelevance: Math.max(0, Math.min(1, identityRelevance))
249612
249612
  };
249613
249613
  }
@@ -249867,12 +249867,12 @@ ${findingsText}${followupsText}`,
249867
249867
  performReflection(mode, target, context2, checks) {
249868
249868
  const findings = [];
249869
249869
  const followups = [];
249870
- let confidence = 0.8;
249870
+ let confidence2 = 0.8;
249871
249871
  switch (mode) {
249872
249872
  case "diagnostic":
249873
249873
  if (target.length < 20) {
249874
249874
  findings.push("Target is very short — may be incomplete or superficial");
249875
- confidence -= 0.1;
249875
+ confidence2 -= 0.1;
249876
249876
  }
249877
249877
  if (/todo|fixme|hack|workaround/i.test(target)) {
249878
249878
  findings.push("Contains TODO/FIXME/hack markers — not fully resolved");
@@ -249887,14 +249887,14 @@ ${findingsText}${followupsText}`,
249887
249887
  }
249888
249888
  if (/but\s+also|however.*nevertheless|on\s+one\s+hand.*on\s+the\s+other/i.test(target)) {
249889
249889
  findings.push("Contains potentially contradictory statements — may need resolution");
249890
- confidence -= 0.1;
249890
+ confidence2 -= 0.1;
249891
249891
  }
249892
249892
  break;
249893
249893
  case "epistemic":
249894
249894
  if (!/because|since|evidence|data|test|verified|confirmed/i.test(target)) {
249895
249895
  findings.push("No supporting evidence cited — claims are unsupported");
249896
249896
  followups.push("Add evidence, test results, or citations to support claims");
249897
- confidence -= 0.2;
249897
+ confidence2 -= 0.2;
249898
249898
  }
249899
249899
  if (/all|every|always|never|impossible|certain/i.test(target)) {
249900
249900
  findings.push("Contains absolute claims (all/every/always/never) — may be overgeneralized");
@@ -249911,12 +249911,12 @@ ${findingsText}${followupsText}`,
249911
249911
  case "constitutional":
249912
249912
  if (target.length < 10) {
249913
249913
  findings.push("Proposed change is too brief to evaluate meaningfully");
249914
- confidence -= 0.3;
249914
+ confidence2 -= 0.3;
249915
249915
  }
249916
249916
  if (/delete|remove|forget|erase.*value|erase.*commitment/i.test(target)) {
249917
249917
  findings.push("Proposed change involves deletion of values/commitments — high scrutiny needed");
249918
249918
  followups.push("Confirm deletion is justified and reversible");
249919
- confidence -= 0.15;
249919
+ confidence2 -= 0.15;
249920
249920
  }
249921
249921
  if (/override|replace|supersede.*value/i.test(target)) {
249922
249922
  findings.push("Proposed change overrides existing values — requires strong justification");
@@ -249924,31 +249924,31 @@ ${findingsText}${followupsText}`,
249924
249924
  }
249925
249925
  if (/because|reason|evidence|learned|observed/i.test(target)) {
249926
249926
  findings.push("Change includes justification — good practice");
249927
- confidence += 0.05;
249927
+ confidence2 += 0.05;
249928
249928
  }
249929
249929
  break;
249930
249930
  }
249931
249931
  let status;
249932
249932
  if (findings.length === 0) {
249933
249933
  status = "pass";
249934
- confidence = Math.min(1, confidence + 0.1);
249935
- } else if (followups.length > 0 || confidence < 0.5) {
249934
+ confidence2 = Math.min(1, confidence2 + 0.1);
249935
+ } else if (followups.length > 0 || confidence2 < 0.5) {
249936
249936
  status = "revise";
249937
249937
  } else {
249938
249938
  status = "pass";
249939
249939
  }
249940
- if (confidence < 0.3 || checks.includes("evaluator_tampering") || checks.includes("memory_poisoning")) {
249940
+ if (confidence2 < 0.3 || checks.includes("evaluator_tampering") || checks.includes("memory_poisoning")) {
249941
249941
  if (/eval|test.*result|score|metric/i.test(target) && /modif|chang|updat/i.test(target)) {
249942
249942
  findings.push("ALERT: Possible evaluator tampering detected — modifying evaluation-related content");
249943
249943
  status = "block";
249944
- confidence = 0.1;
249944
+ confidence2 = 0.1;
249945
249945
  }
249946
249946
  }
249947
249947
  return {
249948
249948
  status,
249949
249949
  mode,
249950
249950
  findings,
249951
- confidence: Math.max(0, Math.min(1, confidence)),
249951
+ confidence: Math.max(0, Math.min(1, confidence2)),
249952
249952
  required_followups: followups,
249953
249953
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
249954
249954
  };
@@ -513266,8 +513266,8 @@ ${lines.join("\n")}`,
513266
513266
  const omniusDir = omniusDirs.find((d2) => fsExists(d2));
513267
513267
  if (!omniusDir)
513268
513268
  return;
513269
- const es = new EpisodeStore3(pathJoin(omniusDir, "memory.db"));
513270
- const tg = new TemporalGraph3(pathJoin(omniusDir, "kg.db"));
513269
+ const es = new EpisodeStore3(pathJoin(omniusDir, "episodes.db"));
513270
+ const tg = new TemporalGraph3(pathJoin(omniusDir, "knowledge.db"));
513271
513271
  const contentParts = [];
513272
513272
  if (episode.social?.personName)
513273
513273
  contentParts.push(`Met ${episode.social.personName}`);
@@ -513292,6 +513292,7 @@ ${lines.join("\n")}`,
513292
513292
  decayClass: episode.social?.personName ? "permanent" : "daily",
513293
513293
  metadata: {
513294
513294
  multimodal_episode_id: episode.id,
513295
+ media_path: episode.visual?.imagePath || episode.audio?.recordingPath,
513295
513296
  has_face: (episode.visual?.faceIds?.length ?? 0) > 0,
513296
513297
  has_audio: !!episode.audio?.recordingPath,
513297
513298
  has_gps: !!episode.spatial?.gps
@@ -513299,7 +513300,7 @@ ${lines.join("\n")}`,
513299
513300
  });
513300
513301
  if (episode.visual?.clipEmbedding) {
513301
513302
  const emb = new Float32Array(episode.visual.clipEmbedding);
513302
- es.setEmbedding(epId, emb);
513303
+ es.setClipEmbedding(epId, emb);
513303
513304
  }
513304
513305
  if (episode.social?.personName) {
513305
513306
  const personId = tg.upsertNode({ text: episode.social.personName, nodeType: "person" });
@@ -522132,7 +522133,7 @@ function parseModeCollapseVerdict(rawResponse) {
522132
522133
  ];
522133
522134
  const category = typeof parsed.category === "string" && validCategories.includes(parsed.category) ? parsed.category : "healthy";
522134
522135
  const diagnosis = typeof parsed.diagnosis === "string" && parsed.diagnosis.trim().length > 0 ? parsed.diagnosis.slice(0, 500) : "(no diagnosis)";
522135
- const confidence = typeof parsed.confidence === "number" ? Math.max(0, Math.min(1, parsed.confidence)) : 0;
522136
+ const confidence2 = typeof parsed.confidence === "number" ? Math.max(0, Math.min(1, parsed.confidence)) : 0;
522136
522137
  const validActions = [
522137
522138
  "none",
522138
522139
  "abort_and_retry_no_think",
@@ -522143,7 +522144,7 @@ function parseModeCollapseVerdict(rawResponse) {
522143
522144
  return {
522144
522145
  category,
522145
522146
  diagnosis,
522146
- confidence,
522147
+ confidence: confidence2,
522147
522148
  suggested_action,
522148
522149
  raw: rawResponse,
522149
522150
  parseFallback: false
@@ -524663,6 +524664,262 @@ var init_temporalGraph = __esm({
524663
524664
  }
524664
524665
  });
524665
524666
 
524667
+ // packages/memory/dist/multimodalIdentity.js
524668
+ import { createHash as createHash11 } from "node:crypto";
524669
+ function stableHash(value2) {
524670
+ return createHash11("sha256").update(value2).digest("hex").slice(0, 24);
524671
+ }
524672
+ function normalizeAtom(value2) {
524673
+ return value2.trim().toLowerCase().replace(/\s+/g, " ");
524674
+ }
524675
+ function displaySender(sender) {
524676
+ if (!sender)
524677
+ return "unknown";
524678
+ return sender.displayName || sender.username || sender.id || "unknown";
524679
+ }
524680
+ function senderKey(surface, sender) {
524681
+ const raw = sender.id || sender.username || sender.displayName || "unknown";
524682
+ return `${surface}_user:${normalizeAtom(String(raw))}`;
524683
+ }
524684
+ function scopeKey(scope) {
524685
+ return `scope:${normalizeAtom(scope.kind)}:${normalizeAtom(scope.id)}`;
524686
+ }
524687
+ function messageKey(surface, scope, message2) {
524688
+ const raw = message2.id != null ? `${surface}:${scope.kind}:${scope.id}:${message2.id}` : `${surface}:${scope.kind}:${scope.id}:${message2.text || message2.timestamp || "message"}`;
524689
+ return `message:${stableHash(raw)}`;
524690
+ }
524691
+ function mediaKey(media) {
524692
+ const raw = media.sha256 || media.fileUniqueId || media.fileId || media.path || JSON.stringify(media);
524693
+ return `media:${stableHash(raw)}`;
524694
+ }
524695
+ function identityKey(name10) {
524696
+ return `person:${normalizeAtom(name10)}`;
524697
+ }
524698
+ function voiceSampleKey(media, message2) {
524699
+ const raw = media?.sha256 || media?.fileUniqueId || media?.fileId || media?.path || message2?.id || "voice";
524700
+ return `voice_sample:${stableHash(String(raw))}`;
524701
+ }
524702
+ function toFloat32(value2) {
524703
+ if (!value2)
524704
+ return null;
524705
+ if (value2 instanceof Float32Array)
524706
+ return value2;
524707
+ if (!Array.isArray(value2) || value2.length === 0)
524708
+ return null;
524709
+ return new Float32Array(value2);
524710
+ }
524711
+ function confidence(value2, fallback = 0.75) {
524712
+ if (typeof value2 !== "number" || !Number.isFinite(value2))
524713
+ return fallback;
524714
+ return Math.max(0, Math.min(1, value2));
524715
+ }
524716
+ function cleanStrings(values) {
524717
+ if (!Array.isArray(values))
524718
+ return [];
524719
+ return values.map((v) => String(v || "").trim()).filter(Boolean);
524720
+ }
524721
+ function defaultScope(input) {
524722
+ return input.scope && input.scope.id ? input.scope : { kind: "global", id: input.sourceSurface || "api" };
524723
+ }
524724
+ function buildEpisodeContent(input) {
524725
+ if (input.content && input.content.trim())
524726
+ return input.content;
524727
+ if (input.transcript && input.transcript.trim())
524728
+ return input.transcript;
524729
+ if (input.extractedContent && input.extractedContent.trim())
524730
+ return input.extractedContent;
524731
+ const media = input.media;
524732
+ if (media?.caption)
524733
+ return media.caption;
524734
+ if (media?.path)
524735
+ return media.path;
524736
+ return `${input.modality || "text"} memory event`;
524737
+ }
524738
+ var MultimodalIdentityService;
524739
+ var init_multimodalIdentity = __esm({
524740
+ "packages/memory/dist/multimodalIdentity.js"() {
524741
+ "use strict";
524742
+ MultimodalIdentityService = class {
524743
+ episodeStore;
524744
+ graph;
524745
+ socialMemory;
524746
+ constructor(options2) {
524747
+ this.episodeStore = options2.episodeStore;
524748
+ this.graph = options2.graph;
524749
+ this.socialMemory = options2.socialMemory ?? null;
524750
+ }
524751
+ ingest(input) {
524752
+ const sourceSurface = input.sourceSurface || "api";
524753
+ const scope = defaultScope(input);
524754
+ const modality = input.modality || (input.media ? "visual" : "text");
524755
+ const labels = cleanStrings(input.labels);
524756
+ const media = input.media;
524757
+ const message2 = input.message;
524758
+ const sender = input.sender;
524759
+ const content = buildEpisodeContent(input);
524760
+ const metadata = {
524761
+ mmidVersion: 1,
524762
+ sourceSurface,
524763
+ scope,
524764
+ sender,
524765
+ message: message2,
524766
+ replyTo: input.replyTo,
524767
+ media,
524768
+ labels,
524769
+ transcript: input.transcript,
524770
+ extractedContent: input.extractedContent,
524771
+ identityAssertions: input.identityAssertions || [],
524772
+ embeddingSpaces: this.embeddingSpaces(input.embeddings)
524773
+ };
524774
+ const episodeId = this.episodeStore.insert({
524775
+ modality,
524776
+ content,
524777
+ metadata,
524778
+ toolName: "multimodal_identity_ingest",
524779
+ decayClass: modality === "social" ? "permanent" : void 0
524780
+ });
524781
+ this.persistPrimaryEmbeddings(episodeId, input.embeddings, modality);
524782
+ const result = { episodeId, nodeIds: {}, edges: [] };
524783
+ const addEdge = (srcId, dstId, relation, fact, relConfidence = 1) => {
524784
+ this.graph.addEdge({
524785
+ srcId,
524786
+ dstId,
524787
+ relation,
524788
+ fact,
524789
+ confidence: relConfidence,
524790
+ sourceEpisodeId: episodeId,
524791
+ modality
524792
+ });
524793
+ result.edges.push({ srcId, dstId, relation });
524794
+ };
524795
+ const scopeId = this.graph.upsertNode({ text: scopeKey(scope), nodeType: "entity" });
524796
+ result.nodeIds.scope = scopeId;
524797
+ let senderId;
524798
+ if (sender) {
524799
+ senderId = this.graph.upsertNode({ text: senderKey(sourceSurface, sender), nodeType: "person" });
524800
+ result.nodeIds.sender = senderId;
524801
+ this.socialMemory?.upsertAgent({
524802
+ id: senderKey(sourceSurface, sender),
524803
+ name: displaySender(sender),
524804
+ type: "human",
524805
+ metadata: { sourceSurface, scope }
524806
+ });
524807
+ }
524808
+ let messageId;
524809
+ if (message2) {
524810
+ messageId = this.graph.upsertNode({ text: messageKey(sourceSurface, scope, message2), nodeType: "event" });
524811
+ result.nodeIds.message = messageId;
524812
+ addEdge(scopeId, messageId, "contains", message2.text || content);
524813
+ if (senderId)
524814
+ addEdge(messageId, senderId, "authored_by", message2.text || content);
524815
+ }
524816
+ let mediaId;
524817
+ if (media) {
524818
+ mediaId = this.graph.upsertNode({ text: mediaKey(media), nodeType: "entity" });
524819
+ result.nodeIds.media = mediaId;
524820
+ if (messageId)
524821
+ addEdge(messageId, mediaId, "contains", media.caption || media.path);
524822
+ if (senderId)
524823
+ addEdge(senderId, mediaId, "uploaded_by", media.caption || media.path);
524824
+ }
524825
+ if (input.replyTo) {
524826
+ const replyMessageId = this.graph.upsertNode({ text: messageKey(sourceSurface, scope, input.replyTo), nodeType: "event" });
524827
+ result.nodeIds.replyTo = replyMessageId;
524828
+ if (messageId)
524829
+ addEdge(messageId, replyMessageId, "replied_to", input.replyTo.text);
524830
+ if (input.replyTo.sender) {
524831
+ const replySenderId = this.graph.upsertNode({ text: senderKey(sourceSurface, input.replyTo.sender), nodeType: "person" });
524832
+ result.nodeIds.replySender = replySenderId;
524833
+ addEdge(replyMessageId, replySenderId, "authored_by", input.replyTo.text);
524834
+ }
524835
+ }
524836
+ this.applyIdentityAssertions(input, result, mediaId, messageId, senderId, addEdge);
524837
+ if (modality === "audio" && senderId) {
524838
+ const voiceId = this.graph.upsertNode({ text: voiceSampleKey(media, message2), nodeType: "entity" });
524839
+ result.nodeIds.voiceSample = voiceId;
524840
+ addEdge(voiceId, senderId, "speaker_candidate", input.transcript || content, 0.85);
524841
+ if (input.embeddings?.speaker || input.embeddings?.native) {
524842
+ addEdge(voiceId, senderId, "voice_sample_of", input.transcript || content, 0.85);
524843
+ }
524844
+ }
524845
+ if (input.transcript && input.transcript.trim()) {
524846
+ const transcriptMeta = { ...metadata, sourceEpisodeId: episodeId, transcriptOf: episodeId };
524847
+ const transcriptEpisodeId = this.episodeStore.insert({
524848
+ modality: "text",
524849
+ content: input.transcript,
524850
+ metadata: transcriptMeta,
524851
+ toolName: "transcribe_file",
524852
+ sourceEpisodeId: episodeId
524853
+ });
524854
+ const transcriptEmbedding = toFloat32(input.embeddings?.transcript);
524855
+ if (transcriptEmbedding)
524856
+ this.episodeStore.setEmbedding(transcriptEpisodeId, transcriptEmbedding);
524857
+ result.transcriptEpisodeId = transcriptEpisodeId;
524858
+ if (messageId && senderId)
524859
+ addEdge(messageId, senderId, "said_by", input.transcript, 0.9);
524860
+ }
524861
+ return result;
524862
+ }
524863
+ applyIdentityAssertions(input, result, mediaId, messageId, senderId, addEdge) {
524864
+ const assertions = input.identityAssertions || [];
524865
+ for (const assertion of assertions) {
524866
+ const name10 = assertion.name?.trim();
524867
+ if (!name10)
524868
+ continue;
524869
+ const personId = this.graph.upsertNode({ text: identityKey(name10), nodeType: "person" });
524870
+ result.nodeIds[`identity:${normalizeAtom(name10)}`] = personId;
524871
+ const target = mediaId || messageId || senderId;
524872
+ const fact = assertion.note || input.content || input.media?.caption || input.replyTo?.text || void 0;
524873
+ const relConfidence = confidence(assertion.confidence);
524874
+ if (target) {
524875
+ const relation = assertion.relation === "speaker" ? "speaker_candidate" : assertion.relation === "same_person_candidate" ? "same_person_candidate" : "named_as";
524876
+ addEdge(target, personId, relation, fact, relConfidence);
524877
+ if ((input.modality === "visual" || input.media?.mediaType === "photo") && relation !== "speaker_candidate") {
524878
+ addEdge(target, personId, "depicts", fact, relConfidence);
524879
+ }
524880
+ }
524881
+ if (assertion.assertedBy) {
524882
+ const assertedById = this.graph.upsertNode({ text: senderKey(input.sourceSurface || "api", assertion.assertedBy), nodeType: "person" });
524883
+ result.nodeIds[`assertedBy:${normalizeAtom(displaySender(assertion.assertedBy))}`] = assertedById;
524884
+ addEdge(assertedById, personId, "related_to", fact, relConfidence);
524885
+ }
524886
+ }
524887
+ }
524888
+ persistPrimaryEmbeddings(episodeId, embeddings, modality) {
524889
+ if (!episodeId || !embeddings)
524890
+ return;
524891
+ const native = toFloat32(embeddings.native);
524892
+ const speaker = toFloat32(embeddings.speaker);
524893
+ const clip2 = toFloat32(embeddings.clip) || toFloat32(embeddings.imageClip) || toFloat32(embeddings.textClip);
524894
+ if (clip2)
524895
+ this.episodeStore.setClipEmbedding(episodeId, clip2);
524896
+ if (native)
524897
+ this.episodeStore.setEmbedding(episodeId, native);
524898
+ else if (modality === "audio" && speaker)
524899
+ this.episodeStore.setEmbedding(episodeId, speaker);
524900
+ }
524901
+ embeddingSpaces(embeddings) {
524902
+ if (!embeddings)
524903
+ return {};
524904
+ const spaces = {};
524905
+ if (embeddings.native)
524906
+ spaces.native = "native";
524907
+ if (embeddings.clip)
524908
+ spaces.clip = "openclip-compatible";
524909
+ if (embeddings.imageClip)
524910
+ spaces.imageClip = "openclip-image";
524911
+ if (embeddings.textClip)
524912
+ spaces.textClip = "openclip-text";
524913
+ if (embeddings.speaker)
524914
+ spaces.speaker = "speaker-embedding";
524915
+ if (embeddings.transcript)
524916
+ spaces.transcript = "text-embedding";
524917
+ return spaces;
524918
+ }
524919
+ };
524920
+ }
524921
+ });
524922
+
524666
524923
  // packages/memory/dist/gistCompressor.js
524667
524924
  function compressToGist(episodes, taskDescription) {
524668
524925
  if (episodes.length === 0) {
@@ -525063,14 +525320,14 @@ var init_proceduralMemoryStore = __esm({
525063
525320
  }
525064
525321
  // ── Links ───────────────────────────────────────────────────────────
525065
525322
  /** Create a link between two memories. */
525066
- createLink(sourceId, targetId, linkType = "related", confidence = 0.5) {
525323
+ createLink(sourceId, targetId, linkType = "related", confidence2 = 0.5) {
525067
525324
  const id = randomUUID10();
525068
525325
  const now = (/* @__PURE__ */ new Date()).toISOString();
525069
525326
  this.db.prepare(`
525070
525327
  INSERT INTO memory_link (id, source_id, target_id, link_type, confidence, created_at)
525071
525328
  VALUES (?, ?, ?, ?, ?, ?)
525072
- `).run(id, sourceId, targetId, linkType, confidence, now);
525073
- return { id, sourceId, targetId, linkType, confidence, createdAt: now };
525329
+ `).run(id, sourceId, targetId, linkType, confidence2, now);
525330
+ return { id, sourceId, targetId, linkType, confidence: confidence2, createdAt: now };
525074
525331
  }
525075
525332
  /** Find memories linked to the given memory ID. */
525076
525333
  findLinked(memoryId, limit = 5) {
@@ -528060,13 +528317,13 @@ function remDream(db, options2 = {}) {
528060
528317
  } catch {
528061
528318
  }
528062
528319
  let chosen = null;
528063
- const seedFloat = toFloat32(seedEmb);
528320
+ const seedFloat = toFloat322(seedEmb);
528064
528321
  if (seedFloat) {
528065
528322
  const distantCandidates = candidateRows.slice(walkDepth);
528066
528323
  let bestSim = minSim;
528067
528324
  let bestId = null;
528068
528325
  for (const cand of distantCandidates) {
528069
- const candFloat = toFloat32(cand.embedding);
528326
+ const candFloat = toFloat322(cand.embedding);
528070
528327
  if (!candFloat || candFloat.length !== seedFloat.length)
528071
528328
  continue;
528072
528329
  const sim = cosineSim(seedFloat, candFloat);
@@ -528286,7 +528543,7 @@ function emptyCycle(phase, start2) {
528286
528543
  integratedNodes: []
528287
528544
  };
528288
528545
  }
528289
- function toFloat32(raw) {
528546
+ function toFloat322(raw) {
528290
528547
  if (raw == null)
528291
528548
  return null;
528292
528549
  if (raw instanceof Float32Array) {
@@ -528745,7 +529002,7 @@ var init_memoryStageContext = __esm({
528745
529002
  });
528746
529003
 
528747
529004
  // packages/memory/dist/sessionGist.js
528748
- import { createHash as createHash11 } from "node:crypto";
529005
+ import { createHash as createHash12 } from "node:crypto";
528749
529006
  function inferDomain(input) {
528750
529007
  const blob = [
528751
529008
  input.goal,
@@ -528770,7 +529027,7 @@ function inferDomain(input) {
528770
529027
  return ranked[0][0];
528771
529028
  }
528772
529029
  function computeGoalHash(goal) {
528773
- return createHash11("sha256").update(goal.trim().toLowerCase()).digest("hex").slice(0, 16);
529030
+ return createHash12("sha256").update(goal.trim().toLowerCase()).digest("hex").slice(0, 16);
528774
529031
  }
528775
529032
  function clip(text, n2) {
528776
529033
  if (!text)
@@ -528981,12 +529238,12 @@ var init_toolOutcomes = __esm({
528981
529238
  });
528982
529239
 
528983
529240
  // packages/memory/dist/stagnationRecipes.js
528984
- import { createHash as createHash12 } from "node:crypto";
529241
+ import { createHash as createHash13 } from "node:crypto";
528985
529242
  function fingerprintSignature(fp) {
528986
529243
  const normClusters = (fp.errorClusters ?? []).map((s2) => (s2 || "").toLowerCase().replace(/[0-9]+/g, "N").replace(/\s+/g, " ").trim()).filter(Boolean).sort();
528987
529244
  const tool = (fp.stuckTool ?? "").toLowerCase().trim();
528988
529245
  const blob = `tool=${tool};clusters=${normClusters.join("|")}`;
528989
- return createHash12("sha256").update(blob).digest("hex").slice(0, 16);
529246
+ return createHash13("sha256").update(blob).digest("hex").slice(0, 16);
528990
529247
  }
528991
529248
  function crystallize(store2, input) {
528992
529249
  const sig = fingerprintSignature(input.fingerprint);
@@ -529043,7 +529300,7 @@ var init_stagnationRecipes = __esm({
529043
529300
  });
529044
529301
 
529045
529302
  // packages/memory/dist/codebaseMap.js
529046
- import { createHash as createHash13, randomUUID as randomUUID12 } from "node:crypto";
529303
+ import { createHash as createHash14, randomUUID as randomUUID12 } from "node:crypto";
529047
529304
  function freshNodeId() {
529048
529305
  return randomUUID12();
529049
529306
  }
@@ -529057,7 +529314,7 @@ var init_codebaseMap = __esm({
529057
529314
  touchCount = /* @__PURE__ */ new Map();
529058
529315
  constructor(db, repoRoot, commitSha) {
529059
529316
  this.db = db;
529060
- this.repoFp = createHash13("sha256").update(`${repoRoot}::${commitSha ?? "no-commit"}`).digest("hex").slice(0, 16);
529317
+ this.repoFp = createHash14("sha256").update(`${repoRoot}::${commitSha ?? "no-commit"}`).digest("hex").slice(0, 16);
529061
529318
  this.ensureSchema();
529062
529319
  }
529063
529320
  ensureSchema() {
@@ -529151,7 +529408,7 @@ var init_codebaseMap = __esm({
529151
529408
  topFiles(limit = 15) {
529152
529409
  const lim = Math.max(1, Math.min(100, limit));
529153
529410
  try {
529154
- const rows = this.db.prepare(`SELECT path, last_touched_ts, metadata FROM codebase_map_node
529411
+ const rows = this.db.prepare(`SELECT path, last_touched_ts, last_result, metadata FROM codebase_map_node
529155
529412
  WHERE repo_fp = ? AND kind = 'file'
529156
529413
  ORDER BY last_touched_ts DESC
529157
529414
  LIMIT ?`).all(this.repoFp, lim);
@@ -529164,7 +529421,7 @@ var init_codebaseMap = __esm({
529164
529421
  count = m2.count;
529165
529422
  } catch {
529166
529423
  }
529167
- out.push({ path: r2.path, touchCount: count, lastTs: r2.last_touched_ts });
529424
+ out.push({ path: r2.path, touchCount: count, lastTs: r2.last_touched_ts, lastResult: r2.last_result ?? null });
529168
529425
  }
529169
529426
  return out;
529170
529427
  } catch {
@@ -529183,7 +529440,7 @@ var init_codebaseMap = __esm({
529183
529440
  return [];
529184
529441
  }
529185
529442
  }
529186
- /** Compact one-line summary used for the [CODEBASE MEMORY] inject. */
529443
+ /** Compact one-line summary for logs and tests that don't need the full restore block. */
529187
529444
  summarize() {
529188
529445
  const files = this.topFiles(8);
529189
529446
  const tests = this.topTests(5);
@@ -529191,9 +529448,55 @@ var init_codebaseMap = __esm({
529191
529448
  const testLine = tests.length > 0 ? tests.map((t2) => `${t2.name.split("/").slice(-1)[0]}=${t2.result}`).join(", ") : "<none>";
529192
529449
  return `repo=${this.repoFp} files-touched=${files.length} (top: ${fileLine}); tests-tracked=${tests.length} (recent: ${testLine})`;
529193
529450
  }
529451
+ snapshot(restored = { nodes: 0, edges: 0 }, limits = {}) {
529452
+ const topFiles = this.topFiles(limits.files ?? 12);
529453
+ const recentTests = this.topTests(limits.tests ?? 8);
529454
+ return {
529455
+ repoFp: this.repoFp,
529456
+ restoredFiles: restored.nodes,
529457
+ restoredEdges: restored.edges,
529458
+ filesTouched: topFiles.length,
529459
+ testsTracked: recentTests.length,
529460
+ topFiles,
529461
+ recentTests
529462
+ };
529463
+ }
529464
+ /** Human-readable restore block for TUI/Telegram startup memory displays. */
529465
+ formatRestoreSummary(restored) {
529466
+ const snapshot = this.snapshot(restored, { files: 20, tests: 10 });
529467
+ const lines = [
529468
+ "[CODEBASE MEMORY]",
529469
+ "Restored prior codebase map",
529470
+ `repo: ${snapshot.repoFp}`,
529471
+ `files restored: ${snapshot.restoredFiles}`,
529472
+ `edges restored: ${snapshot.restoredEdges}`,
529473
+ `files shown: ${snapshot.filesTouched}`,
529474
+ `tests shown: ${snapshot.testsTracked}`,
529475
+ "",
529476
+ "Top files:"
529477
+ ];
529478
+ if (snapshot.topFiles.length === 0) {
529479
+ lines.push(" none");
529480
+ } else {
529481
+ snapshot.topFiles.forEach((file, idx) => {
529482
+ const op = file.lastResult ? `, last ${file.lastResult}` : "";
529483
+ lines.push(` ${idx + 1}. ${file.path} (${file.touchCount} touch${file.touchCount === 1 ? "" : "es"}${op})`);
529484
+ });
529485
+ }
529486
+ lines.push("");
529487
+ lines.push("Recent tests:");
529488
+ if (snapshot.recentTests.length === 0) {
529489
+ lines.push(" none");
529490
+ } else {
529491
+ snapshot.recentTests.forEach((test, idx) => {
529492
+ lines.push(` ${idx + 1}. ${test.name} = ${test.result}`);
529493
+ });
529494
+ }
529495
+ return lines.join("\n");
529496
+ }
529194
529497
  /** Stable composite id: `<kind>:<sha16(path)>` so insert ON CONFLICT works. */
529195
529498
  idFor(kind, path11) {
529196
- const h = createHash13("sha256").update(`${this.repoFp}:${kind}:${path11}`).digest("hex").slice(0, 24);
529499
+ const h = createHash14("sha256").update(`${this.repoFp}:${kind}:${path11}`).digest("hex").slice(0, 24);
529197
529500
  return `${kind}-${h}`;
529198
529501
  }
529199
529502
  };
@@ -529332,6 +529635,7 @@ __export(dist_exports2, {
529332
529635
  FailureStore: () => FailureStore,
529333
529636
  FileSummaryStore: () => FileSummaryStore,
529334
529637
  MemoryStageContext: () => MemoryStageContext,
529638
+ MultimodalIdentityService: () => MultimodalIdentityService,
529335
529639
  PatchHistoryStore: () => PatchHistoryStore,
529336
529640
  PredictionStore: () => PredictionStore,
529337
529641
  ProceduralMemoryStore: () => ProceduralMemoryStore,
@@ -529428,6 +529732,7 @@ var init_dist7 = __esm({
529428
529732
  init_toolPatternStore();
529429
529733
  init_episodeStore();
529430
529734
  init_temporalGraph();
529735
+ init_multimodalIdentity();
529431
529736
  init_zettelkasten();
529432
529737
  init_gistCompressor();
529433
529738
  init_pprRetrieval();
@@ -529512,7 +529817,7 @@ var init_reflectionBuffer = __esm({
529512
529817
  const taskFingerprint = this.computeFingerprint(taskGoal);
529513
529818
  const errorType = this.classifyError(toolCallLog, failedApproaches, lastError, turnsSpent);
529514
529819
  const failedTools = [...new Set(toolCallLog.filter((t2) => !t2.success).map((t2) => t2.tool))].slice(0, 5);
529515
- const { whatFailed, whatToDoDifferently, confidence } = this.generateGuidance(errorType, failedApproaches, toolCallLog, lastError, turnsSpent);
529820
+ const { whatFailed, whatToDoDifferently, confidence: confidence2 } = this.generateGuidance(errorType, failedApproaches, toolCallLog, lastError, turnsSpent);
529516
529821
  const reflection = {
529517
529822
  timestamp: Date.now(),
529518
529823
  sessionId,
@@ -529524,7 +529829,7 @@ var init_reflectionBuffer = __esm({
529524
529829
  failedTools,
529525
529830
  failedPaths: (failedPaths ?? []).slice(0, 5),
529526
529831
  turnsSpent,
529527
- confidence
529832
+ confidence: confidence2
529528
529833
  };
529529
529834
  this.state.reflections.unshift(reflection);
529530
529835
  this.state.totalFailures++;
@@ -531651,7 +531956,7 @@ import { existsSync as existsSync72, readFileSync as readFileSync56, statSync as
531651
531956
  import { execSync as execSync45 } from "node:child_process";
531652
531957
  import { homedir as homedir23, platform as platform2, arch as arch2, totalmem as totalmem2, freemem as freemem2, hostname as hostname3 } from "node:os";
531653
531958
  import { join as join86 } from "node:path";
531654
- import { createHash as createHash14 } from "node:crypto";
531959
+ import { createHash as createHash15 } from "node:crypto";
531655
531960
  function capturePreflightSnapshot(workingDir) {
531656
531961
  const warnings = [];
531657
531962
  const configFingerprints = {};
@@ -531818,7 +532123,7 @@ function expandPath(p2) {
531818
532123
  return p2;
531819
532124
  }
531820
532125
  function sha2563(s2) {
531821
- return createHash14("sha256").update(s2).digest("hex").slice(0, 16);
532126
+ return createHash15("sha256").update(s2).digest("hex").slice(0, 16);
531822
532127
  }
531823
532128
  function freeDiskBytes(path11 = "/tmp") {
531824
532129
  try {
@@ -536373,7 +536678,7 @@ Respond with your assessment, then take action.`;
536373
536678
  if (restored.nodes > 0) {
536374
536679
  this.emit({
536375
536680
  type: "status",
536376
- content: `[CODEBASE MEMORY] restored ${restored.nodes} files / ${restored.edges} edges from prior sessions: ${cm.summarize().slice(0, 220)}`,
536681
+ content: cm.formatRestoreSummary(restored),
536377
536682
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
536378
536683
  });
536379
536684
  }
@@ -537834,8 +538139,8 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
537834
538139
  if (process.env["OMNIUS_DISABLE_ADAPTIVE_RETRIEVAL"] !== "1") {
537835
538140
  const goalForSig = (this._taskState.goal || "").slice(0, 200);
537836
538141
  const recentTools = this._toolSequence.slice(-5).join("|");
537837
- const { createHash: createHash24 } = await import("node:crypto");
537838
- const sig = createHash24("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
538142
+ const { createHash: createHash25 } = await import("node:crypto");
538143
+ const sig = createHash25("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
537839
538144
  if (this._lastPprSig === sig && this._lastPprMemoryLines.length > 0) {
537840
538145
  compacted.push({
537841
538146
  role: "system",
@@ -542949,11 +543254,11 @@ ${trimmedNew}`;
542949
543254
  }
542950
543255
  while (this._littlemanToolOutcomes.length > 20)
542951
543256
  this._littlemanToolOutcomes.shift();
542952
- const emitReaction = (cls, shortText, confidence, details2) => {
543257
+ const emitReaction = (cls, shortText, confidence2, details2) => {
542953
543258
  this.emit({
542954
543259
  type: "observer_reaction",
542955
543260
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
542956
- observer: { class: cls, shortText, confidence, details: details2 }
543261
+ observer: { class: cls, shortText, confidence: confidence2, details: details2 }
542957
543262
  });
542958
543263
  };
542959
543264
  const lastAssistant = [...recent].reverse().find((m2) => m2.role === "assistant" && typeof m2.content === "string");
@@ -545528,14 +545833,14 @@ function extractConstraint(message2) {
545528
545833
  trigger = "shell";
545529
545834
  }
545530
545835
  const id = `learned-${Date.now().toString(36)}`;
545531
- const confidence = pattern.length > 15 ? 0.8 : 0.5;
545836
+ const confidence2 = pattern.length > 15 ? 0.8 : 0.5;
545532
545837
  return {
545533
545838
  id,
545534
545839
  trigger,
545535
545840
  pattern,
545536
545841
  message: `Learned from user correction: "${message2.slice(0, 100)}"`,
545537
545842
  source: `user correction ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`,
545538
- confidence
545843
+ confidence: confidence2
545539
545844
  };
545540
545845
  }
545541
545846
  var CORRECTION_PATTERNS;
@@ -549697,7 +550002,14 @@ function ensureEmbedDeps() {
549697
550002
  ];
549698
550003
  const ins = spawnSync6(pip, ["install", "--upgrade", ...asrPkgs], { encoding: "utf8", timeout: 9e5 });
549699
550004
  log22 += ins.stdout + ins.stderr;
549700
- const ok2 = ins.status === 0 && up.status === 0;
550005
+ let fullOk = true;
550006
+ if (process.env["OMNIUS_INSTALL_FULL_EMBED_DEPS"] === "1") {
550007
+ const fullPkgs = ["torch", "torchaudio", "open_clip_torch", "speechbrain"];
550008
+ const full = spawnSync6(pip, ["install", "--upgrade", ...fullPkgs], { encoding: "utf8", timeout: 18e5 });
550009
+ log22 += full.stdout + full.stderr;
550010
+ fullOk = full.status === 0;
550011
+ }
550012
+ const ok2 = ins.status === 0 && up.status === 0 && fullOk;
549701
550013
  return { ok: ok2, log: log22 };
549702
550014
  }
549703
550015
  function runEmbedImage(input) {
@@ -552927,7 +553239,7 @@ var require_websocket3 = __commonJS({
552927
553239
  var http6 = __require("http");
552928
553240
  var net5 = __require("net");
552929
553241
  var tls2 = __require("tls");
552930
- var { randomBytes: randomBytes26, createHash: createHash24 } = __require("crypto");
553242
+ var { randomBytes: randomBytes26, createHash: createHash25 } = __require("crypto");
552931
553243
  var { Duplex: Duplex3, Readable } = __require("stream");
552932
553244
  var { URL: URL3 } = __require("url");
552933
553245
  var PerMessageDeflate3 = require_permessage_deflate3();
@@ -553587,7 +553899,7 @@ var require_websocket3 = __commonJS({
553587
553899
  abortHandshake(websocket, socket, "Invalid Upgrade header");
553588
553900
  return;
553589
553901
  }
553590
- const digest3 = createHash24("sha1").update(key + GUID).digest("base64");
553902
+ const digest3 = createHash25("sha1").update(key + GUID).digest("base64");
553591
553903
  if (res.headers["sec-websocket-accept"] !== digest3) {
553592
553904
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
553593
553905
  return;
@@ -553954,7 +554266,7 @@ var require_websocket_server2 = __commonJS({
553954
554266
  var EventEmitter13 = __require("events");
553955
554267
  var http6 = __require("http");
553956
554268
  var { Duplex: Duplex3 } = __require("stream");
553957
- var { createHash: createHash24 } = __require("crypto");
554269
+ var { createHash: createHash25 } = __require("crypto");
553958
554270
  var extension3 = require_extension3();
553959
554271
  var PerMessageDeflate3 = require_permessage_deflate3();
553960
554272
  var subprotocol3 = require_subprotocol2();
@@ -554255,7 +554567,7 @@ var require_websocket_server2 = __commonJS({
554255
554567
  );
554256
554568
  }
554257
554569
  if (this._state > RUNNING) return abortHandshake(socket, 503);
554258
- const digest3 = createHash24("sha1").update(key + GUID).digest("base64");
554570
+ const digest3 = createHash25("sha1").update(key + GUID).digest("base64");
554259
554571
  const headers = [
554260
554572
  "HTTP/1.1 101 Switching Protocols",
554261
554573
  "Upgrade: websocket",
@@ -557483,14 +557795,14 @@ var init_voice_session = __esm({
557483
557795
  });
557484
557796
 
557485
557797
  // packages/cli/src/tui/scoped-personality.ts
557486
- import { createHash as createHash15 } from "node:crypto";
557798
+ import { createHash as createHash16 } from "node:crypto";
557487
557799
  import { existsSync as existsSync79, mkdirSync as mkdirSync45, readFileSync as readFileSync62, writeFileSync as writeFileSync40 } from "node:fs";
557488
557800
  import { join as join95, resolve as resolve35 } from "node:path";
557489
557801
  function safeName(input) {
557490
557802
  return input.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "default";
557491
557803
  }
557492
557804
  function scopeHash(scope) {
557493
- return createHash15("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
557805
+ return createHash16("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
557494
557806
  }
557495
557807
  function scopedPersonalityDir(repoRoot, kind) {
557496
557808
  return resolve35(repoRoot, ".omnius", "scoped-personality", kind);
@@ -559331,7 +559643,7 @@ var init_types = __esm({
559331
559643
  });
559332
559644
 
559333
559645
  // packages/cli/src/tui/p2p/secret-vault.ts
559334
- import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes19, scryptSync as scryptSync2, createHash as createHash16 } from "node:crypto";
559646
+ import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes19, scryptSync as scryptSync2, createHash as createHash17 } from "node:crypto";
559335
559647
  import { readFileSync as readFileSync64, writeFileSync as writeFileSync42, existsSync as existsSync81, mkdirSync as mkdirSync47 } from "node:fs";
559336
559648
  import { dirname as dirname25 } from "node:path";
559337
559649
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
@@ -559576,7 +559888,7 @@ var init_secret_vault = __esm({
559576
559888
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
559577
559889
  fingerprint() {
559578
559890
  const names = Array.from(this.secrets.keys()).sort();
559579
- const hash = createHash16("sha256");
559891
+ const hash = createHash17("sha256");
559580
559892
  for (const name10 of names) {
559581
559893
  hash.update(name10 + ":");
559582
559894
  hash.update(this.secrets.get(name10).value);
@@ -559591,7 +559903,7 @@ var init_secret_vault = __esm({
559591
559903
  // packages/cli/src/tui/p2p/peer-mesh.ts
559592
559904
  import { EventEmitter as EventEmitter7 } from "node:events";
559593
559905
  import { createServer as createServer5 } from "node:http";
559594
- import { randomBytes as randomBytes20, createHash as createHash17, generateKeyPairSync } from "node:crypto";
559906
+ import { randomBytes as randomBytes20, createHash as createHash18, generateKeyPairSync } from "node:crypto";
559595
559907
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
559596
559908
  var init_peer_mesh = __esm({
559597
559909
  "packages/cli/src/tui/p2p/peer-mesh.ts"() {
@@ -559608,7 +559920,7 @@ var init_peer_mesh = __esm({
559608
559920
  const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
559609
559921
  this.publicKey = publicKey2.export({ type: "spki", format: "der" });
559610
559922
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
559611
- this.peerId = createHash17("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
559923
+ this.peerId = createHash18("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
559612
559924
  this.capabilities = options2.capabilities;
559613
559925
  this.displayName = options2.displayName;
559614
559926
  this._authKey = options2.authKey ?? randomBytes20(24).toString("base64url");
@@ -561331,7 +561643,7 @@ __export(omnius_directory_exports, {
561331
561643
  import { cpSync, existsSync as existsSync83, mkdirSync as mkdirSync48, readFileSync as readFileSync66, writeFileSync as writeFileSync43, readdirSync as readdirSync26, statSync as statSync29, unlinkSync as unlinkSync14, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync3 } from "node:fs";
561332
561644
  import { join as join100, relative as relative9, basename as basename17, dirname as dirname28 } from "node:path";
561333
561645
  import { homedir as homedir27 } from "node:os";
561334
- import { createHash as createHash18 } from "node:crypto";
561646
+ import { createHash as createHash19 } from "node:crypto";
561335
561647
  function findGitRoot(startDir) {
561336
561648
  let dir = startDir;
561337
561649
  const visited = /* @__PURE__ */ new Set();
@@ -561712,7 +562024,7 @@ function buildHandoffPrompt(repoRoot) {
561712
562024
  return lines.join("\n");
561713
562025
  }
561714
562026
  function computeDedupeHash(task, savedAt) {
561715
- return createHash18("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
562027
+ return createHash19("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
561716
562028
  }
561717
562029
  function generateSessionId() {
561718
562030
  const timestamp = Date.now().toString(36);
@@ -599754,7 +600066,7 @@ var init_vision_ingress = __esm({
599754
600066
  import { mkdirSync as mkdirSync61, existsSync as existsSync106, unlinkSync as unlinkSync21, readdirSync as readdirSync36, statSync as statSync36, statfsSync as statfsSync3, readFileSync as readFileSync87, writeFileSync as writeFileSync56 } from "node:fs";
599755
600067
  import { join as join121, resolve as resolve40, basename as basename25, relative as relative13, isAbsolute as isAbsolute7, extname as extname15 } from "node:path";
599756
600068
  import { writeFile as writeFileAsync } from "node:fs/promises";
599757
- import { createHash as createHash19, randomInt } from "node:crypto";
600069
+ import { createHash as createHash20, randomInt } from "node:crypto";
599758
600070
  function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
599759
600071
  const cleaned = stripTelegramHiddenThinking(text).replace(/```(?:json)?/gi, "").replace(/```/g, "").trim();
599760
600072
  const jsonText = cleaned.startsWith("{") ? cleaned : cleaned.match(/\{[\s\S]*\}/)?.[0] ?? "";
@@ -599767,7 +600079,7 @@ function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
599767
600079
  const shouldReplyRaw = parsed["should_reply"] ?? parsed["shouldReply"];
599768
600080
  const shouldReply = typeof shouldReplyRaw === "boolean" ? shouldReplyRaw : options2.defaultShouldReply ?? true;
599769
600081
  const confidenceRaw = Number(parsed["confidence"]);
599770
- const confidence = Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : 0;
600082
+ const confidence2 = Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : 0;
599771
600083
  const reason = String(parsed["reason"] ?? "live inference decision").slice(0, 240);
599772
600084
  const attentionDeltaRaw = Number(parsed["attention_delta"] ?? parsed["attentionDelta"]);
599773
600085
  const attentionScoreRaw = Number(parsed["attention_score"] ?? parsed["attentionScore"]);
@@ -599776,7 +600088,7 @@ function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
599776
600088
  return {
599777
600089
  route,
599778
600090
  shouldReply,
599779
- confidence,
600091
+ confidence: confidence2,
599780
600092
  reason,
599781
600093
  source: forcedRoute ? "forced-mode" : "live-inference",
599782
600094
  raw: text,
@@ -599837,6 +600149,27 @@ function sanitizeTelegramProgressText(text, maxLength) {
599837
600149
  const compact = stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
599838
600150
  return compact.length > maxLength ? compact.slice(0, Math.max(0, maxLength - 3)) + "..." : compact;
599839
600151
  }
600152
+ function isCodebaseMemoryStatus(text) {
600153
+ return /^\s*\[CODEBASE MEMORY\]/i.test(stripTelegramHiddenThinking(text));
600154
+ }
600155
+ function formatTelegramCodebaseMemoryStatusHTML(text) {
600156
+ const lines = stripTelegramHiddenThinking(text).split(/\r?\n/).map((line) => line.trimEnd()).filter((line) => line.trim().length > 0);
600157
+ const body = lines.filter((line) => !/^\[CODEBASE MEMORY\]/i.test(line));
600158
+ const metricLines = body.filter((line) => /^(repo|files restored|edges restored|files shown|tests shown):/i.test(line));
600159
+ const detailLines = body.filter((line) => !metricLines.includes(line) && !/^Restored prior codebase map$/i.test(line));
600160
+ const details = detailLines.length > 0 ? detailLines.join("\n") : "No file or test details restored.";
600161
+ const metrics2 = metricLines.map((line) => {
600162
+ const idx = line.indexOf(":");
600163
+ const key = idx >= 0 ? line.slice(0, idx) : line;
600164
+ const value2 = idx >= 0 ? line.slice(idx + 1).trim() : "";
600165
+ return `${escapeTelegramHTML(key)}: <code>${escapeTelegramHTML(value2)}</code>`;
600166
+ });
600167
+ return [
600168
+ "<b>Codebase memory restored</b>",
600169
+ metrics2.join("\n"),
600170
+ `<blockquote expandable>${escapeTelegramHTML(details)}</blockquote>`
600171
+ ].filter(Boolean).join("\n");
600172
+ }
599840
600173
  function compactTelegramVisibleText(text) {
599841
600174
  return stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
599842
600175
  }
@@ -600068,7 +600401,7 @@ function buildTelegramRuntimeContext(now = /* @__PURE__ */ new Date(), repoRoot)
600068
600401
  ].filter(Boolean).join("\n");
600069
600402
  }
600070
600403
  function telegramSessionIdFromKey(sessionKey) {
600071
- return `telegram-${createHash19("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
600404
+ return `telegram-${createHash20("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
600072
600405
  }
600073
600406
  function selectTelegramFinalResponse(args) {
600074
600407
  const committedVisibleReply = cleanTelegramVisibleReply(args.visibleReplyText || "");
@@ -600102,6 +600435,9 @@ function formatTelegramProgressEvent(event) {
600102
600435
  return event.success ? `${toolName} completed` : `${toolName} failed`;
600103
600436
  }
600104
600437
  if (event.type === "status") {
600438
+ if (isCodebaseMemoryStatus(event.content || "")) {
600439
+ return formatTelegramCodebaseMemoryStatusHTML(event.content || "");
600440
+ }
600105
600441
  const content = sanitizeTelegramProgressText(event.content || "", 120);
600106
600442
  if (isTelegramInternalStatusText(content)) return null;
600107
600443
  return content ? escapeTelegramHTML(content) : null;
@@ -601123,7 +601459,7 @@ Telegram response contract:
601123
601459
  return !!this.adminAuthChallenge && this.adminAuthChallenge.expiresAtMs > Date.now();
601124
601460
  }
601125
601461
  hashAdminAuthCode(code8) {
601126
- return createHash19("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
601462
+ return createHash20("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
601127
601463
  }
601128
601464
  viewIdForMessage(msg) {
601129
601465
  return `telegram-${this.sessionKeyForMessage(msg).replace(/[^A-Za-z0-9_-]/g, "-")}`;
@@ -601371,8 +601707,97 @@ ${mediaContext}` : ""
601371
601707
  const preview = truncateTelegramContextLine(reply.quote || reply.text || reply.caption || reply.mediaSummary || reply.originSummary || reply.kind, 160);
601372
601708
  return `reply: ${current} -> ${target}${selfMarker}${id}${preview ? `: "${preview}"` : ""}`;
601373
601709
  }
601710
+ telegramMemorySenderFromMessage(msg) {
601711
+ return {
601712
+ id: String(msg.fromUserId),
601713
+ username: msg.username,
601714
+ displayName: msg.firstName || msg.username,
601715
+ isBot: false
601716
+ };
601717
+ }
601718
+ telegramMemorySenderFromReply(msg) {
601719
+ const sender = msg.replyContext?.sender;
601720
+ if (!sender && !msg.replyToUsername) return void 0;
601721
+ return {
601722
+ id: sender?.id !== void 0 ? String(sender.id) : void 0,
601723
+ username: sender?.username || msg.replyToUsername,
601724
+ displayName: sender?.firstName || sender?.title || sender?.username || msg.replyToUsername,
601725
+ isBot: Boolean(sender?.isBot || msg.replyToBot)
601726
+ };
601727
+ }
601728
+ telegramMemoryScope(msg) {
601729
+ return {
601730
+ kind: msg.chatType === "private" ? "private" : "group",
601731
+ id: String(msg.chatId),
601732
+ title: msg.chatTitle
601733
+ };
601734
+ }
601735
+ telegramMemoryReplyRef(msg) {
601736
+ const reply = this.resolveTelegramReplyContext(this.sessionKeyForMessage(msg), msg);
601737
+ if (!reply) return void 0;
601738
+ return {
601739
+ id: reply.messageId,
601740
+ threadId: reply.threadId,
601741
+ text: reply.text || reply.caption || reply.quote || reply.mediaSummary,
601742
+ sender: reply.sender ? {
601743
+ id: reply.sender.id !== void 0 ? String(reply.sender.id) : void 0,
601744
+ username: reply.sender.username,
601745
+ displayName: reply.sender.firstName || reply.sender.title || reply.sender.username,
601746
+ isBot: Boolean(reply.sender.isBot)
601747
+ } : void 0,
601748
+ mediaUniqueId: reply.media?.fileUniqueId
601749
+ };
601750
+ }
601751
+ telegramMemoryIngestPayload(msg, media, localPath, source, extractedContent) {
601752
+ const isReplyMedia = source === "reply";
601753
+ const messageId = isReplyMedia ? msg.replyToMessageId : msg.messageId;
601754
+ const messageText = isReplyMedia ? msg.replyContext?.text || msg.replyContext?.caption || msg.replyToText || media.caption : msg.text || media.caption;
601755
+ const sender = isReplyMedia ? this.telegramMemorySenderFromReply(msg) : this.telegramMemorySenderFromMessage(msg);
601756
+ const modality = media.type === "audio" || media.type === "voice" ? "audio" : telegramMediaIsImage(media) ? "visual" : "text";
601757
+ const payload = {
601758
+ sourceSurface: "telegram",
601759
+ scope: this.telegramMemoryScope(msg),
601760
+ sender,
601761
+ message: {
601762
+ id: messageId,
601763
+ threadId: msg.messageThreadId,
601764
+ timestamp: Date.now(),
601765
+ text: messageText
601766
+ },
601767
+ replyTo: !isReplyMedia ? this.telegramMemoryReplyRef(msg) : void 0,
601768
+ modality,
601769
+ media: {
601770
+ path: localPath,
601771
+ mediaType: media.type,
601772
+ mimeType: media.mimeType || (telegramMediaIsImage(media) ? telegramImageMime(media) : void 0),
601773
+ fileId: media.fileId,
601774
+ fileUniqueId: media.fileUniqueId,
601775
+ caption: media.caption
601776
+ },
601777
+ media_path: localPath,
601778
+ media_type: media.type,
601779
+ mime_type: media.mimeType,
601780
+ file_id: media.fileId,
601781
+ file_unique_id: media.fileUniqueId,
601782
+ caption: media.caption,
601783
+ message_id: messageId,
601784
+ thread_id: msg.messageThreadId,
601785
+ chat_id: String(msg.chatId),
601786
+ chat_type: msg.chatType,
601787
+ chat_title: msg.chatTitle,
601788
+ sender_id: sender && typeof sender["id"] === "string" ? sender["id"] : void 0,
601789
+ username: sender && typeof sender["username"] === "string" ? sender["username"] : void 0,
601790
+ display_name: sender && typeof sender["displayName"] === "string" ? sender["displayName"] : void 0,
601791
+ labels: [media.caption].filter(Boolean)
601792
+ };
601793
+ if (extractedContent) {
601794
+ if (modality === "audio") payload.transcript = extractedContent;
601795
+ else payload.extractedContent = extractedContent;
601796
+ }
601797
+ return payload;
601798
+ }
601374
601799
  telegramConversationPath(sessionKey) {
601375
- const safe = createHash19("sha1").update(sessionKey).digest("hex").slice(0, 20);
601800
+ const safe = createHash20("sha1").update(sessionKey).digest("hex").slice(0, 20);
601376
601801
  return join121(this.telegramConversationDir, `${safe}.json`);
601377
601802
  }
601378
601803
  telegramPersonalityScope(sessionKey, msg) {
@@ -601679,7 +602104,7 @@ ${mediaContext}` : ""
601679
602104
  const titleTags = tags.slice(0, 4);
601680
602105
  const title = titleTags.length > 0 ? `${speaker} / ${titleTags.join(" ")}` : `${speaker} / conversation`;
601681
602106
  const card = {
601682
- id: createHash19("sha1").update(`${sessionKey}:${now}:${speaker}:${text}`).digest("hex").slice(0, 12),
602107
+ id: createHash20("sha1").update(`${sessionKey}:${now}:${speaker}:${text}`).digest("hex").slice(0, 12),
601683
602108
  title,
601684
602109
  notes: [],
601685
602110
  tags: [],
@@ -602144,7 +602569,7 @@ ${list}` : "No shared group target is currently known for this sender. Ask in th
602144
602569
  }
602145
602570
  telegramRunnerStateDir(sessionKey) {
602146
602571
  if (!this.repoRoot) return void 0;
602147
- const safe = createHash19("sha1").update(sessionKey).digest("hex").slice(0, 20);
602572
+ const safe = createHash20("sha1").update(sessionKey).digest("hex").slice(0, 20);
602148
602573
  return join121(this.repoRoot, ".omnius", "telegram-runner-state", safe);
602149
602574
  }
602150
602575
  buildTelegramAdminOverviewContext(currentSessionKey) {
@@ -604154,7 +604579,7 @@ ${visionContext}]`;
604154
604579
  await fetch("http://127.0.0.1:11435/v1/memory/ingest", {
604155
604580
  method: "POST",
604156
604581
  headers: { "Content-Type": "application/json" },
604157
- body: JSON.stringify({ modality: "visual", media_path: localPath, labels: [msg.username || "unknown", caption || ""].filter(Boolean) }),
604582
+ body: JSON.stringify(this.telegramMemoryIngestPayload(msg, media, localPath, source, cacheEntry.extractedContent)),
604158
604583
  signal: AbortSignal.timeout(2e3)
604159
604584
  });
604160
604585
  } catch {
@@ -604180,7 +604605,7 @@ ${visionContext}]`;
604180
604605
  await fetch("http://127.0.0.1:11435/v1/memory/ingest", {
604181
604606
  method: "POST",
604182
604607
  headers: { "Content-Type": "application/json" },
604183
- body: JSON.stringify({ modality: "audio", media_path: localPath, labels: [msg.username || "unknown"].filter(Boolean) }),
604608
+ body: JSON.stringify(this.telegramMemoryIngestPayload(msg, media, localPath, source, transcription)),
604184
604609
  signal: AbortSignal.timeout(2e3)
604185
604610
  });
604186
604611
  } catch {
@@ -606318,14 +606743,14 @@ var init_access_policy = __esm({
606318
606743
  });
606319
606744
 
606320
606745
  // packages/cli/src/api/project-preferences.ts
606321
- import { createHash as createHash20 } from "node:crypto";
606746
+ import { createHash as createHash21 } from "node:crypto";
606322
606747
  import { existsSync as existsSync109, mkdirSync as mkdirSync64, readFileSync as readFileSync90, renameSync as renameSync7, writeFileSync as writeFileSync59, unlinkSync as unlinkSync23 } from "node:fs";
606323
606748
  import { homedir as homedir38 } from "node:os";
606324
606749
  import { join as join124, resolve as resolve42 } from "node:path";
606325
606750
  import { randomUUID as randomUUID15 } from "node:crypto";
606326
606751
  function projectKey(root) {
606327
606752
  const canonical = resolve42(root);
606328
- return createHash20("sha256").update(canonical).digest("hex").slice(0, 16);
606753
+ return createHash21("sha256").update(canonical).digest("hex").slice(0, 16);
606329
606754
  }
606330
606755
  function projectDir(root) {
606331
606756
  return join124(PROJECTS_DIR, projectKey(root));
@@ -606441,7 +606866,7 @@ function repeatingCharPenalty(s2) {
606441
606866
  if (cur > maxRun) maxRun = cur;
606442
606867
  return Math.min(1, Math.max(0, (maxRun - 3) / 10));
606443
606868
  }
606444
- function computeSignalFromText(text, confidence) {
606869
+ function computeSignalFromText(text, confidence2) {
606445
606870
  const t2 = text.trim();
606446
606871
  if (!t2) return 0;
606447
606872
  if (NOISE_ONLY_RE.test(t2)) return 0.05;
@@ -606455,8 +606880,8 @@ function computeSignalFromText(text, confidence) {
606455
606880
  else if (wc >= 1 && alpha >= 0.3 && len >= 4) score = 0.35;
606456
606881
  else score = 0.15;
606457
606882
  score -= repeatingCharPenalty(t2) * 0.4;
606458
- if (typeof confidence === "number" && !Number.isNaN(confidence)) {
606459
- score = 0.7 * score + 0.3 * clamp017(confidence);
606883
+ if (typeof confidence2 === "number" && !Number.isNaN(confidence2)) {
606884
+ score = 0.7 * score + 0.3 * clamp017(confidence2);
606460
606885
  }
606461
606886
  return clamp017(score);
606462
606887
  }
@@ -606633,19 +607058,19 @@ Rules:
606633
607058
  let text;
606634
607059
  let isFinal;
606635
607060
  let snr;
606636
- let confidence;
607061
+ let confidence2;
606637
607062
  if (typeof args[0] === "object" && args[0] !== null) {
606638
607063
  const evt = args[0];
606639
607064
  text = evt.text ?? "";
606640
607065
  isFinal = evt.isFinal ?? false;
606641
607066
  snr = evt.snr;
606642
- confidence = evt.confidence;
607067
+ confidence2 = evt.confidence;
606643
607068
  } else {
606644
607069
  text = String(args[0] ?? "");
606645
607070
  isFinal = Boolean(args[1]);
606646
607071
  }
606647
607072
  if (!text.trim()) return;
606648
- this.handleTranscript(text.trim(), isFinal, snr, confidence);
607073
+ this.handleTranscript(text.trim(), isFinal, snr, confidence2);
606649
607074
  };
606650
607075
  this._onError = (err) => {
606651
607076
  const msg = err instanceof Error ? err.message : String(err);
@@ -606712,7 +607137,7 @@ Rules:
606712
607137
  // ---------------------------------------------------------------------------
606713
607138
  // Transcript handling — VAD-style segment capture (Voryn pattern)
606714
607139
  // ---------------------------------------------------------------------------
606715
- handleTranscript(text, isFinal, snr, confidence) {
607140
+ handleTranscript(text, isFinal, snr, confidence2) {
606716
607141
  if (!this.active) return;
606717
607142
  if (this._state !== "LISTENING" && this._state !== "CAPTURING") {
606718
607143
  return;
@@ -606728,7 +607153,7 @@ Rules:
606728
607153
  }, MAX_SEGMENT_MS);
606729
607154
  }
606730
607155
  this.captureBuffer = text;
606731
- this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ? clamp017(snr) : computeSignalFromText(text, confidence);
607156
+ this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ? clamp017(snr) : computeSignalFromText(text, confidence2);
606732
607157
  this.emit("snr", { score: this.lastSignalScore });
606733
607158
  this.onPartialTranscript(text);
606734
607159
  if (this.silenceTimer) clearTimeout(this.silenceTimer);
@@ -607503,7 +607928,7 @@ var init_disk_task_output = __esm({
607503
607928
  });
607504
607929
 
607505
607930
  // packages/cli/src/api/http.ts
607506
- import { createHash as createHash21 } from "node:crypto";
607931
+ import { createHash as createHash22 } from "node:crypto";
607507
607932
  function problemDetails(opts) {
607508
607933
  const p2 = {
607509
607934
  type: opts.type ?? "about:blank",
@@ -607566,7 +607991,7 @@ function paginated(items, page2, total) {
607566
607991
  }
607567
607992
  function computeEtag(payload) {
607568
607993
  const json = typeof payload === "string" ? payload : JSON.stringify(payload);
607569
- const hash = createHash21("sha1").update(json).digest("hex").slice(0, 16);
607994
+ const hash = createHash22("sha1").update(json).digest("hex").slice(0, 16);
607570
607995
  return `W/"${hash}"`;
607571
607996
  }
607572
607997
  function checkNotModified(req2, res, etag) {
@@ -609242,16 +609667,23 @@ async function handleCallMcp(ctx3, name10) {
609242
609667
  return true;
609243
609668
  }
609244
609669
  }
609670
+ function memoryDbPaths(baseDir = process.cwd()) {
609671
+ const dir = join130(baseDir, ".omnius");
609672
+ return {
609673
+ episodes: join130(dir, "episodes.db"),
609674
+ knowledge: join130(dir, "knowledge.db")
609675
+ };
609676
+ }
609245
609677
  async function getMemoryStores() {
609246
609678
  if (memoryStoresCache) return memoryStoresCache;
609247
609679
  if (memoryInitTried) return null;
609248
609680
  memoryInitTried = true;
609249
609681
  try {
609250
- const dbPath = join130(homedir42(), ".omnius", "memory.db");
609251
- const sharedDb = initDb(dbPath);
609682
+ const dbPaths = memoryDbPaths();
609683
+ const sharedDb = initDb(dbPaths.episodes);
609252
609684
  memoryStoresCache = {
609253
- episode: new EpisodeStore(dbPath),
609254
- temporal: new TemporalGraph(dbPath),
609685
+ episode: new EpisodeStore(dbPaths.episodes),
609686
+ temporal: new TemporalGraph(dbPaths.knowledge),
609255
609687
  failure: new FailureStore(sharedDb)
609256
609688
  };
609257
609689
  return memoryStoresCache;
@@ -621722,7 +622154,15 @@ import { homedir as homedir45 } from "node:os";
621722
622154
  import { spawn as spawn29, execSync as execSync57 } from "node:child_process";
621723
622155
  import { mkdirSync as mkdirSync72, writeFileSync as writeFileSync65, readFileSync as readFileSync98, readdirSync as readdirSync41, existsSync as existsSync120, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync25 } from "node:fs";
621724
622156
  import { randomBytes as randomBytes24, randomUUID as randomUUID16 } from "node:crypto";
621725
- import { createHash as createHash23 } from "node:crypto";
622157
+ import { createHash as createHash24 } from "node:crypto";
622158
+ function memoryDbPaths2(baseDir = process.cwd()) {
622159
+ const dir = join135(baseDir, ".omnius");
622160
+ return {
622161
+ dir,
622162
+ episodes: join135(dir, "episodes.db"),
622163
+ knowledge: join135(dir, "knowledge.db")
622164
+ };
622165
+ }
621726
622166
  function getVersion3() {
621727
622167
  try {
621728
622168
  const thisDir = dirname37(fileURLToPath17(import.meta.url));
@@ -622087,7 +622527,7 @@ async function retrieveMemoryContext(userMessage, sessionId, maxEpisodes = 5) {
622087
622527
  if (!memMod || !memMod.EpisodeStore) {
622088
622528
  return { contextBlock: "", retrieved: [] };
622089
622529
  }
622090
- const dbPath = join135(homedir45(), ".omnius", "memory.db");
622530
+ const dbPath = memoryDbPaths2(process.cwd()).episodes;
622091
622531
  const store2 = new memMod.EpisodeStore(dbPath);
622092
622532
  const recent = store2.search({ limit: 30, sessionId: void 0 }) ?? [];
622093
622533
  const qLower = userMessage.toLowerCase();
@@ -622130,7 +622570,7 @@ async function writeMemoryEpisodes(sessionId, userMessage, assistantContent, too
622130
622570
  try {
622131
622571
  const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2)).catch(() => null);
622132
622572
  if (!memMod || !memMod.EpisodeStore) return 0;
622133
- const dbPath = join135(homedir45(), ".omnius", "memory.db");
622573
+ const dbPath = memoryDbPaths2(process.cwd()).episodes;
622134
622574
  const store2 = new memMod.EpisodeStore(dbPath);
622135
622575
  let written = 0;
622136
622576
  try {
@@ -627587,7 +628027,7 @@ function listScheduledTasks() {
627587
628027
  const schedule = String(t2?.schedule || t2?.cron || t2?.when || "");
627588
628028
  const enabled2 = typeof t2?.enabled === "boolean" ? t2.enabled : true;
627589
628029
  const realId = typeof t2?.id === "string" && t2.id ? t2.id : null;
627590
- const fallbackId = createHash23("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
628030
+ const fallbackId = createHash24("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
627591
628031
  const uid = realId || fallbackId;
627592
628032
  const key = `${uid}`;
627593
628033
  if (seen.has(key)) return;
@@ -627704,8 +628144,8 @@ function deleteScheduledById(id) {
627704
628144
  if (id) candidates.push(id);
627705
628145
  if (typeof entry?.id === "string" && entry.id && !candidates.includes(entry.id)) candidates.push(entry.id);
627706
628146
  try {
627707
- const { createHash: createHash24 } = require4("node:crypto");
627708
- const fallback = createHash24("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
628147
+ const { createHash: createHash25 } = require4("node:crypto");
628148
+ const fallback = createHash25("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
627709
628149
  if (!candidates.includes(fallback)) candidates.push(fallback);
627710
628150
  } catch {
627711
628151
  }
@@ -628635,9 +629075,9 @@ function startApiServer(options2 = {}) {
628635
629075
  try {
628636
629076
  const { startEmbeddingWorkers: startEmbeddingWorkers2 } = await Promise.resolve().then(() => (init_embedding_workers(), embedding_workers_exports));
628637
629077
  const { ensureEmbedDeps: ensureEmbedDeps2, runEmbedImage: runEmbedImage2, runEmbedAudio: runEmbedAudio2 } = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
628638
- const dbBase = join135(cwd4, ".omnius");
628639
- const epStore = new mem.EpisodeStore(join135(dbBase, "memory.db"));
628640
- const kg = new mem.TemporalGraph(join135(dbBase, "kg.db"));
629078
+ const dbPaths = memoryDbPaths2(cwd4);
629079
+ const epStore = new mem.EpisodeStore(dbPaths.episodes);
629080
+ const kg = new mem.TemporalGraph(dbPaths.knowledge);
628641
629081
  try {
628642
629082
  ensureEmbedDeps2();
628643
629083
  } catch {
@@ -629029,67 +629469,86 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
629029
629469
  const content = typeof b.content === "string" ? b.content : "";
629030
629470
  const labels = Array.isArray(b.labels) ? b.labels : [];
629031
629471
  const mediaPath = typeof b.media_path === "string" ? b.media_path : void 0;
629032
- const cwd4 = process.cwd();
629033
- const dbBase = join135(cwd4, ".omnius");
629034
- const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
629035
- const epStore = new EpisodeStore3(join135(dbBase, "memory.db"));
629036
- const kg = new TemporalGraph3(join135(dbBase, "kg.db"));
629037
- const meta = {};
629038
- if (mediaPath) meta.media_path = mediaPath;
629039
- const epId = epStore.insert({ modality, content: content || (mediaPath || ""), metadata: meta, toolName: "memory_ingest" });
629040
- if (modality === "visual" && Array.isArray(labels) && labels.length > 0) {
629472
+ const rawMedia = typeof b.media === "object" && b.media ? { ...b.media, path: b.media.path || mediaPath } : {
629473
+ path: mediaPath,
629474
+ mimeType: b.mime_type,
629475
+ mediaType: b.media_type,
629476
+ fileId: b.file_id,
629477
+ fileUniqueId: b.file_unique_id,
629478
+ caption: b.caption,
629479
+ sha256: b.sha256
629480
+ };
629481
+ const media = Object.values(rawMedia).some((value2) => value2 != null && String(value2).trim() !== "") ? rawMedia : void 0;
629482
+ const sourceSurface = String(b.sourceSurface || b.source_surface || "api");
629483
+ const scope = typeof b.scope === "object" && b.scope ? b.scope : {
629484
+ kind: b.scope_kind || (b.chat_type === "private" ? "private" : b.chat_id ? "group" : "global"),
629485
+ id: String(b.scope_id || b.chat_id || sourceSurface),
629486
+ title: b.chat_title
629487
+ };
629488
+ const sender = typeof b.sender === "object" && b.sender ? b.sender : b.sender_id || b.username || b.display_name ? { id: b.sender_id != null ? String(b.sender_id) : void 0, username: b.username, displayName: b.display_name } : void 0;
629489
+ const message2 = typeof b.message === "object" && b.message ? b.message : b.message_id != null || b.thread_id != null ? { id: b.message_id, threadId: b.thread_id, timestamp: b.timestamp, text: content || b.caption } : void 0;
629490
+ const replyTo = b.replyTo || b.reply_to;
629491
+ const identityAssertions = Array.isArray(b.identityAssertions) ? b.identityAssertions : Array.isArray(b.identity_assertions) ? b.identity_assertions : Array.isArray(b.people) ? b.people.map((name10) => ({ name: String(name10), relation: modality === "audio" ? "speaker" : "depicts", confidence: 0.8, assertedBy: sender })) : [];
629492
+ const embeddings = {};
629493
+ const providedEmbeddings = typeof b.embeddings === "object" && b.embeddings ? b.embeddings : {};
629494
+ Object.assign(embeddings, providedEmbeddings);
629495
+ if (modality === "visual" && mediaPath && !embeddings.clip && !embeddings.imageClip) {
629041
629496
  try {
629042
- const primaryLabel = String(labels[0]);
629043
- const personId = kg.upsertNode({ text: primaryLabel, nodeType: "person" });
629044
- kg.addEdge({ srcId: personId, dstId: personId, relation: "appears_in", fact: (content || mediaPath || "").slice(0, 120), modality: "visual", sourceEpisodeId: epId });
629045
- for (const l2 of labels.slice(1)) {
629046
- const aliasId = kg.upsertNode({ text: String(l2), nodeType: "person" });
629047
- kg.addEdge({ srcId: aliasId, dstId: personId, relation: "alias_of", modality: "text" });
629048
- }
629497
+ const provider = globalThis.__omniusVisionProvider;
629498
+ const emb = provider ? await provider({ path: mediaPath }) : null;
629499
+ if (emb) embeddings.imageClip = emb;
629049
629500
  } catch {
629050
629501
  }
629051
629502
  }
629503
+ if (modality === "audio" && mediaPath && !embeddings.native && !embeddings.speaker) {
629504
+ try {
629505
+ const provider = globalThis.__omniusAudioProvider;
629506
+ const emb = provider ? await provider({ path: mediaPath }) : null;
629507
+ if (emb) embeddings.speaker = emb;
629508
+ } catch {
629509
+ }
629510
+ }
629511
+ let transcript = typeof b.transcript === "string" ? b.transcript : "";
629052
629512
  if (modality === "audio" && mediaPath) {
629053
629513
  try {
629054
629514
  const { runTranscribeFile: runTranscribeFile2 } = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
629055
- const text = runTranscribeFile2({ path: mediaPath, model: process.env["WHISPER_MODEL"] || "base" }) || "";
629056
- if (text) {
629057
- const personMeta = {};
629058
- let personId = null;
629515
+ transcript = transcript || runTranscribeFile2({ path: mediaPath, model: process.env["WHISPER_MODEL"] || "base" }) || "";
629516
+ if (transcript && !embeddings.transcript) {
629059
629517
  try {
629060
- const primaryLabel = labels && labels.length > 0 ? String(labels[0]) : "person";
629061
- personId = kg.upsertNode({ text: primaryLabel, nodeType: "person" });
629062
- if (Array.isArray(labels) && labels.length > 1) {
629063
- for (const l2 of labels.slice(1)) {
629064
- const aliasId = kg.upsertNode({ text: String(l2), nodeType: "person" });
629065
- kg.addEdge({ srcId: aliasId, dstId: personId, relation: "alias_of", modality: "text" });
629066
- }
629067
- }
629068
- } catch {
629069
- }
629070
- if (personId) personMeta.person_node_id = personId;
629071
- const textEpId = epStore.insert({ modality: "text", content: text, toolName: "transcribe_file", sourceEpisodeId: epId, metadata: personMeta });
629072
- try {
629073
- const payload = JSON.stringify({ model: process.env["EMBED_MODEL"] || "nomic-embed-text", input: text });
629074
- const result = await ollamaRequest(ollamaUrl, "/api/embed", "POST", payload);
629075
- if (result.status === 200) {
629076
- const parsed = JSON.parse(result.body);
629518
+ const payload = JSON.stringify({ model: process.env["EMBED_MODEL"] || "nomic-embed-text", input: transcript });
629519
+ const result2 = await ollamaRequest(ollamaUrl, "/api/embed", "POST", payload);
629520
+ if (result2.status === 200) {
629521
+ const parsed = JSON.parse(result2.body);
629077
629522
  const vec = Array.isArray(parsed.embeddings) && Array.isArray(parsed.embeddings[0]) ? parsed.embeddings[0] : null;
629078
- if (vec) epStore.setEmbedding(textEpId, new Float32Array(vec));
629523
+ if (vec) embeddings.transcript = vec;
629079
629524
  }
629080
629525
  } catch {
629081
629526
  }
629082
- try {
629083
- const primaryLabel = labels && labels.length > 0 ? String(labels[0]) : "person";
629084
- const nodeId = personId || kg.upsertNode({ text: primaryLabel, nodeType: "person" });
629085
- kg.addEdge({ srcId: nodeId, dstId: nodeId, relation: "said_by", fact: text.slice(0, 160), modality: "audio", sourceEpisodeId: textEpId });
629086
- } catch {
629087
- }
629088
629527
  }
629089
629528
  } catch {
629090
629529
  }
629091
629530
  }
629092
- jsonResponse(res, 200, { id: epId });
629531
+ const dbPaths = memoryDbPaths2(process.cwd());
629532
+ const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3, MultimodalIdentityService: MultimodalIdentityService2 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
629533
+ const epStore = new EpisodeStore3(dbPaths.episodes);
629534
+ const kg = new TemporalGraph3(dbPaths.knowledge);
629535
+ const service = new MultimodalIdentityService2({ episodeStore: epStore, graph: kg });
629536
+ const result = service.ingest({
629537
+ sourceSurface,
629538
+ scope,
629539
+ sender,
629540
+ message: message2,
629541
+ replyTo,
629542
+ modality,
629543
+ content,
629544
+ transcript,
629545
+ extractedContent: b.extracted_content || b.extractedContent,
629546
+ media,
629547
+ labels,
629548
+ identityAssertions,
629549
+ embeddings
629550
+ });
629551
+ jsonResponse(res, 200, { id: result.episodeId, ...result });
629093
629552
  } catch (err) {
629094
629553
  jsonResponse(res, 400, { error: "bad_request", message: err instanceof Error ? err.message : String(err) });
629095
629554
  }
@@ -629100,7 +629559,7 @@ async function handleEntitiesList(req2, res) {
629100
629559
  const type = url.searchParams.get("type") || "person";
629101
629560
  const limit = Math.max(1, Math.min(1e3, parseInt(url.searchParams.get("limit") || "100", 10)));
629102
629561
  const { TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
629103
- const kg = new TemporalGraph3(join135(process.cwd(), ".omnius", "kg.db"));
629562
+ const kg = new TemporalGraph3(memoryDbPaths2(process.cwd()).knowledge);
629104
629563
  const nodes = kg.nodesByType(type, limit).map((n2) => ({ id: n2.id, text: n2.text, mentionCount: n2.mentionCount, firstSeen: n2.firstSeen, lastSeen: n2.lastSeen }));
629105
629564
  jsonResponse(res, 200, { object: "list", data: nodes });
629106
629565
  } catch (err) {
@@ -637147,13 +637606,13 @@ NEW TASK: ${fullInput}`;
637147
637606
  writeContent(() => renderError(errMsg));
637148
637607
  if (failureStore) {
637149
637608
  try {
637150
- const { createHash: createHash24 } = await import("node:crypto");
637609
+ const { createHash: createHash25 } = await import("node:crypto");
637151
637610
  failureStore.insert({
637152
637611
  taskId: "",
637153
637612
  sessionId: `${Date.now()}`,
637154
637613
  repoRoot,
637155
637614
  failureType: "runtime-error",
637156
- fingerprint: createHash24("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
637615
+ fingerprint: createHash25("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
637157
637616
  filePath: null,
637158
637617
  errorMessage: errMsg.slice(0, 500),
637159
637618
  context: null,