From c1aba358843efca0b1ff6273bd753cc45e25aa2a Mon Sep 17 00:00:00 2001 From: Saket Aryan Date: Fri, 28 Feb 2025 21:43:51 +0530 Subject: [PATCH] Mem0 TS Spec/Docs Update (#2275) --- docs/examples/ai_companion_js.mdx | 4 +- .../features/custom-prompts.mdx | 6 +- docs/open-source-typescript/quickstart.mdx | 140 ++++++++++++------ docs/quickstart.mdx | 4 +- mem0-ts/README.md | 3 + mem0-ts/package.json | 2 +- mem0-ts/src/oss/src/index.ts | 3 + mem0-ts/src/oss/src/memory/index.ts | 47 +++--- mem0-ts/src/oss/src/memory/memory.types.ts | 26 ++++ 9 files changed, 157 insertions(+), 78 deletions(-) create mode 100644 mem0-ts/src/oss/src/memory/memory.types.ts diff --git a/docs/examples/ai_companion_js.mdx b/docs/examples/ai_companion_js.mdx index 42b0f644..d170d12b 100644 --- a/docs/examples/ai_companion_js.mdx +++ b/docs/examples/ai_companion_js.mdx @@ -29,7 +29,7 @@ const openaiClient = new OpenAI(); const memory = new Memory(); async function chatWithMemories(message, userId = "default_user") { - const relevantMemories = await memory.search(message, userId); + const relevantMemories = await memory.search(message, { userId: userId }); const memoriesStr = relevantMemories.results .map(entry => `- ${entry.memory}`) @@ -52,7 +52,7 @@ ${memoriesStr}`; const assistantResponse = response.choices[0].message.content || ""; messages.push({ role: "assistant", content: assistantResponse }); - await memory.add(messages, userId); + await memory.add(messages, { userId: userId }); return assistantResponse; } diff --git a/docs/open-source-typescript/features/custom-prompts.mdx b/docs/open-source-typescript/features/custom-prompts.mdx index be7bfda2..83613131 100644 --- a/docs/open-source-typescript/features/custom-prompts.mdx +++ b/docs/open-source-typescript/features/custom-prompts.mdx @@ -84,7 +84,7 @@ In this example, we are adding a memory of a user ordering a laptop. As seen in ```typescript Code -await memory.add('Yesterday, I ordered a laptop, the order id is 12345', 'user123'); +await memory.add('Yesterday, I ordered a laptop, the order id is 12345', { userId: "user123" }); ``` ```json Output @@ -117,7 +117,7 @@ Hence, the memory is not added. ```typescript Code -await memory.add('I like going to hikes', 'user123'); +await memory.add('I like going to hikes', { userId: "user123" }); ``` ```json Output @@ -135,7 +135,7 @@ const messages = [ { role: 'assistant', content: 'I understand you\'re concerned about your order #54321. Let me help track that for you.' } ]; -await memory.add(messages, 'user123'); +await memory.add(messages, { userId: "user123" }); ``` The custom prompt will process both the user and assistant messages to extract relevant information according to the defined format. diff --git a/docs/open-source-typescript/quickstart.mdx b/docs/open-source-typescript/quickstart.mdx index e17de68f..756458cb 100644 --- a/docs/open-source-typescript/quickstart.mdx +++ b/docs/open-source-typescript/quickstart.mdx @@ -67,15 +67,14 @@ const memory = new Memory({ ```typescript Code -// For a user -const result = await memory.add('Hi, my name is John and I am a software', 'user123'); -console.log(result); +const messages = [ + {"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"}, + {"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."}, + {"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."}, + {"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."} +] -// const messages = [ -// {"role": "user", "content": "Hi, I'm Alex. I like to play cricket on weekends."}, -// {"role": "assistant", "content": "Hello Alex! It's great to know that you enjoy playing cricket on weekends. I'll remember that for future reference."} -// ] -// await memory.add(messages, 'user123'); +await memory.add(messages, { userId: "user123", metadata: { category: "movie_recommendations" } }); ``` ```json Output @@ -83,13 +82,24 @@ console.log(result); "results": [ { "id": "c03c9045-df76-4949-bbc5-d5dc1932aa5c", - "memory": "Name is John", - "metadata": [Object] + "memory": "User is planning to watch a movie tonight.", + "metadata": { + "category": "movie_recommendations" + } }, { "id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4", - "memory": "Is a software", - "metadata": [Object] + "memory": "User is not a big fan of thriller movies.", + "metadata": { + "category": "movie_recommendations" + } + }, + { + "id": "475bde34-21e6-42ab-8bef-0ab84474f156", + "memory": "User loves sci-fi movies.", + "metadata": { + "category": "movie_recommendations" + } } ] } @@ -101,7 +111,7 @@ console.log(result); ```typescript Code // Get all memories -const allMemories = await memory.getAll('user123'); +const allMemories = await memory.getAll({ userId: "user123" }); console.log(allMemories) ``` @@ -110,20 +120,35 @@ console.log(allMemories) "results": [ { "id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e", - "memory": "Name is Alex Jones", + "memory": "User is planning to watch a movie tonight.", "hash": "1a271c007316c94377175ee80e746a19", "createdAt": "2025-02-27T16:33:20.557Z", "updatedAt": "2025-02-27T16:33:27.051Z", - "metadata": {}, + "metadata": { + "category": "movie_recommendations" + }, "userId": "user123" }, { "id": "475bde34-21e6-42ab-8bef-0ab84474f156", - "memory": "Likes to play cricket on weekends", + "memory": "User loves sci-fi movies.", "hash": "285d07801ae42054732314853e9eadd7", "createdAt": "2025-02-27T16:33:20.560Z", "updatedAt": undefined, - "metadata": {}, + "metadata": { + "category": "movie_recommendations" + }, + "userId": "user123" + }, + { + "id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4", + "memory": "User is not a big fan of thriller movies.", + "hash": "285d07801ae42054732314853e9eadd7", + "createdAt": "2025-02-27T16:33:20.560Z", + "updatedAt": undefined, + "metadata": { + "category": "movie_recommendations" + }, "userId": "user123" } ] @@ -137,18 +162,20 @@ console.log(allMemories) ```typescript Code // Get a single memory by ID -const singleMemory = await memory.get('6c1c11a2-4fbc-4a2b-8e8a-d60e67e57aaa'); +const singleMemory = await memory.get('892db2ae-06d9-49e5-8b3e-585ef9b85b8e'); console.log(singleMemory); ``` ```json Output { - "id": "6c1c11a2-4fbc-4a2b-8e8a-d60e67e57aaa", - "memory": "Name is Alex", - "hash": "d0fccc8fa47f7a149ee95750c37bb0ca", - "createdAt": "2025-02-27T16:37:04.378Z", + "id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e", + "memory": "User is planning to watch a movie tonight.", + "hash": "1a271c007316c94377175ee80e746a19", + "createdAt": "2025-02-27T16:33:20.557Z", "updatedAt": undefined, - "metadata": {}, + "metadata": { + "category": "movie_recommendations" + }, "userId": "user123" } ``` @@ -158,7 +185,7 @@ console.log(singleMemory); ```typescript Code -const result = await memory.search('What do you know about me?', 'user123'); +const result = await memory.search('What do you know about me?', { userId: "user123" }); console.log(result); ``` @@ -166,23 +193,39 @@ console.log(result); { "results": [ { - "id": "28c3eee7-186e-4644-8c5d-13b306233d4e", - "memory": "Name is Alex", - "hash": "d0fccc8fa47f7a149ee95750c37bb0ca", - "createdAt": "2025-02-27T16:43:56.310Z", + "id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e", + "memory": "User is planning to watch a movie tonight.", + "hash": "1a271c007316c94377175ee80e746a19", + "createdAt": "2025-02-27T16:33:20.557Z", "updatedAt": undefined, - "score": 0.08920719231944799, - "metadata": {}, + "score": 0.38920719231944799, + "metadata": { + "category": "movie_recommendations" + }, "userId": "user123" }, { - "id": "f3433da0-45f4-444f-a4bc-59a170890a1f", - "memory": "Likes to play cricket on weekends", + "id": "475bde34-21e6-42ab-8bef-0ab84474f156", + "memory": "User loves sci-fi movies.", "hash": "285d07801ae42054732314853e9eadd7", - "createdAt": "2025-02-27T16:43:56.314Z", + "createdAt": "2025-02-27T16:33:20.560Z", "updatedAt": undefined, - "score": 0.06869761478135689, - "metadata": {}, + "score": 0.36869761478135689, + "metadata": { + "category": "movie_recommendations" + }, + "userId": "user123" + }, + { + "id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4", + "memory": "User is not a big fan of thriller movies.", + "hash": "285d07801ae42054732314853e9eadd7", + "createdAt": "2025-02-27T16:33:20.560Z", + "updatedAt": undefined, + "score": 0.33855272141248272, + "metadata": { + "category": "movie_recommendations" + }, "userId": "user123" } ] @@ -195,9 +238,8 @@ console.log(result); ```typescript Code const result = await memory.update( - '6c1c11a2-4fbc-4a2b-8e8a-d60e67e57aaa', - 'I love India, it is my favorite country.', - 'user123' + '892db2ae-06d9-49e5-8b3e-585ef9b85b8e', + 'I love India, it is my favorite country.' ); console.log(result); ``` @@ -213,7 +255,7 @@ console.log(result); ```typescript Code -const history = await memory.history('d2cc4cef-e0c1-47dd-948a-677030482e9e'); +const history = await memory.history('892db2ae-06d9-49e5-8b3e-585ef9b85b8e'); console.log(history); ``` @@ -221,21 +263,21 @@ console.log(history); [ { "id": 39, - "memory_id": "d2cc4cef-e0c1-47dd-948a-677030482e9e", - "previous_value": "Name is Alex", - "new_value": "Name is Alex Jones", + "memory_id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e", + "previous_value": "User is planning to watch a movie tonight.", + "new_value": "I love India, it is my favorite country.", "action": "UPDATE", - "created_at": "2025-02-27T16:46:15.853Z", - "updated_at": "2025-02-27T16:46:20.909Z", + "created_at": "2025-02-27T16:33:20.557Z", + "updated_at": "2025-02-27T16:33:27.051Z", "is_deleted": 0 }, { "id": 37, - "memory_id": "d2cc4cef-e0c1-47dd-948a-677030482e9e", + "memory_id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e", "previous_value": null, - "new_value": "Name is Alex", + "new_value": "User is planning to watch a movie tonight.", "action": "ADD", - "created_at": "2025-02-27T16:46:15.853Z", + "created_at": "2025-02-27T16:33:20.557Z", "updated_at": null, "is_deleted": 0 } @@ -247,10 +289,10 @@ console.log(history); ```typescript // Delete a memory by id -await memory.delete('bf4d4092-cf91-4181-bfeb-b6fa2ed3061b'); +await memory.delete('892db2ae-06d9-49e5-8b3e-585ef9b85b8e'); // Delete all memories for a user -await memory.deleteAll('alice'); +await memory.deleteAll({ userId: "user123" }); ``` ### Reset Memory diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 7cb35292..5709c99e 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -330,7 +330,7 @@ result = m.add("I like to drink coffee in the morning and go for a walk.", user_ ``` ```typescript TypeScript -const result = memory.add("I like to drink coffee in the morning and go for a walk.", 'alice'); +const result = memory.add("I like to drink coffee in the morning and go for a walk.", { userId: "alice", metadata: { category: "preferences" } }); ``` ```json Output @@ -361,7 +361,7 @@ related_memories = m.search("Should I drink coffee or tea?", user_id="alice") ``` ```typescript TypeScript -const relatedMemories = memory.search("Should I drink coffee or tea?", "alice"); +const relatedMemories = memory.search("Should I drink coffee or tea?", { userId: "alice" }); ``` ```json Output diff --git a/mem0-ts/README.md b/mem0-ts/README.md index 5946027b..e0b7c157 100644 --- a/mem0-ts/README.md +++ b/mem0-ts/README.md @@ -2,6 +2,9 @@ Mem0 is a self-improving memory layer for LLM applications, enabling personalized AI experiences that save costs and delight users. We offer both cloud and open-source solutions to cater to different needs. +See the complete [OSS Docs](https://docs.mem0.ai/open-source-typescript/quickstart). +See the complete [Platform API Reference](https://docs.mem0.ai/api-reference/overview). + ## 1. Installation For the open-source version, you can install the Mem0 package using npm: diff --git a/mem0-ts/package.json b/mem0-ts/package.json index f426e399..459e5fa4 100644 --- a/mem0-ts/package.json +++ b/mem0-ts/package.json @@ -1,6 +1,6 @@ { "name": "mem0ai", - "version": "2.0.0", + "version": "2.0.1", "description": "The Memory Layer For Your AI Apps", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/mem0-ts/src/oss/src/index.ts b/mem0-ts/src/oss/src/index.ts index e77a5fab..45322010 100644 --- a/mem0-ts/src/oss/src/index.ts +++ b/mem0-ts/src/oss/src/index.ts @@ -1,4 +1,5 @@ export * from "./memory"; +export * from "./memory/memory.types"; export * from "./types"; export * from "./embeddings/base"; export * from "./embeddings/openai"; @@ -9,4 +10,6 @@ export * from "./llms/anthropic"; export * from "./llms/groq"; export * from "./vector_stores/base"; export * from "./vector_stores/memory"; +export * from "./vector_stores/qdrant"; +export * from "./vector_stores/redis"; export * from "./utils/factory"; diff --git a/mem0-ts/src/oss/src/memory/index.ts b/mem0-ts/src/oss/src/memory/index.ts index fcffa0c7..43c17b42 100644 --- a/mem0-ts/src/oss/src/memory/index.ts +++ b/mem0-ts/src/oss/src/memory/index.ts @@ -24,6 +24,12 @@ import { Embedder } from "../embeddings/base"; import { LLM } from "../llms/base"; import { VectorStore } from "../vector_stores/base"; import { ConfigManager } from "../config/manager"; +import { + AddMemoryOptions, + SearchMemoryOptions, + DeleteAllMemoryOptions, + GetAllMemoryOptions, +} from "./memory.types"; export class Memory { private config: MemoryConfig; @@ -69,13 +75,17 @@ export class Memory { async add( messages: string | Message[], - userId?: string, - agentId?: string, - runId?: string, - metadata: Record = {}, - filters: SearchFilters = {}, - prompt?: string, + config: AddMemoryOptions, ): Promise { + const { + userId, + agentId, + runId, + metadata = {}, + filters = {}, + prompt, + } = config; + if (userId) filters.userId = metadata.userId = userId; if (agentId) filters.agentId = metadata.agentId = agentId; if (runId) filters.runId = metadata.runId = runId; @@ -87,7 +97,7 @@ export class Memory { } const parsedMessages = Array.isArray(messages) - ? messages + ? (messages as Message[]) : [{ role: "user", content: messages }]; const vectorStoreResult = await this.addToVectorStore( @@ -260,12 +270,10 @@ export class Memory { async search( query: string, - userId?: string, - agentId?: string, - runId?: string, - limit: number = 100, - filters: SearchFilters = {}, + config: SearchMemoryOptions, ): Promise { + const { userId, agentId, runId, limit = 100, filters = {} } = config; + if (userId) filters.userId = userId; if (agentId) filters.agentId = agentId; if (runId) filters.runId = runId; @@ -322,10 +330,10 @@ export class Memory { } async deleteAll( - userId?: string, - agentId?: string, - runId?: string, + config: DeleteAllMemoryOptions, ): Promise<{ message: string }> { + const { userId, agentId, runId } = config; + const filters: SearchFilters = {}; if (userId) filters.userId = userId; if (agentId) filters.agentId = agentId; @@ -358,12 +366,9 @@ export class Memory { ); } - async getAll( - userId?: string, - agentId?: string, - runId?: string, - limit: number = 100, - ): Promise { + async getAll(config: GetAllMemoryOptions): Promise { + const { userId, agentId, runId, limit = 100 } = config; + const filters: SearchFilters = {}; if (userId) filters.userId = userId; if (agentId) filters.agentId = agentId; diff --git a/mem0-ts/src/oss/src/memory/memory.types.ts b/mem0-ts/src/oss/src/memory/memory.types.ts new file mode 100644 index 00000000..4187f612 --- /dev/null +++ b/mem0-ts/src/oss/src/memory/memory.types.ts @@ -0,0 +1,26 @@ +import { Message } from "../types"; +import { SearchFilters } from "../types"; + +export interface Entity { + userId?: string; + agentId?: string; + runId?: string; +} + +export interface AddMemoryOptions extends Entity { + metadata?: Record; + filters?: SearchFilters; + prompt?: string; +} + +export interface SearchMemoryOptions extends Entity { + query: string; + limit?: number; + filters?: SearchFilters; +} + +export interface GetAllMemoryOptions extends Entity { + limit?: number; +} + +export interface DeleteAllMemoryOptions extends Entity {}