@bip-krishna/agentmind 0.1.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.
- package/.agentmind/memory.db +0 -0
- package/.context-memory/memory.db +0 -0
- package/README.md +176 -0
- package/apps/dashboard/src/server.ts +369 -0
- package/cli/src/index.ts +163 -0
- package/dist/apps/dashboard/src/server.d.ts +6 -0
- package/dist/apps/dashboard/src/server.d.ts.map +1 -0
- package/dist/apps/dashboard/src/server.js +360 -0
- package/dist/apps/dashboard/src/server.js.map +1 -0
- package/dist/cli/src/index.d.ts +3 -0
- package/dist/cli/src/index.d.ts.map +1 -0
- package/dist/cli/src/index.js +162 -0
- package/dist/cli/src/index.js.map +1 -0
- package/dist/examples/advanced.d.ts +2 -0
- package/dist/examples/advanced.d.ts.map +1 -0
- package/dist/examples/advanced.js +41 -0
- package/dist/examples/advanced.js.map +1 -0
- package/dist/examples/basic.d.ts +2 -0
- package/dist/examples/basic.d.ts.map +1 -0
- package/dist/examples/basic.js +22 -0
- package/dist/examples/basic.js.map +1 -0
- package/dist/packages/core/src/consolidation.d.ts +27 -0
- package/dist/packages/core/src/consolidation.d.ts.map +1 -0
- package/dist/packages/core/src/consolidation.js +97 -0
- package/dist/packages/core/src/consolidation.js.map +1 -0
- package/dist/packages/core/src/events.d.ts +18 -0
- package/dist/packages/core/src/events.d.ts.map +1 -0
- package/dist/packages/core/src/events.js +13 -0
- package/dist/packages/core/src/events.js.map +1 -0
- package/dist/packages/core/src/extraction.d.ts +32 -0
- package/dist/packages/core/src/extraction.d.ts.map +1 -0
- package/dist/packages/core/src/extraction.js +65 -0
- package/dist/packages/core/src/extraction.js.map +1 -0
- package/dist/packages/core/src/index.d.ts +10 -0
- package/dist/packages/core/src/index.d.ts.map +1 -0
- package/dist/packages/core/src/index.js +7 -0
- package/dist/packages/core/src/index.js.map +1 -0
- package/dist/packages/core/src/memory-store.d.ts +36 -0
- package/dist/packages/core/src/memory-store.d.ts.map +1 -0
- package/dist/packages/core/src/memory-store.js +2 -0
- package/dist/packages/core/src/memory-store.js.map +1 -0
- package/dist/packages/core/src/memory.d.ts +75 -0
- package/dist/packages/core/src/memory.d.ts.map +1 -0
- package/dist/packages/core/src/memory.js +402 -0
- package/dist/packages/core/src/memory.js.map +1 -0
- package/dist/packages/core/src/policy.d.ts +17 -0
- package/dist/packages/core/src/policy.d.ts.map +1 -0
- package/dist/packages/core/src/policy.js +22 -0
- package/dist/packages/core/src/policy.js.map +1 -0
- package/dist/packages/core/src/types.d.ts +102 -0
- package/dist/packages/core/src/types.d.ts.map +1 -0
- package/dist/packages/core/src/types.js +23 -0
- package/dist/packages/core/src/types.js.map +1 -0
- package/dist/packages/embeddings/src/index.d.ts +4 -0
- package/dist/packages/embeddings/src/index.d.ts.map +1 -0
- package/dist/packages/embeddings/src/index.js +4 -0
- package/dist/packages/embeddings/src/index.js.map +1 -0
- package/dist/packages/embeddings/src/local.d.ts +15 -0
- package/dist/packages/embeddings/src/local.d.ts.map +1 -0
- package/dist/packages/embeddings/src/local.js +45 -0
- package/dist/packages/embeddings/src/local.js.map +1 -0
- package/dist/packages/embeddings/src/openai.d.ts +17 -0
- package/dist/packages/embeddings/src/openai.d.ts.map +1 -0
- package/dist/packages/embeddings/src/openai.js +41 -0
- package/dist/packages/embeddings/src/openai.js.map +1 -0
- package/dist/packages/embeddings/src/provider.d.ts +8 -0
- package/dist/packages/embeddings/src/provider.d.ts.map +1 -0
- package/dist/packages/embeddings/src/provider.js +12 -0
- package/dist/packages/embeddings/src/provider.js.map +1 -0
- package/dist/packages/integrations/src/anthropic.d.ts +15 -0
- package/dist/packages/integrations/src/anthropic.d.ts.map +1 -0
- package/dist/packages/integrations/src/anthropic.js +25 -0
- package/dist/packages/integrations/src/anthropic.js.map +1 -0
- package/dist/packages/integrations/src/index.d.ts +4 -0
- package/dist/packages/integrations/src/index.d.ts.map +1 -0
- package/dist/packages/integrations/src/index.js +4 -0
- package/dist/packages/integrations/src/index.js.map +1 -0
- package/dist/packages/integrations/src/openai.d.ts +27 -0
- package/dist/packages/integrations/src/openai.d.ts.map +1 -0
- package/dist/packages/integrations/src/openai.js +26 -0
- package/dist/packages/integrations/src/openai.js.map +1 -0
- package/dist/packages/integrations/src/vercel.d.ts +24 -0
- package/dist/packages/integrations/src/vercel.d.ts.map +1 -0
- package/dist/packages/integrations/src/vercel.js +20 -0
- package/dist/packages/integrations/src/vercel.js.map +1 -0
- package/dist/packages/retrieval/src/index.d.ts +3 -0
- package/dist/packages/retrieval/src/index.d.ts.map +1 -0
- package/dist/packages/retrieval/src/index.js +3 -0
- package/dist/packages/retrieval/src/index.js.map +1 -0
- package/dist/packages/retrieval/src/ranker.d.ts +21 -0
- package/dist/packages/retrieval/src/ranker.d.ts.map +1 -0
- package/dist/packages/retrieval/src/ranker.js +54 -0
- package/dist/packages/retrieval/src/ranker.js.map +1 -0
- package/dist/packages/retrieval/src/token.d.ts +3 -0
- package/dist/packages/retrieval/src/token.d.ts.map +1 -0
- package/dist/packages/retrieval/src/token.js +7 -0
- package/dist/packages/retrieval/src/token.js.map +1 -0
- package/dist/packages/storage/src/config.d.ts +14 -0
- package/dist/packages/storage/src/config.d.ts.map +1 -0
- package/dist/packages/storage/src/config.js +41 -0
- package/dist/packages/storage/src/config.js.map +1 -0
- package/dist/packages/storage/src/index.d.ts +4 -0
- package/dist/packages/storage/src/index.d.ts.map +1 -0
- package/dist/packages/storage/src/index.js +4 -0
- package/dist/packages/storage/src/index.js.map +1 -0
- package/dist/packages/storage/src/memory-store.d.ts +37 -0
- package/dist/packages/storage/src/memory-store.d.ts.map +1 -0
- package/dist/packages/storage/src/memory-store.js +107 -0
- package/dist/packages/storage/src/memory-store.js.map +1 -0
- package/dist/packages/storage/src/migrations.d.ts +12 -0
- package/dist/packages/storage/src/migrations.d.ts.map +1 -0
- package/dist/packages/storage/src/migrations.js +89 -0
- package/dist/packages/storage/src/migrations.js.map +1 -0
- package/dist/packages/storage/src/postgres-store.d.ts +45 -0
- package/dist/packages/storage/src/postgres-store.d.ts.map +1 -0
- package/dist/packages/storage/src/postgres-store.js +282 -0
- package/dist/packages/storage/src/postgres-store.js.map +1 -0
- package/dist/packages/storage/src/sqlite-store.d.ts +36 -0
- package/dist/packages/storage/src/sqlite-store.d.ts.map +1 -0
- package/dist/packages/storage/src/sqlite-store.js +243 -0
- package/dist/packages/storage/src/sqlite-store.js.map +1 -0
- package/examples/advanced.ts +46 -0
- package/examples/basic.ts +25 -0
- package/package.json +52 -0
- package/packages/core/package.json +13 -0
- package/packages/core/src/consolidation.ts +104 -0
- package/packages/core/src/events.ts +25 -0
- package/packages/core/src/extraction.ts +81 -0
- package/packages/core/src/index.ts +22 -0
- package/packages/core/src/memory-store.ts +50 -0
- package/packages/core/src/memory.ts +447 -0
- package/packages/core/src/policy.ts +36 -0
- package/packages/core/src/types.ts +119 -0
- package/packages/core/tsconfig.json +6 -0
- package/packages/embeddings/package.json +9 -0
- package/packages/embeddings/src/index.ts +3 -0
- package/packages/embeddings/src/local.ts +47 -0
- package/packages/embeddings/src/openai.ts +50 -0
- package/packages/embeddings/src/provider.d.ts.map +1 -0
- package/packages/embeddings/src/provider.js.map +1 -0
- package/packages/embeddings/src/provider.ts +17 -0
- package/packages/embeddings/tsconfig.json +6 -0
- package/packages/integrations/package.json +7 -0
- package/packages/integrations/src/anthropic.ts +34 -0
- package/packages/integrations/src/index.ts +3 -0
- package/packages/integrations/src/openai.ts +52 -0
- package/packages/integrations/src/vercel.ts +26 -0
- package/packages/retrieval/package.json +8 -0
- package/packages/retrieval/src/index.ts +2 -0
- package/packages/retrieval/src/ranker.d.ts.map +1 -0
- package/packages/retrieval/src/ranker.js.map +1 -0
- package/packages/retrieval/src/ranker.ts +77 -0
- package/packages/retrieval/src/token.d.ts.map +1 -0
- package/packages/retrieval/src/token.js.map +1 -0
- package/packages/retrieval/src/token.ts +5 -0
- package/packages/retrieval/tsconfig.json +6 -0
- package/packages/storage/package.json +11 -0
- package/packages/storage/src/config.ts +44 -0
- package/packages/storage/src/index.ts +3 -0
- package/packages/storage/src/memory-store.ts +100 -0
- package/packages/storage/src/migrations.ts +96 -0
- package/packages/storage/src/postgres-store.ts +299 -0
- package/packages/storage/src/sqlite-store.ts +298 -0
- package/packages/storage/tsconfig.json +6 -0
- package/test-mvp.mjs +82 -0
- package/tests/consolidation.test.ts +45 -0
- package/tests/eval.test.ts +102 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Memory } from "../packages/core/src/memory.js";
|
|
2
|
+
import { InMemoryStore } from "../packages/storage/src/memory-store.js";
|
|
3
|
+
import { LocalEmbeddingProvider } from "../packages/embeddings/src/local.js";
|
|
4
|
+
|
|
5
|
+
const store = new InMemoryStore();
|
|
6
|
+
const memory = await Memory.create({
|
|
7
|
+
project: "research-mesh",
|
|
8
|
+
store,
|
|
9
|
+
embeddingProvider: new LocalEmbeddingProvider(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
await memory.remember({
|
|
13
|
+
type: "decision",
|
|
14
|
+
content: "We decided to use PostgreSQL with pgvector.",
|
|
15
|
+
importance: 0.9,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const context = await memory.context({
|
|
19
|
+
query: "What database did we decide to use?",
|
|
20
|
+
maxTokens: 6000,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
console.log(context.text);
|
|
24
|
+
// Relevant project memory (research-mesh):
|
|
25
|
+
// - We decided to use PostgreSQL with pgvector.
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bip-krishna/agentmind",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Persistent, project-scoped context layer for AI applications",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/packages/core/src/index.js",
|
|
9
|
+
"./storage": "./dist/packages/storage/src/index.js",
|
|
10
|
+
"./embeddings": "./dist/packages/embeddings/src/index.js",
|
|
11
|
+
"./integrations": "./dist/packages/integrations/src/index.js",
|
|
12
|
+
"./retrieval": "./dist/packages/retrieval/src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"agentmind": "./dist/cli/src/index.js",
|
|
16
|
+
"context-memory": "./dist/cli/src/index.js"
|
|
17
|
+
},
|
|
18
|
+
"workspaces": [
|
|
19
|
+
"packages/*",
|
|
20
|
+
"apps/*",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "rm -rf dist && npx tsc",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:mvp": "node test-mvp.mjs",
|
|
27
|
+
"dashboard": "node ./dist/apps/dashboard/src/server.js",
|
|
28
|
+
"cli": "node ./dist/cli/src/index.js"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"memory",
|
|
32
|
+
"vector",
|
|
33
|
+
"ai",
|
|
34
|
+
"context",
|
|
35
|
+
"rag",
|
|
36
|
+
"pgvector"
|
|
37
|
+
],
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^22.0.0",
|
|
44
|
+
"@types/pg": "^8.23.1",
|
|
45
|
+
"typescript": "^5.5.0",
|
|
46
|
+
"vitest": "^1.6.0",
|
|
47
|
+
"zod": "^3.23.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"pg": "^8.23.0"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { MemoryStore } from "./memory-store.js";
|
|
3
|
+
import type { Memory } from "./types.js";
|
|
4
|
+
import type { EmbeddingProvider } from "../../embeddings/src/provider.js";
|
|
5
|
+
import { cosineSimilarity } from "../../embeddings/src/provider.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Memory consolidation: 1000 memories -> 150 useful memories.
|
|
9
|
+
* Keeps originals as archived, creates summary memories.
|
|
10
|
+
* Uses embedding similarity to cluster, then heuristic summary.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export interface ConsolidationResult {
|
|
14
|
+
summary: Memory;
|
|
15
|
+
sourceIds: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Consolidator {
|
|
19
|
+
constructor(private store: MemoryStore, private embed?: EmbeddingProvider) {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Consolidate a project. Groups memories with cosine > threshold (0.82) and creates summaries.
|
|
23
|
+
* Returns summaries created.
|
|
24
|
+
*/
|
|
25
|
+
async consolidate(projectId: string, opts?: { threshold?: number; minClusterSize?: number }): Promise<ConsolidationResult[]> {
|
|
26
|
+
const threshold = opts?.threshold ?? 0.82;
|
|
27
|
+
const minClusterSize = opts?.minClusterSize ?? 3;
|
|
28
|
+
const memories = (await this.store.listMemories(projectId)).filter((m) => !m.archived && m.status === "active");
|
|
29
|
+
if (memories.length < minClusterSize) return [];
|
|
30
|
+
|
|
31
|
+
// Build embedding map
|
|
32
|
+
const vectors = new Map<string, number[]>();
|
|
33
|
+
for (const m of memories) {
|
|
34
|
+
const emb = await this.store.getEmbedding(m.id);
|
|
35
|
+
if (emb) vectors.set(m.id, emb.vector);
|
|
36
|
+
else if (this.embed) {
|
|
37
|
+
const v = await this.embed.embed(m.content);
|
|
38
|
+
vectors.set(m.id, v);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Greedy clustering
|
|
43
|
+
const clusters: string[][] = [];
|
|
44
|
+
const visited = new Set<string>();
|
|
45
|
+
for (const m of memories) {
|
|
46
|
+
if (visited.has(m.id)) continue;
|
|
47
|
+
const cluster = [m.id];
|
|
48
|
+
visited.add(m.id);
|
|
49
|
+
const vecA = vectors.get(m.id);
|
|
50
|
+
if (!vecA) continue;
|
|
51
|
+
for (const other of memories) {
|
|
52
|
+
if (visited.has(other.id)) continue;
|
|
53
|
+
const vecB = vectors.get(other.id);
|
|
54
|
+
if (!vecB) continue;
|
|
55
|
+
if (cosineSimilarity(vecA, vecB) > threshold) {
|
|
56
|
+
cluster.push(other.id);
|
|
57
|
+
visited.add(other.id);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (cluster.length >= minClusterSize) clusters.push(cluster);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const results: ConsolidationResult[] = [];
|
|
64
|
+
for (const cluster of clusters) {
|
|
65
|
+
const sourceMems = cluster.map((id) => memories.find((m) => m.id === id)!).filter(Boolean);
|
|
66
|
+
const summaryContent = this.summarizeCluster(sourceMems);
|
|
67
|
+
const now = new Date();
|
|
68
|
+
const summary: Memory = {
|
|
69
|
+
id: randomUUID(),
|
|
70
|
+
projectId,
|
|
71
|
+
type: "summary",
|
|
72
|
+
content: summaryContent,
|
|
73
|
+
importance: Math.max(...sourceMems.map((m) => m.importance)),
|
|
74
|
+
confidence: 0.85,
|
|
75
|
+
status: "active",
|
|
76
|
+
createdAt: now,
|
|
77
|
+
updatedAt: now,
|
|
78
|
+
accessCount: 0,
|
|
79
|
+
metadata: { consolidatedFrom: cluster, count: cluster.length },
|
|
80
|
+
archived: false,
|
|
81
|
+
};
|
|
82
|
+
await this.store.createMemory(summary);
|
|
83
|
+
if (this.embed) {
|
|
84
|
+
const vec = await this.embed.embed(summaryContent);
|
|
85
|
+
await this.store.upsertEmbedding(summary.id, vec, this.embed.model);
|
|
86
|
+
}
|
|
87
|
+
// Archive sources but keep traceable
|
|
88
|
+
for (const id of cluster) {
|
|
89
|
+
await this.store.updateMemory(id, { archived: true, status: "archived", updatedAt: now });
|
|
90
|
+
}
|
|
91
|
+
results.push({ summary, sourceIds: cluster });
|
|
92
|
+
}
|
|
93
|
+
return results;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private summarizeCluster(mems: Memory[]): string {
|
|
97
|
+
// Simple heuristic: most important + common prefix extraction
|
|
98
|
+
const byImp = [...mems].sort((a, b) => b.importance - a.importance);
|
|
99
|
+
const top = byImp[0].content;
|
|
100
|
+
const count = mems.length;
|
|
101
|
+
const types = [...new Set(mems.map((m) => m.type))].join(", ");
|
|
102
|
+
return `Consolidated ${count} memories (${types}): ${top} (and ${count - 1} related memories about similar topic)`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { Memory, RetrievalEvent } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export type MemoryEventMap = {
|
|
5
|
+
"memory.created": (memory: Memory) => void;
|
|
6
|
+
"memory.updated": (memory: Memory) => void;
|
|
7
|
+
"memory.deleted": (id: string) => void;
|
|
8
|
+
"memory.retrieved": (memories: Memory[], query: string) => void;
|
|
9
|
+
"memory.archived": (memory: Memory) => void;
|
|
10
|
+
"memory.superseded": (old: Memory, next: Memory) => void;
|
|
11
|
+
"retrieval.completed": (event: RetrievalEvent) => void;
|
|
12
|
+
"consolidation.completed": (summary: Memory, sources: string[]) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class MemoryEvents extends EventEmitter {
|
|
16
|
+
emit<K extends keyof MemoryEventMap>(event: K, ...args: Parameters<MemoryEventMap[K]>): boolean {
|
|
17
|
+
return super.emit(event, ...args);
|
|
18
|
+
}
|
|
19
|
+
on<K extends keyof MemoryEventMap>(event: K, listener: MemoryEventMap[K]): this {
|
|
20
|
+
return super.on(event, listener);
|
|
21
|
+
}
|
|
22
|
+
off<K extends keyof MemoryEventMap>(event: K, listener: MemoryEventMap[K]): this {
|
|
23
|
+
return super.off(event, listener);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { MemoryType } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export interface ExtractedMemory {
|
|
4
|
+
type: MemoryType;
|
|
5
|
+
content: string;
|
|
6
|
+
importance: number; // 0-1
|
|
7
|
+
confidence: number; // 0-1
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ExtractorOptions {
|
|
11
|
+
minimumImportance?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ExtractorProvider {
|
|
15
|
+
extract(conversation: string, opts?: ExtractorOptions): Promise<ExtractedMemory[]>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Prompt template for LLM extraction */
|
|
19
|
+
export const EXTRACTION_PROMPT = `Extract only information that is likely to remain useful in future interactions.
|
|
20
|
+
|
|
21
|
+
Do not store:
|
|
22
|
+
- greetings
|
|
23
|
+
- temporary conversation
|
|
24
|
+
- obvious information
|
|
25
|
+
- filler
|
|
26
|
+
- transient thoughts
|
|
27
|
+
- sensitive information unless explicitly configured
|
|
28
|
+
|
|
29
|
+
Return JSON array of {type, content, importance, confidence} where type is one of: fact, preference, decision, event, knowledge, procedure, task, summary.
|
|
30
|
+
Importance 0-1, confidence 0-1. Content must be a concise standalone statement.
|
|
31
|
+
|
|
32
|
+
Conversation:
|
|
33
|
+
{{conversation}}
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Deterministic regex-based extractor for offline / tests.
|
|
38
|
+
* Real provider would call OpenAI / Anthropic with structured output.
|
|
39
|
+
*/
|
|
40
|
+
export class HeuristicExtractor implements ExtractorProvider {
|
|
41
|
+
async extract(conversation: string): Promise<ExtractedMemory[]> {
|
|
42
|
+
const results: ExtractedMemory[] = [];
|
|
43
|
+
const sentences = conversation.split(/[.!?]+/).map((s) => s.trim()).filter(Boolean);
|
|
44
|
+
const keywords = ["decided", "will use", "using", "prefer", "need", "should", "must", "database", "postgres", "mongodb", "api", "always", "never"];
|
|
45
|
+
for (const s of sentences) {
|
|
46
|
+
const lower = s.toLowerCase();
|
|
47
|
+
if (keywords.some((k) => lower.includes(k)) && s.length > 20 && s.length < 300) {
|
|
48
|
+
const type: MemoryType = lower.includes("decided") || lower.includes("will use") ? "decision" : lower.includes("prefer") ? "preference" : "fact";
|
|
49
|
+
results.push({
|
|
50
|
+
type,
|
|
51
|
+
content: s + ".",
|
|
52
|
+
importance: lower.includes("decided") ? 0.9 : 0.6,
|
|
53
|
+
confidence: 0.8,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return results;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* LLM-backed extractor (generic). Provide a chat completion function.
|
|
63
|
+
*/
|
|
64
|
+
export class LLMExtractor implements ExtractorProvider {
|
|
65
|
+
constructor(
|
|
66
|
+
private callLLM: (prompt: string) => Promise<string>,
|
|
67
|
+
private minImportance = 0.65
|
|
68
|
+
) {}
|
|
69
|
+
|
|
70
|
+
async extract(conversation: string, opts?: ExtractorOptions): Promise<ExtractedMemory[]> {
|
|
71
|
+
const prompt = EXTRACTION_PROMPT.replace("{{conversation}}", conversation);
|
|
72
|
+
const raw = await this.callLLM(prompt);
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(raw) as ExtractedMemory[];
|
|
75
|
+
const threshold = opts?.minimumImportance ?? this.minImportance;
|
|
76
|
+
return parsed.filter((m) => m.importance >= threshold);
|
|
77
|
+
} catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
Project,
|
|
3
|
+
Source,
|
|
4
|
+
SourceType,
|
|
5
|
+
MemoryType,
|
|
6
|
+
MemoryStatus,
|
|
7
|
+
RetrievalEvent,
|
|
8
|
+
SearchQuery,
|
|
9
|
+
CandidateMemory,
|
|
10
|
+
SearchResult,
|
|
11
|
+
ContextOptions,
|
|
12
|
+
ContextResult,
|
|
13
|
+
CreateMemoryInput,
|
|
14
|
+
} from "./types.js";
|
|
15
|
+
export type { Memory as MemoryData } from "./types.js";
|
|
16
|
+
export { MemoryTypeSchema, MemoryStatusSchema, CreateMemoryInputSchema } from "./types.js";
|
|
17
|
+
export type { MemoryStore } from "./memory-store.js";
|
|
18
|
+
export { MemoryEngine, Memory } from "./memory.js";
|
|
19
|
+
export * from "./extraction.js";
|
|
20
|
+
export * from "./policy.js";
|
|
21
|
+
export * from "./events.js";
|
|
22
|
+
export * from "./consolidation.js";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Memory,
|
|
3
|
+
Project,
|
|
4
|
+
Source,
|
|
5
|
+
SearchQuery,
|
|
6
|
+
SearchResult,
|
|
7
|
+
RetrievalEvent,
|
|
8
|
+
} from "./types.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Core abstraction — Memory Store.
|
|
12
|
+
* LocalStore (SQLite) and PostgresStore both implement this.
|
|
13
|
+
* Dashboard / CLI / core engine depend only on this interface.
|
|
14
|
+
*/
|
|
15
|
+
export interface MemoryStore {
|
|
16
|
+
// Projects
|
|
17
|
+
createProject(project: Project): Promise<Project>;
|
|
18
|
+
getProject(id: string): Promise<Project | null>;
|
|
19
|
+
getProjectByName(name: string): Promise<Project | null>;
|
|
20
|
+
listProjects(): Promise<Project[]>;
|
|
21
|
+
deleteProject(projectId: string): Promise<void>;
|
|
22
|
+
|
|
23
|
+
// Sources
|
|
24
|
+
createSource(source: Source): Promise<Source>;
|
|
25
|
+
getSource(id: string): Promise<Source | null>;
|
|
26
|
+
|
|
27
|
+
// Memories
|
|
28
|
+
createMemory(memory: Memory): Promise<void>;
|
|
29
|
+
getMemory(id: string): Promise<Memory | null>;
|
|
30
|
+
updateMemory(id: string, update: Partial<Memory>): Promise<void>;
|
|
31
|
+
deleteMemory(id: string): Promise<void>;
|
|
32
|
+
archiveMemory(id: string): Promise<void>;
|
|
33
|
+
listMemories(projectId: string): Promise<Memory[]>;
|
|
34
|
+
search(query: SearchQuery): Promise<SearchResult[]>; // keyword fallback default
|
|
35
|
+
|
|
36
|
+
// Embeddings — stored alongside but decoupled
|
|
37
|
+
upsertEmbedding(memoryId: string, vector: number[], model: string): Promise<void>;
|
|
38
|
+
getEmbedding(memoryId: string): Promise<{ vector: number[]; model: string } | null>;
|
|
39
|
+
deleteEmbedding?(memoryId: string): Promise<void>;
|
|
40
|
+
|
|
41
|
+
// Optional native vector search (pgvector)
|
|
42
|
+
vectorSearch?(projectId: string, queryVector: number[], limit: number): Promise<Array<{ memory: Memory; distance: number }>>;
|
|
43
|
+
|
|
44
|
+
// Retrieval logs
|
|
45
|
+
logRetrieval(event: RetrievalEvent): Promise<void>;
|
|
46
|
+
listRetrievals(projectId: string, limit?: number): Promise<RetrievalEvent[]>;
|
|
47
|
+
|
|
48
|
+
// Admin
|
|
49
|
+
close?(): Promise<void>;
|
|
50
|
+
}
|