@molroo-io/sdk 0.5.2
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/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/cjs/api-client.d.ts +23 -0
- package/dist/cjs/api-client.d.ts.map +1 -0
- package/dist/cjs/api-client.js +55 -0
- package/dist/cjs/defaults/index.d.ts +8 -0
- package/dist/cjs/defaults/index.d.ts.map +1 -0
- package/dist/cjs/defaults/index.js +30 -0
- package/dist/cjs/defaults/persona.json +17 -0
- package/dist/cjs/embedding/cloudflare.d.ts +15 -0
- package/dist/cjs/embedding/cloudflare.d.ts.map +1 -0
- package/dist/cjs/embedding/cloudflare.js +16 -0
- package/dist/cjs/embedding/cohere.d.ts +8 -0
- package/dist/cjs/embedding/cohere.d.ts.map +1 -0
- package/dist/cjs/embedding/cohere.js +31 -0
- package/dist/cjs/embedding/index.d.ts +9 -0
- package/dist/cjs/embedding/index.d.ts.map +1 -0
- package/dist/cjs/embedding/index.js +11 -0
- package/dist/cjs/embedding/local.d.ts +6 -0
- package/dist/cjs/embedding/local.d.ts.map +1 -0
- package/dist/cjs/embedding/local.js +28 -0
- package/dist/cjs/embedding/openai.d.ts +9 -0
- package/dist/cjs/embedding/openai.d.ts.map +1 -0
- package/dist/cjs/embedding/openai.js +26 -0
- package/dist/cjs/errors.d.ts +17 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +21 -0
- package/dist/cjs/events/console.d.ts +25 -0
- package/dist/cjs/events/console.d.ts.map +1 -0
- package/dist/cjs/events/console.js +41 -0
- package/dist/cjs/events/types.d.ts +28 -0
- package/dist/cjs/events/types.d.ts.map +1 -0
- package/dist/cjs/events/types.js +13 -0
- package/dist/cjs/events/webhook.d.ts +30 -0
- package/dist/cjs/events/webhook.d.ts.map +1 -0
- package/dist/cjs/events/webhook.js +79 -0
- package/dist/cjs/generate/persona.d.ts +16 -0
- package/dist/cjs/generate/persona.d.ts.map +1 -0
- package/dist/cjs/generate/persona.js +42 -0
- package/dist/cjs/generate/prompt.d.ts +7 -0
- package/dist/cjs/generate/prompt.d.ts.map +1 -0
- package/dist/cjs/generate/prompt.js +41 -0
- package/dist/cjs/generate/schema.d.ts +32 -0
- package/dist/cjs/generate/schema.d.ts.map +1 -0
- package/dist/cjs/generate/schema.js +54 -0
- package/dist/cjs/generated/index.d.ts +2 -0
- package/dist/cjs/generated/index.d.ts.map +1 -0
- package/dist/cjs/generated/index.js +2 -0
- package/dist/cjs/index.d.ts +66 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +69 -0
- package/dist/cjs/llm/adapter.d.ts +61 -0
- package/dist/cjs/llm/adapter.d.ts.map +1 -0
- package/dist/cjs/llm/adapter.js +2 -0
- package/dist/cjs/llm/resolve.d.ts +28 -0
- package/dist/cjs/llm/resolve.d.ts.map +1 -0
- package/dist/cjs/llm/resolve.js +20 -0
- package/dist/cjs/llm/schema.d.ts +60 -0
- package/dist/cjs/llm/schema.d.ts.map +1 -0
- package/dist/cjs/llm/schema.js +72 -0
- package/dist/cjs/llm/types.d.ts +24 -0
- package/dist/cjs/llm/types.d.ts.map +1 -0
- package/dist/cjs/llm/types.js +2 -0
- package/dist/cjs/llm/vercel-ai/adapter.d.ts +29 -0
- package/dist/cjs/llm/vercel-ai/adapter.d.ts.map +1 -0
- package/dist/cjs/llm/vercel-ai/adapter.js +234 -0
- package/dist/cjs/llm/vercel-ai/config.d.ts +9 -0
- package/dist/cjs/llm/vercel-ai/config.d.ts.map +1 -0
- package/dist/cjs/llm/vercel-ai/config.js +2 -0
- package/dist/cjs/llm/vercel-ai/index.d.ts +9 -0
- package/dist/cjs/llm/vercel-ai/index.d.ts.map +1 -0
- package/dist/cjs/llm/vercel-ai/index.js +13 -0
- package/dist/cjs/memory/cloudflare/index.d.ts +3 -0
- package/dist/cjs/memory/cloudflare/index.d.ts.map +1 -0
- package/dist/cjs/memory/cloudflare/index.js +5 -0
- package/dist/cjs/memory/cloudflare/vectorize.d.ts +62 -0
- package/dist/cjs/memory/cloudflare/vectorize.d.ts.map +1 -0
- package/dist/cjs/memory/cloudflare/vectorize.js +55 -0
- package/dist/cjs/memory/in-memory-semantic.d.ts +16 -0
- package/dist/cjs/memory/in-memory-semantic.d.ts.map +1 -0
- package/dist/cjs/memory/in-memory-semantic.js +57 -0
- package/dist/cjs/memory/in-memory.d.ts +46 -0
- package/dist/cjs/memory/in-memory.d.ts.map +1 -0
- package/dist/cjs/memory/in-memory.js +115 -0
- package/dist/cjs/memory/pinecone/index.d.ts +7 -0
- package/dist/cjs/memory/pinecone/index.d.ts.map +1 -0
- package/dist/cjs/memory/pinecone/index.js +8 -0
- package/dist/cjs/memory/pinecone/memory-adapter.d.ts +62 -0
- package/dist/cjs/memory/pinecone/memory-adapter.d.ts.map +1 -0
- package/dist/cjs/memory/pinecone/memory-adapter.js +220 -0
- package/dist/cjs/memory/pinecone/semantic.d.ts +44 -0
- package/dist/cjs/memory/pinecone/semantic.d.ts.map +1 -0
- package/dist/cjs/memory/pinecone/semantic.js +90 -0
- package/dist/cjs/memory/recall.d.ts +58 -0
- package/dist/cjs/memory/recall.d.ts.map +1 -0
- package/dist/cjs/memory/recall.js +220 -0
- package/dist/cjs/memory/semantic.d.ts +24 -0
- package/dist/cjs/memory/semantic.d.ts.map +1 -0
- package/dist/cjs/memory/semantic.js +2 -0
- package/dist/cjs/memory/sqlite/index.d.ts +3 -0
- package/dist/cjs/memory/sqlite/index.d.ts.map +1 -0
- package/dist/cjs/memory/sqlite/index.js +5 -0
- package/dist/cjs/memory/sqlite/memory-adapter.d.ts +58 -0
- package/dist/cjs/memory/sqlite/memory-adapter.d.ts.map +1 -0
- package/dist/cjs/memory/sqlite/memory-adapter.js +336 -0
- package/dist/cjs/memory/sqlite/schema.d.ts +4 -0
- package/dist/cjs/memory/sqlite/schema.d.ts.map +1 -0
- package/dist/cjs/memory/sqlite/schema.js +91 -0
- package/dist/cjs/memory/supabase/index.d.ts +7 -0
- package/dist/cjs/memory/supabase/index.d.ts.map +1 -0
- package/dist/cjs/memory/supabase/index.js +8 -0
- package/dist/cjs/memory/supabase/memory-adapter.d.ts +67 -0
- package/dist/cjs/memory/supabase/memory-adapter.d.ts.map +1 -0
- package/dist/cjs/memory/supabase/memory-adapter.js +335 -0
- package/dist/cjs/memory/supabase/semantic.d.ts +44 -0
- package/dist/cjs/memory/supabase/semantic.d.ts.map +1 -0
- package/dist/cjs/memory/supabase/semantic.js +72 -0
- package/dist/cjs/memory/types.d.ts +231 -0
- package/dist/cjs/memory/types.d.ts.map +1 -0
- package/dist/cjs/memory/types.js +12 -0
- package/dist/cjs/persona.d.ts +326 -0
- package/dist/cjs/persona.d.ts.map +1 -0
- package/dist/cjs/persona.js +824 -0
- package/dist/cjs/types.d.ts +263 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +15 -0
- package/dist/cjs/world/client.d.ts +36 -0
- package/dist/cjs/world/client.d.ts.map +1 -0
- package/dist/cjs/world/client.js +59 -0
- package/dist/cjs/world/errors.d.ts +9 -0
- package/dist/cjs/world/errors.d.ts.map +1 -0
- package/dist/cjs/world/errors.js +15 -0
- package/dist/cjs/world/index.d.ts +10 -0
- package/dist/cjs/world/index.d.ts.map +1 -0
- package/dist/cjs/world/index.js +16 -0
- package/dist/cjs/world/types.d.ts +101 -0
- package/dist/cjs/world/types.d.ts.map +1 -0
- package/dist/cjs/world/types.js +8 -0
- package/dist/cjs/world/village.d.ts +75 -0
- package/dist/cjs/world/village.d.ts.map +1 -0
- package/dist/cjs/world/village.js +278 -0
- package/dist/cjs/world/world-persona.d.ts +182 -0
- package/dist/cjs/world/world-persona.d.ts.map +1 -0
- package/dist/cjs/world/world-persona.js +192 -0
- package/dist/cjs/world/world.d.ts +41 -0
- package/dist/cjs/world/world.d.ts.map +1 -0
- package/dist/cjs/world/world.js +91 -0
- package/dist/esm/api-client.d.ts +23 -0
- package/dist/esm/api-client.d.ts.map +1 -0
- package/dist/esm/api-client.js +48 -0
- package/dist/esm/defaults/index.d.ts +8 -0
- package/dist/esm/defaults/index.d.ts.map +1 -0
- package/dist/esm/defaults/index.js +23 -0
- package/dist/esm/defaults/persona.json +17 -0
- package/dist/esm/embedding/cloudflare.d.ts +15 -0
- package/dist/esm/embedding/cloudflare.d.ts.map +1 -0
- package/dist/esm/embedding/cloudflare.js +13 -0
- package/dist/esm/embedding/cohere.d.ts +8 -0
- package/dist/esm/embedding/cohere.d.ts.map +1 -0
- package/dist/esm/embedding/cohere.js +28 -0
- package/dist/esm/embedding/index.d.ts +9 -0
- package/dist/esm/embedding/index.d.ts.map +1 -0
- package/dist/esm/embedding/index.js +4 -0
- package/dist/esm/embedding/local.d.ts +6 -0
- package/dist/esm/embedding/local.d.ts.map +1 -0
- package/dist/esm/embedding/local.js +25 -0
- package/dist/esm/embedding/openai.d.ts +9 -0
- package/dist/esm/embedding/openai.d.ts.map +1 -0
- package/dist/esm/embedding/openai.js +23 -0
- package/dist/esm/errors.d.ts +17 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +17 -0
- package/dist/esm/events/console.d.ts +25 -0
- package/dist/esm/events/console.d.ts.map +1 -0
- package/dist/esm/events/console.js +37 -0
- package/dist/esm/events/types.d.ts +28 -0
- package/dist/esm/events/types.d.ts.map +1 -0
- package/dist/esm/events/types.js +12 -0
- package/dist/esm/events/webhook.d.ts +30 -0
- package/dist/esm/events/webhook.d.ts.map +1 -0
- package/dist/esm/events/webhook.js +75 -0
- package/dist/esm/generate/persona.d.ts +16 -0
- package/dist/esm/generate/persona.d.ts.map +1 -0
- package/dist/esm/generate/persona.js +39 -0
- package/dist/esm/generate/prompt.d.ts +7 -0
- package/dist/esm/generate/prompt.d.ts.map +1 -0
- package/dist/esm/generate/prompt.js +38 -0
- package/dist/esm/generate/schema.d.ts +32 -0
- package/dist/esm/generate/schema.d.ts.map +1 -0
- package/dist/esm/generate/schema.js +51 -0
- package/dist/esm/generated/index.d.ts +2 -0
- package/dist/esm/generated/index.d.ts.map +1 -0
- package/dist/esm/generated/index.js +1 -0
- package/dist/esm/index.d.ts +66 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +49 -0
- package/dist/esm/llm/adapter.d.ts +61 -0
- package/dist/esm/llm/adapter.d.ts.map +1 -0
- package/dist/esm/llm/adapter.js +1 -0
- package/dist/esm/llm/resolve.d.ts +28 -0
- package/dist/esm/llm/resolve.d.ts.map +1 -0
- package/dist/esm/llm/resolve.js +17 -0
- package/dist/esm/llm/schema.d.ts +60 -0
- package/dist/esm/llm/schema.d.ts.map +1 -0
- package/dist/esm/llm/schema.js +69 -0
- package/dist/esm/llm/types.d.ts +24 -0
- package/dist/esm/llm/types.d.ts.map +1 -0
- package/dist/esm/llm/types.js +1 -0
- package/dist/esm/llm/vercel-ai/adapter.d.ts +29 -0
- package/dist/esm/llm/vercel-ai/adapter.d.ts.map +1 -0
- package/dist/esm/llm/vercel-ai/adapter.js +196 -0
- package/dist/esm/llm/vercel-ai/config.d.ts +9 -0
- package/dist/esm/llm/vercel-ai/config.d.ts.map +1 -0
- package/dist/esm/llm/vercel-ai/config.js +1 -0
- package/dist/esm/llm/vercel-ai/index.d.ts +9 -0
- package/dist/esm/llm/vercel-ai/index.d.ts.map +1 -0
- package/dist/esm/llm/vercel-ai/index.js +8 -0
- package/dist/esm/memory/cloudflare/index.d.ts +3 -0
- package/dist/esm/memory/cloudflare/index.d.ts.map +1 -0
- package/dist/esm/memory/cloudflare/index.js +1 -0
- package/dist/esm/memory/cloudflare/vectorize.d.ts +62 -0
- package/dist/esm/memory/cloudflare/vectorize.d.ts.map +1 -0
- package/dist/esm/memory/cloudflare/vectorize.js +51 -0
- package/dist/esm/memory/in-memory-semantic.d.ts +16 -0
- package/dist/esm/memory/in-memory-semantic.d.ts.map +1 -0
- package/dist/esm/memory/in-memory-semantic.js +53 -0
- package/dist/esm/memory/in-memory.d.ts +46 -0
- package/dist/esm/memory/in-memory.d.ts.map +1 -0
- package/dist/esm/memory/in-memory.js +111 -0
- package/dist/esm/memory/pinecone/index.d.ts +7 -0
- package/dist/esm/memory/pinecone/index.d.ts.map +1 -0
- package/dist/esm/memory/pinecone/index.js +3 -0
- package/dist/esm/memory/pinecone/memory-adapter.d.ts +62 -0
- package/dist/esm/memory/pinecone/memory-adapter.d.ts.map +1 -0
- package/dist/esm/memory/pinecone/memory-adapter.js +216 -0
- package/dist/esm/memory/pinecone/semantic.d.ts +44 -0
- package/dist/esm/memory/pinecone/semantic.d.ts.map +1 -0
- package/dist/esm/memory/pinecone/semantic.js +86 -0
- package/dist/esm/memory/recall.d.ts +58 -0
- package/dist/esm/memory/recall.d.ts.map +1 -0
- package/dist/esm/memory/recall.js +215 -0
- package/dist/esm/memory/semantic.d.ts +24 -0
- package/dist/esm/memory/semantic.d.ts.map +1 -0
- package/dist/esm/memory/semantic.js +1 -0
- package/dist/esm/memory/sqlite/index.d.ts +3 -0
- package/dist/esm/memory/sqlite/index.d.ts.map +1 -0
- package/dist/esm/memory/sqlite/index.js +1 -0
- package/dist/esm/memory/sqlite/memory-adapter.d.ts +58 -0
- package/dist/esm/memory/sqlite/memory-adapter.d.ts.map +1 -0
- package/dist/esm/memory/sqlite/memory-adapter.js +296 -0
- package/dist/esm/memory/sqlite/schema.d.ts +4 -0
- package/dist/esm/memory/sqlite/schema.d.ts.map +1 -0
- package/dist/esm/memory/sqlite/schema.js +86 -0
- package/dist/esm/memory/supabase/index.d.ts +7 -0
- package/dist/esm/memory/supabase/index.d.ts.map +1 -0
- package/dist/esm/memory/supabase/index.js +3 -0
- package/dist/esm/memory/supabase/memory-adapter.d.ts +67 -0
- package/dist/esm/memory/supabase/memory-adapter.d.ts.map +1 -0
- package/dist/esm/memory/supabase/memory-adapter.js +331 -0
- package/dist/esm/memory/supabase/semantic.d.ts +44 -0
- package/dist/esm/memory/supabase/semantic.d.ts.map +1 -0
- package/dist/esm/memory/supabase/semantic.js +68 -0
- package/dist/esm/memory/types.d.ts +231 -0
- package/dist/esm/memory/types.d.ts.map +1 -0
- package/dist/esm/memory/types.js +9 -0
- package/dist/esm/persona.d.ts +326 -0
- package/dist/esm/persona.d.ts.map +1 -0
- package/dist/esm/persona.js +787 -0
- package/dist/esm/types.d.ts +263 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +11 -0
- package/dist/esm/world/client.d.ts +36 -0
- package/dist/esm/world/client.d.ts.map +1 -0
- package/dist/esm/world/client.js +52 -0
- package/dist/esm/world/errors.d.ts +9 -0
- package/dist/esm/world/errors.d.ts.map +1 -0
- package/dist/esm/world/errors.js +11 -0
- package/dist/esm/world/index.d.ts +10 -0
- package/dist/esm/world/index.d.ts.map +1 -0
- package/dist/esm/world/index.js +8 -0
- package/dist/esm/world/types.d.ts +101 -0
- package/dist/esm/world/types.d.ts.map +1 -0
- package/dist/esm/world/types.js +7 -0
- package/dist/esm/world/village.d.ts +75 -0
- package/dist/esm/world/village.d.ts.map +1 -0
- package/dist/esm/world/village.js +274 -0
- package/dist/esm/world/world-persona.d.ts +182 -0
- package/dist/esm/world/world-persona.d.ts.map +1 -0
- package/dist/esm/world/world-persona.js +188 -0
- package/dist/esm/world/world.d.ts +41 -0
- package/dist/esm/world/world.d.ts.map +1 -0
- package/dist/esm/world/world.js +87 -0
- package/package.json +207 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory implementation of both EpisodeAdapter and MemoryAdapter.
|
|
3
|
+
*
|
|
4
|
+
* Useful for demos, testing, and prototyping. Data is lost on process exit
|
|
5
|
+
* unless explicitly serialized via `toJSON()` / `fromJSON()`.
|
|
6
|
+
*
|
|
7
|
+
* Can be used as:
|
|
8
|
+
* - `memory: { episodes: new InMemoryEpisodeAdapter() }` (split config)
|
|
9
|
+
* - `memory: new InMemoryEpisodeAdapter()` (single adapter)
|
|
10
|
+
*/
|
|
11
|
+
export class InMemoryEpisodeAdapter {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.episodes = [];
|
|
14
|
+
this.reflections = [];
|
|
15
|
+
}
|
|
16
|
+
async saveEpisode(episode) {
|
|
17
|
+
const idx = this.episodes.findIndex(e => e.id === episode.id);
|
|
18
|
+
if (idx >= 0) {
|
|
19
|
+
this.episodes[idx] = episode;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.episodes.push(episode);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recall episodes by query.
|
|
27
|
+
* Accepts both `EpisodeQuery` (with `contextContains`) and `RecallQuery` (with `context`).
|
|
28
|
+
*/
|
|
29
|
+
async recall(query) {
|
|
30
|
+
let results = [...this.episodes];
|
|
31
|
+
if (query.sourceEntity) {
|
|
32
|
+
results = results.filter(e => e.sourceEntity === query.sourceEntity);
|
|
33
|
+
}
|
|
34
|
+
// Support both EpisodeQuery.contextContains and RecallQuery.context
|
|
35
|
+
const contextSearch = ('contextContains' in query ? query.contextContains : undefined)
|
|
36
|
+
?? ('context' in query ? query.context : undefined);
|
|
37
|
+
if (contextSearch) {
|
|
38
|
+
const lower = contextSearch.toLowerCase();
|
|
39
|
+
results = results.filter(e => e.context?.toLowerCase().includes(lower));
|
|
40
|
+
}
|
|
41
|
+
if (query.type !== undefined) {
|
|
42
|
+
const types = Array.isArray(query.type) ? query.type : [query.type];
|
|
43
|
+
results = results.filter(e => e.type !== undefined && types.includes(e.type));
|
|
44
|
+
}
|
|
45
|
+
if (query.minImportance !== undefined) {
|
|
46
|
+
results = results.filter(e => e.importance >= query.minImportance);
|
|
47
|
+
}
|
|
48
|
+
if (query.timeRange) {
|
|
49
|
+
const [from, to] = query.timeRange;
|
|
50
|
+
results = results.filter(e => e.timestamp >= from && e.timestamp <= to);
|
|
51
|
+
}
|
|
52
|
+
if ('valenceRange' in query && query.valenceRange) {
|
|
53
|
+
const [min, max] = query.valenceRange;
|
|
54
|
+
results = results.filter(e => e.emotionSnapshot.V >= min && e.emotionSnapshot.V <= max);
|
|
55
|
+
}
|
|
56
|
+
// Sort by timestamp descending (most recent first)
|
|
57
|
+
results.sort((a, b) => b.timestamp - a.timestamp);
|
|
58
|
+
const limit = query.limit ?? 10;
|
|
59
|
+
return results.slice(0, limit);
|
|
60
|
+
}
|
|
61
|
+
async getByIds(ids) {
|
|
62
|
+
const idSet = new Set(ids);
|
|
63
|
+
return this.episodes.filter(e => idSet.has(e.id));
|
|
64
|
+
}
|
|
65
|
+
async saveReflection(reflection) {
|
|
66
|
+
const idx = this.reflections.findIndex(r => r.id === reflection.id);
|
|
67
|
+
if (idx >= 0) {
|
|
68
|
+
this.reflections[idx] = reflection;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.reflections.push(reflection);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async getReflections(sourceEntity, limit) {
|
|
75
|
+
let results = [...this.reflections];
|
|
76
|
+
if (sourceEntity) {
|
|
77
|
+
results = results.filter(r => r.sourceEntity === sourceEntity);
|
|
78
|
+
}
|
|
79
|
+
// Sort by timestamp descending
|
|
80
|
+
results.sort((a, b) => b.timestamp - a.timestamp);
|
|
81
|
+
return results.slice(0, limit ?? 10);
|
|
82
|
+
}
|
|
83
|
+
// ── Serialization helpers ──
|
|
84
|
+
/** Export all data for persistence (save slots, etc.). */
|
|
85
|
+
toJSON() {
|
|
86
|
+
return {
|
|
87
|
+
episodes: [...this.episodes],
|
|
88
|
+
reflections: [...this.reflections],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/** Restore data from a previous export. */
|
|
92
|
+
fromJSON(data) {
|
|
93
|
+
this.episodes = data.episodes ? [...data.episodes] : [];
|
|
94
|
+
this.reflections = data.reflections ? [...data.reflections] : [];
|
|
95
|
+
}
|
|
96
|
+
/** Number of stored episodes. */
|
|
97
|
+
get episodeCount() {
|
|
98
|
+
return this.episodes.length;
|
|
99
|
+
}
|
|
100
|
+
/** Number of stored reflections. */
|
|
101
|
+
get reflectionCount() {
|
|
102
|
+
return this.reflections.length;
|
|
103
|
+
}
|
|
104
|
+
/** Clear all data. */
|
|
105
|
+
clear() {
|
|
106
|
+
this.episodes = [];
|
|
107
|
+
this.reflections = [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** @deprecated Use InMemoryEpisodeAdapter */
|
|
111
|
+
export const InMemoryEpisodeStore = InMemoryEpisodeAdapter;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { PineconeSemanticMemory } from './semantic';
|
|
2
|
+
export type { PineconeSemanticMemoryOptions } from './semantic';
|
|
3
|
+
/** @deprecated Use PineconeSemanticMemory */
|
|
4
|
+
export { PineconeMemoryAdapter } from './memory-adapter';
|
|
5
|
+
/** @deprecated Use PineconeSemanticMemoryOptions */
|
|
6
|
+
export type { PineconeMemoryAdapterOptions } from './memory-adapter';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/memory/pinecone/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEhE,6CAA6C;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,oDAAoD;AACpD,YAAY,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { MemoryAdapter, Episode, Reflection, RecallQuery, SemanticRecallOptions, EpisodePatch, CountQuery, EmbeddingAdapter } from '../types';
|
|
2
|
+
export interface PineconeMemoryAdapterOptions {
|
|
3
|
+
/** Pinecone API key. */
|
|
4
|
+
apiKey: string;
|
|
5
|
+
/** Pinecone index name. */
|
|
6
|
+
indexName: string;
|
|
7
|
+
/** Pinecone namespace. Default: 'default'. */
|
|
8
|
+
namespace?: string;
|
|
9
|
+
/** Embedding provider (embed function + dimension). */
|
|
10
|
+
embedding: EmbeddingAdapter;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Pinecone-backed MemoryAdapter combining in-memory arrays (RDB) with
|
|
14
|
+
* Pinecone vector search (semanticRecall).
|
|
15
|
+
*
|
|
16
|
+
* RDB operations (saveEpisode, recall, saveReflection, getReflections,
|
|
17
|
+
* getByIds, countEpisodes, updateEpisode, deleteEpisode, expireEpisodes)
|
|
18
|
+
* all operate on in-memory arrays, identical to InMemoryAdapter.
|
|
19
|
+
*
|
|
20
|
+
* Vector search (semanticRecall) delegates to Pinecone after embedding
|
|
21
|
+
* the query text via the provided EmbeddingAdapter.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const memory = new PineconeMemoryAdapter({
|
|
26
|
+
* apiKey: process.env.PINECONE_API_KEY!,
|
|
27
|
+
* indexName: 'molroo-memory',
|
|
28
|
+
* namespace: 'world-123',
|
|
29
|
+
* embedding: openaiEmbedding({ apiKey: '...' }),
|
|
30
|
+
* });
|
|
31
|
+
* await memory.init();
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class PineconeMemoryAdapter implements MemoryAdapter {
|
|
35
|
+
private client;
|
|
36
|
+
private pcIndex;
|
|
37
|
+
private namespace;
|
|
38
|
+
private indexName;
|
|
39
|
+
private embedding;
|
|
40
|
+
private initialized;
|
|
41
|
+
private episodes;
|
|
42
|
+
private reflections;
|
|
43
|
+
constructor(options: PineconeMemoryAdapterOptions);
|
|
44
|
+
/**
|
|
45
|
+
* Initialize the adapter. Must be called before use.
|
|
46
|
+
* Validates embedding dimension against Pinecone index.
|
|
47
|
+
*/
|
|
48
|
+
init(): Promise<void>;
|
|
49
|
+
private ensureInitialized;
|
|
50
|
+
private ns;
|
|
51
|
+
saveEpisode(episode: Episode): Promise<void>;
|
|
52
|
+
recall(query: RecallQuery): Promise<Episode[]>;
|
|
53
|
+
saveReflection(reflection: Reflection): Promise<void>;
|
|
54
|
+
getReflections(sourceEntity?: string): Promise<Reflection[]>;
|
|
55
|
+
semanticRecall(query: string, options?: SemanticRecallOptions): Promise<Episode[]>;
|
|
56
|
+
getByIds(ids: string[]): Promise<Episode[]>;
|
|
57
|
+
countEpisodes(query: CountQuery): Promise<number>;
|
|
58
|
+
updateEpisode(id: string, patch: EpisodePatch): Promise<void>;
|
|
59
|
+
deleteEpisode(id: string): Promise<void>;
|
|
60
|
+
expireEpisodes(before: number, minImportance?: number): Promise<number>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=memory-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-adapter.d.ts","sourceRoot":"","sources":["../../../../src/memory/pinecone/memory-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,OAAO,EACP,UAAU,EACV,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,4BAA4B;IAC3C,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAoB;gBAE3B,OAAO,EAAE,4BAA4B;IAOjD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,EAAE;IAMJ,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB5C,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuC9C,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrD,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAU5D,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,OAAO,EAAE,CAAC;IAqCf,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAM3C,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBjD,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7D,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxC,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;CA2BnB"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
2
|
+
/**
|
|
3
|
+
* Pinecone-backed MemoryAdapter combining in-memory arrays (RDB) with
|
|
4
|
+
* Pinecone vector search (semanticRecall).
|
|
5
|
+
*
|
|
6
|
+
* RDB operations (saveEpisode, recall, saveReflection, getReflections,
|
|
7
|
+
* getByIds, countEpisodes, updateEpisode, deleteEpisode, expireEpisodes)
|
|
8
|
+
* all operate on in-memory arrays, identical to InMemoryAdapter.
|
|
9
|
+
*
|
|
10
|
+
* Vector search (semanticRecall) delegates to Pinecone after embedding
|
|
11
|
+
* the query text via the provided EmbeddingAdapter.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const memory = new PineconeMemoryAdapter({
|
|
16
|
+
* apiKey: process.env.PINECONE_API_KEY!,
|
|
17
|
+
* indexName: 'molroo-memory',
|
|
18
|
+
* namespace: 'world-123',
|
|
19
|
+
* embedding: openaiEmbedding({ apiKey: '...' }),
|
|
20
|
+
* });
|
|
21
|
+
* await memory.init();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class PineconeMemoryAdapter {
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.initialized = false;
|
|
27
|
+
this.episodes = [];
|
|
28
|
+
this.reflections = [];
|
|
29
|
+
this.client = new Pinecone({ apiKey: options.apiKey });
|
|
30
|
+
this.indexName = options.indexName;
|
|
31
|
+
this.namespace = options.namespace ?? 'default';
|
|
32
|
+
this.embedding = options.embedding;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Initialize the adapter. Must be called before use.
|
|
36
|
+
* Validates embedding dimension against Pinecone index.
|
|
37
|
+
*/
|
|
38
|
+
async init() {
|
|
39
|
+
this.pcIndex = this.client.index(this.indexName);
|
|
40
|
+
const stats = await this.pcIndex.describeIndexStats();
|
|
41
|
+
if (stats.dimension && stats.dimension !== this.embedding.dimension) {
|
|
42
|
+
throw new Error(`Dimension mismatch: Pinecone index expects ${stats.dimension}d, ` +
|
|
43
|
+
`but embedding provider has ${this.embedding.dimension}d`);
|
|
44
|
+
}
|
|
45
|
+
this.initialized = true;
|
|
46
|
+
}
|
|
47
|
+
ensureInitialized() {
|
|
48
|
+
if (!this.initialized) {
|
|
49
|
+
throw new Error('PineconeMemoryAdapter not initialized. Call init() first.');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
ns() {
|
|
53
|
+
return this.pcIndex.namespace(this.namespace);
|
|
54
|
+
}
|
|
55
|
+
// ── Required methods (in-memory, identical to InMemoryAdapter) ──
|
|
56
|
+
async saveEpisode(episode) {
|
|
57
|
+
this.ensureInitialized();
|
|
58
|
+
this.episodes.push(episode);
|
|
59
|
+
// Auto-upsert embedding to Pinecone (best-effort)
|
|
60
|
+
const text = episode.context ?? episode.sourceEntity ?? '';
|
|
61
|
+
if (text) {
|
|
62
|
+
try {
|
|
63
|
+
const embedding = await this.embedding.embed(text);
|
|
64
|
+
await this.ns().upsert([{
|
|
65
|
+
id: episode.id,
|
|
66
|
+
values: embedding,
|
|
67
|
+
metadata: {
|
|
68
|
+
type: 'episode',
|
|
69
|
+
sourceEntity: episode.sourceEntity ?? '',
|
|
70
|
+
timestamp: episode.timestamp,
|
|
71
|
+
importance: episode.importance,
|
|
72
|
+
},
|
|
73
|
+
}]);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Best-effort: vector indexing failure doesn't block episode save.
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async recall(query) {
|
|
81
|
+
this.ensureInitialized();
|
|
82
|
+
let results = this.episodes;
|
|
83
|
+
if (query.sourceEntity) {
|
|
84
|
+
results = results.filter((e) => e.sourceEntity === query.sourceEntity);
|
|
85
|
+
}
|
|
86
|
+
if (query.context) {
|
|
87
|
+
const ctx = query.context.toLowerCase();
|
|
88
|
+
results = results.filter((e) => e.context && e.context.toLowerCase().includes(ctx));
|
|
89
|
+
}
|
|
90
|
+
if (query.valenceRange) {
|
|
91
|
+
const [min, max] = query.valenceRange;
|
|
92
|
+
results = results.filter((e) => e.emotionSnapshot.V >= min && e.emotionSnapshot.V <= max);
|
|
93
|
+
}
|
|
94
|
+
if (query.minImportance !== undefined) {
|
|
95
|
+
results = results.filter((e) => e.importance >= query.minImportance);
|
|
96
|
+
}
|
|
97
|
+
if (query.timeRange) {
|
|
98
|
+
const [start, end] = query.timeRange;
|
|
99
|
+
results = results.filter((e) => e.timestamp >= start && e.timestamp <= end);
|
|
100
|
+
}
|
|
101
|
+
// Return most recent first
|
|
102
|
+
results = results.slice().sort((a, b) => b.timestamp - a.timestamp);
|
|
103
|
+
if (query.limit && query.limit > 0) {
|
|
104
|
+
results = results.slice(0, query.limit);
|
|
105
|
+
}
|
|
106
|
+
return results;
|
|
107
|
+
}
|
|
108
|
+
async saveReflection(reflection) {
|
|
109
|
+
this.ensureInitialized();
|
|
110
|
+
this.reflections.push(reflection);
|
|
111
|
+
}
|
|
112
|
+
async getReflections(sourceEntity) {
|
|
113
|
+
this.ensureInitialized();
|
|
114
|
+
if (sourceEntity) {
|
|
115
|
+
return this.reflections.filter((r) => r.sourceEntity === sourceEntity);
|
|
116
|
+
}
|
|
117
|
+
return [...this.reflections];
|
|
118
|
+
}
|
|
119
|
+
// ── Optional methods ──
|
|
120
|
+
async semanticRecall(query, options) {
|
|
121
|
+
this.ensureInitialized();
|
|
122
|
+
const embedding = await this.embedding.embed(query);
|
|
123
|
+
const topK = options?.topK ?? 5;
|
|
124
|
+
// Build Pinecone filter
|
|
125
|
+
const filter = {};
|
|
126
|
+
if (options?.filter?.sourceEntity) {
|
|
127
|
+
filter.sourceEntity = { $eq: options.filter.sourceEntity };
|
|
128
|
+
}
|
|
129
|
+
if (options?.filter?.minImportance !== undefined) {
|
|
130
|
+
filter.importance = { $gte: options.filter.minImportance };
|
|
131
|
+
}
|
|
132
|
+
// Over-fetch to account for in-memory-only episodes that may not be in Pinecone
|
|
133
|
+
const hasFilter = Object.keys(filter).length > 0;
|
|
134
|
+
const fetchK = hasFilter ? topK * 4 : topK;
|
|
135
|
+
const results = await this.ns().query({
|
|
136
|
+
vector: embedding,
|
|
137
|
+
topK: fetchK,
|
|
138
|
+
filter: hasFilter ? filter : undefined,
|
|
139
|
+
includeMetadata: true,
|
|
140
|
+
});
|
|
141
|
+
// Map Pinecone results to episodes via in-memory lookup
|
|
142
|
+
const matches = results.matches ?? [];
|
|
143
|
+
const idSet = new Set(matches.map((m) => m.id));
|
|
144
|
+
const matched = this.episodes.filter((e) => idSet.has(e.id));
|
|
145
|
+
// Sort by Pinecone score order (highest first), limit to topK
|
|
146
|
+
const scoreMap = new Map(matches.map((m) => [m.id, m.score ?? 0]));
|
|
147
|
+
return matched
|
|
148
|
+
.sort((a, b) => (scoreMap.get(b.id) ?? 0) - (scoreMap.get(a.id) ?? 0))
|
|
149
|
+
.slice(0, topK);
|
|
150
|
+
}
|
|
151
|
+
async getByIds(ids) {
|
|
152
|
+
this.ensureInitialized();
|
|
153
|
+
const idSet = new Set(ids);
|
|
154
|
+
return this.episodes.filter((e) => idSet.has(e.id));
|
|
155
|
+
}
|
|
156
|
+
async countEpisodes(query) {
|
|
157
|
+
this.ensureInitialized();
|
|
158
|
+
let results = this.episodes;
|
|
159
|
+
if (query.sourceEntity) {
|
|
160
|
+
results = results.filter((e) => e.sourceEntity === query.sourceEntity);
|
|
161
|
+
}
|
|
162
|
+
if (query.context) {
|
|
163
|
+
const ctx = query.context.toLowerCase();
|
|
164
|
+
results = results.filter((e) => e.context && e.context.toLowerCase().includes(ctx));
|
|
165
|
+
}
|
|
166
|
+
if (query.timeRange) {
|
|
167
|
+
const [start, end] = query.timeRange;
|
|
168
|
+
results = results.filter((e) => e.timestamp >= start && e.timestamp <= end);
|
|
169
|
+
}
|
|
170
|
+
return results.length;
|
|
171
|
+
}
|
|
172
|
+
async updateEpisode(id, patch) {
|
|
173
|
+
this.ensureInitialized();
|
|
174
|
+
const episode = this.episodes.find((e) => e.id === id);
|
|
175
|
+
if (!episode)
|
|
176
|
+
return;
|
|
177
|
+
if (patch.importance !== undefined)
|
|
178
|
+
episode.importance = patch.importance;
|
|
179
|
+
if (patch.intensity !== undefined)
|
|
180
|
+
episode.intensity = patch.intensity;
|
|
181
|
+
if (patch.emotionSnapshot !== undefined)
|
|
182
|
+
episode.emotionSnapshot = patch.emotionSnapshot;
|
|
183
|
+
}
|
|
184
|
+
async deleteEpisode(id) {
|
|
185
|
+
this.ensureInitialized();
|
|
186
|
+
this.episodes = this.episodes.filter((e) => e.id !== id);
|
|
187
|
+
// Best-effort Pinecone cleanup
|
|
188
|
+
try {
|
|
189
|
+
await this.ns().deleteOne(id);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Non-fatal: Pinecone cleanup failure doesn't affect in-memory state.
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async expireEpisodes(before, minImportance) {
|
|
196
|
+
this.ensureInitialized();
|
|
197
|
+
const threshold = minImportance ?? 0;
|
|
198
|
+
const original = this.episodes.length;
|
|
199
|
+
// Collect IDs of episodes to expire for Pinecone cleanup
|
|
200
|
+
const expiredIds = this.episodes
|
|
201
|
+
.filter((e) => e.timestamp < before && e.importance < threshold)
|
|
202
|
+
.map((e) => e.id);
|
|
203
|
+
this.episodes = this.episodes.filter((e) => e.timestamp >= before || e.importance >= threshold);
|
|
204
|
+
const count = original - this.episodes.length;
|
|
205
|
+
// Best-effort Pinecone cleanup
|
|
206
|
+
if (expiredIds.length > 0) {
|
|
207
|
+
try {
|
|
208
|
+
await this.ns().deleteMany({ ids: expiredIds });
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Non-fatal: Pinecone cleanup failure doesn't affect in-memory state.
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return count;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EmbeddingAdapter } from '../types';
|
|
2
|
+
import type { SemanticMemory, SearchOptions, SearchResult } from '../semantic';
|
|
3
|
+
export interface PineconeSemanticMemoryOptions {
|
|
4
|
+
/** Pinecone API key. */
|
|
5
|
+
apiKey: string;
|
|
6
|
+
/** Pinecone index name. */
|
|
7
|
+
indexName: string;
|
|
8
|
+
/** Pinecone namespace. Default: 'default'. */
|
|
9
|
+
namespace?: string;
|
|
10
|
+
/** Embedding provider (embed function + dimension). */
|
|
11
|
+
embedding: EmbeddingAdapter;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pinecone-backed SemanticMemory.
|
|
15
|
+
*
|
|
16
|
+
* Call `init()` before use to validate embedding dimension against Pinecone index.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const memory = new PineconeSemanticMemory({
|
|
21
|
+
* apiKey: process.env.PINECONE_API_KEY!,
|
|
22
|
+
* indexName: 'my-index',
|
|
23
|
+
* embedding: openaiEmbedding({ apiKey: '...' }),
|
|
24
|
+
* });
|
|
25
|
+
* await memory.init();
|
|
26
|
+
* await memory.store('user likes coffee');
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class PineconeSemanticMemory implements SemanticMemory {
|
|
30
|
+
private client;
|
|
31
|
+
private pcIndex;
|
|
32
|
+
private namespace;
|
|
33
|
+
private indexName;
|
|
34
|
+
private embedding;
|
|
35
|
+
private initialized;
|
|
36
|
+
constructor(options: PineconeSemanticMemoryOptions);
|
|
37
|
+
init(): Promise<void>;
|
|
38
|
+
private ensureInit;
|
|
39
|
+
private ns;
|
|
40
|
+
store(text: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
41
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
42
|
+
delete(ids: string[]): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=semantic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../../../src/memory/pinecone/semantic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,WAAW,6BAA6B;IAC5C,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AAOD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,6BAA6B;IAO5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,EAAE;IAIJ,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,MAAM,CAAC;IAqBZ,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IA4BpB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAM3C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
2
|
+
/**
|
|
3
|
+
* Pinecone-backed SemanticMemory.
|
|
4
|
+
*
|
|
5
|
+
* Call `init()` before use to validate embedding dimension against Pinecone index.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const memory = new PineconeSemanticMemory({
|
|
10
|
+
* apiKey: process.env.PINECONE_API_KEY!,
|
|
11
|
+
* indexName: 'my-index',
|
|
12
|
+
* embedding: openaiEmbedding({ apiKey: '...' }),
|
|
13
|
+
* });
|
|
14
|
+
* await memory.init();
|
|
15
|
+
* await memory.store('user likes coffee');
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export class PineconeSemanticMemory {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.initialized = false;
|
|
21
|
+
this.client = new Pinecone({ apiKey: options.apiKey });
|
|
22
|
+
this.indexName = options.indexName;
|
|
23
|
+
this.namespace = options.namespace ?? 'default';
|
|
24
|
+
this.embedding = options.embedding;
|
|
25
|
+
}
|
|
26
|
+
async init() {
|
|
27
|
+
this.pcIndex = this.client.index(this.indexName);
|
|
28
|
+
const stats = await this.pcIndex.describeIndexStats();
|
|
29
|
+
if (stats.dimension && stats.dimension !== this.embedding.dimension) {
|
|
30
|
+
throw new Error(`Dimension mismatch: Pinecone index expects ${stats.dimension}d, ` +
|
|
31
|
+
`but embedding provider has ${this.embedding.dimension}d`);
|
|
32
|
+
}
|
|
33
|
+
this.initialized = true;
|
|
34
|
+
}
|
|
35
|
+
ensureInit() {
|
|
36
|
+
if (!this.initialized) {
|
|
37
|
+
throw new Error('PineconeSemanticMemory not initialized. Call init() first.');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
ns() {
|
|
41
|
+
return this.pcIndex.namespace(this.namespace);
|
|
42
|
+
}
|
|
43
|
+
async store(text, metadata = {}) {
|
|
44
|
+
this.ensureInit();
|
|
45
|
+
const id = crypto.randomUUID();
|
|
46
|
+
const values = await this.embedding.embed(text);
|
|
47
|
+
const pineconeMetadata = {
|
|
48
|
+
text,
|
|
49
|
+
...Object.fromEntries(Object.entries(metadata).filter(([, v]) => typeof v === 'string' ||
|
|
50
|
+
typeof v === 'number' ||
|
|
51
|
+
typeof v === 'boolean' ||
|
|
52
|
+
Array.isArray(v))),
|
|
53
|
+
};
|
|
54
|
+
await this.ns().upsert([{ id, values, metadata: pineconeMetadata }]);
|
|
55
|
+
return id;
|
|
56
|
+
}
|
|
57
|
+
async search(query, options = {}) {
|
|
58
|
+
this.ensureInit();
|
|
59
|
+
const topK = options.topK ?? 5;
|
|
60
|
+
const threshold = options.scoreThreshold ?? 0;
|
|
61
|
+
const vector = await this.embedding.embed(query);
|
|
62
|
+
const filter = options.filter;
|
|
63
|
+
const hasFilter = filter && Object.keys(filter).length > 0;
|
|
64
|
+
const results = await this.ns().query({
|
|
65
|
+
vector,
|
|
66
|
+
topK,
|
|
67
|
+
filter: hasFilter ? filter : undefined,
|
|
68
|
+
includeMetadata: true,
|
|
69
|
+
});
|
|
70
|
+
const matchList = results.matches ?? [];
|
|
71
|
+
return matchList
|
|
72
|
+
.filter((m) => (m.score ?? 0) >= threshold)
|
|
73
|
+
.map((m) => ({
|
|
74
|
+
id: m.id,
|
|
75
|
+
text: m.metadata?.text ?? '',
|
|
76
|
+
score: m.score ?? 0,
|
|
77
|
+
metadata: m.metadata ?? {},
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
async delete(ids) {
|
|
81
|
+
this.ensureInit();
|
|
82
|
+
if (ids.length > 0) {
|
|
83
|
+
await this.ns().deleteMany({ ids });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared memory recall and prompt-building utilities.
|
|
3
|
+
*
|
|
4
|
+
* Used by MolrooPersona to recall episodic/semantic memories and
|
|
5
|
+
* format them for LLM system prompts. Supports both:
|
|
6
|
+
* - Single MemoryAdapter (new, preferred)
|
|
7
|
+
* - Split EpisodeAdapter + SemanticAdapter + EmbeddingAdapter (backward compat)
|
|
8
|
+
*/
|
|
9
|
+
import type { Episode } from '../types';
|
|
10
|
+
import type { EpisodeAdapter, SemanticAdapter, EmbeddingAdapter, MemoryAdapter, Reflection } from './types';
|
|
11
|
+
/**
|
|
12
|
+
* Strip leading `[...]` metadata tags from text before embedding.
|
|
13
|
+
* These tags (channel info, scene hints, timestamps) add noise to
|
|
14
|
+
* semantic similarity and should not influence vector search.
|
|
15
|
+
*/
|
|
16
|
+
export declare function stripMetaTags(text: string): string;
|
|
17
|
+
/** Recall tuning parameters. */
|
|
18
|
+
export interface RecallConfig {
|
|
19
|
+
episodicLimit?: number;
|
|
20
|
+
semanticLimit?: number;
|
|
21
|
+
reflectionLimit?: number;
|
|
22
|
+
minImportance?: number;
|
|
23
|
+
/** Filter episodic recall to these episode types. Undefined = all types. */
|
|
24
|
+
types?: string[];
|
|
25
|
+
}
|
|
26
|
+
/** Result of a memory recall operation. */
|
|
27
|
+
export interface RecallResult {
|
|
28
|
+
episodic: Episode[];
|
|
29
|
+
semantic: Episode[];
|
|
30
|
+
reflections: Reflection[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Recall episodic + semantic + reflection memories in parallel.
|
|
34
|
+
*
|
|
35
|
+
* Supports two paths:
|
|
36
|
+
* 1. Single MemoryAdapter (`memoryAdapter` param) — adapter handles everything
|
|
37
|
+
* 2. Split stores (`episodeStore` + `semanticStore` + `embeddingProvider`) — legacy
|
|
38
|
+
*
|
|
39
|
+
* @param message - Current user message (used for semantic embedding).
|
|
40
|
+
* @param opts - Stores, provider, config, and entity filter.
|
|
41
|
+
* @returns Recalled memories grouped by type.
|
|
42
|
+
*/
|
|
43
|
+
export declare function recallMemories(message: string, opts: {
|
|
44
|
+
memoryAdapter?: MemoryAdapter | null;
|
|
45
|
+
episodeStore: EpisodeAdapter | null;
|
|
46
|
+
semanticStore: SemanticAdapter | null;
|
|
47
|
+
embeddingProvider: EmbeddingAdapter | null;
|
|
48
|
+
config?: RecallConfig;
|
|
49
|
+
sourceEntity?: string;
|
|
50
|
+
reflectionEntity?: string;
|
|
51
|
+
}): Promise<RecallResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Format recalled memories into a text block for LLM system prompt injection.
|
|
54
|
+
* Groups episodic memories by type: conversations vs events.
|
|
55
|
+
* Deduplicates semantic results that overlap with episodic results.
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildMemoryBlock(episodicMemories?: Episode[], semanticMemories?: Episode[], reflections?: Reflection[]): string;
|
|
58
|
+
//# sourceMappingURL=recall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../../src/memory/recall.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,UAAU,EAEX,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,gCAAgC;AAChC,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAgFD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,YAAY,EAAE,cAAc,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,eAAe,GAAG,IAAI,CAAC;IACtC,iBAAiB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACA,OAAO,CAAC,YAAY,CAAC,CA2FvB;AAcD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAC5B,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAC5B,WAAW,CAAC,EAAE,UAAU,EAAE,GACzB,MAAM,CAwCR"}
|