@cogitator-ai/memory 0.9.1 → 0.11.0

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 (41) hide show
  1. package/README.md +207 -90
  2. package/dist/adapters/postgres.d.ts +1 -0
  3. package/dist/adapters/postgres.d.ts.map +1 -1
  4. package/dist/adapters/postgres.js +78 -38
  5. package/dist/adapters/postgres.js.map +1 -1
  6. package/dist/adapters/qdrant.d.ts.map +1 -1
  7. package/dist/adapters/qdrant.js +16 -2
  8. package/dist/adapters/qdrant.js.map +1 -1
  9. package/dist/adapters/sqlite.d.ts +1 -0
  10. package/dist/adapters/sqlite.d.ts.map +1 -1
  11. package/dist/adapters/sqlite.js +17 -16
  12. package/dist/adapters/sqlite.js.map +1 -1
  13. package/dist/compaction.d.ts +14 -1
  14. package/dist/compaction.d.ts.map +1 -1
  15. package/dist/compaction.js +4 -1
  16. package/dist/compaction.js.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/knowledge-graph/entity-extractor.d.ts +24 -11
  22. package/dist/knowledge-graph/entity-extractor.d.ts.map +1 -1
  23. package/dist/knowledge-graph/entity-extractor.js +15 -3
  24. package/dist/knowledge-graph/entity-extractor.js.map +1 -1
  25. package/dist/knowledge-graph/graph-adapter.d.ts +1 -0
  26. package/dist/knowledge-graph/graph-adapter.d.ts.map +1 -1
  27. package/dist/knowledge-graph/graph-adapter.js +470 -448
  28. package/dist/knowledge-graph/graph-adapter.js.map +1 -1
  29. package/dist/knowledge-graph/sqlite-graph-adapter.d.ts +1 -0
  30. package/dist/knowledge-graph/sqlite-graph-adapter.d.ts.map +1 -1
  31. package/dist/knowledge-graph/sqlite-graph-adapter.js +459 -435
  32. package/dist/knowledge-graph/sqlite-graph-adapter.js.map +1 -1
  33. package/dist/result.d.ts +11 -0
  34. package/dist/result.d.ts.map +1 -0
  35. package/dist/result.js +14 -0
  36. package/dist/result.js.map +1 -0
  37. package/dist/schema.d.ts +4 -0
  38. package/dist/schema.d.ts.map +1 -1
  39. package/dist/schema.js +2 -0
  40. package/dist/schema.js.map +1 -1
  41. package/package.json +4 -4
package/README.md CHANGED
@@ -15,6 +15,8 @@ pnpm add mongodb # For MongoDB adapter
15
15
  pnpm add @qdrant/js-client-rest # For Qdrant embedding adapter
16
16
  ```
17
17
 
18
+ With `@cogitator-ai/core` you usually configure memory on the runtime (`new Cogitator({ memory: { adapter: 'postgres', postgres: { ... } } })`) and read it with `await cog.getMemory()`; the adapters below are for direct use. Website docs: [Memory](https://cogitator.app/docs/memory), [Adapters](https://cogitator.app/docs/memory/adapters), [Embeddings](https://cogitator.app/docs/memory/embeddings), [Hybrid Search](https://cogitator.app/docs/memory/hybrid-search), [Knowledge Graphs](https://cogitator.app/docs/memory/knowledge-graphs).
19
+
18
20
  ## Features
19
21
 
20
22
  - **Multiple Adapters** - In-memory, Redis (standalone + cluster), PostgreSQL with pgvector, SQLite, MongoDB, Qdrant
@@ -24,10 +26,10 @@ pnpm add @qdrant/js-client-rest # For Qdrant embedding adapter
24
26
  - **Context Builder** - Token-aware context with `recent`, `relevant` (embedding-ranked) and `hybrid` strategies
25
27
  - **Scoped Semantic Memory** - Embeddings tagged with `metadata.agentId` / `metadata.threadId` never leak to other agents
26
28
  - **Sessions & Compaction** - `SessionManager` for channel sessions, `CompactionService` for summarizing long histories
27
- - **Embedding Services** - OpenAI and Ollama embedding integration
29
+ - **Embedding Services** - OpenAI, Ollama and Google embedding integration
28
30
  - **Semantic Search** - Vector similarity search with pgvector
29
31
  - **Hybrid Search** - BM25 + Vector with Reciprocal Rank Fusion
30
- - **Facts Storage** - Store and retrieve agent knowledge
32
+ - **Facts Storage** - Store and retrieve agent knowledge (`FactAdapter` on PostgreSQL, `CoreFactsStore` on SQLite)
31
33
  - **Knowledge Graph** - Entity-relationship memory with multi-hop traversal
32
34
  - **Zod Schemas** - Type-safe configuration validation
33
35
 
@@ -36,22 +38,23 @@ pnpm add @qdrant/js-client-rest # For Qdrant embedding adapter
36
38
  ## Quick Start
37
39
 
38
40
  ```typescript
39
- import { InMemoryAdapter, ContextBuilder } from '@cogitator-ai/memory';
41
+ import { InMemoryAdapter, ContextBuilder, unwrap } from '@cogitator-ai/memory';
40
42
 
41
43
  const memory = new InMemoryAdapter();
42
44
  await memory.connect();
43
45
 
44
- const threadResult = await memory.createThread('agent-1', { topic: 'greeting' });
45
- const thread = threadResult.data!;
46
+ const thread = unwrap(await memory.createThread('agent-1', { topic: 'greeting' }));
46
47
 
47
48
  await memory.addEntry({
48
49
  threadId: thread.id,
49
50
  message: { role: 'user', content: 'Hello!' },
51
+ tokenCount: 2,
50
52
  });
51
53
 
52
54
  await memory.addEntry({
53
55
  threadId: thread.id,
54
56
  message: { role: 'assistant', content: 'Hi there!' },
57
+ tokenCount: 3,
55
58
  });
56
59
 
57
60
  const builder = new ContextBuilder(
@@ -68,6 +71,17 @@ const context = await builder.build({
68
71
  console.log(context.messages);
69
72
  ```
70
73
 
74
+ Adapter calls return a `MemoryResult` — `{ success: true, data }` or `{ success: false, error }` — instead of throwing. `unwrap(result)` returns the data or throws an `Error` with the adapter's message; check `result.success` yourself where a failure is expected:
75
+
76
+ ```typescript
77
+ const result = await memory.getThread('thread_123');
78
+ if (!result.success) {
79
+ console.error('Memory unavailable:', result.error);
80
+ } else if (result.data) {
81
+ console.log(result.data.metadata);
82
+ }
83
+ ```
84
+
71
85
  ---
72
86
 
73
87
  ## Memory Adapters
@@ -130,9 +144,11 @@ import { SQLiteAdapter } from '@cogitator-ai/memory';
130
144
 
131
145
  const memory = new SQLiteAdapter({
132
146
  provider: 'sqlite',
133
- path: './cogitator.db',
147
+ path: './cogitator.db', // ':memory:' for an in-memory database
134
148
  walMode: true,
135
149
  });
150
+
151
+ await memory.connect();
136
152
  ```
137
153
 
138
154
  ### MongoDB Adapter
@@ -145,6 +161,8 @@ const memory = new MongoDBAdapter({
145
161
  uri: 'mongodb://localhost:27017',
146
162
  database: 'cogitator',
147
163
  });
164
+
165
+ await memory.connect();
148
166
  ```
149
167
 
150
168
  ### Qdrant Adapter (Embedding)
@@ -158,8 +176,12 @@ const embeddings = new QdrantAdapter({
158
176
  collection: 'cogitator',
159
177
  dimensions: 1536,
160
178
  });
179
+
180
+ await embeddings.connect();
161
181
  ```
162
182
 
183
+ `QdrantAdapter` is an `EmbeddingAdapter` (store and search vectors), not a thread store; pair it with one of the adapters above. Points are stored under a deterministic UUID derived from the embedding id (Qdrant accepts only integer and UUID point ids); the `emb_…` id stays in `payload.embeddingId` and is what `search` returns.
184
+
163
185
  ### Factory Function
164
186
 
165
187
  ```typescript
@@ -186,8 +208,12 @@ const qdrant = await createEmbeddingAdapter({
186
208
  provider: 'qdrant',
187
209
  dimensions: 1536,
188
210
  });
211
+
212
+ await postgres.connect(); // the factories create adapters; connect them before use
189
213
  ```
190
214
 
215
+ `createMemoryAdapter` loads the adapter's driver lazily, so only the drivers you use need to be installed.
216
+
191
217
  ---
192
218
 
193
219
  ## MemoryAdapter Interface
@@ -219,13 +245,14 @@ interface MemoryAdapter {
219
245
  `createThread(agentId, metadata, threadId)` with an existing `threadId` is an upsert: entries and `createdAt` are kept and only the metadata is updated, so it is safe to call on every run.
220
246
 
221
247
  ```typescript
222
- const result = await memory.createThread('agent-1', {
223
- topic: 'support',
224
- user: 'user-123',
225
- });
226
- const thread = result.data!;
248
+ const thread = unwrap(
249
+ await memory.createThread('agent-1', {
250
+ topic: 'support',
251
+ user: 'user-123',
252
+ })
253
+ );
227
254
 
228
- const threadResult = await memory.getThread(thread.id);
255
+ const found = unwrap(await memory.getThread(thread.id)); // Thread | null
229
256
 
230
257
  await memory.updateThread(thread.id, {
231
258
  resolved: true,
@@ -237,21 +264,26 @@ await memory.deleteThread(thread.id);
237
264
  ### Entry Operations
238
265
 
239
266
  ```typescript
240
- const entry = await memory.addEntry({
241
- threadId: thread.id,
242
- message: { role: 'user', content: 'Hello' },
243
- tokenCount: 10,
244
- });
267
+ const entry = unwrap(
268
+ await memory.addEntry({
269
+ threadId: thread.id,
270
+ message: { role: 'user', content: 'Hello' },
271
+ tokenCount: 10,
272
+ })
273
+ );
245
274
 
246
- const entries = await memory.getEntries({
247
- threadId: thread.id,
248
- limit: 50,
249
- includeToolCalls: true,
250
- });
275
+ const entries = unwrap(
276
+ await memory.getEntries({
277
+ threadId: thread.id,
278
+ limit: 50, // the most recent 50, oldest first
279
+ includeToolCalls: true,
280
+ // before / after: Date bounds
281
+ })
282
+ );
251
283
 
252
- const single = await memory.getEntry(entry.data!.id);
284
+ const single = unwrap(await memory.getEntry(entry.id));
253
285
 
254
- await memory.deleteEntry(entry.data!.id);
286
+ await memory.deleteEntry(entry.id);
255
287
 
256
288
  await memory.clearThread(thread.id);
257
289
  ```
@@ -272,6 +304,8 @@ interface ContextBuilderConfig {
272
304
  includeSystemPrompt?: boolean;
273
305
  includeFacts?: boolean;
274
306
  includeSemanticContext?: boolean;
307
+ includeGraphContext?: boolean;
308
+ graphContextOptions?: GraphContextOptions;
275
309
  }
276
310
  ```
277
311
 
@@ -345,6 +379,7 @@ interface BuiltContext {
345
379
  messages: Message[];
346
380
  facts: Fact[];
347
381
  semanticResults: (Embedding & { score: number })[];
382
+ graphContext?: GraphContext; // with includeGraphContext and a graph adapter
348
383
  tokenCount: number;
349
384
  truncated: boolean;
350
385
  metadata: {
@@ -363,12 +398,26 @@ interface BuiltContext {
363
398
  `SessionManager` maps channel conversations (user + channel + agent) onto memory threads. `CompactionService` replaces old history with an LLM summary placed before the most recent messages.
364
399
 
365
400
  ```typescript
401
+ import { createLLMBackend } from '@cogitator-ai/core';
366
402
  import { InMemoryAdapter, SessionManager, CompactionService } from '@cogitator-ai/memory';
367
403
 
368
404
  const memory = new InMemoryAdapter();
405
+ const llm = createLLMBackend('google', {
406
+ providers: { google: { apiKey: process.env.GOOGLE_API_KEY! } },
407
+ });
408
+
369
409
  const compaction = new CompactionService({
370
410
  adapter: memory,
371
- summarize: async (messages) => `Summary of ${messages.length} messages`,
411
+ summarize: async (messages, { model, prompt } = {}) => {
412
+ const response = await llm.chat({
413
+ model: model ?? 'gemini-3.5-flash-lite',
414
+ messages: [
415
+ { role: 'system', content: prompt ?? 'Summarize this conversation in a few sentences.' },
416
+ ...messages,
417
+ ],
418
+ });
419
+ return response.content;
420
+ },
372
421
  });
373
422
  const sessions = new SessionManager(memory, { compaction });
374
423
 
@@ -382,10 +431,36 @@ const session = await sessions.getOrCreate({
382
431
  const all = await sessions.list();
383
432
  const mine = await sessions.list({ userId: 'user-1', status: 'active', limit: 20 });
384
433
 
385
- await sessions.compact(session.id, { strategy: 'summary', threshold: 8000, keepRecent: 10 });
434
+ await sessions.compact(session.id, {
435
+ strategy: 'summary',
436
+ threshold: 8000,
437
+ keepRecent: 10,
438
+ summaryModel: 'gemini-3.5-flash',
439
+ summaryPrompt: 'Keep names, decisions and open questions.',
440
+ });
386
441
  ```
387
442
 
388
- `list()` works with or without a `userId` filter (sessions are tracked in an index thread). `compact()` requires the `compaction` option; without it use `CompactionService` directly.
443
+ `list()` works with or without a `userId` filter (sessions are tracked in an index thread). `compact()` requires the `compaction` option; without it use `CompactionService` directly. The summarizer (`SummarizeFn`) is called as `summarize(messages, options)`, where `options` is a `SummarizeOptions` `{ model?, prompt? }` filled from the `summaryModel` / `summaryPrompt` of the compaction config.
444
+
445
+ ---
446
+
447
+ ## Core Facts
448
+
449
+ `CoreFactsStore` keeps a small set of key/value facts about the user in SQLite (with history), formatted for a system prompt:
450
+
451
+ ```typescript
452
+ import { CoreFactsStore } from '@cogitator-ai/memory';
453
+
454
+ const facts = new CoreFactsStore({ path: './facts.db' }); // or { db } to share a better-sqlite3 database
455
+ await facts.initialize();
456
+
457
+ await facts.set('name', 'Alice');
458
+ await facts.get('name'); // 'Alice'
459
+ await facts.getAll(); // { name: 'Alice' }
460
+ await facts.getHistory('name'); // [{ value, setAt }]
461
+ const prompt = await facts.formatForPrompt();
462
+ await facts.close();
463
+ ```
389
464
 
390
465
  ---
391
466
 
@@ -424,10 +499,12 @@ import { OpenAIEmbeddingService, createEmbeddingService } from '@cogitator-ai/me
424
499
 
425
500
  const embeddings = new OpenAIEmbeddingService({
426
501
  apiKey: process.env.OPENAI_API_KEY!,
427
- model: 'text-embedding-3-small',
502
+ model: 'text-embedding-3-small', // default
503
+ dimensions: 512, // optional, text-embedding-3-* only
428
504
  });
429
505
 
430
- const embeddings = createEmbeddingService({
506
+ // or through the factory
507
+ const viaFactory = createEmbeddingService({
431
508
  provider: 'openai',
432
509
  apiKey: process.env.OPENAI_API_KEY!,
433
510
  });
@@ -447,7 +524,7 @@ const embeddings = new OllamaEmbeddingService({
447
524
  baseUrl: 'http://localhost:11434',
448
525
  });
449
526
 
450
- const embeddings = createEmbeddingService({
527
+ const viaFactory = createEmbeddingService({
451
528
  provider: 'ollama',
452
529
  model: 'nomic-embed-text',
453
530
  });
@@ -466,7 +543,7 @@ const embeddings = new GoogleEmbeddingService({
466
543
  dimensions: 768,
467
544
  });
468
545
 
469
- const embeddings = createEmbeddingService({
546
+ const viaFactory = createEmbeddingService({
470
547
  provider: 'google',
471
548
  apiKey: process.env.GOOGLE_API_KEY!,
472
549
  });
@@ -529,15 +606,15 @@ const hybridResults = await search.search({
529
606
  });
530
607
 
531
608
  // Results include both scores
532
- hybridResults.data.forEach((result) => {
609
+ for (const result of unwrap(hybridResults)) {
533
610
  console.log(`${result.content} — score: ${result.score}`);
534
611
  console.log(` vector: ${result.vectorScore}, keyword: ${result.keywordScore}`);
535
- });
612
+ }
536
613
  ```
537
614
 
538
615
  ### Document Indexing
539
616
 
540
- For keyword search, documents must be indexed:
617
+ With a `keywordAdapter`, keyword search runs on that adapter's own index (embeddings added to `InMemoryEmbeddingAdapter` or `PostgresAdapter` are searchable right away). Without one, `HybridSearch` keeps a local BM25 index that you fill yourself (it ignores `filter`):
541
618
 
542
619
  ```typescript
543
620
  // Add documents to BM25 index
@@ -652,12 +729,12 @@ import type {
652
729
  ### Conversation History
653
730
 
654
731
  ```typescript
655
- import { InMemoryAdapter } from '@cogitator-ai/memory';
732
+ import { InMemoryAdapter, countMessageTokens, unwrap } from '@cogitator-ai/memory';
656
733
 
657
734
  const memory = new InMemoryAdapter();
658
735
  await memory.connect();
659
736
 
660
- const thread = await memory.createThread('chatbot');
737
+ const thread = unwrap(await memory.createThread('chatbot'));
661
738
 
662
739
  const messages = [
663
740
  { role: 'user' as const, content: 'What is AI?' },
@@ -667,15 +744,18 @@ const messages = [
667
744
 
668
745
  for (const msg of messages) {
669
746
  await memory.addEntry({
670
- threadId: thread.data!.id,
747
+ threadId: thread.id,
671
748
  message: msg,
749
+ tokenCount: countMessageTokens(msg),
672
750
  });
673
751
  }
674
752
 
675
- const history = await memory.getEntries({
676
- threadId: thread.data!.id,
677
- limit: 10,
678
- });
753
+ const history = unwrap(
754
+ await memory.getEntries({
755
+ threadId: thread.id,
756
+ limit: 10,
757
+ })
758
+ );
679
759
  ```
680
760
 
681
761
  ### Token-Limited Context
@@ -707,7 +787,7 @@ console.log(
707
787
  ### Semantic Memory with PostgreSQL
708
788
 
709
789
  ```typescript
710
- import { PostgresAdapter, OpenAIEmbeddingService } from '@cogitator-ai/memory';
790
+ import { PostgresAdapter, OpenAIEmbeddingService, unwrap } from '@cogitator-ai/memory';
711
791
 
712
792
  const memory = new PostgresAdapter({
713
793
  provider: 'postgres',
@@ -721,7 +801,22 @@ const embeddings = new OpenAIEmbeddingService({
721
801
  await memory.connect();
722
802
 
723
803
  const content = 'Machine learning is a subset of AI...';
724
- const vector = await embeddings.embed(content);
804
+ await memory.addEmbedding({
805
+ sourceId: 'doc-1',
806
+ sourceType: 'document',
807
+ content,
808
+ vector: await embeddings.embed(content),
809
+ metadata: { agentId: 'agent-1' },
810
+ });
811
+
812
+ const matches = unwrap(
813
+ await memory.search({
814
+ vector: await embeddings.embed('What is ML?'),
815
+ limit: 5,
816
+ threshold: 0.7,
817
+ filter: { agentId: 'agent-1' },
818
+ })
819
+ );
725
820
  ```
726
821
 
727
822
  ---
@@ -732,32 +827,39 @@ Entity-relationship memory with multi-hop traversal and semantic reasoning.
732
827
 
733
828
  ### PostgresGraphAdapter
734
829
 
735
- ```typescript
736
- import { PostgresGraphAdapter } from '@cogitator-ai/memory';
830
+ Graph adapters return `MemoryResult`s like the memory adapters. `PostgresGraphAdapter` takes an existing `pg` pool and creates its tables on first use; `SQLiteGraphAdapter` takes `{ path, walMode? }`.
737
831
 
738
- const graph = new PostgresGraphAdapter({
739
- connectionString: process.env.DATABASE_URL!,
740
- });
832
+ ```typescript
833
+ import { PostgresGraphAdapter, unwrap } from '@cogitator-ai/memory';
834
+ import pg from 'pg';
741
835
 
742
- await graph.connect();
836
+ const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
837
+ const graph = new PostgresGraphAdapter({ pool, vectorDimensions: 1536 }); // default 768
743
838
 
744
- const person = await graph.addNode({
745
- agentId: 'agent-1',
746
- type: 'person',
747
- name: 'Alice',
748
- description: 'Software engineer',
749
- properties: { role: 'developer' },
750
- confidence: 1.0,
751
- source: 'user',
752
- });
839
+ const person = unwrap(
840
+ await graph.addNode({
841
+ agentId: 'agent-1',
842
+ type: 'person',
843
+ name: 'Alice',
844
+ aliases: [],
845
+ description: 'Software engineer',
846
+ properties: { role: 'developer' },
847
+ confidence: 1.0,
848
+ source: 'user',
849
+ })
850
+ );
753
851
 
754
- const company = await graph.addNode({
755
- agentId: 'agent-1',
756
- type: 'organization',
757
- name: 'TechCorp',
758
- confidence: 1.0,
759
- source: 'extracted',
760
- });
852
+ const company = unwrap(
853
+ await graph.addNode({
854
+ agentId: 'agent-1',
855
+ type: 'organization',
856
+ name: 'TechCorp',
857
+ aliases: [],
858
+ properties: {},
859
+ confidence: 1.0,
860
+ source: 'extracted',
861
+ })
862
+ );
761
863
 
762
864
  await graph.addEdge({
763
865
  agentId: 'agent-1',
@@ -765,6 +867,8 @@ await graph.addEdge({
765
867
  targetNodeId: company.id,
766
868
  type: 'works_at',
767
869
  weight: 1.0,
870
+ bidirectional: false,
871
+ properties: {},
768
872
  confidence: 0.95,
769
873
  source: 'extracted',
770
874
  });
@@ -773,12 +877,15 @@ await graph.addEdge({
773
877
  ### Multi-hop Traversal
774
878
 
775
879
  ```typescript
776
- const result = await graph.traverse({
777
- startNodeId: person.id,
778
- maxDepth: 3,
779
- direction: 'outgoing',
780
- edgeTypes: ['works_at', 'knows', 'located_in'],
781
- });
880
+ const result = unwrap(
881
+ await graph.traverse({
882
+ agentId: 'agent-1',
883
+ startNodeId: person.id,
884
+ maxDepth: 3,
885
+ direction: 'outgoing', // 'outgoing' | 'incoming' | 'both'
886
+ edgeTypes: ['works_at', 'knows', 'located_in'],
887
+ })
888
+ );
782
889
 
783
890
  console.log('Visited nodes:', result.visitedNodes);
784
891
  console.log('Paths found:', result.paths);
@@ -787,7 +894,7 @@ console.log('Paths found:', result.paths);
787
894
  ### Shortest Path
788
895
 
789
896
  ```typescript
790
- const path = await graph.findShortestPath(startNodeId, endNodeId);
897
+ const path = unwrap(await graph.findShortestPath('agent-1', person.id, company.id, 5));
791
898
  if (path) {
792
899
  console.log('Path:', path.nodes.map((n) => n.name).join(' -> '));
793
900
  console.log('Total weight:', path.totalWeight);
@@ -797,12 +904,14 @@ if (path) {
797
904
  ### Semantic Node Search
798
905
 
799
906
  ```typescript
800
- const similar = await graph.searchNodesSemantic({
801
- agentId: 'agent-1',
802
- query: 'machine learning engineer',
803
- limit: 10,
804
- threshold: 0.7,
805
- });
907
+ const similar = unwrap(
908
+ await graph.searchNodesSemantic({
909
+ agentId: 'agent-1',
910
+ vector: await embeddingService.embed('machine learning engineer'), // a vector is required
911
+ limit: 10,
912
+ threshold: 0.7,
913
+ })
914
+ ); // nodes with a `score`
806
915
  ```
807
916
 
808
917
  ### LLM Entity Extraction
@@ -810,32 +919,39 @@ const similar = await graph.searchNodesSemantic({
810
919
  ```typescript
811
920
  import { LLMEntityExtractor } from '@cogitator-ai/memory';
812
921
 
813
- const extractor = new LLMEntityExtractor(llmBackend, {
922
+ const backend = cog.getLLMBackend('openai/gpt-5.5');
923
+
924
+ const extractor = new LLMEntityExtractor(backend, {
925
+ model: 'gpt-5.5', // required with an LLMBackend
814
926
  minConfidence: 0.7,
815
927
  maxEntitiesPerText: 20,
928
+ maxRelationsPerText: 30,
816
929
  });
817
930
 
818
931
  const result = await extractor.extract(
819
- 'Alice works at TechCorp in San Francisco. She knows Bob from the AI conference.'
932
+ 'Alice works at TechCorp in San Francisco. She knows Bob from the AI conference.',
933
+ { agentId: 'agent-1' }
820
934
  );
821
935
 
822
936
  console.log('Entities:', result.entities);
823
937
  console.log('Relations:', result.relations);
824
938
  ```
825
939
 
940
+ Any object with a `chat({ model?, messages, responseFormat })` method resolving to `{ content }` (`LLMBackendMinimal`) also works as the first argument; there `model` is optional and, when set, is passed through in each request.
941
+
826
942
  ### Graph Inference Engine
827
943
 
828
944
  ```typescript
829
945
  import { GraphInferenceEngine } from '@cogitator-ai/memory';
830
946
 
831
- const engine = new GraphInferenceEngine(graph, {
832
- minConfidence: 0.5,
833
- maxInferredEdges: 100,
834
- });
947
+ const engine = new GraphInferenceEngine(graph); // built-in rules; pass false to start without them
948
+
949
+ const inferred = await engine.infer('agent-1', { minConfidence: 0.5, maxInferences: 100 });
950
+ for (const edge of inferred) {
951
+ console.log(edge.type, edge.sourceNodeId, '->', edge.targetNodeId, 'via rule', edge.ruleId);
952
+ }
835
953
 
836
- const inferred = await engine.infer('agent-1');
837
- console.log('Inferred edges:', inferred.edges);
838
- console.log('Rules applied:', inferred.rulesApplied);
954
+ await engine.materialize(inferred); // store them as edges
839
955
  ```
840
956
 
841
957
  ### Graph Context Builder
@@ -849,13 +965,14 @@ const contextBuilder = new GraphContextBuilder(graph, embeddingService, {
849
965
  includeInferred: true,
850
966
  });
851
967
 
852
- const context = await contextBuilder.buildContext({
853
- agentId: 'agent-1',
854
- query: 'Tell me about Alice and her work',
968
+ const context = await contextBuilder.buildContext('agent-1', 'Tell me about Alice and her work', {
969
+ maxDepth: 2,
970
+ userId: 'user-1', // leave out other users' nodes (metadata.userId)
855
971
  });
856
972
 
857
973
  console.log('Relevant nodes:', context.nodes);
858
974
  console.log('Relationships:', context.edges);
975
+ console.log(context.formattedContext); // ready for a system prompt
859
976
  ```
860
977
 
861
978
  ---
@@ -44,6 +44,7 @@ export declare class PostgresAdapter extends BaseMemoryAdapter implements FactAd
44
44
  * `metadata.threadId`, and a user filter also lets through embeddings of no user.
45
45
  */
46
46
  private embeddingFilterClause;
47
+ private rowToThread;
47
48
  setVectorDimensions(dimensions: number): void;
48
49
  }
49
50
  //# sourceMappingURL=postgres.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/adapters/postgres.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/adapters/postgres.ts"],"names":[],"mappings":"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"}