@oh-my-pi/pi-mnemopi 16.3.12 → 16.3.13

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-mnemopi",
4
- "version": "16.3.12",
4
+ "version": "16.3.13",
5
5
  "description": "Local SQLite memory engine for Oh My Pi agents",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -39,9 +39,9 @@
39
39
  "fmt": "biome format --write ."
40
40
  },
41
41
  "dependencies": {
42
- "@oh-my-pi/pi-ai": "16.3.12",
43
- "@oh-my-pi/pi-catalog": "16.3.12",
44
- "@oh-my-pi/pi-utils": "16.3.12",
42
+ "@oh-my-pi/pi-ai": "16.3.13",
43
+ "@oh-my-pi/pi-catalog": "16.3.13",
44
+ "@oh-my-pi/pi-utils": "16.3.13",
45
45
  "lru-cache": "11.5.1"
46
46
  },
47
47
  "peerDependencies": {
@@ -665,7 +665,46 @@ export function get(beam: BeamMemoryState, memoryId: string): Row | null {
665
665
  WHERE id = ? AND (session_id = ? OR scope = 'global')
666
666
  `)
667
667
  .get(memoryId, beam.sessionId) as Row | null | undefined;
668
- return episodic == null ? null : { ...episodic, metadata: episodic.metadata_json, memory_store: "episodic" };
668
+ if (episodic != null) return { ...episodic, metadata: episodic.metadata_json, memory_store: "episodic" };
669
+
670
+ return getFact(beam, memoryId);
671
+ }
672
+
673
+ /**
674
+ * Read-only resolution for ids minted from the `facts` table. `recall`
675
+ * surfaces `facts.fact_id` as a result id (`factRecall`), so `get` must
676
+ * resolve those ids too — otherwise every surfaced fact id is a dead end
677
+ * for the read path (issue #4725). Visibility mirrors `factRecall`:
678
+ * same-session facts plus explicitly global ones (`scope` is an optional
679
+ * column on `facts`; `SELECT *` tolerates banks without it, in which case
680
+ * only same-session facts resolve). The row is shaped like the
681
+ * working/episodic hits with the full triple as content;
682
+ * `memory_store: "fact"` marks it read-only — no update/forget/invalidate
683
+ * path mutates `facts`.
684
+ */
685
+ function getFact(beam: BeamMemoryState, memoryId: string): Row | null {
686
+ const fact = beam.db.prepare("SELECT * FROM facts WHERE fact_id = ?").get(memoryId) as Row | null | undefined;
687
+ if (fact == null) return null;
688
+ if (fact.session_id !== beam.sessionId && fact.scope !== "global") return null;
689
+ const subject = typeof fact.subject === "string" ? fact.subject : "";
690
+ const predicate = typeof fact.predicate === "string" ? fact.predicate : "";
691
+ const object = typeof fact.object === "string" ? fact.object : "";
692
+ return {
693
+ id: fact.fact_id,
694
+ content: [subject, predicate, object].filter(part => part.length > 0).join(" "),
695
+ source: "facts",
696
+ timestamp: fact.timestamp ?? null,
697
+ session_id: fact.session_id ?? null,
698
+ importance: fact.confidence ?? null,
699
+ metadata: JSON.stringify({
700
+ subject,
701
+ predicate,
702
+ object,
703
+ source_msg_id: fact.source_msg_id ?? null,
704
+ }),
705
+ created_at: fact.created_at ?? null,
706
+ memory_store: "fact",
707
+ };
669
708
  }
670
709
 
671
710
  export function forgetWorking(beam: BeamMemoryState, memoryId: string): boolean {