@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.
Files changed (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/dist/cjs/api-client.d.ts +23 -0
  4. package/dist/cjs/api-client.d.ts.map +1 -0
  5. package/dist/cjs/api-client.js +55 -0
  6. package/dist/cjs/defaults/index.d.ts +8 -0
  7. package/dist/cjs/defaults/index.d.ts.map +1 -0
  8. package/dist/cjs/defaults/index.js +30 -0
  9. package/dist/cjs/defaults/persona.json +17 -0
  10. package/dist/cjs/embedding/cloudflare.d.ts +15 -0
  11. package/dist/cjs/embedding/cloudflare.d.ts.map +1 -0
  12. package/dist/cjs/embedding/cloudflare.js +16 -0
  13. package/dist/cjs/embedding/cohere.d.ts +8 -0
  14. package/dist/cjs/embedding/cohere.d.ts.map +1 -0
  15. package/dist/cjs/embedding/cohere.js +31 -0
  16. package/dist/cjs/embedding/index.d.ts +9 -0
  17. package/dist/cjs/embedding/index.d.ts.map +1 -0
  18. package/dist/cjs/embedding/index.js +11 -0
  19. package/dist/cjs/embedding/local.d.ts +6 -0
  20. package/dist/cjs/embedding/local.d.ts.map +1 -0
  21. package/dist/cjs/embedding/local.js +28 -0
  22. package/dist/cjs/embedding/openai.d.ts +9 -0
  23. package/dist/cjs/embedding/openai.d.ts.map +1 -0
  24. package/dist/cjs/embedding/openai.js +26 -0
  25. package/dist/cjs/errors.d.ts +17 -0
  26. package/dist/cjs/errors.d.ts.map +1 -0
  27. package/dist/cjs/errors.js +21 -0
  28. package/dist/cjs/events/console.d.ts +25 -0
  29. package/dist/cjs/events/console.d.ts.map +1 -0
  30. package/dist/cjs/events/console.js +41 -0
  31. package/dist/cjs/events/types.d.ts +28 -0
  32. package/dist/cjs/events/types.d.ts.map +1 -0
  33. package/dist/cjs/events/types.js +13 -0
  34. package/dist/cjs/events/webhook.d.ts +30 -0
  35. package/dist/cjs/events/webhook.d.ts.map +1 -0
  36. package/dist/cjs/events/webhook.js +79 -0
  37. package/dist/cjs/generate/persona.d.ts +16 -0
  38. package/dist/cjs/generate/persona.d.ts.map +1 -0
  39. package/dist/cjs/generate/persona.js +42 -0
  40. package/dist/cjs/generate/prompt.d.ts +7 -0
  41. package/dist/cjs/generate/prompt.d.ts.map +1 -0
  42. package/dist/cjs/generate/prompt.js +41 -0
  43. package/dist/cjs/generate/schema.d.ts +32 -0
  44. package/dist/cjs/generate/schema.d.ts.map +1 -0
  45. package/dist/cjs/generate/schema.js +54 -0
  46. package/dist/cjs/generated/index.d.ts +2 -0
  47. package/dist/cjs/generated/index.d.ts.map +1 -0
  48. package/dist/cjs/generated/index.js +2 -0
  49. package/dist/cjs/index.d.ts +66 -0
  50. package/dist/cjs/index.d.ts.map +1 -0
  51. package/dist/cjs/index.js +69 -0
  52. package/dist/cjs/llm/adapter.d.ts +61 -0
  53. package/dist/cjs/llm/adapter.d.ts.map +1 -0
  54. package/dist/cjs/llm/adapter.js +2 -0
  55. package/dist/cjs/llm/resolve.d.ts +28 -0
  56. package/dist/cjs/llm/resolve.d.ts.map +1 -0
  57. package/dist/cjs/llm/resolve.js +20 -0
  58. package/dist/cjs/llm/schema.d.ts +60 -0
  59. package/dist/cjs/llm/schema.d.ts.map +1 -0
  60. package/dist/cjs/llm/schema.js +72 -0
  61. package/dist/cjs/llm/types.d.ts +24 -0
  62. package/dist/cjs/llm/types.d.ts.map +1 -0
  63. package/dist/cjs/llm/types.js +2 -0
  64. package/dist/cjs/llm/vercel-ai/adapter.d.ts +29 -0
  65. package/dist/cjs/llm/vercel-ai/adapter.d.ts.map +1 -0
  66. package/dist/cjs/llm/vercel-ai/adapter.js +234 -0
  67. package/dist/cjs/llm/vercel-ai/config.d.ts +9 -0
  68. package/dist/cjs/llm/vercel-ai/config.d.ts.map +1 -0
  69. package/dist/cjs/llm/vercel-ai/config.js +2 -0
  70. package/dist/cjs/llm/vercel-ai/index.d.ts +9 -0
  71. package/dist/cjs/llm/vercel-ai/index.d.ts.map +1 -0
  72. package/dist/cjs/llm/vercel-ai/index.js +13 -0
  73. package/dist/cjs/memory/cloudflare/index.d.ts +3 -0
  74. package/dist/cjs/memory/cloudflare/index.d.ts.map +1 -0
  75. package/dist/cjs/memory/cloudflare/index.js +5 -0
  76. package/dist/cjs/memory/cloudflare/vectorize.d.ts +62 -0
  77. package/dist/cjs/memory/cloudflare/vectorize.d.ts.map +1 -0
  78. package/dist/cjs/memory/cloudflare/vectorize.js +55 -0
  79. package/dist/cjs/memory/in-memory-semantic.d.ts +16 -0
  80. package/dist/cjs/memory/in-memory-semantic.d.ts.map +1 -0
  81. package/dist/cjs/memory/in-memory-semantic.js +57 -0
  82. package/dist/cjs/memory/in-memory.d.ts +46 -0
  83. package/dist/cjs/memory/in-memory.d.ts.map +1 -0
  84. package/dist/cjs/memory/in-memory.js +115 -0
  85. package/dist/cjs/memory/pinecone/index.d.ts +7 -0
  86. package/dist/cjs/memory/pinecone/index.d.ts.map +1 -0
  87. package/dist/cjs/memory/pinecone/index.js +8 -0
  88. package/dist/cjs/memory/pinecone/memory-adapter.d.ts +62 -0
  89. package/dist/cjs/memory/pinecone/memory-adapter.d.ts.map +1 -0
  90. package/dist/cjs/memory/pinecone/memory-adapter.js +220 -0
  91. package/dist/cjs/memory/pinecone/semantic.d.ts +44 -0
  92. package/dist/cjs/memory/pinecone/semantic.d.ts.map +1 -0
  93. package/dist/cjs/memory/pinecone/semantic.js +90 -0
  94. package/dist/cjs/memory/recall.d.ts +58 -0
  95. package/dist/cjs/memory/recall.d.ts.map +1 -0
  96. package/dist/cjs/memory/recall.js +220 -0
  97. package/dist/cjs/memory/semantic.d.ts +24 -0
  98. package/dist/cjs/memory/semantic.d.ts.map +1 -0
  99. package/dist/cjs/memory/semantic.js +2 -0
  100. package/dist/cjs/memory/sqlite/index.d.ts +3 -0
  101. package/dist/cjs/memory/sqlite/index.d.ts.map +1 -0
  102. package/dist/cjs/memory/sqlite/index.js +5 -0
  103. package/dist/cjs/memory/sqlite/memory-adapter.d.ts +58 -0
  104. package/dist/cjs/memory/sqlite/memory-adapter.d.ts.map +1 -0
  105. package/dist/cjs/memory/sqlite/memory-adapter.js +336 -0
  106. package/dist/cjs/memory/sqlite/schema.d.ts +4 -0
  107. package/dist/cjs/memory/sqlite/schema.d.ts.map +1 -0
  108. package/dist/cjs/memory/sqlite/schema.js +91 -0
  109. package/dist/cjs/memory/supabase/index.d.ts +7 -0
  110. package/dist/cjs/memory/supabase/index.d.ts.map +1 -0
  111. package/dist/cjs/memory/supabase/index.js +8 -0
  112. package/dist/cjs/memory/supabase/memory-adapter.d.ts +67 -0
  113. package/dist/cjs/memory/supabase/memory-adapter.d.ts.map +1 -0
  114. package/dist/cjs/memory/supabase/memory-adapter.js +335 -0
  115. package/dist/cjs/memory/supabase/semantic.d.ts +44 -0
  116. package/dist/cjs/memory/supabase/semantic.d.ts.map +1 -0
  117. package/dist/cjs/memory/supabase/semantic.js +72 -0
  118. package/dist/cjs/memory/types.d.ts +231 -0
  119. package/dist/cjs/memory/types.d.ts.map +1 -0
  120. package/dist/cjs/memory/types.js +12 -0
  121. package/dist/cjs/persona.d.ts +326 -0
  122. package/dist/cjs/persona.d.ts.map +1 -0
  123. package/dist/cjs/persona.js +824 -0
  124. package/dist/cjs/types.d.ts +263 -0
  125. package/dist/cjs/types.d.ts.map +1 -0
  126. package/dist/cjs/types.js +15 -0
  127. package/dist/cjs/world/client.d.ts +36 -0
  128. package/dist/cjs/world/client.d.ts.map +1 -0
  129. package/dist/cjs/world/client.js +59 -0
  130. package/dist/cjs/world/errors.d.ts +9 -0
  131. package/dist/cjs/world/errors.d.ts.map +1 -0
  132. package/dist/cjs/world/errors.js +15 -0
  133. package/dist/cjs/world/index.d.ts +10 -0
  134. package/dist/cjs/world/index.d.ts.map +1 -0
  135. package/dist/cjs/world/index.js +16 -0
  136. package/dist/cjs/world/types.d.ts +101 -0
  137. package/dist/cjs/world/types.d.ts.map +1 -0
  138. package/dist/cjs/world/types.js +8 -0
  139. package/dist/cjs/world/village.d.ts +75 -0
  140. package/dist/cjs/world/village.d.ts.map +1 -0
  141. package/dist/cjs/world/village.js +278 -0
  142. package/dist/cjs/world/world-persona.d.ts +182 -0
  143. package/dist/cjs/world/world-persona.d.ts.map +1 -0
  144. package/dist/cjs/world/world-persona.js +192 -0
  145. package/dist/cjs/world/world.d.ts +41 -0
  146. package/dist/cjs/world/world.d.ts.map +1 -0
  147. package/dist/cjs/world/world.js +91 -0
  148. package/dist/esm/api-client.d.ts +23 -0
  149. package/dist/esm/api-client.d.ts.map +1 -0
  150. package/dist/esm/api-client.js +48 -0
  151. package/dist/esm/defaults/index.d.ts +8 -0
  152. package/dist/esm/defaults/index.d.ts.map +1 -0
  153. package/dist/esm/defaults/index.js +23 -0
  154. package/dist/esm/defaults/persona.json +17 -0
  155. package/dist/esm/embedding/cloudflare.d.ts +15 -0
  156. package/dist/esm/embedding/cloudflare.d.ts.map +1 -0
  157. package/dist/esm/embedding/cloudflare.js +13 -0
  158. package/dist/esm/embedding/cohere.d.ts +8 -0
  159. package/dist/esm/embedding/cohere.d.ts.map +1 -0
  160. package/dist/esm/embedding/cohere.js +28 -0
  161. package/dist/esm/embedding/index.d.ts +9 -0
  162. package/dist/esm/embedding/index.d.ts.map +1 -0
  163. package/dist/esm/embedding/index.js +4 -0
  164. package/dist/esm/embedding/local.d.ts +6 -0
  165. package/dist/esm/embedding/local.d.ts.map +1 -0
  166. package/dist/esm/embedding/local.js +25 -0
  167. package/dist/esm/embedding/openai.d.ts +9 -0
  168. package/dist/esm/embedding/openai.d.ts.map +1 -0
  169. package/dist/esm/embedding/openai.js +23 -0
  170. package/dist/esm/errors.d.ts +17 -0
  171. package/dist/esm/errors.d.ts.map +1 -0
  172. package/dist/esm/errors.js +17 -0
  173. package/dist/esm/events/console.d.ts +25 -0
  174. package/dist/esm/events/console.d.ts.map +1 -0
  175. package/dist/esm/events/console.js +37 -0
  176. package/dist/esm/events/types.d.ts +28 -0
  177. package/dist/esm/events/types.d.ts.map +1 -0
  178. package/dist/esm/events/types.js +12 -0
  179. package/dist/esm/events/webhook.d.ts +30 -0
  180. package/dist/esm/events/webhook.d.ts.map +1 -0
  181. package/dist/esm/events/webhook.js +75 -0
  182. package/dist/esm/generate/persona.d.ts +16 -0
  183. package/dist/esm/generate/persona.d.ts.map +1 -0
  184. package/dist/esm/generate/persona.js +39 -0
  185. package/dist/esm/generate/prompt.d.ts +7 -0
  186. package/dist/esm/generate/prompt.d.ts.map +1 -0
  187. package/dist/esm/generate/prompt.js +38 -0
  188. package/dist/esm/generate/schema.d.ts +32 -0
  189. package/dist/esm/generate/schema.d.ts.map +1 -0
  190. package/dist/esm/generate/schema.js +51 -0
  191. package/dist/esm/generated/index.d.ts +2 -0
  192. package/dist/esm/generated/index.d.ts.map +1 -0
  193. package/dist/esm/generated/index.js +1 -0
  194. package/dist/esm/index.d.ts +66 -0
  195. package/dist/esm/index.d.ts.map +1 -0
  196. package/dist/esm/index.js +49 -0
  197. package/dist/esm/llm/adapter.d.ts +61 -0
  198. package/dist/esm/llm/adapter.d.ts.map +1 -0
  199. package/dist/esm/llm/adapter.js +1 -0
  200. package/dist/esm/llm/resolve.d.ts +28 -0
  201. package/dist/esm/llm/resolve.d.ts.map +1 -0
  202. package/dist/esm/llm/resolve.js +17 -0
  203. package/dist/esm/llm/schema.d.ts +60 -0
  204. package/dist/esm/llm/schema.d.ts.map +1 -0
  205. package/dist/esm/llm/schema.js +69 -0
  206. package/dist/esm/llm/types.d.ts +24 -0
  207. package/dist/esm/llm/types.d.ts.map +1 -0
  208. package/dist/esm/llm/types.js +1 -0
  209. package/dist/esm/llm/vercel-ai/adapter.d.ts +29 -0
  210. package/dist/esm/llm/vercel-ai/adapter.d.ts.map +1 -0
  211. package/dist/esm/llm/vercel-ai/adapter.js +196 -0
  212. package/dist/esm/llm/vercel-ai/config.d.ts +9 -0
  213. package/dist/esm/llm/vercel-ai/config.d.ts.map +1 -0
  214. package/dist/esm/llm/vercel-ai/config.js +1 -0
  215. package/dist/esm/llm/vercel-ai/index.d.ts +9 -0
  216. package/dist/esm/llm/vercel-ai/index.d.ts.map +1 -0
  217. package/dist/esm/llm/vercel-ai/index.js +8 -0
  218. package/dist/esm/memory/cloudflare/index.d.ts +3 -0
  219. package/dist/esm/memory/cloudflare/index.d.ts.map +1 -0
  220. package/dist/esm/memory/cloudflare/index.js +1 -0
  221. package/dist/esm/memory/cloudflare/vectorize.d.ts +62 -0
  222. package/dist/esm/memory/cloudflare/vectorize.d.ts.map +1 -0
  223. package/dist/esm/memory/cloudflare/vectorize.js +51 -0
  224. package/dist/esm/memory/in-memory-semantic.d.ts +16 -0
  225. package/dist/esm/memory/in-memory-semantic.d.ts.map +1 -0
  226. package/dist/esm/memory/in-memory-semantic.js +53 -0
  227. package/dist/esm/memory/in-memory.d.ts +46 -0
  228. package/dist/esm/memory/in-memory.d.ts.map +1 -0
  229. package/dist/esm/memory/in-memory.js +111 -0
  230. package/dist/esm/memory/pinecone/index.d.ts +7 -0
  231. package/dist/esm/memory/pinecone/index.d.ts.map +1 -0
  232. package/dist/esm/memory/pinecone/index.js +3 -0
  233. package/dist/esm/memory/pinecone/memory-adapter.d.ts +62 -0
  234. package/dist/esm/memory/pinecone/memory-adapter.d.ts.map +1 -0
  235. package/dist/esm/memory/pinecone/memory-adapter.js +216 -0
  236. package/dist/esm/memory/pinecone/semantic.d.ts +44 -0
  237. package/dist/esm/memory/pinecone/semantic.d.ts.map +1 -0
  238. package/dist/esm/memory/pinecone/semantic.js +86 -0
  239. package/dist/esm/memory/recall.d.ts +58 -0
  240. package/dist/esm/memory/recall.d.ts.map +1 -0
  241. package/dist/esm/memory/recall.js +215 -0
  242. package/dist/esm/memory/semantic.d.ts +24 -0
  243. package/dist/esm/memory/semantic.d.ts.map +1 -0
  244. package/dist/esm/memory/semantic.js +1 -0
  245. package/dist/esm/memory/sqlite/index.d.ts +3 -0
  246. package/dist/esm/memory/sqlite/index.d.ts.map +1 -0
  247. package/dist/esm/memory/sqlite/index.js +1 -0
  248. package/dist/esm/memory/sqlite/memory-adapter.d.ts +58 -0
  249. package/dist/esm/memory/sqlite/memory-adapter.d.ts.map +1 -0
  250. package/dist/esm/memory/sqlite/memory-adapter.js +296 -0
  251. package/dist/esm/memory/sqlite/schema.d.ts +4 -0
  252. package/dist/esm/memory/sqlite/schema.d.ts.map +1 -0
  253. package/dist/esm/memory/sqlite/schema.js +86 -0
  254. package/dist/esm/memory/supabase/index.d.ts +7 -0
  255. package/dist/esm/memory/supabase/index.d.ts.map +1 -0
  256. package/dist/esm/memory/supabase/index.js +3 -0
  257. package/dist/esm/memory/supabase/memory-adapter.d.ts +67 -0
  258. package/dist/esm/memory/supabase/memory-adapter.d.ts.map +1 -0
  259. package/dist/esm/memory/supabase/memory-adapter.js +331 -0
  260. package/dist/esm/memory/supabase/semantic.d.ts +44 -0
  261. package/dist/esm/memory/supabase/semantic.d.ts.map +1 -0
  262. package/dist/esm/memory/supabase/semantic.js +68 -0
  263. package/dist/esm/memory/types.d.ts +231 -0
  264. package/dist/esm/memory/types.d.ts.map +1 -0
  265. package/dist/esm/memory/types.js +9 -0
  266. package/dist/esm/persona.d.ts +326 -0
  267. package/dist/esm/persona.d.ts.map +1 -0
  268. package/dist/esm/persona.js +787 -0
  269. package/dist/esm/types.d.ts +263 -0
  270. package/dist/esm/types.d.ts.map +1 -0
  271. package/dist/esm/types.js +11 -0
  272. package/dist/esm/world/client.d.ts +36 -0
  273. package/dist/esm/world/client.d.ts.map +1 -0
  274. package/dist/esm/world/client.js +52 -0
  275. package/dist/esm/world/errors.d.ts +9 -0
  276. package/dist/esm/world/errors.d.ts.map +1 -0
  277. package/dist/esm/world/errors.js +11 -0
  278. package/dist/esm/world/index.d.ts +10 -0
  279. package/dist/esm/world/index.d.ts.map +1 -0
  280. package/dist/esm/world/index.js +8 -0
  281. package/dist/esm/world/types.d.ts +101 -0
  282. package/dist/esm/world/types.d.ts.map +1 -0
  283. package/dist/esm/world/types.js +7 -0
  284. package/dist/esm/world/village.d.ts +75 -0
  285. package/dist/esm/world/village.d.ts.map +1 -0
  286. package/dist/esm/world/village.js +274 -0
  287. package/dist/esm/world/world-persona.d.ts +182 -0
  288. package/dist/esm/world/world-persona.d.ts.map +1 -0
  289. package/dist/esm/world/world-persona.js +188 -0
  290. package/dist/esm/world/world.d.ts +41 -0
  291. package/dist/esm/world/world.d.ts.map +1 -0
  292. package/dist/esm/world/world.js +87 -0
  293. package/package.json +207 -0
@@ -0,0 +1,86 @@
1
+ export const SCHEMA_VERSION = 2;
2
+ export function createSchema(embeddingDim) {
3
+ return `
4
+ CREATE TABLE IF NOT EXISTS _meta (
5
+ key TEXT PRIMARY KEY,
6
+ value TEXT NOT NULL
7
+ );
8
+
9
+ INSERT OR IGNORE INTO _meta (key, value) VALUES ('schema_version', '${SCHEMA_VERSION}');
10
+
11
+ CREATE TABLE IF NOT EXISTS episodes (
12
+ id TEXT PRIMARY KEY,
13
+ timestamp INTEGER NOT NULL,
14
+ source_entity TEXT,
15
+ context TEXT,
16
+ appraisal TEXT NOT NULL,
17
+ emotion_v REAL NOT NULL,
18
+ emotion_a REAL NOT NULL,
19
+ emotion_d REAL NOT NULL,
20
+ intensity REAL NOT NULL,
21
+ importance REAL NOT NULL
22
+ );
23
+
24
+ CREATE INDEX IF NOT EXISTS idx_episodes_source ON episodes(source_entity);
25
+ CREATE INDEX IF NOT EXISTS idx_episodes_timestamp ON episodes(timestamp DESC);
26
+ CREATE INDEX IF NOT EXISTS idx_episodes_importance ON episodes(importance);
27
+
28
+ CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(
29
+ id TEXT PRIMARY KEY,
30
+ embedding FLOAT[${embeddingDim}]
31
+ );
32
+
33
+ CREATE TABLE IF NOT EXISTS reflections (
34
+ id TEXT PRIMARY KEY,
35
+ timestamp INTEGER NOT NULL,
36
+ source_entity TEXT,
37
+ content TEXT NOT NULL,
38
+ trigger_type TEXT NOT NULL,
39
+ emotion_v REAL NOT NULL,
40
+ emotion_a REAL NOT NULL,
41
+ emotion_d REAL NOT NULL
42
+ );
43
+
44
+ CREATE INDEX IF NOT EXISTS idx_reflections_source ON reflections(source_entity);
45
+ `;
46
+ }
47
+ export function createSchemaWithoutVec() {
48
+ return `
49
+ CREATE TABLE IF NOT EXISTS _meta (
50
+ key TEXT PRIMARY KEY,
51
+ value TEXT NOT NULL
52
+ );
53
+
54
+ INSERT OR IGNORE INTO _meta (key, value) VALUES ('schema_version', '${SCHEMA_VERSION}');
55
+
56
+ CREATE TABLE IF NOT EXISTS episodes (
57
+ id TEXT PRIMARY KEY,
58
+ timestamp INTEGER NOT NULL,
59
+ source_entity TEXT,
60
+ context TEXT,
61
+ appraisal TEXT NOT NULL,
62
+ emotion_v REAL NOT NULL,
63
+ emotion_a REAL NOT NULL,
64
+ emotion_d REAL NOT NULL,
65
+ intensity REAL NOT NULL,
66
+ importance REAL NOT NULL
67
+ );
68
+
69
+ CREATE INDEX IF NOT EXISTS idx_episodes_source ON episodes(source_entity);
70
+ CREATE INDEX IF NOT EXISTS idx_episodes_timestamp ON episodes(timestamp DESC);
71
+ CREATE INDEX IF NOT EXISTS idx_episodes_importance ON episodes(importance);
72
+
73
+ CREATE TABLE IF NOT EXISTS reflections (
74
+ id TEXT PRIMARY KEY,
75
+ timestamp INTEGER NOT NULL,
76
+ source_entity TEXT,
77
+ content TEXT NOT NULL,
78
+ trigger_type TEXT NOT NULL,
79
+ emotion_v REAL NOT NULL,
80
+ emotion_a REAL NOT NULL,
81
+ emotion_d REAL NOT NULL
82
+ );
83
+
84
+ CREATE INDEX IF NOT EXISTS idx_reflections_source ON reflections(source_entity);
85
+ `;
86
+ }
@@ -0,0 +1,7 @@
1
+ export { SupabaseSemanticMemory } from './semantic';
2
+ export type { SupabaseSemanticMemoryOptions } from './semantic';
3
+ /** @deprecated Use SupabaseSemanticMemory */
4
+ export { SupabaseMemoryAdapter } from './memory-adapter';
5
+ /** @deprecated Use SupabaseSemanticMemoryOptions */
6
+ export type { SupabaseMemoryAdapterOptions } from './memory-adapter';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/memory/supabase/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,3 @@
1
+ export { SupabaseSemanticMemory } from './semantic';
2
+ /** @deprecated Use SupabaseSemanticMemory */
3
+ export { SupabaseMemoryAdapter } from './memory-adapter';
@@ -0,0 +1,67 @@
1
+ import type { MemoryAdapter, Episode, Reflection, RecallQuery, SemanticRecallOptions, EpisodePatch, CountQuery, EmbeddingAdapter } from '../types';
2
+ export interface SupabaseMemoryAdapterOptions {
3
+ /** Supabase project URL. */
4
+ supabaseUrl: string;
5
+ /** Supabase anon or service-role key. */
6
+ supabaseKey: string;
7
+ /** Persona/world ID for RLS scoping. */
8
+ personaId: string;
9
+ /** RLS strategy. Default: 'application'. */
10
+ rlsStrategy?: 'application' | 'jwt';
11
+ /** Enable vector search. When absent, semanticRecall falls back to text recall. */
12
+ vector?: {
13
+ /** Embedding provider (embed function + dimension). */
14
+ embedding: EmbeddingAdapter;
15
+ /** Match threshold for pgvector similarity. Default: 0.7. */
16
+ matchThreshold?: number;
17
+ };
18
+ }
19
+ /**
20
+ * Supabase-backed MemoryAdapter with optional pgvector semantic search.
21
+ *
22
+ * Combines episode/reflection RDB storage with optional pgvector embeddings
23
+ * into a single unified MemoryAdapter interface.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // RDB only (no vector search)
28
+ * const adapter = new SupabaseMemoryAdapter({
29
+ * supabaseUrl: process.env.SUPABASE_URL!,
30
+ * supabaseKey: process.env.SUPABASE_KEY!,
31
+ * personaId: 'world-123',
32
+ * });
33
+ *
34
+ * // With vector search
35
+ * const adapter = new SupabaseMemoryAdapter({
36
+ * supabaseUrl: process.env.SUPABASE_URL!,
37
+ * supabaseKey: process.env.SUPABASE_KEY!,
38
+ * personaId: 'world-123',
39
+ * vector: {
40
+ * embedding: openaiEmbedding({ apiKey: '...' }),
41
+ * matchThreshold: 0.75,
42
+ * },
43
+ * });
44
+ * ```
45
+ */
46
+ export declare class SupabaseMemoryAdapter implements MemoryAdapter {
47
+ private client;
48
+ private personaId;
49
+ private rlsStrategy;
50
+ private vectorEnabled;
51
+ private embedding?;
52
+ private matchThreshold;
53
+ constructor(options: SupabaseMemoryAdapterOptions);
54
+ private setPersonaContext;
55
+ saveEpisode(episode: Episode): Promise<void>;
56
+ recall(query: RecallQuery): Promise<Episode[]>;
57
+ saveReflection(reflection: Reflection): Promise<void>;
58
+ getReflections(sourceEntity?: string): Promise<Reflection[]>;
59
+ semanticRecall(query: string, options?: SemanticRecallOptions): Promise<Episode[]>;
60
+ getByIds(ids: string[]): Promise<Episode[]>;
61
+ countEpisodes(query: CountQuery): Promise<number>;
62
+ updateEpisode(id: string, patch: EpisodePatch): Promise<void>;
63
+ deleteEpisode(id: string): Promise<void>;
64
+ expireEpisodes(before: number, minImportance?: number): Promise<number>;
65
+ private indexEmbedding;
66
+ }
67
+ //# sourceMappingURL=memory-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-adapter.d.ts","sourceRoot":"","sources":["../../../../src/memory/supabase/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,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,aAAa,GAAG,KAAK,CAAC;IACpC,mFAAmF;IACnF,MAAM,CAAC,EAAE;QACP,uDAAuD;QACvD,SAAS,EAAE,gBAAgB,CAAC;QAC5B,6DAA6D;QAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAmB;IACrC,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE,4BAA4B;YASnC,iBAAiB;IAazB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC5C,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAgC9C,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrD,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAmB5D,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,OAAO,EAAE,CAAC;IA+Bf,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAY3C,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBjD,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB7D,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxC,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;YAwCJ,cAAc;CAqB7B"}
@@ -0,0 +1,331 @@
1
+ import { createClient } from '@supabase/supabase-js';
2
+ /**
3
+ * Supabase-backed MemoryAdapter with optional pgvector semantic search.
4
+ *
5
+ * Combines episode/reflection RDB storage with optional pgvector embeddings
6
+ * into a single unified MemoryAdapter interface.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // RDB only (no vector search)
11
+ * const adapter = new SupabaseMemoryAdapter({
12
+ * supabaseUrl: process.env.SUPABASE_URL!,
13
+ * supabaseKey: process.env.SUPABASE_KEY!,
14
+ * personaId: 'world-123',
15
+ * });
16
+ *
17
+ * // With vector search
18
+ * const adapter = new SupabaseMemoryAdapter({
19
+ * supabaseUrl: process.env.SUPABASE_URL!,
20
+ * supabaseKey: process.env.SUPABASE_KEY!,
21
+ * personaId: 'world-123',
22
+ * vector: {
23
+ * embedding: openaiEmbedding({ apiKey: '...' }),
24
+ * matchThreshold: 0.75,
25
+ * },
26
+ * });
27
+ * ```
28
+ */
29
+ export class SupabaseMemoryAdapter {
30
+ constructor(options) {
31
+ this.client = createClient(options.supabaseUrl, options.supabaseKey);
32
+ this.personaId = options.personaId;
33
+ this.rlsStrategy = options.rlsStrategy ?? 'application';
34
+ this.vectorEnabled = !!options.vector;
35
+ this.embedding = options.vector?.embedding;
36
+ this.matchThreshold = options.vector?.matchThreshold ?? 0.7;
37
+ }
38
+ async setPersonaContext() {
39
+ if (this.rlsStrategy === 'application') {
40
+ await this.client
41
+ .rpc('set_config', {
42
+ setting: 'app.current_persona_id',
43
+ value: this.personaId,
44
+ })
45
+ .throwOnError();
46
+ }
47
+ }
48
+ // ── Required methods ──
49
+ async saveEpisode(episode) {
50
+ await this.setPersonaContext();
51
+ const { error } = await this.client.from('episodes').upsert({
52
+ id: episode.id,
53
+ persona_id: this.personaId,
54
+ source_entity: episode.sourceEntity ?? null,
55
+ context: episode.context ?? null,
56
+ timestamp: episode.timestamp,
57
+ importance: episode.importance,
58
+ intensity: episode.intensity,
59
+ vad_v: episode.emotionSnapshot.V,
60
+ vad_a: episode.emotionSnapshot.A,
61
+ vad_d: episode.emotionSnapshot.D,
62
+ appraisal: episode.appraisal,
63
+ });
64
+ if (error)
65
+ throw new Error(`saveEpisode failed: ${error.message}`);
66
+ // Auto-index embedding when vector is enabled
67
+ if (this.vectorEnabled && this.embedding) {
68
+ try {
69
+ const text = episode.context ?? episode.sourceEntity ?? '';
70
+ if (text) {
71
+ const embedding = await this.embedding.embed(text);
72
+ await this.indexEmbedding(episode.id, embedding, {
73
+ type: 'episode',
74
+ sourceEntity: episode.sourceEntity,
75
+ timestamp: episode.timestamp,
76
+ importance: episode.importance,
77
+ });
78
+ }
79
+ }
80
+ catch {
81
+ // Best-effort: vector indexing failure doesn't block episode save.
82
+ }
83
+ }
84
+ }
85
+ async recall(query) {
86
+ await this.setPersonaContext();
87
+ const limit = query.limit ?? 10;
88
+ let q = this.client
89
+ .from('episodes')
90
+ .select('*')
91
+ .eq('persona_id', this.personaId);
92
+ if (query.sourceEntity)
93
+ q = q.eq('source_entity', query.sourceEntity);
94
+ if (query.context)
95
+ q = q.ilike('context', `%${query.context}%`);
96
+ if (query.minImportance !== undefined)
97
+ q = q.gte('importance', query.minImportance);
98
+ if (query.valenceRange) {
99
+ q = q
100
+ .gte('vad_v', query.valenceRange[0])
101
+ .lte('vad_v', query.valenceRange[1]);
102
+ }
103
+ if (query.timeRange) {
104
+ q = q
105
+ .gte('timestamp', query.timeRange[0])
106
+ .lte('timestamp', query.timeRange[1]);
107
+ }
108
+ const { data, error } = await q
109
+ .order('timestamp', { ascending: false })
110
+ .limit(limit);
111
+ if (error)
112
+ throw new Error(`recall failed: ${error.message}`);
113
+ return (data ?? []).map(rowToEpisode);
114
+ }
115
+ async saveReflection(reflection) {
116
+ await this.setPersonaContext();
117
+ const { error } = await this.client.from('reflections').upsert({
118
+ id: reflection.id,
119
+ persona_id: this.personaId,
120
+ source_entity: reflection.sourceEntity ?? null,
121
+ content: reflection.content,
122
+ trigger: reflection.trigger,
123
+ timestamp: reflection.timestamp,
124
+ vad_v: reflection.emotionSnapshot.V,
125
+ vad_a: reflection.emotionSnapshot.A,
126
+ vad_d: reflection.emotionSnapshot.D,
127
+ });
128
+ if (error)
129
+ throw new Error(`saveReflection failed: ${error.message}`);
130
+ }
131
+ async getReflections(sourceEntity) {
132
+ await this.setPersonaContext();
133
+ const maxRows = 100;
134
+ let q = this.client
135
+ .from('reflections')
136
+ .select('*')
137
+ .eq('persona_id', this.personaId)
138
+ .order('timestamp', { ascending: false });
139
+ if (sourceEntity)
140
+ q = q.eq('source_entity', sourceEntity);
141
+ const { data, error } = await q.limit(maxRows);
142
+ if (error)
143
+ throw new Error(`getReflections failed: ${error.message}`);
144
+ return (data ?? []).map(rowToReflection);
145
+ }
146
+ // ── Optional methods ──
147
+ async semanticRecall(query, options) {
148
+ if (!this.vectorEnabled || !this.embedding) {
149
+ // Fallback to text-based recall
150
+ return this.recall({ context: query, limit: options?.topK ?? 10 });
151
+ }
152
+ await this.setPersonaContext();
153
+ const embedding = await this.embedding.embed(query);
154
+ const topK = options?.topK ?? 5;
155
+ const { data, error } = await this.client.rpc('match_embeddings', {
156
+ query_embedding: embedding,
157
+ match_threshold: this.matchThreshold,
158
+ match_count: topK,
159
+ filter_persona_id: this.personaId,
160
+ filter_type: 'episode',
161
+ filter_source_entity: options?.filter?.sourceEntity ?? null,
162
+ filter_min_importance: options?.filter?.minImportance ?? null,
163
+ });
164
+ if (error)
165
+ throw new Error(`semanticRecall failed: ${error.message}`);
166
+ const matchedIds = (data ?? []).map((row) => row.id);
167
+ if (matchedIds.length === 0)
168
+ return [];
169
+ // Fetch full episodes for matched IDs
170
+ return this.getByIds(matchedIds);
171
+ }
172
+ async getByIds(ids) {
173
+ if (ids.length === 0)
174
+ return [];
175
+ await this.setPersonaContext();
176
+ const { data, error } = await this.client
177
+ .from('episodes')
178
+ .select('*')
179
+ .eq('persona_id', this.personaId)
180
+ .in('id', ids);
181
+ if (error)
182
+ throw new Error(`getByIds failed: ${error.message}`);
183
+ return (data ?? []).map(rowToEpisode);
184
+ }
185
+ async countEpisodes(query) {
186
+ await this.setPersonaContext();
187
+ let q = this.client
188
+ .from('episodes')
189
+ .select('*', { count: 'exact', head: true })
190
+ .eq('persona_id', this.personaId);
191
+ if (query.sourceEntity)
192
+ q = q.eq('source_entity', query.sourceEntity);
193
+ if (query.context)
194
+ q = q.ilike('context', `%${query.context}%`);
195
+ if (query.timeRange) {
196
+ q = q
197
+ .gte('timestamp', query.timeRange[0])
198
+ .lte('timestamp', query.timeRange[1]);
199
+ }
200
+ const { count, error } = await q;
201
+ if (error)
202
+ throw new Error(`countEpisodes failed: ${error.message}`);
203
+ return count ?? 0;
204
+ }
205
+ async updateEpisode(id, patch) {
206
+ await this.setPersonaContext();
207
+ const updates = {};
208
+ if (patch.importance !== undefined)
209
+ updates.importance = patch.importance;
210
+ if (patch.intensity !== undefined)
211
+ updates.intensity = patch.intensity;
212
+ if (patch.emotionSnapshot !== undefined) {
213
+ updates.vad_v = patch.emotionSnapshot.V;
214
+ updates.vad_a = patch.emotionSnapshot.A;
215
+ updates.vad_d = patch.emotionSnapshot.D;
216
+ }
217
+ if (Object.keys(updates).length === 0)
218
+ return;
219
+ const { error } = await this.client
220
+ .from('episodes')
221
+ .update(updates)
222
+ .eq('id', id)
223
+ .eq('persona_id', this.personaId);
224
+ if (error)
225
+ throw new Error(`updateEpisode failed: ${error.message}`);
226
+ }
227
+ async deleteEpisode(id) {
228
+ await this.setPersonaContext();
229
+ const { error } = await this.client
230
+ .from('episodes')
231
+ .delete()
232
+ .eq('id', id)
233
+ .eq('persona_id', this.personaId);
234
+ if (error)
235
+ throw new Error(`deleteEpisode failed: ${error.message}`);
236
+ // Best-effort: clean up embedding
237
+ if (this.vectorEnabled) {
238
+ try {
239
+ await this.client
240
+ .from('memory_embeddings')
241
+ .delete()
242
+ .eq('id', id)
243
+ .eq('persona_id', this.personaId);
244
+ }
245
+ catch {
246
+ // Non-fatal: vector cleanup failure is acceptable.
247
+ }
248
+ }
249
+ }
250
+ async expireEpisodes(before, minImportance) {
251
+ await this.setPersonaContext();
252
+ const threshold = minImportance ?? 0;
253
+ // Count first, then delete (Supabase delete doesn't return count reliably)
254
+ const { count, error: countErr } = await this.client
255
+ .from('episodes')
256
+ .select('*', { count: 'exact', head: true })
257
+ .eq('persona_id', this.personaId)
258
+ .lt('timestamp', before)
259
+ .lt('importance', threshold);
260
+ if (countErr)
261
+ throw new Error(`expireEpisodes count failed: ${countErr.message}`);
262
+ const expired = count ?? 0;
263
+ if (expired === 0)
264
+ return 0;
265
+ const { error } = await this.client
266
+ .from('episodes')
267
+ .delete()
268
+ .eq('persona_id', this.personaId)
269
+ .lt('timestamp', before)
270
+ .lt('importance', threshold);
271
+ if (error)
272
+ throw new Error(`expireEpisodes failed: ${error.message}`);
273
+ // Best-effort: clean up orphaned embeddings
274
+ if (this.vectorEnabled) {
275
+ try {
276
+ await this.client.rpc('cleanup_orphaned_embeddings', {
277
+ filter_persona_id: this.personaId,
278
+ });
279
+ }
280
+ catch {
281
+ // Non-fatal: orphan cleanup failure is acceptable.
282
+ }
283
+ }
284
+ return expired;
285
+ }
286
+ // ── Utility ──
287
+ async indexEmbedding(id, embedding, metadata) {
288
+ const { error } = await this.client.from('memory_embeddings').upsert({
289
+ id,
290
+ persona_id: this.personaId,
291
+ type: metadata.type,
292
+ source_entity: metadata.sourceEntity ?? null,
293
+ timestamp: metadata.timestamp,
294
+ importance: metadata.importance ?? 0,
295
+ embedding,
296
+ });
297
+ if (error)
298
+ throw new Error(`indexEmbedding failed: ${error.message}`);
299
+ }
300
+ }
301
+ // ── Row mappers ──
302
+ function rowToEpisode(row) {
303
+ return {
304
+ id: row.id,
305
+ timestamp: row.timestamp,
306
+ sourceEntity: row.source_entity || undefined,
307
+ context: row.context || undefined,
308
+ appraisal: row.appraisal,
309
+ emotionSnapshot: {
310
+ V: row.vad_v,
311
+ A: row.vad_a,
312
+ D: row.vad_d,
313
+ },
314
+ intensity: row.intensity,
315
+ importance: row.importance,
316
+ };
317
+ }
318
+ function rowToReflection(row) {
319
+ return {
320
+ id: row.id,
321
+ timestamp: row.timestamp,
322
+ sourceEntity: row.source_entity || undefined,
323
+ content: row.content,
324
+ trigger: row.trigger,
325
+ emotionSnapshot: {
326
+ V: row.vad_v,
327
+ A: row.vad_a,
328
+ D: row.vad_d,
329
+ },
330
+ };
331
+ }
@@ -0,0 +1,44 @@
1
+ import type { EmbeddingAdapter } from '../types';
2
+ import type { SemanticMemory, SearchOptions, SearchResult } from '../semantic';
3
+ export interface SupabaseSemanticMemoryOptions {
4
+ /** Supabase project URL. */
5
+ supabaseUrl: string;
6
+ /** Supabase anon or service-role key. */
7
+ supabaseKey: string;
8
+ /** Embedding provider (embed function + dimension). */
9
+ embedding: EmbeddingAdapter;
10
+ /** Match threshold for pgvector similarity. Default: 0.7. */
11
+ matchThreshold?: number;
12
+ /** Table name for embeddings. Default: 'memory_embeddings'. */
13
+ tableName?: string;
14
+ /** RPC function name for similarity search. Default: 'match_semantic_memory'. */
15
+ matchFunction?: string;
16
+ }
17
+ /**
18
+ * Supabase pgvector-backed SemanticMemory.
19
+ *
20
+ * Requires a table with columns: id (text PK), text (text), embedding (vector),
21
+ * metadata (jsonb), and an RPC function for similarity search.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const memory = new SupabaseSemanticMemory({
26
+ * supabaseUrl: process.env.SUPABASE_URL!,
27
+ * supabaseKey: process.env.SUPABASE_KEY!,
28
+ * embedding: openaiEmbedding({ apiKey: '...' }),
29
+ * });
30
+ * await memory.store('user likes coffee', { userId: '123' });
31
+ * ```
32
+ */
33
+ export declare class SupabaseSemanticMemory implements SemanticMemory {
34
+ private client;
35
+ private embedding;
36
+ private matchThreshold;
37
+ private tableName;
38
+ private matchFunction;
39
+ constructor(options: SupabaseSemanticMemoryOptions);
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/supabase/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,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,CAAC;IAC5B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;gBAElB,OAAO,EAAE,6BAA6B;IAQ5C,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,MAAM,CAAC;IAcZ,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IAwBpB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ3C"}
@@ -0,0 +1,68 @@
1
+ import { createClient } from '@supabase/supabase-js';
2
+ /**
3
+ * Supabase pgvector-backed SemanticMemory.
4
+ *
5
+ * Requires a table with columns: id (text PK), text (text), embedding (vector),
6
+ * metadata (jsonb), and an RPC function for similarity search.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const memory = new SupabaseSemanticMemory({
11
+ * supabaseUrl: process.env.SUPABASE_URL!,
12
+ * supabaseKey: process.env.SUPABASE_KEY!,
13
+ * embedding: openaiEmbedding({ apiKey: '...' }),
14
+ * });
15
+ * await memory.store('user likes coffee', { userId: '123' });
16
+ * ```
17
+ */
18
+ export class SupabaseSemanticMemory {
19
+ constructor(options) {
20
+ this.client = createClient(options.supabaseUrl, options.supabaseKey);
21
+ this.embedding = options.embedding;
22
+ this.matchThreshold = options.matchThreshold ?? 0.7;
23
+ this.tableName = options.tableName ?? 'memory_embeddings';
24
+ this.matchFunction = options.matchFunction ?? 'match_semantic_memory';
25
+ }
26
+ async store(text, metadata = {}) {
27
+ const id = crypto.randomUUID();
28
+ const vector = await this.embedding.embed(text);
29
+ const { error } = await this.client.from(this.tableName).upsert({
30
+ id,
31
+ text,
32
+ embedding: vector,
33
+ metadata,
34
+ });
35
+ if (error)
36
+ throw new Error(`store failed: ${error.message}`);
37
+ return id;
38
+ }
39
+ async search(query, options = {}) {
40
+ const topK = options.topK ?? 5;
41
+ const threshold = options.scoreThreshold ?? this.matchThreshold;
42
+ const vector = await this.embedding.embed(query);
43
+ const { data, error } = await this.client.rpc(this.matchFunction, {
44
+ query_embedding: vector,
45
+ match_threshold: threshold,
46
+ match_count: topK,
47
+ filter_metadata: options.filter ?? null,
48
+ });
49
+ if (error)
50
+ throw new Error(`search failed: ${error.message}`);
51
+ return (data ?? []).map((row) => ({
52
+ id: row.id,
53
+ text: row.text,
54
+ score: row.similarity,
55
+ metadata: row.metadata ?? {},
56
+ }));
57
+ }
58
+ async delete(ids) {
59
+ if (ids.length === 0)
60
+ return;
61
+ const { error } = await this.client
62
+ .from(this.tableName)
63
+ .delete()
64
+ .in('id', ids);
65
+ if (error)
66
+ throw new Error(`delete failed: ${error.message}`);
67
+ }
68
+ }