nlm-memory 0.5.17 → 0.5.19

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.
Files changed (74) hide show
  1. package/README.md +22 -1
  2. package/dist/cli/nlm.js +161 -81
  3. package/dist/cli/nlm.js.map +1 -1
  4. package/dist/cli/supersede.js +5 -2
  5. package/dist/cli/supersede.js.map +1 -1
  6. package/dist/core/actions/actions-log.d.ts +9 -0
  7. package/dist/core/actions/actions-log.js +86 -0
  8. package/dist/core/actions/actions-log.js.map +1 -1
  9. package/dist/core/digest/compose.d.ts +0 -1
  10. package/dist/core/digest/compose.js +0 -4
  11. package/dist/core/digest/compose.js.map +1 -1
  12. package/dist/core/providers/provider-registry.d.ts +15 -0
  13. package/dist/core/providers/provider-registry.js +85 -0
  14. package/dist/core/providers/provider-registry.js.map +1 -1
  15. package/dist/core/recall/query-log.d.ts +1 -2
  16. package/dist/core/recall/query-log.js +1 -5
  17. package/dist/core/recall/query-log.js.map +1 -1
  18. package/dist/core/scheduler/scan-once.d.ts +4 -0
  19. package/dist/core/scheduler/scan-once.js +64 -0
  20. package/dist/core/scheduler/scan-once.js.map +1 -1
  21. package/dist/core/scheduler/scheduler.js +25 -9
  22. package/dist/core/scheduler/scheduler.js.map +1 -1
  23. package/dist/core/sources/source-registry.d.ts +16 -0
  24. package/dist/core/sources/source-registry.js +123 -0
  25. package/dist/core/sources/source-registry.js.map +1 -1
  26. package/dist/core/storage/pg-fact-store.d.ts +24 -0
  27. package/dist/core/storage/pg-fact-store.js +233 -0
  28. package/dist/core/storage/pg-fact-store.js.map +1 -0
  29. package/dist/core/storage/pg-session-store.d.ts +29 -0
  30. package/dist/core/storage/pg-session-store.js +315 -0
  31. package/dist/core/storage/pg-session-store.js.map +1 -0
  32. package/dist/core/storage/pg-storage.d.ts +36 -0
  33. package/dist/core/storage/pg-storage.js +87 -0
  34. package/dist/core/storage/pg-storage.js.map +1 -0
  35. package/dist/core/storage/pg-tx-context.d.ts +44 -0
  36. package/dist/core/storage/pg-tx-context.js +133 -0
  37. package/dist/core/storage/pg-tx-context.js.map +1 -0
  38. package/dist/core/storage/sqlite-fact-store.d.ts +13 -7
  39. package/dist/core/storage/sqlite-fact-store.js +38 -12
  40. package/dist/core/storage/sqlite-fact-store.js.map +1 -1
  41. package/dist/core/storage/sqlite-session-store.d.ts +6 -16
  42. package/dist/core/storage/sqlite-session-store.js +51 -42
  43. package/dist/core/storage/sqlite-session-store.js.map +1 -1
  44. package/dist/core/storage/sqlite-storage.d.ts +38 -0
  45. package/dist/core/storage/sqlite-storage.js +66 -0
  46. package/dist/core/storage/sqlite-storage.js.map +1 -0
  47. package/dist/hook/pi-extension.d.ts +43 -0
  48. package/dist/hook/pi-extension.js +50 -0
  49. package/dist/hook/pi-extension.js.map +1 -0
  50. package/dist/hook/prompt-recall-hook.js +1 -36
  51. package/dist/hook/prompt-recall-hook.js.map +1 -1
  52. package/dist/hook/recall-over-http.d.ts +10 -0
  53. package/dist/hook/recall-over-http.js +41 -0
  54. package/dist/hook/recall-over-http.js.map +1 -0
  55. package/dist/hook/stop-hook.d.ts +1 -3
  56. package/dist/hook/stop-hook.js +1 -3
  57. package/dist/hook/stop-hook.js.map +1 -1
  58. package/dist/http/app.d.ts +6 -5
  59. package/dist/http/app.js +15 -4
  60. package/dist/http/app.js.map +1 -1
  61. package/dist/install/pi.d.ts +42 -0
  62. package/dist/install/pi.js +84 -0
  63. package/dist/install/pi.js.map +1 -0
  64. package/dist/install/setup.js +21 -5
  65. package/dist/install/setup.js.map +1 -1
  66. package/dist/ports/fact-store.d.ts +26 -0
  67. package/dist/ports/storage.d.ts +45 -0
  68. package/dist/ports/storage.js +14 -0
  69. package/dist/ports/storage.js.map +1 -0
  70. package/package.json +5 -1
  71. package/plugin/scripts/prompt-recall-hook.mjs +31 -29
  72. package/plugin-pi/README.md +71 -0
  73. package/plugin-pi/package.json +12 -0
  74. package/plugin-pi/scripts/nlm-extension.mjs +280 -0
@@ -0,0 +1,233 @@
1
+ /**
2
+ * PgFactStore — FactStore implementation over pg.Pool + pgvector.
3
+ *
4
+ * Receives its Pool from PgStorage. Never opens its own connection.
5
+ */
6
+ export class PgFactStore {
7
+ pool;
8
+ constructor(pool) {
9
+ this.pool = pool;
10
+ }
11
+ async insert(fact) {
12
+ await this.pool.query(`INSERT INTO facts (id, kind, subject, predicate, value, source_session_id,
13
+ source_quote, created_at, superseded_by, confidence)
14
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, [fact.id, fact.kind, fact.subject, fact.predicate, fact.value,
15
+ fact.sourceSessionId, fact.sourceQuote, fact.createdAt, fact.supersededBy, fact.confidence]);
16
+ }
17
+ async insertMany(facts) {
18
+ if (facts.length === 0)
19
+ return;
20
+ const client = await this.pool.connect();
21
+ try {
22
+ await client.query("BEGIN");
23
+ for (const f of facts) {
24
+ await client.query(`INSERT INTO facts (id, kind, subject, predicate, value, source_session_id,
25
+ source_quote, created_at, superseded_by, confidence)
26
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, [f.id, f.kind, f.subject, f.predicate, f.value,
27
+ f.sourceSessionId, f.sourceQuote, f.createdAt, f.supersededBy, f.confidence]);
28
+ }
29
+ await client.query("COMMIT");
30
+ }
31
+ catch (err) {
32
+ await client.query("ROLLBACK");
33
+ throw err;
34
+ }
35
+ finally {
36
+ client.release();
37
+ }
38
+ }
39
+ async getById(id) {
40
+ const result = await this.pool.query(`SELECT id, kind, subject, predicate, value, source_session_id,
41
+ source_quote, created_at, superseded_by, confidence
42
+ FROM facts WHERE id = $1`, [id]);
43
+ return result.rows[0] ? rowToFact(result.rows[0]) : null;
44
+ }
45
+ async findCurrent(subject, predicate) {
46
+ const result = await this.pool.query(`SELECT id, kind, subject, predicate, value, source_session_id,
47
+ source_quote, created_at, superseded_by, confidence
48
+ FROM facts
49
+ WHERE subject = $1 AND predicate = $2 AND superseded_by IS NULL
50
+ ORDER BY created_at DESC
51
+ LIMIT 1`, [subject, predicate]);
52
+ return result.rows[0] ? rowToFact(result.rows[0]) : null;
53
+ }
54
+ async list(query) {
55
+ const limit = Math.max(1, Math.trunc(query.limit ?? 50));
56
+ const includeSuperseded = query.includeSuperseded === true;
57
+ const where = ["subject = $1"];
58
+ const params = [query.subject];
59
+ let idx = 2;
60
+ if (query.predicate !== undefined) {
61
+ where.push(`predicate = $${idx++}`);
62
+ params.push(query.predicate);
63
+ }
64
+ if (!includeSuperseded)
65
+ where.push("superseded_by IS NULL");
66
+ params.push(limit);
67
+ const result = await this.pool.query(`SELECT id, kind, subject, predicate, value, source_session_id,
68
+ source_quote, created_at, superseded_by, confidence
69
+ FROM facts
70
+ WHERE ${where.join(" AND ")}
71
+ ORDER BY created_at DESC
72
+ LIMIT $${idx}`, params);
73
+ return result.rows.map(rowToFact);
74
+ }
75
+ async listBySession(sessionId) {
76
+ const result = await this.pool.query(`SELECT id, kind, subject, predicate, value, source_session_id,
77
+ source_quote, created_at, superseded_by, confidence
78
+ FROM facts
79
+ WHERE source_session_id = $1
80
+ ORDER BY created_at ASC`, [sessionId]);
81
+ return result.rows.map(rowToFact);
82
+ }
83
+ async listForRecall(filter) {
84
+ const where = [];
85
+ const params = [];
86
+ let idx = 1;
87
+ if (filter.subject !== undefined) {
88
+ where.push(`subject = $${idx++}`);
89
+ params.push(filter.subject);
90
+ }
91
+ if (filter.predicate !== undefined) {
92
+ where.push(`predicate = $${idx++}`);
93
+ params.push(filter.predicate);
94
+ }
95
+ if (filter.kind !== undefined) {
96
+ where.push(`kind = $${idx++}`);
97
+ params.push(filter.kind);
98
+ }
99
+ if (filter.minConfidence !== undefined) {
100
+ where.push(`confidence >= $${idx++}`);
101
+ params.push(filter.minConfidence);
102
+ }
103
+ if (filter.includeSuperseded !== true)
104
+ where.push("superseded_by IS NULL");
105
+ const limit = Math.max(1, Math.trunc(filter.limit ?? 500));
106
+ params.push(limit);
107
+ const sql = `
108
+ SELECT id, kind, subject, predicate, value, source_session_id,
109
+ source_quote, created_at, superseded_by, confidence
110
+ FROM facts
111
+ ${where.length > 0 ? "WHERE " + where.join(" AND ") : ""}
112
+ ORDER BY created_at DESC
113
+ LIMIT $${idx}
114
+ `;
115
+ const result = await this.pool.query(sql, params);
116
+ return result.rows.map(rowToFact);
117
+ }
118
+ async markSuperseded(oldId, newId) {
119
+ if (newId !== null && oldId === newId) {
120
+ throw new Error("A fact cannot supersede itself");
121
+ }
122
+ const client = await this.pool.connect();
123
+ try {
124
+ await client.query("BEGIN");
125
+ const old = await client.query("SELECT id FROM facts WHERE id = $1", [oldId]);
126
+ if (old.rows.length === 0)
127
+ throw new Error(`Fact ${oldId} not found`);
128
+ if (newId !== null) {
129
+ const next = await client.query("SELECT id FROM facts WHERE id = $1", [newId]);
130
+ if (next.rows.length === 0)
131
+ throw new Error(`Fact ${newId} not found`);
132
+ }
133
+ await client.query("UPDATE facts SET superseded_by = $1 WHERE id = $2", [newId, oldId]);
134
+ await client.query("COMMIT");
135
+ }
136
+ catch (err) {
137
+ await client.query("ROLLBACK");
138
+ throw err;
139
+ }
140
+ finally {
141
+ client.release();
142
+ }
143
+ }
144
+ async ingestSessionFacts(sessionId, facts) {
145
+ const client = await this.pool.connect();
146
+ try {
147
+ await client.query("BEGIN");
148
+ await client.query("DELETE FROM facts WHERE source_session_id = $1", [sessionId]);
149
+ if (facts.length > 0) {
150
+ for (const f of facts) {
151
+ await client.query(`INSERT INTO facts (id, kind, subject, predicate, value, source_session_id,
152
+ source_quote, created_at, superseded_by, confidence)
153
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, [f.id, f.kind, f.subject, f.predicate, f.value,
154
+ f.sourceSessionId, f.sourceQuote, f.createdAt, f.supersededBy, f.confidence]);
155
+ }
156
+ const values = facts
157
+ .map((_, i) => `($${i * 3 + 1}, $${i * 3 + 2}, $${i * 3 + 3})`)
158
+ .join(", ");
159
+ const params = [];
160
+ for (const f of facts)
161
+ params.push(f.subject, f.predicate, f.id);
162
+ await client.query(`UPDATE facts AS old
163
+ SET superseded_by = new_f.new_id
164
+ FROM (VALUES ${values}) AS new_f(subject, predicate, new_id)
165
+ WHERE old.subject = new_f.subject
166
+ AND old.predicate = new_f.predicate
167
+ AND old.superseded_by IS NULL
168
+ AND old.id != new_f.new_id`, params);
169
+ }
170
+ await client.query("COMMIT");
171
+ }
172
+ catch (err) {
173
+ await client.query("ROLLBACK");
174
+ throw err;
175
+ }
176
+ finally {
177
+ client.release();
178
+ }
179
+ }
180
+ async upsertEmbedding(factId, vector) {
181
+ const vecStr = `[${Array.from(vector).join(",")}]`;
182
+ await this.pool.query(`INSERT INTO fact_embeddings (fact_id, embedding)
183
+ VALUES ($1, $2::vector)
184
+ ON CONFLICT (fact_id) DO UPDATE SET embedding = EXCLUDED.embedding`, [factId, vecStr]);
185
+ }
186
+ async semanticSearch(queryVector, limit) {
187
+ const k = Math.max(1, Math.trunc(limit));
188
+ const vecStr = `[${Array.from(queryVector).join(",")}]`;
189
+ const result = await this.pool.query(`SELECT fact_id, embedding <-> $1::vector AS distance
190
+ FROM fact_embeddings
191
+ ORDER BY embedding <-> $1::vector
192
+ LIMIT $2`, [vecStr, k]);
193
+ return result.rows.map((r) => ({ factId: r.fact_id, distance: r.distance }));
194
+ }
195
+ async getHistory(subject, predicate) {
196
+ const result = predicate
197
+ ? await this.pool.query(`SELECT id, kind, subject, predicate, value, source_session_id,
198
+ source_quote, created_at, superseded_by, confidence
199
+ FROM facts
200
+ WHERE subject = $1 AND predicate = $2
201
+ ORDER BY predicate ASC, created_at DESC`, [subject, predicate])
202
+ : await this.pool.query(`SELECT id, kind, subject, predicate, value, source_session_id,
203
+ source_quote, created_at, superseded_by, confidence
204
+ FROM facts
205
+ WHERE subject = $1
206
+ ORDER BY predicate ASC, created_at DESC`, [subject]);
207
+ const byPred = new Map();
208
+ for (const row of result.rows) {
209
+ const fact = rowToFact(row);
210
+ const bucket = byPred.get(fact.predicate);
211
+ if (bucket)
212
+ bucket.push(fact);
213
+ else
214
+ byPred.set(fact.predicate, [fact]);
215
+ }
216
+ return [...byPred.entries()].map(([pred, history]) => ({ subject, predicate: pred, history }));
217
+ }
218
+ }
219
+ function rowToFact(row) {
220
+ return {
221
+ id: row.id,
222
+ kind: row.kind,
223
+ subject: row.subject,
224
+ predicate: row.predicate,
225
+ value: row.value,
226
+ sourceSessionId: row.source_session_id,
227
+ sourceQuote: row.source_quote,
228
+ createdAt: row.created_at,
229
+ supersededBy: row.superseded_by,
230
+ confidence: row.confidence,
231
+ };
232
+ }
233
+ //# sourceMappingURL=pg-fact-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-fact-store.js","sourceRoot":"","sources":["../../../src/core/storage/pg-fact-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * PgSessionStore — SessionStore implementation over pg.Pool + pgvector.
3
+ *
4
+ * Constructor takes the Pool from PgStorage. Also exposes recentWrites()
5
+ * and recentMarkers() for the /live HTTP endpoints, and insertSession() +
6
+ * insertSessionForTest() for ingest and test seeding.
7
+ */
8
+ import type { Pool } from "pg";
9
+ import type { KeywordNeighbor, SemanticNeighbor, SessionFilter, SessionStore } from "../../ports/session-store.js";
10
+ import type { Session, SessionStatus } from "../../shared/types.js";
11
+ import type { IngestRecord, RecentMarker, RecentWrite } from "./sqlite-session-store.js";
12
+ export declare class PgSessionStore implements SessionStore {
13
+ private readonly pool;
14
+ constructor(pool: Pool);
15
+ list(filter?: SessionFilter): Promise<ReadonlyArray<Session>>;
16
+ getById(sessionId: string): Promise<Session | null>;
17
+ getByIds(ids: ReadonlyArray<string>): Promise<ReadonlyArray<Session>>;
18
+ semanticSearch(queryVector: Float32Array, limit: number): Promise<ReadonlyArray<SemanticNeighbor>>;
19
+ keywordSearch(query: string, limit: number): Promise<ReadonlyArray<KeywordNeighbor>>;
20
+ updateStatus(sessionId: string, status: SessionStatus): Promise<void>;
21
+ markSuperseded(predecessorId: string, successorId: string): Promise<void>;
22
+ recentWrites(limit: number): Promise<RecentWrite[]>;
23
+ recentMarkers(limit: number): Promise<RecentMarker[]>;
24
+ insertSession(record: IngestRecord, embedder?: import("../../ports/llm-client.js").LLMClient | null, supersedes?: string | null): Promise<void>;
25
+ insertSessionForTest(session: Session): Promise<void>;
26
+ private loadEntities;
27
+ private loadMarkers;
28
+ private loadEdges;
29
+ }
@@ -0,0 +1,315 @@
1
+ /**
2
+ * PgSessionStore — SessionStore implementation over pg.Pool + pgvector.
3
+ *
4
+ * Constructor takes the Pool from PgStorage. Also exposes recentWrites()
5
+ * and recentMarkers() for the /live HTTP endpoints, and insertSession() +
6
+ * insertSessionForTest() for ingest and test seeding.
7
+ */
8
+ import { chunkSessionText } from "../embedding/chunk-body.js";
9
+ export class PgSessionStore {
10
+ pool;
11
+ constructor(pool) {
12
+ this.pool = pool;
13
+ }
14
+ async list(filter) {
15
+ const result = await this.pool.query(`SELECT id, runtime, runtime_session_id, started_at, ended_at, duration_min,
16
+ label, summary, status, transcript_kind, transcript_path, body
17
+ FROM sessions ORDER BY started_at ASC`);
18
+ if (result.rows.length === 0)
19
+ return [];
20
+ const ids = result.rows.map((r) => r.id);
21
+ const [entitiesMap, markersMap] = await Promise.all([
22
+ this.loadEntities(ids),
23
+ this.loadMarkers(ids),
24
+ ]);
25
+ const sessions = result.rows.map((r) => rowToSession(r, entitiesMap, markersMap));
26
+ if (!filter)
27
+ return sessions;
28
+ return sessions.filter((s) => {
29
+ if (filter.entity !== undefined && !s.entities.includes(filter.entity))
30
+ return false;
31
+ if (filter.hasDecisions === true && s.decisions.length === 0)
32
+ return false;
33
+ if (filter.hasOpenQuestions === true && s.open.length === 0)
34
+ return false;
35
+ return true;
36
+ });
37
+ }
38
+ async getById(sessionId) {
39
+ const result = await this.pool.query(`SELECT id, runtime, runtime_session_id, started_at, ended_at, duration_min,
40
+ label, summary, status, transcript_kind, transcript_path, body
41
+ FROM sessions WHERE id = $1`, [sessionId]);
42
+ if (!result.rows[0])
43
+ return null;
44
+ const [entitiesMap, markersMap, edgesMap] = await Promise.all([
45
+ this.loadEntities([sessionId]),
46
+ this.loadMarkers([sessionId]),
47
+ this.loadEdges([sessionId]),
48
+ ]);
49
+ const edges = edgesMap.get(sessionId);
50
+ return rowToSession(result.rows[0], entitiesMap, markersMap, edges);
51
+ }
52
+ async getByIds(ids) {
53
+ if (ids.length === 0)
54
+ return [];
55
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(",");
56
+ const result = await this.pool.query(`SELECT id, runtime, runtime_session_id, started_at, ended_at, duration_min,
57
+ label, summary, status, transcript_kind, transcript_path
58
+ FROM sessions WHERE id IN (${placeholders})`, [...ids]);
59
+ if (result.rows.length === 0)
60
+ return [];
61
+ const foundIds = result.rows.map((r) => r.id);
62
+ const [entitiesMap, markersMap] = await Promise.all([
63
+ this.loadEntities(foundIds),
64
+ this.loadMarkers(foundIds),
65
+ ]);
66
+ return result.rows.map((r) => rowToSession({ ...r, body: null }, entitiesMap, markersMap));
67
+ }
68
+ async semanticSearch(queryVector, limit) {
69
+ const k = Math.max(1, Math.trunc(limit));
70
+ const vecStr = `[${Array.from(queryVector).join(",")}]`;
71
+ const result = await this.pool.query(`SELECT session_id, MIN(embedding <-> $1::vector) AS distance
72
+ FROM session_embedding_chunks
73
+ GROUP BY session_id
74
+ ORDER BY distance
75
+ LIMIT $2`, [vecStr, k]);
76
+ return result.rows.map((r) => ({ sessionId: r.session_id, distance: r.distance }));
77
+ }
78
+ async keywordSearch(query, limit) {
79
+ if (!query.trim())
80
+ return [];
81
+ const k = Math.max(1, Math.trunc(limit));
82
+ const result = await this.pool.query(`SELECT id AS session_id,
83
+ ts_rank_cd(fts_vector, websearch_to_tsquery('english', $1)) AS score
84
+ FROM sessions
85
+ WHERE fts_vector @@ websearch_to_tsquery('english', $1)
86
+ ORDER BY score DESC
87
+ LIMIT $2`, [query, k]);
88
+ return result.rows.map((r) => ({ sessionId: r.session_id, score: r.score }));
89
+ }
90
+ async updateStatus(sessionId, status) {
91
+ if (status === "idle") {
92
+ throw new Error("Cannot persist derived status 'idle' — only active/closed/superseded");
93
+ }
94
+ await this.pool.query("UPDATE sessions SET status = $1, updated_at = NOW() WHERE id = $2", [status, sessionId]);
95
+ }
96
+ async markSuperseded(predecessorId, successorId) {
97
+ if (predecessorId === successorId) {
98
+ throw new Error("A session cannot supersede itself");
99
+ }
100
+ const client = await this.pool.connect();
101
+ try {
102
+ await client.query("BEGIN");
103
+ const predExists = await client.query("SELECT COUNT(*) AS c FROM sessions WHERE id = $1", [predecessorId]);
104
+ if (Number(predExists.rows[0]?.c) === 0) {
105
+ throw new Error(`predecessor session ${predecessorId} not found`);
106
+ }
107
+ const succExists = await client.query("SELECT COUNT(*) AS c FROM sessions WHERE id = $1", [successorId]);
108
+ if (Number(succExists.rows[0]?.c) === 0) {
109
+ throw new Error(`successor session ${successorId} not found`);
110
+ }
111
+ await client.query(`DELETE FROM session_edges WHERE to_session = $1 AND kind = 'supersedes' AND from_session != $2`, [predecessorId, successorId]);
112
+ await client.query(`INSERT INTO session_edges (from_session, to_session, kind)
113
+ VALUES ($1, $2, 'supersedes')
114
+ ON CONFLICT DO NOTHING`, [successorId, predecessorId]);
115
+ await client.query("UPDATE sessions SET status = 'superseded', updated_at = NOW() WHERE id = $1", [predecessorId]);
116
+ await client.query("COMMIT");
117
+ }
118
+ catch (err) {
119
+ await client.query("ROLLBACK");
120
+ throw err;
121
+ }
122
+ finally {
123
+ client.release();
124
+ }
125
+ }
126
+ async recentWrites(limit) {
127
+ const result = await this.pool.query(`SELECT id, runtime, label, summary, created_at AS "createdAt"
128
+ FROM sessions ORDER BY created_at DESC LIMIT $1`, [limit]);
129
+ return result.rows;
130
+ }
131
+ async recentMarkers(limit) {
132
+ const result = await this.pool.query(`SELECT m.session_id AS "sessionId", m.kind, m.text, s.label, s.created_at AS "createdAt"
133
+ FROM markers m
134
+ JOIN sessions s ON s.id = m.session_id
135
+ ORDER BY s.created_at DESC, m.position ASC
136
+ LIMIT $1`, [limit]);
137
+ return result.rows;
138
+ }
139
+ async insertSession(record, embedder = null, supersedes = null) {
140
+ const client = await this.pool.connect();
141
+ try {
142
+ await client.query("BEGIN");
143
+ await client.query(`INSERT INTO sessions (
144
+ id, runtime, runtime_session_id, started_at, ended_at, duration_min,
145
+ label, summary, body, status, transcript_kind, transcript_path,
146
+ transcript_offset, transcript_length
147
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
148
+ ON CONFLICT (id) DO UPDATE SET
149
+ ended_at = EXCLUDED.ended_at,
150
+ duration_min = EXCLUDED.duration_min,
151
+ label = EXCLUDED.label,
152
+ summary = EXCLUDED.summary,
153
+ body = EXCLUDED.body,
154
+ status = EXCLUDED.status,
155
+ updated_at = NOW()`, [
156
+ record.id, record.runtime, record.runtimeSessionId,
157
+ record.startedAt, record.endedAt, record.durationMin,
158
+ record.label, record.summary, record.body,
159
+ record.status === "idle" ? "active" : record.status,
160
+ record.transcriptKind, record.transcriptPath,
161
+ record.transcriptOffset, record.transcriptLength,
162
+ ]);
163
+ await client.query("DELETE FROM markers WHERE session_id = $1", [record.id]);
164
+ for (let i = 0; i < record.decisions.length; i++) {
165
+ await client.query("INSERT INTO markers (session_id, kind, text, position) VALUES ($1, 'decision', $2, $3)", [record.id, record.decisions[i].trim(), i]);
166
+ }
167
+ for (let i = 0; i < record.openQuestions.length; i++) {
168
+ await client.query("INSERT INTO markers (session_id, kind, text, position) VALUES ($1, 'open', $2, $3)", [record.id, record.openQuestions[i].trim(), i]);
169
+ }
170
+ for (const raw of record.entities) {
171
+ const name = raw.trim();
172
+ if (!name)
173
+ continue;
174
+ await client.query(`INSERT INTO entities (canonical, type, status, source, first_seen_session, last_seen_session, session_count)
175
+ VALUES ($1, 'candidate', 'candidate', 'auto-detected', $2, $2, 0)
176
+ ON CONFLICT (canonical) DO UPDATE SET
177
+ last_seen_session = $2,
178
+ session_count = entities.session_count + 1,
179
+ updated_at = NOW()`, [name, record.id]);
180
+ await client.query("INSERT INTO session_entities (session_id, entity_canonical) VALUES ($1, $2) ON CONFLICT DO NOTHING", [record.id, name]);
181
+ }
182
+ if (supersedes) {
183
+ await client.query(`INSERT INTO session_edges (from_session, to_session, kind)
184
+ VALUES ($1, $2, 'supersedes') ON CONFLICT DO NOTHING`, [record.id, supersedes]);
185
+ await client.query("UPDATE sessions SET status = 'superseded', updated_at = NOW() WHERE id = $1", [supersedes]);
186
+ }
187
+ await client.query("COMMIT");
188
+ }
189
+ catch (err) {
190
+ await client.query("ROLLBACK");
191
+ throw err;
192
+ }
193
+ finally {
194
+ client.release();
195
+ }
196
+ if (embedder) {
197
+ const chunks = chunkSessionText({ label: record.label, summary: record.summary, body: record.body });
198
+ await this.pool.query("DELETE FROM session_embedding_chunks WHERE session_id = $1", [record.id]);
199
+ for (let chunkIdx = 0; chunkIdx < chunks.length; chunkIdx++) {
200
+ const text = chunks[chunkIdx];
201
+ if (!text)
202
+ continue;
203
+ try {
204
+ const { vector } = await embedder.embed(text, "document");
205
+ const vecStr = `[${Array.from(vector).join(",")}]`;
206
+ const ins = await this.pool.query(`INSERT INTO session_embedding_chunks (session_id, chunk_idx, embedding)
207
+ VALUES ($1, $2, $3::vector) RETURNING chunk_id`, [record.id, chunkIdx, vecStr]);
208
+ const chunkId = ins.rows[0].chunk_id;
209
+ await this.pool.query("INSERT INTO session_chunk_map (chunk_id, session_id, chunk_idx) VALUES ($1, $2, $3)", [chunkId, record.id, chunkIdx]);
210
+ }
211
+ catch (err) {
212
+ process.stderr.write(`[nlm] embedding chunk failed session=${record.id} chunk=${chunkIdx}: ${String(err)}\n`);
213
+ }
214
+ }
215
+ }
216
+ }
217
+ async insertSessionForTest(session) {
218
+ const status = session.status === "idle" ? "active" : session.status;
219
+ await this.pool.query(`INSERT INTO sessions (id, runtime, runtime_session_id, started_at, ended_at,
220
+ duration_min, label, summary, body, status, transcript_kind, transcript_path)
221
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, [
222
+ session.id, session.runtime, session.runtimeSessionId, session.startedAt,
223
+ session.endedAt, session.durationMin, session.label, session.summary,
224
+ session.body, status, session.transcriptKind, session.transcriptPath,
225
+ ]);
226
+ for (const e of session.entities) {
227
+ await this.pool.query("INSERT INTO entities (canonical, type, status) VALUES ($1, 'candidate', 'active') ON CONFLICT DO NOTHING", [e]);
228
+ await this.pool.query("INSERT INTO session_entities (session_id, entity_canonical) VALUES ($1, $2) ON CONFLICT DO NOTHING", [session.id, e]);
229
+ }
230
+ for (let i = 0; i < session.decisions.length; i++) {
231
+ await this.pool.query("INSERT INTO markers (session_id, kind, text, position) VALUES ($1, 'decision', $2, $3)", [session.id, session.decisions[i], i]);
232
+ }
233
+ for (let i = 0; i < session.open.length; i++) {
234
+ await this.pool.query("INSERT INTO markers (session_id, kind, text, position) VALUES ($1, 'open', $2, $3)", [session.id, session.open[i], i]);
235
+ }
236
+ }
237
+ async loadEntities(ids) {
238
+ if (ids.length === 0)
239
+ return new Map();
240
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(",");
241
+ const result = await this.pool.query(`SELECT session_id, entity_canonical FROM session_entities
242
+ WHERE session_id IN (${placeholders}) ORDER BY session_id`, [...ids]);
243
+ const out = new Map();
244
+ for (const r of result.rows) {
245
+ const list = out.get(r.session_id);
246
+ if (list)
247
+ list.push(r.entity_canonical);
248
+ else
249
+ out.set(r.session_id, [r.entity_canonical]);
250
+ }
251
+ return out;
252
+ }
253
+ async loadMarkers(ids) {
254
+ if (ids.length === 0)
255
+ return new Map();
256
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(",");
257
+ const result = await this.pool.query(`SELECT session_id, kind, text FROM markers
258
+ WHERE session_id IN (${placeholders}) ORDER BY session_id, position`, [...ids]);
259
+ const out = new Map();
260
+ for (const r of result.rows) {
261
+ let bucket = out.get(r.session_id);
262
+ if (!bucket) {
263
+ bucket = { decisions: [], open: [] };
264
+ out.set(r.session_id, bucket);
265
+ }
266
+ if (r.kind === "decision")
267
+ bucket.decisions.push(r.text);
268
+ else
269
+ bucket.open.push(r.text);
270
+ }
271
+ return out;
272
+ }
273
+ async loadEdges(ids) {
274
+ if (ids.length === 0)
275
+ return new Map();
276
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(",");
277
+ const result = await this.pool.query(`SELECT from_session, to_session FROM session_edges
278
+ WHERE kind = 'supersedes'
279
+ AND (from_session IN (${placeholders}) OR to_session IN (${placeholders}))`, [...ids, ...ids]);
280
+ const out = new Map();
281
+ for (const id of ids)
282
+ out.set(id, { supersededBy: null, supersedes: [] });
283
+ for (const r of result.rows) {
284
+ out.get(r.from_session)?.supersedes.push(r.to_session);
285
+ const toEntry = out.get(r.to_session);
286
+ if (toEntry)
287
+ toEntry.supersededBy = r.from_session;
288
+ }
289
+ return out;
290
+ }
291
+ }
292
+ function rowToSession(row, entitiesById, markersById, edges) {
293
+ const m = markersById.get(row.id);
294
+ return {
295
+ id: row.id,
296
+ runtime: row.runtime,
297
+ runtimeSessionId: row.runtime_session_id ?? "",
298
+ startedAt: row.started_at,
299
+ endedAt: row.ended_at,
300
+ durationMin: row.duration_min,
301
+ label: row.label,
302
+ summary: row.summary,
303
+ status: row.status,
304
+ transcriptKind: row.transcript_kind ?? "",
305
+ transcriptPath: row.transcript_path,
306
+ body: row.body ?? "",
307
+ entities: entitiesById.get(row.id) ?? [],
308
+ decisions: m?.decisions ?? [],
309
+ open: m?.open ?? [],
310
+ ...(edges !== undefined
311
+ ? { supersededBy: edges.supersededBy, supersedes: edges.supersedes }
312
+ : {}),
313
+ };
314
+ }
315
+ //# sourceMappingURL=pg-session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-session-store.js","sourceRoot":"","sources":["../../../src/core/storage/pg-session-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * PgStorage — canonical Storage adapter for PostgreSQL + pgvector.
3
+ *
4
+ * Implements the Storage port (init/close/withTransaction). withTransaction
5
+ * uses the write-queue pattern: the sync callback queues SQL ops, then
6
+ * PgStorage flushes the queue inside a single BEGIN/COMMIT after the
7
+ * callback returns.
8
+ *
9
+ * pgPool() is a deprecated escape hatch for callers not yet ported to the
10
+ * Storage interface. Tracked for removal in #215a (PG branch).
11
+ */
12
+ import { Pool } from "pg";
13
+ import type { Storage, StorageContext } from "../../ports/storage.js";
14
+ import { PgFactStore } from "./pg-fact-store.js";
15
+ import { PgSessionStore } from "./pg-session-store.js";
16
+ export interface PgStorageOptions {
17
+ readonly connectionString: string;
18
+ readonly migrationsDir: string;
19
+ }
20
+ export declare class PgStorage implements Storage {
21
+ readonly facts: PgFactStore;
22
+ readonly sessions: PgSessionStore;
23
+ private readonly _pool;
24
+ private readonly _migrationsDir;
25
+ private inTxn;
26
+ private constructor();
27
+ static create(opts: PgStorageOptions): PgStorage;
28
+ init(): Promise<void>;
29
+ close(): Promise<void>;
30
+ withTransaction<T>(fn: (ctx: StorageContext) => T): Promise<T>;
31
+ /**
32
+ * @deprecated Escape hatch for callers not yet ported to the Storage
33
+ * interface. Tracked for removal in #215a (PG branch).
34
+ */
35
+ pgPool(): Pool;
36
+ }