Compare commits

...

199 Commits

Author SHA1 Message Date
kartik-mem0 d5b04e70fa Merge remote-tracking branch 'origin/main' into docs/stale-migration
# Conflicts:
#	docs/migration/api-changes.mdx
2026-06-27 13:10:29 +05:30
Kartik 7e7682a06d docs(vectordbs): correct vector store config defaults & imports (#5843) 2026-06-27 12:40:16 +05:30
Kartik f38608fb50 docs(api-reference): align API docs & openapi.json with v3 spec (#5848) 2026-06-26 22:07:53 +05:30
Kartik fb11cdffbb docs(changelog): fix score_details fields, graph-store note & dead link (#5845) 2026-06-26 22:05:14 +05:30
Kartik ee600705c2 docs: remove inaccurate api-changes migration page (#5857) 2026-06-26 22:03:53 +05:30
Hrushikesh Yadav f4ccef5157 fix(ts/redis): use nullish coalescing for hash/timestamps in insert/update (#5860)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-26 19:01:58 +05:30
mintlify[bot] 08da741a31 SEO & metadata audit: expand short API reference descriptions (#5897)
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-06-26 16:34:52 +05:30
kartik-mem0 dc857e43ca docs(migration): clarify data= vs text= parameter divergence in update()
Add a Note inside the Update Memory accordion explaining that OSS
Memory.update() takes data= while Platform MemoryClient.update()
(Python and JS/TS) takes text=, so migrating users know to rename
the keyword argument.

Addresses reviewer comment on oss-to-platform.mdx:224/391.
2026-06-26 16:06:00 +05:30
Kartik e4efdd2e29 docs: add SECURITY.md and improve contribution guidelines (#5855) 2026-06-26 16:02:53 +05:30
Kartik a87c9ce367 docs: fix mangled Python formatting in pgvector & Neon vector store guides (#5853) 2026-06-26 16:00:58 +05:30
Kartik d258b638ef docs: document FastEmbed embedder + missing org/project API endpoints (#5852) 2026-06-26 16:00:12 +05:30
Harsh Vardhan Gupta bbbfcfea07 fix(deps): bump undici to >=6.27.0 (CVE-2026-12151) (#5861) 2026-06-26 15:32:09 +05:30
Kartik fbef369b91 docs(open-source): fix OSS feature docs for v3 SDK (#5847) 2026-06-26 14:14:33 +05:30
Kartik a7ed68e697 docs(integrations): fix retired model IDs, v3 response shapes & vercel deps (#5842) 2026-06-26 13:59:33 +05:30
Kartik 8a92cf0306 docs(integrations): sync agent-plugin hook tables with actual hooks.json (#5839) 2026-06-26 13:58:28 +05:30
soumil-rathi 0fbbb2f525 feat(memory): expose expiration controls in client docs (#5874)
Co-authored-by: Soumil Rathi <soumilrathi@gmail.com>
2026-06-25 17:14:33 -07:00
Barry Collins 818c2981b7 feat(ts-sdk): add MiniMax LLM provider (#5858)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-25 17:01:50 +05:30
Rod Boev 1f66aadfa3 fix(openclaw): normalize Windows skill-loader URLs before fileURLToPath (#5679) 2026-06-25 16:36:11 +05:30
Hrushikesh Yadav b91c745fbc fix: apply remove_code_blocks() to LangChain path in async _create_procedural_memory (#5711) 2026-06-25 16:34:28 +05:30
Muhammad Furqan af70668308 fix(reranker): score HuggingFace reranker with sigmoid, not min-max (#5715) 2026-06-25 16:18:02 +05:30
rafid001 890473f891 fix(core): validate and trim entity IDs in delete_all() (#5735)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-25 16:14:30 +05:30
Hrushikesh Yadav d2ff83cf72 fix(redis): use .get() for hash/created_at in insert() to handle entity payloads (#5709) 2026-06-25 16:13:44 +05:30
Rod Boev 0e02effaf7 fix(notices): derive scale counts for Redis and search backends (#5687) 2026-06-25 16:04:44 +05:30
Rod Boev 9269a0ad6e feat(ts-sdk): add LiteLLM as LLM provider (#5830)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-25 15:52:46 +05:30
Hrushikesh Yadav 3d06006f36 fix(valkey): escape special chars in FT.SEARCH tag filter values (#5750) 2026-06-25 15:20:13 +05:30
kartik-mem0 7e056281e5 docs(migration): drop api-changes redirect (page stays in nav with corrected content) 2026-06-25 12:30:25 +05:30
kartik-mem0 b5789d4afe docs(migration): correct migration guides to match v3 (update available, no async_mode/graph_store/offset) 2026-06-25 12:00:49 +05:30
Rod Boev 6bb1d328ad fix(mem0-ts): support pgvector connection strings and ssl (#5789) 2026-06-25 11:57:37 +05:30
Taranjeet Singh ac296f7534 docs: make example code fences copy-safe (#5833) 2026-06-24 22:19:40 -07:00
Kartik ac8f862ff7 fix(mem0-plugin): store files_touched as a list to stop double JSON-encoding (#5806) 2026-06-25 09:06:11 +05:30
soumil-rathi b33fa5427c fix(memory): align entity extraction precision (#5829)
Making the entity extraction function cleaner


Co-authored-by: Soumil Rathi <soumilrathi@gmail.com>
2026-06-24 15:48:37 -07:00
Ashutosh Kasudhan 5d573dd2ae docs: added typescript support to deepseek provider (#5723) 2026-06-24 20:55:14 +05:30
Kartik 98dbf90864 chore: update changelog, bump SDK versions to Python 2.0.8 and TypeScript 3.0.10 (#5825) 2026-06-24 20:21:06 +05:30
David Shrader 6ddf1669f4 fix(vector_stores): point fastembed-missing warning at mem0ai[extras] (#5622) 2026-06-24 14:47:02 +05:30
David Shrader d3d2e89fd5 fix(llms): skip JSON response_format for Groq compound models (#5513) 2026-06-24 14:42:22 +05:30
Xiaoju 43175d85f2 fix: preserve empty Azure AI Search update values (#5524)
Signed-off-by: Xiaoju <xiaojuchh@gmail.com>
2026-06-24 14:41:55 +05:30
Kartik 661ecb9f0f docs(hermes): update for v3 API, OSS self-hosted mode, and new tools (#5807) 2026-06-24 11:59:13 +05:30
冯基魁 09f181c577 fix(server): fetch filtered dashboard memories beyond default page (#5753) 2026-06-24 11:49:06 +05:30
Zaid 3497f26a00 fix: add auto_refresh option for OpenSearch Serverless compatibility (#3893)
Co-authored-by: Zaid Malhis <Malhis@users.noreply.github.com>
2026-06-24 11:48:52 +05:30
Bartok e9c0547423 fix(ts-sdk): preserve customCategories names through key conversion (#5741) 2026-06-24 11:15:19 +05:30
Yash Singh 25bc1b7426 fix(memory): guard against malformed image_url in parse_vision_messages (#5631) 2026-06-24 11:10:36 +05:30
Hrushikesh Yadav fee344db85 fix(chroma): wrap scalar vector_id in list for delete() (#5703) 2026-06-24 10:54:36 +05:30
Bartok b611f69381 fix(chroma): wrap update() ids/embeddings/metadatas in lists (#5757) 2026-06-24 10:54:15 +05:30
Muhammad Furqan c2862831db fix(reranker): log reranking failures instead of swallowing them silently (#5717) 2026-06-24 10:44:37 +05:30
홍찬희 1678e682ee fix(ts-sdk): check message.role instead of content for system messages (#3921) 2026-06-23 17:18:00 +05:30
Bartok ced4af681f fix(claude-plugin): rerank auto-injected memory context by default (#5690) 2026-06-23 16:52:35 +05:30
Hrushikesh Yadav 565db27121 fix(milvus,baidu): sanitize filter values to prevent expression injection (#5746) 2026-06-23 16:51:05 +05:30
Hrushikesh Yadav c0ac9f81fa fix(milvus): wrap scalar vector_id in list for delete() (#5704) 2026-06-23 16:48:47 +05:30
Yash Singh 879c68555c fix(memory): return attributed_to from get/get_all/search (#5629) 2026-06-23 16:43:30 +05:30
Abhishek Chauhan c2e723352e fix(ts-oss): return attributedTo from get/search/getAll (#5675) 2026-06-23 16:42:57 +05:30
Hrushikesh Yadav 716f021df8 fix(pinecone): map all comparison operators in _create_filter() (#5707) 2026-06-23 16:38:28 +05:30
Jiangtian Feng 7fa996261d perf: batch BM25 sparse encoding in Qdrant insert (#5592) 2026-06-23 16:29:16 +05:30
Yash Singh 87bd2d91e0 fix(llms): preserve reasoning fields in base-to-provider config conversion (#5638) 2026-06-23 16:27:43 +05:30
Yash Singh 15a930dac2 fix(llms): pass configured anthropic_base_url to the Anthropic client (#5626) 2026-06-23 16:26:22 +05:30
Bartok fa9abc77a6 fix(ts-oss): honor configured baseURL in AnthropicLLM (#5740) 2026-06-23 16:25:51 +05:30
Hrushikesh Yadav 4e448269bc fix(mongodb): reject dict filter values to prevent NoSQL operator injection (#5748) 2026-06-22 18:09:01 +05:30
Hrushikesh Yadav 29d131f7aa fix(chroma): return None instead of {} from _generate_where_clause for empty filters (#5713) 2026-06-22 12:05:28 +05:30
Bartok 42fe129330 fix(opensearch): return [[]] from list() error path to honor list() contract (#5727) 2026-06-22 11:58:37 +05:30
Hrushikesh Yadav bd5996f41e fix(pinecone): return [[]] from list() error path instead of dict (#5706) 2026-06-22 11:57:52 +05:30
Bartok 299c423213 fix(faiss): return [[]] for uninitialized index to honor list() contract (#5725) 2026-06-22 11:57:06 +05:30
Hrushikesh Yadav ce0531a13e fix(mongodb): wrap list() return in outer list to match interface contract (#5729) 2026-06-22 11:54:16 +05:30
Lucas Kim 513b56159f fix(embeddings): forward embedding_dims to Titan V2 in AWS Bedrock embedder (#5671)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 11:49:23 +05:30
Yash Singh 1676b3168d fix(server): return 404/400 instead of 502 for not-found and invalid input (#5634) 2026-06-22 11:47:48 +05:30
Davide Leopardi 8a786bf72d fix(azure): stop mutating and corrupting caller messages in content rewrite (#5731) 2026-06-22 11:45:46 +05:30
Yash Singh a48f34cf77 fix(vector_stores): deep-copy Redis DEFAULT_FIELDS so instances keep distinct dims (#5633) 2026-06-22 11:29:25 +05:30
Hrushikesh Yadav 650b734b1b fix: reset() only drops history table, leaving stale messages (#5541) 2026-06-22 11:28:17 +05:30
youneshima 871a1de7d2 docs: fix add memory v3 behavior (#5694) 2026-06-21 12:18:58 -07:00
fran3cc e615cc66de docs: rebrand Keywords AI integration to Respan (#5098)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-20 23:10:15 +05:30
Harsh Vardhan Gupta ca86a164bd fix(pi-agent-plugin): resolve undici CVE-2026-9697 / CVE-2026-9678 (#5669) 2026-06-19 16:21:18 +05:30
Kartik 2ac3f3956a fix(cli): pass telemetry context via stdin instead of argv (#5668)
Co-authored-by: JunghwanNA <70629228+shaun0927@users.noreply.github.com>
2026-06-19 13:57:53 +05:30
Yash Raj Pandey 7a9f03af3f fix(llms,embeddings): repair HTTP proxy support (httpx>=0.28) and preserve proxies in LlmFactory (#5447)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-19 13:45:21 +05:30
Yash Singh 48f1d6f010 fix(reranker): clamp out-of-range LLM scores instead of mis-parsing them (#5635) 2026-06-19 12:49:50 +05:30
Yash Singh f0ccd99924 fix(vertex): pass required vectors arg in list and similarity search (#5627) 2026-06-19 12:44:48 +05:30
ly-wang19 c5971193a2 fix(vector_stores): return None from Redis.get() for missing IDs (#5625)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-19 12:25:24 +05:30
Yash Singh ff53fd60b7 fix(graph): keep distinct entities that share a substring prefix (#5630) 2026-06-19 12:23:15 +05:30
Yash Singh ffa334537a fix(client): check HTTP status before parsing ping response in _validate_api_key (#5639) 2026-06-19 12:19:13 +05:30
Yash Singh bd7ce2c13c fix(vector_stores): drop stray print in Weaviate list_cols (#5637) 2026-06-19 12:07:10 +05:30
Yash Singh 5d767219ff fix(reranker): export all five rerankers from package root (#5636) 2026-06-19 12:06:12 +05:30
Haochen 6b744845c3 fix(oss-ts): preserve message roles in extraction input so assistant facts aren't attributed to the user (#5643) 2026-06-19 09:17:52 +05:30
Yash Singh 5b4478458b fix(server): return 404 not 500 for malformed api key id on revoke (#5640) 2026-06-18 17:45:05 +05:30
Bartok 1751e7bff9 fix(ts-oss): reject empty/blank messages in Memory.add() to prevent hallucinated memories (#5545) 2026-06-18 17:36:19 +05:30
Bartok 7ae6a8c36a fix(memory): guard entity embed_batch count mismatch in v3 add pipeline (#5604)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-18 17:22:44 +05:30
Harsh Vardhan Gupta 1dcee153b9 fix(deps): patch js-yaml, ai, python-dotenv vulnerabilities (CVE-2026-53550, CVE-2025-48985, CVE-2026-28684) (#5641)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 17:13:15 +05:30
Md. Mamun Hossain 4065e846f6 fix(ts-sdk): prevent hallucinated memories on empty messages payload … (#5613) 2026-06-18 17:01:02 +05:30
Hrushikesh Yadav 466249113c fix: async delete_all race condition corrupts entity store linked_memory_ids (#5553) 2026-06-18 16:57:03 +05:30
Alok Tripathi 3e2ae734e7 feat(embeddings): add native embed_batch to 5 embedders (LMStudio, Together, HuggingFace, VertexAI, GoogleGenAI) (#5609) 2026-06-18 16:46:31 +05:30
Harsh Vardhan Gupta 96b31c4bc0 fix(form-data): upgrade to >=4.0.6 across pnpm workspaces (CVE-2026-12143) (#5618)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:44:05 +05:30
Rocke Dong 0117d5838b fix(server): use 127.0.0.1 in dashboard healthcheck to avoid IPv6 localhost resolution (#5612) 2026-06-18 11:53:06 +05:30
Abhishek Chauhan 42a3b4043c fix(ts-sdk): preserve user metadata keys across the case-conversion round-trip (#5515) 2026-06-18 11:35:20 +05:30
Kartik 158e9111cb chore: update changelog, bump SDK versions to Python 2.0.7 and TypeScript 3.0.9 (#5615) 2026-06-17 21:45:28 +05:30
ChrisFloofyKitsune 9ed1983b85 refactor(opencode): use existing mem0 SDK instead of delegating to MCP, load skills properly instead of dumping them in .opencode (#5323)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-17 21:18:39 +05:30
Yash Raj Pandey 703e8a035d fix: FAISS filtered search drops over-fetched candidates before filtering (#5453)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-17 16:34:27 +05:30
Hrushikesh Yadav 7ed2faab84 fix: api_error_handler silently drops return values from async methods (#5540) 2026-06-17 14:46:08 +05:30
Abhishek Chauhan 0d66d3d127 fix(ts-sdk): preserve user-defined schema keys in createMemoryExport (#5594) 2026-06-17 14:40:33 +05:30
Lucas Kim 137b7519f7 fix(embeddings): honor aws_session_token in AWS Bedrock embeddings (#5566)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:36:33 +05:30
Alok Tripathi e34f5835bd feat(embeddings): add native embed_batch to OllamaEmbedding (#5415)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-17 14:12:53 +05:30
Yash Raj Pandey f122eb7c65 fix(weaviate): pass embedding dims in reset() so it does not crash (#5570) 2026-06-17 13:29:13 +05:30
mintlify[bot] a5123b8a5e docs: tighten Graph Memory description for SEO (#5603)
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-06-17 05:10:38 +00:00
rudrajmehta-mem0 6aa9bffa55 docs: reinstate graph memory terminology (native entity linking) (#5601) 2026-06-16 21:22:55 -07:00
Aayush Soni d772f9a961 feat: support Gemini via Vertex AI as LLM provider (#4030)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-16 16:59:06 +05:30
Yash Raj Pandey 7c841a2bce fix(redis): do not crash on empty or None filters in search and list (#5446)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-16 16:10:57 +05:30
Hrushikesh Yadav 6a6dfb4935 fix(huggingface): use self.config instead of raw config parameter (#5538) 2026-06-16 15:51:27 +05:30
Hrushikesh Yadav 8b370def80 fix: AsyncMemory.reset() does not reset entity store (#5535) 2026-06-16 15:50:30 +05:30
Hrushikesh Yadav d46464282c fix(pinecone): hybrid search crashes when filters is None (#5533) 2026-06-16 15:49:26 +05:30
Hrushikesh Yadav bb4a239cb1 fix(mongodb): reset() passes wrong argument to create_col() (#5532) 2026-06-16 15:48:45 +05:30
Hrushikesh Yadav e30f0d91fe fix(weaviate): reset() crashes with missing vector_size argument (#5531) 2026-06-16 15:45:47 +05:30
Hrushikesh Yadav 9f34e858c7 fix(ollama): json format mutates caller's messages list in-place (#5539) 2026-06-16 15:37:22 +05:30
Bartok 94bbc13de0 fix(memory): skip messages without a content key in message parsers (#5575) 2026-06-16 15:29:53 +05:30
Hrushikesh Yadav a2f01a8fcc fix: async delete_all aborts on first error, leaving partial deletion (#5529) 2026-06-16 11:59:33 +05:30
Hrushikesh Yadav 30d172e826 fix: omit None config values from Gemini GenerateContentConfig (#5528) 2026-06-16 11:54:42 +05:30
ly-wang19 bb69b036b5 fix(vector_stores): return None from get() for missing IDs (milvus/weaviate/supabase) (#5562)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-16 11:52:59 +05:30
Hrushikesh Yadav b55c51e004 fix(anthropic): tool_choice format and tool response parsing (#5537)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-15 17:28:45 +05:30
Harsh Vardhan Gupta 4492e75d04 fix(deps): bump esbuild >=0.28.1 across all npm packages (#5563)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:04:11 +05:30
Hrushikesh Yadav 4d949022f2 fix: preserve custom metadata fields during memory update (#5480) 2026-06-15 16:29:44 +05:30
ly-wang19 3ef034a9e4 fix(vector_stores): return None from ChromaDB.get() for missing IDs (#5561)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-15 16:11:03 +05:30
Yash Singh b90e3c0b76 fix(reranker): respect config.top_k in Cohere and ZeroEntropy fallback paths (#5560) 2026-06-15 16:10:00 +05:30
ly-wang19 a8eeddde64 fix(llms): honor reasoning-model params in AzureOpenAIStructuredLLM (#5548)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-15 16:07:19 +05:30
Hrushikesh Yadav 09a9e34382 fix(litellm): function-calling check blocks all calls on non-tool models (#5536) 2026-06-15 15:59:46 +05:30
anish 66c4394b40 fix(pyproject): rename vector_stores extra to vector-stores for PEP 503/508 compliance (#4934)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-15 12:38:23 +05:30
ly-wang19 32575a65fc fix(llms): honor reasoning-model params in OpenAIStructuredLLM (#5458)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-15 12:36:15 +05:30
Yash Singh 66901d7393 fix(llms): accept and forward **kwargs in Together/LangChain/Sarvam providers (#5556) 2026-06-15 12:23:04 +05:30
Hrushikesh Yadav a1eefc31bc fix(bedrock): use dict literal instead of set in AI21 response parse default (#5527) 2026-06-15 12:09:34 +05:30
Davide Leopardi de471799d1 fix(llms): send max_completion_tokens for the GPT-5 family across providers (#5547) 2026-06-15 12:04:19 +05:30
Rod Boev 3951ad4705 fix(openclaw): reduce skills-mode triage prompt footprint (#5502) 2026-06-15 11:18:39 +05:30
Kartik 9315e3036f chore: retire in-repo evaluation/ in favor of mem0ai/memory-benchmarks (#5520) 2026-06-14 00:43:02 +05:30
Kartik b3ede5b7c0 chore: update changelog, bump SDK and package versions to 3.0.8 and 2.0.6 (#5522) 2026-06-13 20:59:53 +05:30
youneshima 3553fc79dd feat(memory): add OSS-to-Platform notices (#5494) 2026-06-13 18:34:20 +05:30
Kartik f322cf82b9 chore: consolidate cookbooks/ into an indexed examples/ directory (#5517) 2026-06-13 18:25:50 +05:30
Kartik 73c975ba68 chore: bump version to 0.1.3, update mem0ai to ^3.0.7, and adjust CHANGELOG (#5521) 2026-06-13 18:10:50 +05:30
Kartik 931d579ba5 chore(openclaw): release v1.0.13 and backfill v1.0.12 changelog (#5519) 2026-06-13 17:59:04 +05:30
Kartik f4773a0baf fix(mem0-plugin): accurate per-editor telemetry attribution + OpenCode telemetry (#5518) 2026-06-13 16:48:29 +05:30
Kartik 06d33f6cc4 fix: relax flaky entity boost parallelism timing threshold (#5511) 2026-06-12 21:07:47 +05:30
Hrushikesh Yadav 8f3b60f3e1 fix: prevent crash in parse_vision_messages when vision is disabled (#5487) 2026-06-12 20:41:18 +05:30
Harsh Vardhan Gupta a6e27dcc9c fix(@mem0/community): upgrade @langchain/community to ^1.1.18 (CVE-2026-27795, CVE-2026-26019) (#5510) 2026-06-12 20:07:03 +05:30
Yufeng He 4f10c986b5 fix: expose Qdrant https option (#5380) 2026-06-12 20:06:26 +05:30
mjzcng 821152bd14 Fix OpenClaw Mem0 custom categories payload (#5345)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-12 19:48:53 +05:30
youneshima f48b133101 feat(skills): add mem0-oss-to-platform migration skill (#5455)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-12 19:48:37 +05:30
UmranPros 1d56f85705 fix(cli): resolve Windows environment compatibility issues in python CLI tests (#5464)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-12 19:40:26 +05:30
Hrushikesh Yadav ced852033b fix: return 400 instead of 502 for invalid search filters (#5482) 2026-06-12 19:35:24 +05:30
Yufeng He b9ad8fa8b2 fix(openclaw): skip runtime setup during metadata registration (#5383) 2026-06-12 19:32:59 +05:30
Yufeng He e3f5ce7b41 fix: use valid S3 entity index names (#5416)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-12 19:22:32 +05:30
Kartik f681889b14 fix(pi-agent-plugin): make command results visible and relevance-filtered (#5504) 2026-06-12 19:13:31 +05:30
Kartik b5ec46be5b fix(plugin): guard bare $USER refs in on_session_start.sh for Windows (#5492) 2026-06-12 19:13:19 +05:30
Harsh Vardhan Gupta 168ad358d5 fix(deps): resolve all open MEDIUM Dependabot alerts (npm overrides + Python pins) (#5489)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:15:26 +05:30
Kartik 2c796d144f refactor: consolidate agent/editor plugins under integrations/ (#5491)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-12 10:31:35 +05:30
Rocke Dong c676c2c458 fix(dashboard): pin pnpm to 10.34.2 so docker build works on node:20-alpine (#5483)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-11 22:45:52 +05:30
Oleg Ovcharuk b36847622d fix(langchain): search() crashes with TypeError when score is None (#5072)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-11 22:34:06 +05:30
Hrushikesh Yadav 32c8849044 fix: remove dead _process_config method in Memory and AsyncMemory (#5486) 2026-06-11 22:26:53 +05:30
Hrushikesh Yadav 2dd2872c08 fix: use 'is not None' instead of truthiness for vector/payload in pgvector update (#5488) 2026-06-11 22:12:38 +05:30
Harshit Anand cf268da19d fix(demo): guard against undefined data in useMemories hook (v2 async response) (#5029)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-11 21:50:35 +05:30
Sense_wang 7a5df64746 fix: allow dashboard refresh cookie on http deployments (#5026) 2026-06-11 21:29:54 +05:30
Eldar Shlomi 4c41f6deeb fix(vector-stores): index Valkey 'memory' field as TEXT not TAG (#5443)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-11 21:28:42 +05:30
Hrushikesh Yadav f84aa1eb31 fix: implement $not filter support in ChromaDB vector store (#5485) 2026-06-11 20:12:39 +05:30
Saket Aryan 9226ee2229 ci: aggregate all PR testing behind a single required CI Gate workflow (#5476) 2026-06-11 15:24:51 +05:30
Kartik 8399b088a5 chore: release Python SDK v2.0.5 and TypeScript SDK v3.0.7 (#5470) 2026-06-10 22:17:16 +05:30
Saket Aryan 437f0b5495 ci: route all release publishing through a single Release Router workflow (#5475) 2026-06-10 22:16:58 +05:30
Saket Aryan 0ffaffa88c fix(pi-agent-plugin): correct repository.url for npm provenance validation (#5473) 2026-06-10 21:29:16 +05:30
Saket Aryan 433ff494f1 chore(pi-agent-plugin): bump version to 0.1.1 (#5471) 2026-06-10 21:16:55 +05:30
Saket Aryan de03c52ed3 ci: add CI and CD workflows for pi-agent-plugin (#5469) 2026-06-10 21:11:39 +05:30
Abhishek Chauhan b4a50e3dc8 feat(vercel-ai-sdk): migrate to Vercel AI SDK v6 (#4741)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-10 18:41:15 +05:30
shafdev b819d95d18 fix(pgvector): use open=False to prevent ConnectionPool hang in Docker (#5155)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-10 17:15:53 +05:30
Sense_wang 3ac1c9452c fix(vector-stores): filter S3 vector list results (#5018)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-10 16:55:31 +05:30
Gaurav Dubey d6347f6660 fix(vector_stores): pass namespace as top-level kwarg to UpstashVector query_many (#5202) 2026-06-10 16:41:26 +05:30
Hrushikesh Yadav e769502baa feat: warn when hybrid search silently degrades to semantic-only (#5444) 2026-06-10 16:26:48 +05:30
Aarkin Karnik 652193d599 fix(llms/xai): forward tools, add XAIConfig, parse tool_calls (#5190) 2026-06-10 12:46:27 +05:30
Chirag Arora a86c87236d fix(server): forward explain in REST search (#5423) 2026-06-10 12:15:31 +05:30
Kartik 2274b5acad feat: add @mem0/pi-agent-plugin for Pi Agent memory (#5459) 2026-06-10 01:04:09 +05:30
Harsh Vardhan Gupta 9b0705c345 fix(deps): bump mem0ai 3.0.3→3.0.6 in openclaw to remediate axios CVEs (#5460) 2026-06-09 19:00:59 +05:30
Atahan Yıldırım d31fa168eb mem0-plugin hooks: honor auto_save=false in capture entry points (#5450) 2026-06-08 21:24:24 +05:30
Ritwij Aryan Parmar f32eb4406b fix(memory): reject empty search queries (#5258) 2026-06-08 21:11:11 +05:30
youneshima 366945965d feat(server): add information on self-hosted dashboard (#5325) 2026-06-06 03:18:43 +05:30
youneshima 6702fa3e3e docs: match migration callout color styling (#5157) 2026-06-05 14:40:24 -07:00
Chirag Arora a44855af9e feat(memory): add search score explanations (#5102)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-05 21:30:10 +05:30
Kartik d817aa9c12 fix(oss): parallelize entity boost searches in Memory.search (#5377) 2026-06-05 21:03:42 +05:30
Kartik 7ac8ab154b fix(vector_stores): normalize scores to similarity (higher = better) across all backends (#5391) 2026-06-05 19:13:26 +05:30
Kartik b00a1a1065 docs(google-adk): rewrite integration guide to use official ADK MemoryService APIs (#5392)
Co-authored-by: Nishar <nishar@dayos.com>
Co-authored-by: Nishar Miya <miyannishar786@gmail.com>
2026-06-05 19:13:00 +05:30
Dominik K. 2e90ed4f78 docs: add Neon vector store guide (#5119)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-05 19:06:59 +05:30
Bartok 069ea0887c fix(llms): add is_reasoning_model config override for versioned deployments (#5327)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-05 18:42:56 +05:30
Kartik ae7f406265 fix(server): harden self-hosted server — pgvector upgrade, admin auth, endpoint security (#5360) 2026-06-05 16:35:12 +05:30
Harsh Vardhan Gupta 90f2d24e83 fix(deps): upgrade vitest 1.5→4.1 + vite 6 to patch CVE-2026-47429 (#5375)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 02:54:00 +05:30
Pragnyan Ramtha 64b9646e7d fix(ts): request float OpenAI embeddings (#5170)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-04 20:29:53 +05:30
Ren yiwei 866888df41 Fix pgvector sslmode handling for PostgreSQL URIs (#5308) 2026-06-04 19:32:47 +05:30
Abhinav 95b6f95f7b fix: replace mutable default arguments with None sentinels (B006) (#5302) 2026-06-04 18:53:03 +05:30
Kartik 74771b4e76 feat(mem0-plugin): file-context injection, stop-hook summaries & activity timeline (#5346) 2026-06-03 00:55:07 +05:30
Harsh Vardhan Gupta 8e65ce915d fix(deps): remediate high-severity vulnerabilities in npm packages (#5294) 2026-06-02 01:36:29 +05:30
Kartik a3154d59e5 fix(docs): fix broken metadata filtering examples (#5317) 2026-05-30 20:16:56 +05:30
Kartik 1019f0e17c feat(mem0-plugin): auto coding categories, global search, OpenCode parity (#5300) 2026-05-30 00:18:46 +05:30
Saket Aryan 9328c36a46 chore(opencode-plugin): bump to 0.1.1 to test CI/CD publish flow (#5288) 2026-05-28 20:35:06 +05:30
Saket Aryan eb4afc6ef7 ci(opencode-plugin): add build & publish workflows for @mem0/opencode-plugin (#5287)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 20:20:05 +05:30
Kartik fea748d7e6 fix(antigravity-plugin): remove unnecessary skills symlink from install steps (#5283) 2026-05-28 13:49:02 +05:30
Kartik e83297f150 fix(antigravity-plugin): fix install commands to include skills and scripts (#5282) 2026-05-28 13:28:13 +05:30
rudrajmehta-mem0 eaca45dcdb docs: remove deprecated Graph Memory references (#5277) 2026-05-28 12:58:15 +05:30
Kartik add6aad40b fix(opencode-plugin): fix tsconfig, add publishConfig and bun lockfile (#5273) 2026-05-28 11:28:21 +05:30
Kartik 116c439b1d fix(opencode-plugin): rename package to @mem0/opencode-plugin (#5272) 2026-05-28 00:16:45 +05:30
Kartik 49b7953c44 fix(opencode-plugin): add plugin array to bundled opencode.json (#5271) 2026-05-27 23:46:05 +05:30
Kartik 3e6ab39429 feat(mem0-plugin): add OpenCode & Antigravity plugins, CC parity, docs cleanup (#5268) 2026-05-27 23:17:37 +05:30
Chaithanya Kumar 75a37ec93d feat(sdk): add delete_linked option to MemoryClient.delete (Python + TS) (#5270)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:38:16 +05:30
youneshima 88934304c6 fix(cli-node): forward --no-infer flag to add (#5267)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 10:05:30 +05:30
youneshima 098a599579 fix: refresh stale mem0ai pins in examples and openclaw (#5212)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:08:45 +05:30
668 changed files with 46910 additions and 13455 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
"name": "mem0",
"source": {
"source": "local",
"path": "./mem0-plugin"
"path": "./integrations/mem0-plugin"
},
"policy": {
"installation": "AVAILABLE",
+2 -2
View File
@@ -10,9 +10,9 @@
"plugins": [
{
"name": "mem0",
"source": "./mem0-plugin",
"source": "./integrations/mem0-plugin",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Claude workflows.",
"version": "0.2.6"
"version": "0.2.11"
}
]
}
+20
View File
@@ -0,0 +1,20 @@
{
"name": "mem0-plugins",
"interface": {
"displayName": "Mem0 Plugins"
},
"plugins": [
{
"name": "mem0",
"source": {
"source": "local",
"path": "./integrations/mem0-plugin"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
+2 -2
View File
@@ -10,9 +10,9 @@
"plugins": [
{
"name": "mem0",
"source": "./mem0-plugin",
"source": "./integrations/mem0-plugin",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search.",
"version": "0.2.6"
"version": "0.2.11"
}
]
}
+18 -4
View File
@@ -1,18 +1,33 @@
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
# Dispatched by release.yml (Release Router) when a release tagged v* is
# published. Can also be dispatched manually to re-publish a tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. v1.2.3)'
required: true
type: string
prerelease:
description: 'Unused for PyPI (pre-releases are expressed in the version itself); accepted for router uniformity'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
if: startsWith(github.event.release.tag_name, 'v')
# Pure SDK version tags only (v1.2.3) — excludes package-prefixed tags
# like vercel-ai-v* that also start with 'v'
if: startsWith(inputs.tag, 'v') && !contains(inputs.tag, '-v')
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v2
with:
ref: ${{ inputs.tag }}
- name: Set up Python
uses: actions/setup-python@v2
@@ -39,7 +54,6 @@ jobs:
# packages_dir: dist/
- name: Publish distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags/v')
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages_dir: dist/
+171
View File
@@ -0,0 +1,171 @@
name: CI Gate
# Single required status check for all PRs.
#
# Path-filtered CI workflows can't be marked as required in branch
# protection: on a PR that doesn't touch their paths they never report, and
# the required check hangs at "Expected" forever. This gate solves that. It
# runs on every PR, detects which packages changed, calls only the relevant
# package CI workflows (as reusable workflows), and the final "CI Gate" job
# reports the aggregate result — success when every invoked pipeline passed
# (skipped pipelines are fine), failure when any failed.
#
# Branch protection should require exactly one status check: "CI Gate".
#
# Package CI workflows keep their own push-to-main and workflow_dispatch
# triggers; only their pull_request triggers moved here. To wire in a new
# package: add a filter under the `changes` job, a call job that `uses:` the
# package workflow, and list the call job in the gate's `needs`.
on:
pull_request:
concurrency:
group: ci-gate-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: read
jobs:
changes:
name: Detect changed packages
runs-on: ubuntu-latest
outputs:
python_sdk: ${{ steps.filter.outputs.python_sdk }}
ts_sdk: ${{ steps.filter.outputs.ts_sdk }}
cli_python: ${{ steps.filter.outputs.cli_python }}
cli_node: ${{ steps.filter.outputs.cli_node }}
openclaw: ${{ steps.filter.outputs.openclaw }}
opencode_plugin: ${{ steps.filter.outputs.opencode_plugin }}
pi_agent_plugin: ${{ steps.filter.outputs.pi_agent_plugin }}
docs_llms_txt: ${{ steps.filter.outputs.docs_llms_txt }}
steps:
- uses: dorny/paths-filter@v3
id: filter
with:
# Each filter mirrors the package workflow's old pull_request
# paths, plus the package workflow file itself and this gate file
# (changing either must re-exercise the pipeline).
filters: |
python_sdk:
- 'mem0/**'
- 'tests/**'
- 'pyproject.toml'
- '.github/workflows/ci.yml'
- '.github/workflows/ci-gate.yml'
ts_sdk:
- 'mem0-ts/**'
- '.github/workflows/ts-sdk-ci.yml'
- '.github/workflows/ci-gate.yml'
cli_python:
- 'cli/python/**'
- '.github/workflows/cli-python-ci.yml'
- '.github/workflows/ci-gate.yml'
cli_node:
- 'cli/node/**'
- '.github/workflows/cli-node-ci.yml'
- '.github/workflows/ci-gate.yml'
openclaw:
- 'integrations/openclaw/**'
- '.github/workflows/openclaw-checks.yml'
- '.github/workflows/ci-gate.yml'
opencode_plugin:
- 'integrations/mem0-plugin/.opencode-plugin/**'
- '.github/workflows/opencode-plugin-checks.yml'
- '.github/workflows/ci-gate.yml'
pi_agent_plugin:
- 'integrations/pi-agent-plugin/**'
- '.github/workflows/pi-agent-plugin-checks.yml'
- '.github/workflows/ci-gate.yml'
docs_llms_txt:
- 'docs/**/*.mdx'
- 'docs/llms.txt'
- 'scripts/check-llms-txt-coverage.py'
- 'scripts/llms-txt-ignore.txt'
- '.github/workflows/docs-llms-txt-check.yml'
- '.github/workflows/ci-gate.yml'
python-sdk:
name: Python SDK
needs: changes
if: needs.changes.outputs.python_sdk == 'true'
uses: ./.github/workflows/ci.yml
secrets: inherit
ts-sdk:
name: TypeScript SDK
needs: changes
if: needs.changes.outputs.ts_sdk == 'true'
uses: ./.github/workflows/ts-sdk-ci.yml
secrets: inherit
cli-python:
name: Python CLI
needs: changes
if: needs.changes.outputs.cli_python == 'true'
uses: ./.github/workflows/cli-python-ci.yml
secrets: inherit
cli-node:
name: Node CLI
needs: changes
if: needs.changes.outputs.cli_node == 'true'
uses: ./.github/workflows/cli-node-ci.yml
secrets: inherit
openclaw:
name: OpenClaw
needs: changes
if: needs.changes.outputs.openclaw == 'true'
uses: ./.github/workflows/openclaw-checks.yml
secrets: inherit
opencode-plugin:
name: OpenCode Plugin
needs: changes
if: needs.changes.outputs.opencode_plugin == 'true'
uses: ./.github/workflows/opencode-plugin-checks.yml
secrets: inherit
pi-agent-plugin:
name: Pi Agent Plugin
needs: changes
if: needs.changes.outputs.pi_agent_plugin == 'true'
uses: ./.github/workflows/pi-agent-plugin-checks.yml
secrets: inherit
docs-llms-txt:
name: docs llms.txt
needs: changes
if: needs.changes.outputs.docs_llms_txt == 'true'
uses: ./.github/workflows/docs-llms-txt-check.yml
secrets: inherit
gate:
name: CI Gate
needs:
- changes
- python-sdk
- ts-sdk
- cli-python
- cli-node
- openclaw
- opencode-plugin
- pi-agent-plugin
- docs-llms-txt
if: always()
runs-on: ubuntu-latest
steps:
- name: Evaluate pipeline results
env:
NEEDS: ${{ toJSON(needs) }}
run: |
echo "$NEEDS" | jq -r 'to_entries[] | "\(.key): \(.value.result)"'
failed=$(echo "$NEEDS" | jq -r '[to_entries[] | select(.value.result == "failure" or .value.result == "cancelled") | .key] | join(", ")')
if [ -n "$failed" ]; then
echo "::error::Failing pipelines: $failed"
exit 1
fi
echo "All pipelines relevant to this change passed."
+3 -1
View File
@@ -1,9 +1,11 @@
name: ci
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main runs remain standalone.
on:
push:
branches: [main]
pull_request:
workflow_call:
jobs:
changelog_check:
+18 -4
View File
@@ -1,13 +1,25 @@
name: Publish @mem0/cli 📦 to npm
# Dispatched by release.yml (Release Router) when a release tagged
# cli-node-v* is published. Can also be dispatched manually to re-publish
# a tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. cli-node-v0.2.0)'
required: true
type: string
prerelease:
description: 'Publish under the version preid dist-tag instead of latest'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish @mem0/cli 📦 to npm
if: startsWith(github.event.release.tag_name, 'cli-node-v')
if: startsWith(inputs.tag, 'cli-node-v')
runs-on: ubuntu-latest
permissions:
id-token: write
@@ -16,6 +28,8 @@ jobs:
working-directory: cli/node
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Install pnpm
uses: pnpm/action-setup@v4
@@ -38,7 +52,7 @@ jobs:
- name: Publish to npm
run: |
if [ "${{ github.event.release.prerelease }}" = "true" ]; then
if [ "${{ inputs.prerelease }}" = "true" ]; then
PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
npx npm@latest publish --provenance --access public --tag "$PREID"
else
+3 -4
View File
@@ -1,5 +1,7 @@
name: CLI Node CI
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on:
workflow_dispatch:
push:
@@ -7,10 +9,7 @@ on:
paths:
- 'cli/node/**'
- '.github/workflows/cli-node-ci.yml'
pull_request:
paths:
- 'cli/node/**'
- '.github/workflows/cli-node-ci.yml'
workflow_call:
jobs:
lint:
+16 -3
View File
@@ -1,13 +1,24 @@
name: Publish mem0-cli 🐍 distributions 📦 to PyPI
# Dispatched by release.yml (Release Router) when a release tagged cli-v* is
# published. Can also be dispatched manually to re-publish a tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. cli-v0.2.0)'
required: true
type: string
prerelease:
description: 'Unused for PyPI (pre-releases are expressed in the version itself); accepted for router uniformity'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish mem0-cli 📦 to PyPI
if: startsWith(github.event.release.tag_name, 'cli-v')
if: startsWith(inputs.tag, 'cli-v')
runs-on: ubuntu-latest
permissions:
id-token: write
@@ -16,6 +27,8 @@ jobs:
working-directory: cli/python
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Set up Python
uses: actions/setup-python@v5
+3 -4
View File
@@ -1,5 +1,7 @@
name: CLI Python CI
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on:
workflow_dispatch:
push:
@@ -7,10 +9,7 @@ on:
paths:
- 'cli/python/**'
- '.github/workflows/cli-python-ci.yml'
pull_request:
paths:
- 'cli/python/**'
- '.github/workflows/cli-python-ci.yml'
workflow_call:
jobs:
lint:
+3 -6
View File
@@ -6,13 +6,10 @@ name: docs - llms.txt check
# python scripts/check-llms-txt-coverage.py # read-only
# python scripts/check-llms-txt-coverage.py --write # scaffold placeholders
# On PRs this is invoked by ci-gate.yml (the single required check);
# manual runs remain standalone.
on:
pull_request:
paths:
- 'docs/**/*.mdx'
- 'docs/llms.txt'
- 'scripts/check-llms-txt-coverage.py'
- 'scripts/llms-txt-ignore.txt'
workflow_call:
workflow_dispatch: {}
permissions:
+20 -6
View File
@@ -1,21 +1,35 @@
name: Publish @mem0/openclaw-mem0 📦 to npm
# Dispatched by release.yml (Release Router) when a release tagged
# openclaw-v* is published. Can also be dispatched manually to re-publish
# a tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. openclaw-v0.5.0)'
required: true
type: string
prerelease:
description: 'Publish under the version preid dist-tag instead of latest'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish @mem0/openclaw-mem0 📦 to npm
if: startsWith(github.event.release.tag_name, 'openclaw-v')
if: startsWith(inputs.tag, 'openclaw-v')
runs-on: ubuntu-latest
permissions:
id-token: write
defaults:
run:
working-directory: openclaw
working-directory: integrations/openclaw
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Install pnpm
uses: pnpm/action-setup@v4
@@ -28,7 +42,7 @@ jobs:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml
cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
@@ -38,7 +52,7 @@ jobs:
- name: Publish to npm
run: |
if [ "${{ github.event.release.prerelease }}" = "true" ]; then
if [ "${{ inputs.prerelease }}" = "true" ]; then
PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
npx npm@latest publish --provenance --access public --tag "$PREID"
else
+16 -17
View File
@@ -1,16 +1,15 @@
name: openclaw checks
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on:
workflow_dispatch:
push:
branches: [main]
paths:
- 'openclaw/**'
- '.github/workflows/openclaw-checks.yml'
pull_request:
paths:
- 'openclaw/**'
- 'integrations/openclaw/**'
- '.github/workflows/openclaw-checks.yml'
workflow_call:
jobs:
lint:
@@ -28,13 +27,13 @@ jobs:
with:
node-version: 20
cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml
cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies
run: cd openclaw && pnpm install --frozen-lockfile
run: cd integrations/openclaw && pnpm install --frozen-lockfile
- name: Type check
run: cd openclaw && pnpm exec tsc --noEmit
run: cd integrations/openclaw && pnpm exec tsc --noEmit
test:
runs-on: ubuntu-latest
@@ -54,20 +53,20 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml
cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies
run: cd openclaw && pnpm install --frozen-lockfile
run: cd integrations/openclaw && pnpm install --frozen-lockfile
- name: Run tests with coverage
run: cd openclaw && pnpm exec vitest run --coverage
run: cd integrations/openclaw && pnpm exec vitest run --coverage
- name: Upload coverage to Codecov
if: matrix.node-version == 20
uses: codecov/codecov-action@v4
with:
flags: openclaw
directory: openclaw/coverage
directory: integrations/openclaw/coverage
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -86,15 +85,15 @@ jobs:
with:
node-version: 20
cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml
cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies
run: cd openclaw && pnpm install --frozen-lockfile
run: cd integrations/openclaw && pnpm install --frozen-lockfile
- name: Build
run: cd openclaw && pnpm build
run: cd integrations/openclaw && pnpm build
- name: Verify dist output exists
run: |
test -f openclaw/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
test -f openclaw/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1)
test -f integrations/openclaw/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
test -f integrations/openclaw/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1)
+58
View File
@@ -0,0 +1,58 @@
name: Publish @mem0/opencode-plugin 📦 to npm
# Dispatched by release.yml (Release Router) when a release tagged
# opencode-v* is published. Can also be dispatched manually to re-publish
# a tag.
on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. opencode-v0.2.0)'
required: true
type: string
prerelease:
description: 'Publish under the version preid dist-tag instead of latest'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish @mem0/opencode-plugin 📦 to npm
if: startsWith(inputs.tag, 'opencode-v')
runs-on: ubuntu-latest
permissions:
id-token: write
defaults:
run:
working-directory: integrations/mem0-plugin/.opencode-plugin
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Install Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build
run: bun run build
- name: Publish to npm
run: |
if [ "${{ inputs.prerelease }}" = "true" ]; then
PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
npx npm@latest publish --provenance --access public --tag "$PREID"
else
npx npm@latest publish --provenance --access public
fi
@@ -0,0 +1,39 @@
name: opencode-plugin checks
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on:
workflow_dispatch:
push:
branches: [main]
paths:
- 'integrations/mem0-plugin/.opencode-plugin/**'
- '.github/workflows/opencode-plugin-checks.yml'
workflow_call:
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: integrations/mem0-plugin/.opencode-plugin
steps:
- uses: actions/checkout@v4
- name: Install Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Type check
run: bun run type-check
- name: Build
run: bun run build
- name: Verify dist output exists
run: |
test -f dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
+60
View File
@@ -0,0 +1,60 @@
name: Publish @mem0/pi-agent-plugin 📦 to npm
# Dispatched by release.yml (Release Router) when a release tagged
# pi-agent-v* is published. Can also be dispatched manually to re-publish
# a tag.
on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. pi-agent-v0.1.1)'
required: true
type: string
prerelease:
description: 'Publish under the version preid dist-tag instead of latest'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish @mem0/pi-agent-plugin 📦 to npm
if: startsWith(inputs.tag, 'pi-agent-v')
runs-on: ubuntu-latest
permissions:
id-token: write
defaults:
run:
working-directory: integrations/pi-agent-plugin
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Publish to npm
run: |
if [ "${{ inputs.prerelease }}" = "true" ]; then
PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
npx npm@latest publish --provenance --access public --tag "$PREID"
else
npx npm@latest publish --provenance --access public
fi
@@ -0,0 +1,92 @@
name: pi-agent-plugin checks
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on:
workflow_dispatch:
push:
branches: [main]
paths:
- 'integrations/pi-agent-plugin/**'
- '.github/workflows/pi-agent-plugin-checks.yml'
workflow_call:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies
run: cd integrations/pi-agent-plugin && pnpm install --frozen-lockfile
- name: Type check
run: cd integrations/pi-agent-plugin && pnpm exec tsc --noEmit
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20, 22]
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies
run: cd integrations/pi-agent-plugin && pnpm install --frozen-lockfile
- name: Run tests
run: cd integrations/pi-agent-plugin && pnpm exec vitest run
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies
run: cd integrations/pi-agent-plugin && pnpm install --frozen-lockfile
- name: Build
run: cd integrations/pi-agent-plugin && pnpm build
- name: Verify dist output exists
run: |
test -f integrations/pi-agent-plugin/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
test -f integrations/pi-agent-plugin/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1)
test -f integrations/pi-agent-plugin/dist/entry.js || (echo "Build output missing: dist/entry.js" && exit 1)
test -f integrations/pi-agent-plugin/dist/entry.d.ts || (echo "Build output missing: dist/entry.d.ts" && exit 1)
+68
View File
@@ -0,0 +1,68 @@
name: Release Router 🚦
# Single entry point for all release publishing.
#
# Package CD workflows no longer listen to release events themselves — this
# router inspects the release tag and dispatches only the matching pipeline,
# so each release produces one routed run instead of one real run plus seven
# skipped ones.
#
# Re-publishing a release (e.g. after fixing registry settings) does NOT
# require deleting and recreating it anymore — manually dispatch the
# package's CD workflow from the tag instead:
#
# gh workflow run <package>-cd.yml --ref refs/tags/<tag> -f tag=<tag>
#
# Note: dispatching runs the workflow file as it exists at the given ref, so
# this router can only dispatch tags created after the workflow_dispatch
# conversion landed on main. For older tags, dispatch manually from main.
on:
release:
types: [published]
permissions:
actions: write
jobs:
route:
name: Route ${{ github.event.release.tag_name }} to its CD pipeline
runs-on: ubuntu-latest
steps:
- name: Match tag prefix to CD workflow
id: match
env:
TAG: ${{ github.event.release.tag_name }}
run: |
# Specific package prefixes first; the bare v* (Python SDK) arm
# must stay last so prefixed tags that also start with 'v'
# (vercel-ai-v*) can never be routed to the Python pipeline.
case "$TAG" in
ts-v*) workflow="ts-sdk-cd.yml" ;;
cli-node-v*) workflow="cli-node-cd.yml" ;;
cli-v*) workflow="cli-python-cd.yml" ;;
vercel-ai-v*) workflow="vercel-ai-cd.yml" ;;
openclaw-v*) workflow="openclaw-cd.yml" ;;
opencode-v*) workflow="opencode-plugin-cd.yml" ;;
pi-agent-v*) workflow="pi-agent-plugin-cd.yml" ;;
v*) workflow="cd.yml" ;;
*)
echo "::error::Release tag '$TAG' does not match any known package prefix — nothing will be published. See the tag prefix table in AGENTS.md."
exit 1
;;
esac
echo "workflow=$workflow" >> "$GITHUB_OUTPUT"
echo ":outbox_tray: Routed \`$TAG\` → \`$workflow\`" >> "$GITHUB_STEP_SUMMARY"
- name: Dispatch ${{ steps.match.outputs.workflow }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.event.release.tag_name }}
run: |
# --ref points at the tag so the dispatched run builds (and signs
# provenance for) the exact tagged commit.
gh workflow run "${{ steps.match.outputs.workflow }}" \
--repo "$GITHUB_REPOSITORY" \
--ref "refs/tags/$TAG" \
-f tag="$TAG" \
-f prerelease="${{ github.event.release.prerelease }}"
+17 -4
View File
@@ -1,13 +1,24 @@
name: Publish mem0ai 📦 to npm
# Dispatched by release.yml (Release Router) when a release tagged ts-v* is
# published. Can also be dispatched manually to re-publish a tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. ts-v2.1.0)'
required: true
type: string
prerelease:
description: 'Publish under the version preid dist-tag instead of latest'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish mem0ai 📦 to npm
if: startsWith(github.event.release.tag_name, 'ts-v')
if: startsWith(inputs.tag, 'ts-v')
runs-on: ubuntu-latest
permissions:
id-token: write
@@ -16,6 +27,8 @@ jobs:
working-directory: mem0-ts
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Install pnpm
uses: pnpm/action-setup@v4
@@ -38,7 +51,7 @@ jobs:
- name: Publish to npm
run: |
if [ "${{ github.event.release.prerelease }}" = "true" ]; then
if [ "${{ inputs.prerelease }}" = "true" ]; then
PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
npx npm@latest publish --provenance --access public --tag "$PREID"
else
+3 -3
View File
@@ -1,14 +1,14 @@
name: TypeScript SDK CI
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main runs remain standalone.
on:
push:
branches: [main]
paths:
- 'mem0-ts/**'
- '.github/workflows/ts-sdk-ci.yml'
pull_request:
paths:
- 'mem0-ts/**'
workflow_call:
jobs:
check_changes:
+20 -6
View File
@@ -1,21 +1,35 @@
name: Publish @mem0/vercel-ai-provider 📦 to npm
# Dispatched by release.yml (Release Router) when a release tagged
# vercel-ai-v* is published. Can also be dispatched manually to re-publish
# a tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build and publish (e.g. vercel-ai-v2.0.7)'
required: true
type: string
prerelease:
description: 'Publish under the version preid dist-tag instead of latest'
required: false
type: boolean
default: false
jobs:
build-n-publish:
name: Build and publish @mem0/vercel-ai-provider 📦 to npm
if: startsWith(github.event.release.tag_name, 'vercel-ai-v')
if: startsWith(inputs.tag, 'vercel-ai-v')
runs-on: ubuntu-latest
permissions:
id-token: write
defaults:
run:
working-directory: vercel-ai-sdk
working-directory: integrations/vercel-ai-sdk
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag }}
- name: Install pnpm
uses: pnpm/action-setup@v4
@@ -28,7 +42,7 @@ jobs:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
cache-dependency-path: vercel-ai-sdk/pnpm-lock.yaml
cache-dependency-path: integrations/vercel-ai-sdk/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
@@ -38,7 +52,7 @@ jobs:
- name: Publish to npm
run: |
if [ "${{ github.event.release.prerelease }}" = "true" ]; then
if [ "${{ inputs.prerelease }}" = "true" ]; then
PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
npx npm@latest publish --provenance --access public --tag "$PREID"
else
+2
View File
@@ -189,3 +189,5 @@ eval/
qdrant_storage/
.crossnote
testing.ipynb
.weave/
+4
View File
@@ -0,0 +1,4 @@
[submodule "evaluation"]
path = evaluation
url = https://github.com/mem0ai/memory-benchmarks
branch = main
+67 -38
View File
@@ -12,7 +12,7 @@ This file provides context for AI coding assistants (Claude Code, Cursor, GitHub
## Repository Structure
This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs, servers, plugins, documentation, and evaluation tooling.
This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs, servers, plugins, and documentation.
### Key Directories
@@ -22,17 +22,18 @@ This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs,
| `mem0-ts/` | TypeScript SDK (`mem0ai` on npm) — client + OSS memory |
| `cli/python/` | Python CLI (`mem0-cli` on PyPI) — Typer-based, entry point `mem0` |
| `cli/node/` | Node CLI (`@mem0/cli` on npm) — Commander-based, entry point `mem0` |
| `vercel-ai-sdk/` | `@mem0/vercel-ai-provider` — Vercel AI SDK memory provider |
| `openclaw/` | `@mem0/openclaw-mem0` — OpenClaw plugin for Claude Code / AI editors |
| `integrations/` | **Agent & editor integrations**, one directory per integration (see "Adding a New Integration") |
| `integrations/mem0-plugin/` | AI editor plugins (Claude Code, Cursor, Codex) — MCP server connection, lifecycle hooks, skills. Contains nested `.opencode-plugin/` (`@mem0/opencode-plugin`) |
| `integrations/openclaw/` | `@mem0/openclaw-mem0` — OpenClaw plugin for Claude Code / AI editors |
| `integrations/pi-agent-plugin/` | `@mem0/pi-agent-plugin` — Pi Agent plugin |
| `integrations/vercel-ai-sdk/` | `@mem0/vercel-ai-provider` — Vercel AI SDK memory provider |
| `server/` | FastAPI REST server for self-hosted Mem0 (Docker: FastAPI + PostgreSQL/pgvector + Neo4j) |
| `openmemory/` | Self-hosted memory platform — `api/` (FastAPI + Alembic + MCP server) and `ui/` (Next.js 15 + React 19) |
| `mem0-plugin/` | AI editor plugins (Claude Code, Cursor, Codex) — MCP server connection, lifecycle hooks, skills |
| `skills/` | Claude Code skill definitions. Reference skills (SDK knowledge, always-on): `mem0/`, `mem0-cli/`, `mem0-vercel-ai-sdk/`. Pipeline skills (run on demand): `mem0-integrate/`, `mem0-test-integration/` |
| `skills/` | Claude Code skill definitions. Reference skills (SDK knowledge, always-on): `mem0/`, `mem0-cli/`, `mem0-vercel-ai-sdk/`. Pipeline skills (run on demand): `mem0-integrate/`, `mem0-test-integration/`, `mem0-oss-to-platform/` |
| `docs/` | Documentation site (Mintlify) |
| `tests/` | Python SDK tests (pytest) |
| `evaluation/` | Benchmarking framework — LOCOMO evals, experiment runner, score generation |
| `examples/` | Sample projects — demo apps, Chrome extension, multi-agent patterns |
| `cookbooks/` | Jupyter notebooks — customer support chatbot, AutoGen integration |
| `evaluation/` | Submodule → [`mem0ai/memory-benchmarks`](https://github.com/mem0ai/memory-benchmarks) — benchmarking (LOCOMO, LongMemEval, BEAM) lives in that repo |
| `examples/` | Sample projects & runnable demos — apps, Chrome extension, multi-agent patterns, and Jupyter notebooks (`notebooks/`) |
| `pr-reviews/` | Pull request review materials |
| `scripts/` | Repo-wide utility scripts (e.g., `check-llms-txt-coverage.py` for docs/llms.txt sync) |
@@ -49,8 +50,8 @@ mem0 (Python SDK) mem0-ts (TypeScript SDK)
cli/python/ ──▶ mem0ai (optional, for OSS mode)
cli/node/ ──▶ mem0ai (npm, for API calls)
vercel-ai-sdk/ ──▶ ai, @ai-sdk/* providers
openclaw/ ──▶ mem0ai (npm)
integrations/vercel-ai-sdk/ ──▶ ai, @ai-sdk/* providers
integrations/openclaw/ ──▶ mem0ai (npm)
```
## Development Setup
@@ -73,8 +74,8 @@ pre-commit install # install git hooks
# TypeScript packages
cd mem0-ts && pnpm install # TS SDK
cd cli/node && pnpm install # Node CLI
cd vercel-ai-sdk && pnpm install # Vercel AI provider
cd openclaw && pnpm install # OpenClaw plugin
cd integrations/vercel-ai-sdk && pnpm install # Vercel AI provider
cd integrations/openclaw && pnpm install # OpenClaw plugin
```
## Build, Lint, and Test Commands
@@ -162,10 +163,10 @@ pnpm run dev # tsx src/index.ts (development)
- **Test:** vitest (not jest)
- **Framework:** Commander + Chalk + ora + cli-table3
### Vercel AI SDK Provider (`vercel-ai-sdk/`)
### Vercel AI SDK Provider (`integrations/vercel-ai-sdk/`)
```bash
cd vercel-ai-sdk
cd integrations/vercel-ai-sdk
pnpm install
pnpm run build # tsup
pnpm run lint # eslint
@@ -180,10 +181,10 @@ pnpm run test:node # vitest (node runtime)
- **Lint:** ESLint + Prettier
- **Test:** jest + vitest (edge/node configs)
### OpenClaw Plugin (`openclaw/`)
### OpenClaw Plugin (`integrations/openclaw/`)
```bash
cd openclaw
cd integrations/openclaw
pnpm install
pnpm run build # tsup
pnpm run test # vitest run
@@ -245,18 +246,19 @@ make docs # or: cd docs && mintlify dev
- **API spec:** `docs/openapi.json`
- **Structure:** `api-reference/`, `open-source/`, `platform/`, `integrations/`, `cookbooks/`, `core-concepts/`
### Evaluation (`evaluation/`)
### Evaluation / Benchmarking
Benchmarking lives in the external [`mem0ai/memory-benchmarks`](https://github.com/mem0ai/memory-benchmarks) repo (LOCOMO + LongMemEval + BEAM). The in-repo `evaluation/` path is a **git submodule** pinned to that repo's `main` — populate it with `git submodule update --init evaluation` (or clone mem0 with `--recurse-submodules`), or clone the benchmarks repo standalone:
```bash
cd evaluation
make run-mem0-add # Run mem0 add experiments
make run-mem0-search # Run mem0 search experiments
make run-mem0-plus-add # With graph memory
make run-mem0-plus-search # With graph memory
make run-rag # RAG baseline
make run-full-context # Full context baseline
make run-langmem # LangMem comparison
make run-openai # OpenAI comparison
git clone https://github.com/mem0ai/memory-benchmarks.git
cd memory-benchmarks
pip install -r requirements.txt
# Run a benchmark (Mem0 Cloud; use docker compose for OSS)
python -m benchmarks.locomo.run --project-name my-test --backend cloud --mem0-api-key $MEM0_API_KEY
python -m benchmarks.longmemeval.run --project-name my-test --backend cloud --mem0-api-key $MEM0_API_KEY --all-questions
python -m benchmarks.beam.run --project-name my-test --backend cloud --mem0-api-key $MEM0_API_KEY --chat-sizes 100K --conversations 0-9
```
## Core APIs
@@ -342,8 +344,8 @@ make run-openai # OpenAI comparison
|---------|--------|-----------|---------------|
| `mem0-ts/` | — | Prettier | jest |
| `cli/node/` | Biome | Biome | vitest |
| `vercel-ai-sdk/` | ESLint | Prettier | jest + vitest |
| `openclaw/` | — | — | vitest |
| `integrations/vercel-ai-sdk/` | ESLint | Prettier | jest + vitest |
| `integrations/openclaw/` | — | — | vitest |
### Type Checking
@@ -381,14 +383,14 @@ Model Context Protocol support in multiple places:
- **Remote:** MCP server at `mcp.mem0.ai`
- **Local:** MCP server in `openmemory/api/` (FastAPI-based)
- **Plugin:** MCP tools in `mem0-plugin/` — 9 tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`
- **Plugin:** MCP tools in `integrations/mem0-plugin/` — 9 tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`
### Plugin & Skills System
- `mem0-plugin/` provides integrations for Claude Code, Cursor, and Codex via MCP server connections and lifecycle hooks for automatic memory capture.
- `integrations/mem0-plugin/` provides integrations for Claude Code, Cursor, and Codex via MCP server connections and lifecycle hooks for automatic memory capture.
- `skills/` contains structured skill definitions for AI agents, split into two categories:
- **Reference skills** (always-on SDK knowledge): `mem0` (Python + TS SDKs, framework integrations), `mem0-cli` (terminal workflows), `mem0-vercel-ai-sdk` (Vercel AI provider).
- **Pipeline skills** (run on demand): `mem0-integrate` wires Mem0 into an existing repo via a TDD pipeline; `mem0-test-integration` verifies what the integrator produced on the same branch. The two are loosely coupled via `.mem0-integration/` artifacts.
- **Pipeline skills** (run on demand): `mem0-integrate` wires Mem0 into an existing repo via a TDD pipeline; `mem0-test-integration` verifies what the integrator produced on the same branch (the two are loosely coupled via `.mem0-integration/` artifacts); `mem0-oss-to-platform` migrates an existing project from Mem0 OSS to the hosted Platform SDK (plan, then execute on approval).
### Adding a New Provider
@@ -402,31 +404,58 @@ To add a new LLM, embedding, vector store, or reranker provider:
6. Add any new dependencies to the appropriate optional group in `pyproject.toml` (never to core `dependencies`)
7. Follow the exact pattern of existing providers in the same category — match method signatures, error handling, and config structure
### Adding a New Integration
Agent/editor integrations live under `integrations/`. Each is a self-contained directory (its own `package.json`/lockfile, build, and tests). To add one:
1. Create `integrations/<name>/` and build the integration there.
2. If it publishes to a registry, set `repository.directory: "integrations/<name>"` in its `package.json` so npm provenance links to the correct subdirectory.
3. Add CI/CD under `.github/workflows/` (`<name>-checks.yml`, `<name>-cd.yml`). Use `integrations/<name>` in `paths:` triggers, `working-directory`, and `cache-dependency-path`. Register the release tag prefix in the `case` block in `release.yml` (keep the bare `v*` arm last). Keep workflow **filenames** stable — npm OIDC trusted publishing is pinned to repo + workflow filename.
4. If it is a Claude Code / editor marketplace plugin, register its path in the five `marketplace.json` files (root + `.claude-plugin/`, `.cursor-plugin/`, `.codex-plugin/`, `.agents/plugins/`).
5. Document it under `docs/integrations/` and add the page to `docs/docs.json` and `docs/llms.txt`.
6. Add rows to the "Key Directories" table and the CI/CD tables in this file.
## CI/CD
### CI Workflows (automated testing)
| Workflow | File | Triggers | Tests |
|----------|------|----------|-------|
| Python SDK | `ci.yml` | Push to main, PRs on `mem0/`, `tests/`, `pyproject.toml` | Ruff lint + pytest on Python 3.10, 3.11, 3.12 |
| TypeScript SDK | `ts-sdk-ci.yml` | Push to main, PRs on `mem0-ts/` | Prettier + build + jest on Node 20, 22 |
| Python CLI | `cli-python-ci.yml` | Push to `cli/python/`, PRs, manual | Ruff lint + pytest + hatch build on Python 3.10, 3.11, 3.12 |
| Node CLI | `cli-node-ci.yml` | Push to `cli/node/`, PRs, manual | Biome lint + tsc + vitest + tsup build on Node 20, 22 |
| OpenClaw | `openclaw-checks.yml` | Push to `openclaw/`, PRs, manual | tsc + vitest (with Codecov) + tsup build on Node 20, 22 |
PR testing is orchestrated by a single entry point: **`ci-gate.yml` (CI Gate)** runs on every PR, detects which packages changed, and invokes only the relevant package workflows below as reusable workflows (`workflow_call`). Its final **`CI Gate`** job aggregates the results (skipped pipelines pass; failed or cancelled ones fail) and is the **only status check that needs to be required** in branch protection. Package workflows keep their own push-to-main and manual triggers; their `pull_request` triggers moved into the gate's path filters.
| Workflow | File | Standalone Triggers | Tests |
|----------|------|---------------------|-------|
| CI Gate | `ci-gate.yml` | All PRs | Routes to and aggregates the workflows below |
| Python SDK | `ci.yml` | Push to main | Ruff lint + pytest on Python 3.10, 3.11, 3.12 |
| TypeScript SDK | `ts-sdk-ci.yml` | Push to main (on `mem0-ts/`) | Prettier + build + jest on Node 20, 22 |
| Python CLI | `cli-python-ci.yml` | Push to main (on `cli/python/`), manual | Ruff lint + pytest + hatch build on Python 3.10, 3.11, 3.12 |
| Node CLI | `cli-node-ci.yml` | Push to main (on `cli/node/`), manual | Biome lint + tsc + vitest + tsup build on Node 20, 22 |
| OpenClaw | `openclaw-checks.yml` | Push to main (on `integrations/openclaw/`), manual | tsc + vitest (with Codecov) + tsup build on Node 20, 22 |
| OpenCode Plugin | `opencode-plugin-checks.yml` | Push to main (on `integrations/mem0-plugin/.opencode-plugin/`), manual | Bun: tsc type-check + build + dist artifact check |
| Pi Agent Plugin | `pi-agent-plugin-checks.yml` | Push to main (on `integrations/pi-agent-plugin/`), manual | tsc + vitest + tsup build (dist artifact check) on Node 20, 22 |
| docs llms.txt | `docs-llms-txt-check.yml` | Manual | `docs/llms.txt` coverage check |
When adding a new package CI workflow: give it `workflow_call` (plus `push`/`workflow_dispatch` as needed, but no `pull_request` trigger), then register it in `ci-gate.yml` — a path filter under the `changes` job, a call job, and an entry in the gate job's `needs` list.
### CD Workflows (automated publishing)
Publishing is routed through a single entry point: **`release.yml` (Release Router)** is the only workflow that listens to `release: published` events. It matches the release tag prefix and dispatches the corresponding package workflow via `workflow_dispatch`, so each release produces exactly one routed run (no skipped runs from the other pipelines).
| Workflow | File | Tag Prefix | Target |
|----------|------|------------|--------|
| Release Router | `release.yml` | (all releases) | dispatches the matching workflow below |
| Python SDK | `cd.yml` | `v*` | PyPI (`mem0ai`) |
| TypeScript SDK | `ts-sdk-cd.yml` | `ts-v*` | npm (`mem0ai`) |
| Python CLI | `cli-python-cd.yml` | `cli-v*` | PyPI (`mem0-cli`) |
| Node CLI | `cli-node-cd.yml` | `cli-node-v*` | npm (`@mem0/cli`) |
| Vercel AI SDK | `vercel-ai-cd.yml` | `vercel-ai-v*` | npm (`@mem0/vercel-ai-provider`) |
| OpenClaw | `openclaw-cd.yml` | `openclaw-v*` | npm (`@mem0/openclaw-mem0`) |
| OpenCode Plugin | `opencode-plugin-cd.yml` | `opencode-v*` | npm (`@mem0/opencode-plugin`) |
| Pi Agent Plugin | `pi-agent-plugin-cd.yml` | `pi-agent-v*` | npm (`@mem0/pi-agent-plugin`) |
- Package CD workflows are `workflow_dispatch`-only (inputs: `tag`, `prerelease`); they check out and build the given tag. Registry trusted-publisher settings stay pinned to each package's own workflow filename.
- All publishing uses **OIDC trusted publishing** — no tokens or secrets required.
- First publish of a new npm package must be done manually; OIDC works for subsequent versions.
- To re-publish a release (e.g. after a registry settings fix), do **not** delete/recreate the GitHub release — manually dispatch the package workflow instead: `gh workflow run <package>-cd.yml --ref refs/tags/<tag> -f tag=<tag>`.
- When adding a new package: add its CD workflow (`workflow_dispatch` with `tag`/`prerelease` inputs), then register its tag prefix in the `case` block in `release.yml`. Keep the bare `v*` arm last.
### Utility Workflows
+134 -47
View File
@@ -1,72 +1,157 @@
# Contributing to mem0
# Contributing to Mem0
Let us make contribution easy, collaborative and fun.
First off, thank you for taking the time to contribute! 🎉 Mem0 is a
community-driven project and we welcome contributions of all kinds — bug fixes,
new features, documentation, examples, and integrations.
## Submit your Contribution through PR
Mem0 is a polyglot monorepo, and this guide covers contributing to both the
**Python SDK** and the **TypeScript SDK** (and the rest of the repository).
To make a contribution, follow these steps:
## Before You Start
1. Fork and clone this repository
2. Do the changes on your fork with dedicated feature branch `feature/f1`
3. If you modified the code (new feature or bug-fix), please add tests for it
4. Include proper documentation / docstring and examples to run the feature
5. Ensure that all tests pass
6. Submit a pull request
### 1. Open an Issue First
For more details about pull requests, please read [GitHub's guides](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
**Always open an issue before opening a pull request.** This lets us discuss the
change, avoid duplicate effort, and agree on the approach before you invest time
in code.
- Search [existing issues](https://github.com/mem0ai/mem0/issues) first to see if
your bug or idea already exists.
- If it doesn't, open a
[bug report](https://github.com/mem0ai/mem0/issues/new?template=bug_report.yml) or
[feature request](https://github.com/mem0ai/mem0/issues/new?template=feature_request.yml).
- For anything beyond a trivial fix, wait for a maintainer to confirm the approach
before starting significant work.
### 📦 Development Environment
Every pull request must link to an issue using `Closes #<issue-number>`.
We use `hatch` for managing development environments. To set up:
### 2. Sign the Contributor License Agreement (CLA)
**We cannot accept or merge any pull request until you have signed our Contributor
License Agreement (CLA).**
When you open your first PR, the CLA bot will automatically comment with a link to
sign. Signing takes less than a minute and only needs to be done once. Pull
requests from contributors who have not signed the CLA will be blocked from
merging.
## Repository Layout
The two most common contribution targets are the SDKs:
| Package | Path | Language | Package manager |
| --------------------- | ---------- | ------------ | --------------- |
| Python SDK (`mem0ai`) | `mem0/` | Python 3.9+ | `hatch` |
| TypeScript SDK (`mem0ai`) | `mem0-ts/` | TypeScript | `pnpm` |
Other packages include the CLIs (`cli/python/`, `cli/node/`), integrations
(`integrations/`), the self-hosted `server/`, `openmemory/`, and the docs site
(`docs/`). See [AGENTS.md](./AGENTS.md) for a full map of the repository.
## Development Workflow
1. **Fork** the repository and **clone** your fork.
2. Create a **feature branch** from `main` (e.g. `feature/my-new-feature` or
`fix/issue-1234`).
3. Make your changes — add **tests**, **documentation**, and **examples** as
appropriate.
4. Run **linting and tests** for every package you touched (see below).
5. Commit using [Conventional Commits](https://www.conventionalcommits.org/)
(e.g. `feat:`, `fix:`, `docs:`, `refactor:`, `test:`).
6. Push and open a **pull request** against `main`, linking the issue with
`Closes #<number>` and filling out the
[PR template](./.github/PULL_REQUEST_TEMPLATE.md).
### Contributing to the Python SDK (`mem0/`)
We use [`hatch`](https://hatch.pypa.io/latest/install/) to manage environments.
**Do not use `pip` or `conda` for dependency management.**
```bash
# Activate environment for specific Python version:
hatch shell dev_py_3_9 # Python 3.9
hatch shell dev_py_3_10 # Python 3.10
hatch shell dev_py_3_11 # Python 3.11
hatch shell dev_py_3_12 # Python 3.12
# Activate a dev environment (3.9 / 3.10 / 3.11 / 3.12)
hatch shell dev_py_3_11
# The environment will automatically install all dev dependencies
# Run tests within the activated shell:
make test
```
### 📌 Pre-commit
To ensure our standards, make sure to install pre-commit before starting to contribute.
```bash
# Install pre-commit hooks (runs ruff + isort on commit)
pre-commit install
# Lint, format, and sort imports
make lint
make format
make sort
# Run the test suite (run `make install_all` first if deps are missing)
make test
```
### 🧪 Testing
- **Linter / formatter:** Ruff (line length **120**)
- **Import sorting:** isort (`profile = "black"`)
- **Tests:** pytest (in `tests/`)
We use `pytest` to test our code across multiple Python versions. You can run tests using:
See the full [Development guide](https://docs.mem0.ai/contributing/development) for
environment details.
### Contributing to the TypeScript SDK (`mem0-ts/`)
We use [`pnpm`](https://pnpm.io/) (v10+) for all TypeScript packages. **Do not use
`npm` or `yarn`.**
```bash
# Run tests with default Python version
make test
cd mem0-ts
pnpm install
# Test specific Python versions:
make test-py-3.9 # Python 3.9 environment
make test-py-3.10 # Python 3.10 environment
make test-py-3.11 # Python 3.11 environment
make test-py-3.12 # Python 3.12 environment
# When using hatch shells, run tests with:
make test # After activating a shell with hatch shell test_XX
pnpm run build # tsup (CJS + ESM)
pnpm run test # jest (all tests)
pnpm run test:unit # unit tests with coverage
```
Make sure that all tests pass across all supported Python versions before submitting a pull request.
- **Build:** tsup
- **Formatter:** Prettier
- **Tests:** jest
- Always run type checking after changes: `pnpm run typecheck` (or `tsc --noEmit`).
- Use ES module `import` syntax — never `require()`.
We look forward to your pull requests and can't wait to see your contributions!
## Good Contribution Practices
### 🚀 Releasing
- **Keep PRs small and focused.** One logical change per PR is easier to review and
merge.
- **Follow existing patterns.** Match the style, structure, and conventions of the
code around you. Don't introduce new frameworks or abstractions without
discussion.
- **Write tests** that would fail without your change — regression tests for bugs,
coverage for new features.
- **Update documentation** in `docs/` for any user-facing change. New `.mdx` pages
must be added to `docs/llms.txt` (run
`python scripts/check-llms-txt-coverage.py --write` to scaffold entries).
- **Add examples** when introducing new user-facing behavior.
- **Run linters and tests locally** before pushing — CI re-runs them on every PR
via the CI Gate.
- **Never commit secrets** — no `.env` files, API keys, or credentials.
- **Don't add core dependencies lightly.** New Python dependencies belong in an
optional group in `pyproject.toml`, not the core `dependencies` list.
- **Be responsive** to review feedback and keep your branch up to date with `main`.
All packages are published automatically via GitHub Actions when a GitHub Release is created with the correct tag prefix.
## Pull Request Checklist
#### Tag Prefixes
Before requesting review, make sure:
- [ ] An issue exists and is linked with `Closes #<number>`
- [ ] You have signed the CLA
- [ ] Your code follows the project's style guidelines (lint passes)
- [ ] You performed a self-review of your changes
- [ ] Tests are added/updated and pass locally
- [ ] Documentation is updated if needed
## Reporting Security Issues
**Do not report security vulnerabilities through public issues or pull requests.**
Please follow our [Security Policy](./SECURITY.md) to report them privately.
## Releasing
All packages are published automatically via GitHub Actions when a GitHub Release
is created with the correct tag prefix.
### Tag Prefixes
| Package | Registry | Tag Prefix | Example |
|---------|----------|------------|---------|
@@ -77,15 +162,17 @@ All packages are published automatically via GitHub Actions when a GitHub Releas
| `@mem0/vercel-ai-provider` | npm | `vercel-ai-v*` | `vercel-ai-v2.0.6` |
| `@mem0/openclaw-mem0` | npm | `openclaw-v*` | `openclaw-v1.0.1` |
#### How to Release
### How to Release
1. Bump the version in `pyproject.toml` (Python) or `package.json` (Node)
2. Create a [GitHub Release](https://github.com/mem0ai/mem0/releases/new) with the matching tag prefix
3. The correct workflow will trigger automatically — verify in the [Actions tab](https://github.com/mem0ai/mem0/actions)
#### Publishing Details
### Publishing Details
- **PyPI packages** use OIDC trusted publishing via `pypa/gh-action-pypi-publish`
- **npm packages** use OIDC trusted publishing via npm CLI (>= 11.5.1) — no tokens or secrets required
- All workflows require `permissions: id-token: write` for OIDC authentication
- First publish of a new npm package must be done manually; OIDC works for subsequent versions
We look forward to your pull requests and can't wait to see your contributions!
+2 -1
View File
@@ -1026,7 +1026,8 @@ def get_user_preferences(user_id: str):
### AutoGen Integration
```python
from cookbooks.helper.mem0_teachability import Mem0Teachability
# Mem0Teachability lives in examples/notebooks/helper/ — see examples/notebooks/mem0-autogen.ipynb
from helper.mem0_teachability import Mem0Teachability
from mem0 import Memory
# Add memory capability to AutoGen agents
-221
View File
@@ -1,221 +0,0 @@
# Migration Guide: Upgrading to mem0 1.0.0
## TL;DR
**What changed?** We simplified the API by removing confusing version parameters. Now everything returns a consistent format: `{"results": [...]}`.
**What you need to do:**
1. Upgrade: `pip install mem0ai==1.0.0`
2. Remove `version` and `output_format` parameters from your code
3. Update response handling to use `result["results"]` instead of treating responses as lists
**Time needed:** ~5-10 minutes for most projects
---
## Quick Migration Guide
### 1. Install the Update
```bash
pip install mem0ai==1.0.0
```
### 2. Update Your Code
**If you're using the Memory API:**
```python
# Before
memory = Memory(config=MemoryConfig(version="v1.1"))
result = memory.add("I like pizza")
# After
memory = Memory() # That's it - version is automatic now
result = memory.add("I like pizza")
```
**If you're using the Client API:**
```python
# Before
client.add(messages, output_format="v1.1")
client.search(query, version="v2", output_format="v1.1")
# After
client.add(messages) # Just remove those extra parameters
client.search(query)
```
### 3. Update How You Handle Responses
All responses now use the same format: a dictionary with `"results"` key.
```python
# Before - you might have done this
result = memory.add("I like pizza")
for item in result: # Treating it as a list
print(item)
# After - do this instead
result = memory.add("I like pizza")
for item in result["results"]: # Access the results key
print(item)
# Graph relations (if you use them)
if "relations" in result:
for relation in result["relations"]:
print(relation)
```
---
## Enhanced Message Handling
The platform client (MemoryClient) now supports the same flexible message formats as the OSS version:
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
# All three formats now work:
# 1. Single string (automatically converted to user message)
client.add("I like pizza", user_id="alice")
# 2. Single message dictionary
client.add({"role": "user", "content": "I like pizza"}, user_id="alice")
# 3. List of messages (conversation)
client.add([
{"role": "user", "content": "I like pizza"},
{"role": "assistant", "content": "I'll remember that!"}
], user_id="alice")
```
### Async Mode Configuration
The `async_mode` parameter now defaults to `True` but can be configured:
```python
# Default behavior (async_mode=True)
client.add(messages, user_id="alice")
# Explicitly set async mode
client.add(messages, user_id="alice", async_mode=True)
# Disable async mode if needed
client.add(messages, user_id="alice", async_mode=False)
```
**Note:** `async_mode=True` provides better performance for most use cases. Only set it to `False` if you have specific synchronous processing requirements.
---
## That's It!
For most users, that's all you need to know. The changes are:
- ✅ No more `version` or `output_format` parameters
- ✅ Consistent `{"results": [...]}` response format
- ✅ Cleaner, simpler API
---
## Common Issues
**Getting `KeyError: 'results'`?**
Your code is still treating the response as a list. Update it:
```python
# Change this:
for memory in response:
# To this:
for memory in response["results"]:
```
**Getting `TypeError: unexpected keyword argument`?**
You're still passing old parameters. Remove them:
```python
# Change this:
client.add(messages, output_format="v1.1")
# To this:
client.add(messages)
```
**Seeing deprecation warnings?**
Remove any explicit `version="v1.0"` from your config:
```python
# Change this:
memory = Memory(config=MemoryConfig(version="v1.0"))
# To this:
memory = Memory()
```
---
## What's New in 1.0.0
- **Better vector stores:** Fixed OpenSearch and improved reliability across all stores
- **Cleaner API:** One way to do things, no more confusing options
- **Enhanced GCP support:** Better Vertex AI configuration options
- **Flexible message input:** Platform client now accepts strings, dicts, and lists (aligned with OSS)
- **Configurable async_mode:** Now defaults to `True` but users can override if needed
---
## Need Help?
- Check [GitHub Issues](https://github.com/mem0ai/mem0/issues)
- Read the [documentation](https://docs.mem0.ai/)
- Open a new issue if you're stuck
---
## Advanced: Configuration Changes
**If you configured vector stores with version:**
```python
# Before
config = MemoryConfig(
version="v1.1",
vector_store=VectorStoreConfig(...)
)
# After
config = MemoryConfig(
vector_store=VectorStoreConfig(...)
)
```
---
## Testing Your Migration
Quick sanity check:
```python
from mem0 import Memory
memory = Memory()
# Add should return a dict with "results"
result = memory.add("I like pizza", user_id="test")
assert "results" in result
# Search should return a dict with "results"
search = memory.search("food", user_id="test")
assert "results" in search
# Get all should return a dict with "results"
all_memories = memory.get_all(user_id="test")
assert "results" in all_memories
print("✅ Migration successful!")
```
+2 -1
View File
@@ -186,9 +186,10 @@ npx skills add https://github.com/mem0ai/mem0 --skill mem0-vercel-ai-sdk
```bash
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
npx skills add https://github.com/mem0ai/mem0 --skill mem0-oss-to-platform
```
Use `/mem0-integrate` to wire Mem0 into an existing repo via a test-first pipeline, then `/mem0-test-integration` to verify. See the [skills catalog](./skills/) or [Vibecoding with Mem0](https://docs.mem0.ai/vibecoding) for the full picture.
Use `/mem0-integrate` to wire Mem0 into an existing repo via a test-first pipeline, then `/mem0-test-integration` to verify. Use `/mem0-oss-to-platform` to migrate an existing project from Mem0 OSS to the hosted Platform SDK. See the [skills catalog](./skills/) or [Vibecoding with Mem0](https://docs.mem0.ai/vibecoding) for the full picture.
### Basic Usage
+48
View File
@@ -0,0 +1,48 @@
# Security Policy
We take the security of Mem0 and our community seriously. Thank you for helping
keep Mem0 and its users safe by disclosing vulnerabilities responsibly.
## Reporting a Vulnerability
Please **do not** report security vulnerabilities through public GitHub issues,
pull requests, or discussions.
If you believe you have found a security vulnerability in Mem0, please report it
privately through one of the following channels:
1. **GitHub Private Vulnerability Reporting** — open a
[private security advisory](https://github.com/mem0ai/mem0/security/advisories/new)
directly on this repository.
2. **Email** the maintainers at **support@mem0.ai** with the subject line:
`SECURITY: Mem0 vulnerability report`
To help us triage and resolve the issue quickly, please include as much of the
following as you can:
- Affected component or package (e.g. Python SDK, TypeScript SDK, server, OpenMemory)
- Affected version, tag, or commit
- Clear, step-by-step reproduction instructions
- The security impact and a proof of concept, if available
- Any suggested fix or mitigation
## Response Process
- We will acknowledge receipt of your report within **72 hours**.
- We will work with you privately to confirm the issue and assess its impact.
- Once a fix or mitigation is ready, we will coordinate a disclosure timeline
with you and credit you for the discovery, unless you prefer to remain anonymous.
## Public Disclosure
Please avoid sharing technical details of the vulnerability publicly until the
maintainers have reviewed the issue and a fix or mitigation has been released. We
are committed to resolving valid reports promptly and keeping you informed
throughout the process.
## Supported Versions
We release security fixes against the latest published version of each package.
Whenever possible, please reproduce the issue on the most recent release before
reporting.
+24
View File
@@ -5,6 +5,30 @@ All notable changes to `@mem0/cli` are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.2.9] — 2026-06-19
### Security
- Telemetry no longer passes the Mem0 API key to its child process via
command-line arguments. The context is now sent over stdin, so the key is no
longer visible in the process list (`ps`, `/proc/<pid>/cmdline`, Activity
Monitor). Fixes #4862.
## [0.2.8] — 2026-06-01
### Security
- Pinned transitive dependencies via pnpm overrides to remediate high-severity CVEs:
- `jws` → 4.0.1 (CVE-2025-65945)
- `langsmith` → ^0.6.0 (CVE-2026-45134)
- `tar-fs` → ^2.1.4 (CVE-2025-48387, CVE-2025-59343)
- `picomatch` → ^2.3.2 (CVE-2026-33671)
- `minimatch` → ^3.1.3 / ^5.1.8 / ^9.0.7 (CVE-2026-27903, CVE-2026-27904, CVE-2026-26996)
- `path-to-regexp` → ^8.4.0 (CVE-2026-4926)
- `rollup` → ^4.59.0 (CVE-2026-27606)
- `glob` → ^10.5.0 (CVE-2025-64756)
- `@modelcontextprotocol/sdk` → ^1.25.4 (CVE-2025-66414, CVE-2026-0621)
## [0.2.7] — 2026-05-20
### Added
+13 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@mem0/cli",
"version": "0.2.7",
"version": "0.2.9",
"description": "The official CLI for mem0 — the memory layer for AI agents",
"type": "module",
"bin": {
@@ -40,8 +40,19 @@
"typescript": "^5.4.0",
"tsup": "^8.0.0",
"tsx": "^4.7.0",
"vitest": "^1.5.0",
"vite": "^6.0.0",
"vitest": "^4.1.0",
"@biomejs/biome": "^1.7.0",
"@types/node": "^20.0.0"
},
"pnpm": {
"overrides": {
"jws@4.0.0": "4.0.1",
"langsmith@<0.6.0": "^0.6.0",
"tar-fs@>=2.0.0 <2.1.4": "^2.1.4",
"picomatch@<2.3.2": "^2.3.2",
"postcss@<8.5.10": ">=8.5.10",
"esbuild": ">=0.28.1"
}
}
}
+310 -723
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
packages:
- '.'
onlyBuiltDependencies:
- "@biomejs/biome"
- esbuild
overrides:
jws@4.0.0: 4.0.1
langsmith@<0.6.0: ^0.6.0
tar-fs@>=2.0.0 <2.1.4: ^2.1.4
picomatch@<2.3.2: ^2.3.2
"postcss@<8.5.10": ">=8.5.10"
"esbuild": ">=0.28.1"
+2 -2
View File
@@ -46,7 +46,7 @@ export async function cmdAdd(
file?: string;
metadata?: string;
immutable: boolean;
noInfer: boolean;
infer?: boolean;
expires?: string;
categories?: string;
output: string;
@@ -136,7 +136,7 @@ export async function cmdAdd(
runId: opts.runId,
metadata: meta,
immutable: opts.immutable,
infer: !opts.noInfer,
infer: opts.infer !== false,
expires: opts.expires,
categories: cats,
});
+5 -5
View File
@@ -145,11 +145,11 @@ export function captureEvent(
anonDistinctIdToAlias: anonIdToAlias,
};
const child = spawn(
process.execPath,
[SENDER_SCRIPT, JSON.stringify(context)],
{ detached: true, stdio: "ignore" },
);
const child = spawn(process.execPath, [SENDER_SCRIPT], {
detached: true,
stdio: ["pipe", "ignore", "ignore"],
});
child.stdin?.end(JSON.stringify(context));
child.unref();
} catch {
/* silently swallow */
+28 -2
View File
@@ -1,7 +1,8 @@
/**
* Standalone telemetry sender — runs as a detached child process.
*
* Usage: node telemetry-sender.cjs '<json context>'
* Usage: node telemetry-sender.cjs (JSON context is read from stdin; a single
* argv argument is still accepted as a legacy fallback)
*
* This script is spawned by telemetry.captureEvent() and runs independently
* of the parent CLI process. It:
@@ -19,6 +20,31 @@
const https = require("https");
const fs = require("fs");
function loadContext() {
return new Promise((resolve, reject) => {
if (process.argv[2]) {
try {
resolve(JSON.parse(process.argv[2]));
} catch (err) {
reject(err);
}
return;
}
let data = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => (data += chunk));
process.stdin.on("end", () => {
try {
resolve(JSON.parse(data));
} catch (err) {
reject(err);
}
});
process.stdin.on("error", reject);
});
}
function httpsRequest(url, method, headers, body) {
return new Promise((resolve, reject) => {
const u = new URL(url);
@@ -108,7 +134,7 @@ async function sendIdentifyEvent(ctx, payload, anonId) {
}
async function main() {
const ctx = JSON.parse(process.argv[2]);
const ctx = await loadContext();
const payload = ctx.payload;
if (ctx.needsEmail && ctx.mem0ApiKey) {
+48 -16
View File
@@ -3,6 +3,7 @@
*/
import { describe, it, expect, vi, beforeEach } from "vitest";
import { Command } from "commander";
import { createMockBackend } from "./setup.js";
import type { Backend } from "../src/backend/base.js";
import { setAgentMode } from "../src/state.js";
@@ -41,8 +42,6 @@ describe("cmdAdd", () => {
await cmdAdd(mockBackend, "I prefer dark mode", {
userId: "alice",
immutable: false,
noInfer: false,
output: "text",
});
expect(mockBackend.add).toHaveBeenCalledOnce();
@@ -54,8 +53,6 @@ describe("cmdAdd", () => {
userId: "alice",
messages: JSON.stringify([{ role: "user", content: "I love Python" }]),
immutable: false,
noInfer: false,
output: "text",
});
expect(mockBackend.add).toHaveBeenCalledOnce();
@@ -66,8 +63,6 @@ describe("cmdAdd", () => {
await cmdAdd(mockBackend, "test", {
userId: "alice",
immutable: false,
noInfer: false,
output: "json",
});
expect(output).toContain("results");
@@ -78,14 +73,59 @@ describe("cmdAdd", () => {
await cmdAdd(mockBackend, "test", {
userId: "alice",
immutable: false,
noInfer: false,
output: "quiet",
});
expect(output).not.toContain("dark mode");
});
});
describe("cmdAdd forwards --no-infer (regression for #5261)", () => {
it("forwards infer: false when --no-infer is set", async () => {
const { cmdAdd } = await import("../src/commands/memory.js");
// `infer: false` is the shape Commander produces for `--no-infer`.
await cmdAdd(mockBackend, "store me verbatim", {
userId: "alice",
immutable: false,
infer: false,
output: "text",
});
expect(mockBackend.add).toHaveBeenCalledWith(
"store me verbatim",
undefined,
expect.objectContaining({ infer: false }),
);
});
it("forwards infer: true by default (flag absent)", async () => {
const { cmdAdd } = await import("../src/commands/memory.js");
await cmdAdd(mockBackend, "infer me", {
userId: "alice",
immutable: false,
output: "text",
});
expect(mockBackend.add).toHaveBeenCalledWith(
"infer me",
undefined,
expect.objectContaining({ infer: true }),
);
});
it("Commander stores --no-infer as opts.infer, not opts.noInfer", () => {
// Pins the assumption the fix relies on: Commander's `--no-X` option
// populates the positive camelCase key (`infer`), never `noInfer`.
const withFlag = new Command();
withFlag.option("--no-infer", "Skip inference, store raw.").action(() => {});
withFlag.parse(["--no-infer"], { from: "user" });
expect(withFlag.opts().infer).toBe(false);
expect(withFlag.opts().noInfer).toBeUndefined();
const withoutFlag = new Command();
withoutFlag.option("--no-infer", "Skip inference, store raw.").action(() => {});
withoutFlag.parse([], { from: "user" });
expect(withoutFlag.opts().infer).toBe(true);
});
});
describe("cmdAdd deduplicates PENDING", () => {
const DUPLICATE_PENDING = {
results: [
@@ -100,8 +140,6 @@ describe("cmdAdd deduplicates PENDING", () => {
await cmdAdd(mockBackend, "test", {
userId: "alice",
immutable: false,
noInfer: false,
output: "text",
});
expect(output.match(/Queued/g)?.length).toBe(1);
@@ -113,8 +151,6 @@ describe("cmdAdd deduplicates PENDING", () => {
await cmdAdd(mockBackend, "test", {
userId: "alice",
immutable: false,
noInfer: false,
output: "json",
});
const data = JSON.parse(output);
@@ -129,8 +165,6 @@ describe("cmdAdd deduplicates PENDING", () => {
await cmdAdd(mockBackend, "test", {
userId: "alice",
immutable: false,
noInfer: false,
output: "agent",
});
const data = JSON.parse(output);
@@ -315,8 +349,6 @@ describe("agent mode", () => {
await cmdAdd(mockBackend, "test preference", {
userId: "alice",
immutable: false,
noInfer: false,
output: "agent",
});
const parsed = JSON.parse(output.trim());
+59
View File
@@ -0,0 +1,59 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
const mockLoadConfig = vi.fn();
const mockSaveConfig = vi.fn();
const mockSpawn = vi.fn();
vi.mock("../src/config.js", () => ({
CONFIG_FILE: "/tmp/mem0-config.json",
loadConfig: mockLoadConfig,
saveConfig: mockSaveConfig,
}));
vi.mock("node:child_process", () => ({
spawn: mockSpawn,
}));
describe("captureEvent", () => {
beforeEach(() => {
vi.resetModules();
mockLoadConfig.mockReset();
mockSaveConfig.mockReset();
mockSpawn.mockReset();
delete process.env.MEM0_TELEMETRY;
});
it("pipes the telemetry context through stdin instead of argv", async () => {
mockLoadConfig.mockReturnValue({
platform: {
apiKey: "m0-node-secret",
baseUrl: "https://api.mem0.ai",
userEmail: "",
},
telemetry: {
anonymousId: "cli-anon-node",
},
});
const stdin = { end: vi.fn() };
const child = { stdin, unref: vi.fn() };
mockSpawn.mockReturnValue(child);
const { captureEvent } = await import("../src/telemetry.js");
captureEvent("node_test_event", { case: "stdin-secret" });
expect(mockSpawn).toHaveBeenCalledTimes(1);
const [execPath, args, options] = mockSpawn.mock.calls[0];
expect(execPath).toBe(process.execPath);
expect(args).toHaveLength(1);
expect(String(args[0])).toContain("telemetry-sender.cjs");
expect(JSON.stringify(args)).not.toContain("m0-node-secret");
expect(options).toMatchObject({ detached: true, stdio: ["pipe", "ignore", "ignore"] });
expect(stdin.end).toHaveBeenCalledTimes(1);
const payload = JSON.parse(stdin.end.mock.calls[0][0]);
expect(payload.mem0ApiKey).toBe("m0-node-secret");
expect(payload.payload.event).toBe("node_test_event");
expect(child.unref).toHaveBeenCalledTimes(1);
});
});
+6
View File
@@ -8,4 +8,10 @@ export default defineConfig({
define: {
__CLI_VERSION__: JSON.stringify(pkg.version),
},
test: {
// Integration tests spawn the CLI via `npx tsx` (15s subprocess
// timeout); the first spawn in a file pays a cold-start cost that can
// exceed vitest's 5s default on CI runners.
testTimeout: 30_000,
},
});
+13
View File
@@ -5,6 +5,19 @@ All notable changes to `mem0-cli` (Python) are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.2.8] — 2026-06-19
### Security
- Telemetry no longer passes the Mem0 API key to its child process via
command-line arguments. The context is now sent over stdin, so the key is no
longer visible in the process list (`ps`, `/proc/<pid>/cmdline`, Activity
Monitor). Fixes #4862.
### Fixed
- `__version__` now matches the packaged version (was stale at 0.2.4).
## [0.2.7] — 2026-05-20
### Added
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "mem0-cli"
version = "0.2.7"
version = "0.2.8"
description = "The official CLI for mem0 — the memory layer for AI agents"
readme = "README.md"
license = "Apache-2.0"
+1 -1
View File
@@ -1,3 +1,3 @@
"""mem0 CLI — the command-line interface for the mem0 memory layer."""
__version__ = "0.2.4"
__version__ = "0.2.8"
+9 -2
View File
@@ -137,12 +137,19 @@ def capture_event(
"anon_distinct_id_to_alias": anon_id_to_alias,
}
subprocess.Popen(
[sys.executable, "-m", "mem0_cli.telemetry_sender", json.dumps(context)],
child = subprocess.Popen(
[sys.executable, "-m", "mem0_cli.telemetry_sender"],
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True,
close_fds=True,
text=True,
)
if child.stdin:
with contextlib.suppress(Exception):
child.stdin.write(json.dumps(context))
with contextlib.suppress(Exception):
child.stdin.close()
except Exception:
pass
+13 -2
View File
@@ -1,6 +1,7 @@
"""Standalone telemetry sender — runs as a detached subprocess.
Usage: python -m mem0_cli.telemetry_sender '<json context>'
Usage: python -m mem0_cli.telemetry_sender (JSON context is read from stdin;
a single argv argument is still accepted as a legacy fallback)
This module is spawned by telemetry.capture_event() and runs independently
of the parent CLI process. It:
@@ -20,8 +21,18 @@ import sys
import urllib.request
def _load_context() -> dict:
"""Load telemetry context from stdin, falling back to argv for compatibility."""
raw = ""
if not sys.stdin.isatty():
raw = sys.stdin.read().strip()
if not raw and len(sys.argv) > 1:
raw = sys.argv[1]
return json.loads(raw)
def main() -> None:
ctx = json.loads(sys.argv[1])
ctx = _load_context()
payload = ctx["payload"]
if ctx.get("needs_email") and ctx.get("mem0_api_key"):
+6 -3
View File
@@ -32,12 +32,13 @@ def _run(args: list[str], home_dir: str | None = None) -> subprocess.CompletedPr
if key.startswith("MEM0_"):
del env[key]
env.pop("FORCE_COLOR", None)
env["PYTHONIOENCODING"] = "utf-8"
if home_dir:
env["HOME"] = home_dir
result = subprocess.run(
[sys.executable, "-m", "mem0_cli", *args],
capture_output=True,
text=True,
encoding="utf-8",
env=env,
timeout=15,
)
@@ -99,12 +100,13 @@ class TestArgvPreprocessing:
result = subprocess.run(
[sys.executable, "-m", "mem0_cli", "init", "--agent"],
capture_output=True,
text=True,
encoding="utf-8",
env={
**{k: v for k, v in os.environ.items() if not k.startswith("MEM0_")},
"HOME": clean_home,
"MEM0_BASE_URL": "http://127.0.0.1:1", # blackhole
"FORCE_COLOR": "0",
"PYTHONIOENCODING": "utf-8",
},
timeout=15,
)
@@ -133,12 +135,13 @@ class TestJsonEnvelopeParity:
result = subprocess.run(
[sys.executable, "-m", "mem0_cli", "init", "--agent", "--json"],
capture_output=True,
text=True,
encoding="utf-8",
env={
**{k: v for k, v in os.environ.items() if not k.startswith("MEM0_")},
"HOME": clean_home,
"MEM0_BASE_URL": "http://127.0.0.1:1",
"FORCE_COLOR": "0",
"PYTHONIOENCODING": "utf-8",
},
timeout=15,
)
+2 -1
View File
@@ -49,6 +49,7 @@ def _run(
if key.startswith("MEM0_"):
del env[key]
env.pop("FORCE_COLOR", None)
env["PYTHONIOENCODING"] = "utf-8"
if home_dir:
env["HOME"] = home_dir
if env_override:
@@ -56,7 +57,7 @@ def _run(
result = subprocess.run(
[sys.executable, "-m", "mem0_cli", *args],
capture_output=True,
text=True,
encoding="utf-8",
env=env,
)
return subprocess.CompletedProcess(
+7 -7
View File
@@ -8,8 +8,8 @@ from io import StringIO
from unittest.mock import patch
import pytest
from click.exceptions import Exit as ClickExit
from rich.console import Console
from typer import Exit as TyperExit
from mem0_cli.commands.config_cmd import (
cmd_config_get,
@@ -181,7 +181,7 @@ class TestAddCommand:
patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console),
patch("mem0_cli.commands.memory._stdin_is_piped", return_value=False),
pytest.raises((SystemExit, ClickExit)),
pytest.raises((SystemExit, TyperExit)),
):
cmd_add(
mock_backend,
@@ -206,7 +206,7 @@ class TestAddCommand:
with (
patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console),
pytest.raises((SystemExit, ClickExit)),
pytest.raises((SystemExit, TyperExit)),
):
cmd_add(
mock_backend,
@@ -764,7 +764,7 @@ class TestImportCommand:
with (
patch("mem0_cli.commands.utils.console", console),
patch("mem0_cli.commands.utils.err_console", err_console),
pytest.raises((SystemExit, ClickExit)),
pytest.raises((SystemExit, TyperExit)),
):
cmd_import(mock_backend, "/nonexistent/file.json", user_id=None, agent_id=None)
@@ -801,7 +801,7 @@ class TestEntitiesListCommand:
with (
patch("mem0_cli.commands.entities.console", console),
patch("mem0_cli.commands.entities.err_console", err_console),
pytest.raises((SystemExit, ClickExit)),
pytest.raises((SystemExit, TyperExit)),
):
cmd_entities_list(mock_backend, "invalid", output="table")
@@ -944,7 +944,7 @@ class TestEntitiesDeleteCommand:
with (
patch("mem0_cli.commands.entities.console", console),
patch("mem0_cli.commands.entities.err_console", err_console),
pytest.raises((SystemExit, ClickExit)),
pytest.raises((SystemExit, TyperExit)),
):
cmd_entities_delete(
mock_backend,
@@ -1308,7 +1308,7 @@ class TestAgentMode:
patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console),
patch("sys.stdout", captured_stdout),
pytest.raises((SystemExit, ClickExit)),
pytest.raises((SystemExit, TyperExit)),
):
cmd_get(mock_backend, "bad-id", output="text")
+2 -1
View File
@@ -67,7 +67,8 @@ class TestConfig:
from mem0_cli.config import CONFIG_FILE
mode = os.stat(CONFIG_FILE).st_mode & 0o777
assert mode == 0o600
if os.name != "nt":
assert mode == 0o600
def test_defaults_save_and_load(self, isolate_config):
config = Mem0Config()
+80
View File
@@ -0,0 +1,80 @@
"""Tests for telemetry subprocess secret handling."""
from __future__ import annotations
import io
import json
import subprocess
import sys
from mem0_cli.config import Mem0Config, save_config
from mem0_cli.telemetry import capture_event
from mem0_cli.telemetry_sender import _load_context
class _CaptureStdin:
def __init__(self):
self.buffer = ""
self.closed = False
def write(self, value: str) -> None:
self.buffer += value
def close(self) -> None:
self.closed = True
class _DummyProcess:
def __init__(self):
self.stdin = _CaptureStdin()
def test_capture_event_writes_context_to_stdin_not_argv(isolate_config, monkeypatch):
config = Mem0Config()
config.platform.api_key = "m0-test-secret"
config.telemetry.anonymous_id = "cli-anon-test"
save_config(config)
captured: dict[str, object] = {}
proc = _DummyProcess()
def fake_popen(args, **kwargs):
captured["args"] = args
captured["kwargs"] = kwargs
return proc
monkeypatch.setattr("mem0_cli.telemetry.subprocess.Popen", fake_popen)
capture_event("unit_test_event", {"case": "stdin-secret"})
argv = captured["args"]
assert argv == [sys.executable, "-m", "mem0_cli.telemetry_sender"]
assert all("m0-test-secret" not in arg for arg in argv)
kwargs = captured["kwargs"]
assert kwargs["stdin"] == subprocess.PIPE
assert kwargs["text"] is True
ctx = json.loads(proc.stdin.buffer)
assert ctx["mem0_api_key"] == "m0-test-secret"
assert ctx["payload"]["event"] == "unit_test_event"
assert proc.stdin.closed
def test_load_context_reads_from_stdin(monkeypatch):
monkeypatch.setattr("sys.argv", ["telemetry_sender"])
monkeypatch.setattr("sys.stdin", io.StringIO('{"payload": {"event": "stdin"}}'))
ctx = _load_context()
assert ctx["payload"]["event"] == "stdin"
def test_load_context_falls_back_to_argv(monkeypatch):
monkeypatch.setattr("sys.argv", ["telemetry_sender", '{"payload": {"event": "argv"}}'])
monkeypatch.setattr("sys.stdin", io.StringIO(""))
ctx = _load_context()
assert ctx["payload"]["event"] == "argv"
@@ -50,6 +50,7 @@ Provide conversation messages for Mem0 to extract memories from. At least one en
| `app_id` | string | No* | Associates the memory with an app. |
| `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). |
| `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
| `expiration_date` | string | Optional | Date in `YYYY-MM-DD` format. The memory is visible through this date and hidden by default after it passes. |
> \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required.
@@ -83,3 +84,11 @@ The request is queued for background processing. The response contains an `event
<Info>
Poll the event status via `GET /v1/event/{event_id}/`. Status will be `SUCCEEDED` or `FAILED` once processing completes.
</Info>
<Info>
Memories with `expiration_date` remain stored after they expire. Search and get-all hide them by default; pass `show_expired: true` to include them.
</Info>
<Info>
Python uses `expiration_date`; TypeScript uses `expirationDate`.
</Info>
@@ -4,4 +4,4 @@ description: "Submit an export job to create a structured memory export using a
openapi: post /v1/exports/
---
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `run_id`, or `session_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `app_id`, or `run_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
@@ -6,6 +6,10 @@ openapi: post /v3/memories/
List memories scoped by filters with paginated results. Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400.
Expired memories are hidden by default. Pass `show_expired: true` to include memories whose `expiration_date` has passed.
Python uses `show_expired`; TypeScript uses `showExpired`.
The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators:
- `in`: Matches any of the values specified
@@ -32,6 +36,7 @@ memories = client.get_all(
}
]
},
show_expired=False,
page=1,
page_size=50
)
@@ -46,12 +51,14 @@ memories = client.get_all(
{
"id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c",
"memory": "Alex is planning a trip to San Francisco from July 1st to July 10th",
"expiration_date": null,
"created_at": "2024-07-01T12:00:00Z",
"updated_at": "2024-07-01T12:00:00Z"
},
{
"id": "a2b8c3d4-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
"memory": "Alex prefers vegetarian restaurants",
"expiration_date": null,
"created_at": "2024-07-05T15:30:00Z",
"updated_at": "2024-07-05T15:30:00Z"
}
@@ -4,4 +4,4 @@ description: "Retrieve the latest structured memory export after submitting an e
openapi: post /v1/exports/get
---
Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `run_id`, `session_id`, or `app_id` to get the most recent export matching your filters.
Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `agent_id`, `app_id`, `run_id`, `created_at`, or `updated_at` to get the most recent export matching your filters.
+11 -5
View File
@@ -8,6 +8,10 @@ Relevance-ranked hybrid search across stored memories. V3 uses multi-signal retr
Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400. At least one entity ID is required.
Expired memories are hidden by default. Pass `show_expired: true` to include memories whose `expiration_date` has passed.
Python uses `show_expired`; TypeScript uses `showExpired`.
The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators:
- `in`: Matches any of the values specified
- `gte`: Greater than or equal to
@@ -20,16 +24,17 @@ The `filters` object supports complex logical operations (AND, OR, NOT) and comp
### Search parameter defaults
| Parameter | V1/V2 | V3 |
| --- | --- | --- |
| `top_k` | Supported (default 10) | Supported (1-1000, default 10) |
| `threshold` | No default | Default `0.1` (pass `0.0` to disable) |
| `rerank` | Default `true` | Default `false` (pass `true` to enable) |
| Parameter | Default |
| --- | --- |
| `top_k` | `10` (range 1–1000) |
| `threshold` | `0.1` (pass `0.0` to disable) |
| `rerank` | `false` (pass `true` to enable) |
<CodeGroup>
```python Platform API Example
related_memories = client.search(
query="What are Alice's hobbies?",
show_expired=False,
filters={
"OR": [
{
@@ -54,6 +59,7 @@ related_memories = client.search(
"category": "hobbies"
},
"score": 0.82,
"expiration_date": null,
"created_at": "2024-07-26T10:29:36.630547-07:00",
"updated_at": null,
"categories": ["hobbies"]
+11 -2
View File
@@ -1,5 +1,14 @@
---
title: 'Update Memory'
description: "Update the content or metadata of a single memory by its unique ID using the PUT endpoint."
description: "Update the content, metadata, timestamp, or expiration date of a single memory by its unique ID using the PUT endpoint."
openapi: put /v1/memories/{memory_id}/
---
---
Use this endpoint to update mutable memory fields. To make a memory expire, set `expiration_date` to a `YYYY-MM-DD` date. To make it permanent again, send `expiration_date: null`.
```python
client.update("mem_123", expiration_date="2030-01-31")
client.update("mem_123", expiration_date=None)
```
TypeScript uses `expirationDate`.
@@ -0,0 +1,5 @@
---
title: "Remove Organization Member"
description: "Remove a member from an organization to revoke their access to its projects and resources."
openapi: "delete /api/v1/orgs/organizations/{org_id}/members/"
---
@@ -0,0 +1,5 @@
---
title: "Update Organization Member"
description: "Update an existing member's role within an organization to change their permissions and access level."
openapi: "put /api/v1/orgs/organizations/{org_id}/members/"
---
+41 -2
View File
@@ -14,7 +14,7 @@ Organizations and projects are **optional** features. You can use Mem0 without t
## Key Capabilities
- **Multi-org/project Support**: Specify organization and project when initializing the Mem0 client to attribute API usage appropriately
- **Multi-org/project Support**: Organization and project are resolved automatically from your API key via `/v1/ping/` — no org or project params are accepted by `MemoryClient.__init__`. Use a project-specific API key to target a particular project.
- **Member Management**: Control access to data through organization and project membership
- **Access Control**: Only members can access memories and data within their organization/project scope
- **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration
@@ -79,7 +79,7 @@ new_project = client.project.create(
### Update Project Settings
Modify project configuration including custom instructions, categories, graph settings, and language preferences:
Modify project configuration including custom instructions, categories, language preferences, retrieval criteria, and memory decay:
```python
# Update project with custom categories
@@ -98,6 +98,17 @@ client.project.update(
# Use the input language for memory storage and retrieval
client.project.update(multilingual=True)
# Set retrieval criteria to control which memories are surfaced in search
client.project.update(
retrieval_criteria=[
{"name": "relevance", "description": "How directly relevant this memory is to the current topic or user query", "weight": 3},
{"name": "access_frequency", "description": "How often this memory has been accessed or surfaced recently", "weight": 1}
]
)
# Enable Memory Decay (boosts recently-accessed memories at search time)
client.project.update(decay=True)
# Update multiple settings at once
client.project.update(
custom_instructions="...",
@@ -109,6 +120,34 @@ client.project.update(
)
```
#### Set Retrieval Criteria
`retrieval_criteria` is a per-project list of dictionaries (`List[Dict]`) that shapes how memories are ranked and filtered during search. Each dictionary has three fields: `name` (identifier), `description` (interpreted by the LLM to score each memory), and `weight` (relative influence on the final score). Use this to focus retrieval on intent-aligned or signal-specific memories:
```python
client.project.update(
retrieval_criteria=[
{
"name": "joy",
"description": "Measure the intensity of positive emotions such as happiness, excitement, or amusement expressed in the memory. A higher score reflects greater joy.",
"weight": 3
},
{
"name": "curiosity",
"description": "Assess the extent to which the memory reflects inquisitiveness or interest in exploring new information. A higher score reflects stronger curiosity.",
"weight": 2
},
{
"name": "access_frequency",
"description": "How often this memory has been accessed or surfaced recently.",
"weight": 1
}
]
)
```
Pass an empty list to clear all criteria and restore default retrieval behaviour.
#### Toggle Memory Decay
`decay` is a per-project boolean that turns on [Memory Decay](/platform/features/memory-decay) — a search-time ranking bias that reinforces recently-accessed memories and gently dampens stale ones. The flag is `false` by default; set it via the same project-update endpoint:
@@ -0,0 +1,5 @@
---
title: "Remove Project Member"
description: "Remove a member from a project to revoke their access to its memories, configuration, and resources."
openapi: "delete /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/"
---
@@ -0,0 +1,5 @@
---
title: "Update Project Member"
description: "Update an existing member's role within a project to change their permissions and access level."
openapi: "put /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/"
---
@@ -0,0 +1,5 @@
---
title: "Update Project"
description: "Update a project's settings, including name, custom instructions, and other configuration options."
openapi: "patch /api/v1/orgs/organizations/{org_id}/projects/{project_id}/"
---
+3 -3
View File
@@ -46,9 +46,9 @@ Ground-up rewrite of the memory pipeline with 20+ point benchmark improvements:
- **~3-4x fewer tokens** — Under 7K tokens per retrieval vs 25K+ for full-context approaches
- **ADD-only extraction** — Memories accumulate; nothing is overwritten or deleted
- **Hybrid retrieval** — Semantic + BM25 keyword + entity boost, scored in parallel
- **Entity linking** — Entities extracted, embedded, and linked across memories
- **Graph memory (built-in)**: entities extracted, embedded, and linked across memories, with no external graph store required
Breaking changes: Graph memory removed from OSS, `search()` defaults changed, deprecated params removed. See [migration guide](/migration/oss-v2-to-v3).
Breaking changes: external graph stores removed from OSS (replaced by built-in graph memory), `search()` defaults changed, deprecated params removed. See [migration guide](/migration/oss-v2-to-v3).
</Update>
@@ -113,7 +113,7 @@ Launched a unified Mem0 plugin across three major AI development environments
Major expansion of the provider ecosystem:
- **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE)
- **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE). **Note:** All external graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE) were subsequently removed in v2.0.0 (2026-04-14). Graph memory is now built-in entity linking with no external graph store required; see the [v2.0.0 entry above](#mem0-sdk-v2-0-0-v3-0-0).
- **Turbopuffer** — New vector database provider for Python SDK
- **MiniMax** — New LLM provider with dedicated AWS Bedrock support
- **pgvector for Node.js** — PostgreSQL vector support added to the TypeScript OSS SDK
+33
View File
@@ -4,6 +4,39 @@ description: "Release notes for the OpenClaw plugin and agent harness."
mode: "wide"
---
<Update label="2026-06-12" description="v1.0.13">
**Fixes:**
- **Custom categories payload:** `customCategories` (a `Record<string, string>` map) is now converted via the new `customCategoryMapToList()` helper into the `Array<Record<string, string>>` shape the Mem0 SDK expects on `add` calls — previously the raw object was passed as `custom_categories` and silently ignored ([#5345](https://github.com/mem0ai/mem0/pull/5345))
- **Skip runtime setup during metadata registration:** `register()` now detects `registrationMode === "cli-metadata"`, registers only the CLI commands, and returns early — avoiding backend initialization, service/tool registration, and hook installation during OpenClaw's metadata-only registration pass ([#5383](https://github.com/mem0ai/mem0/pull/5383))
**Security:**
- Bumped `mem0ai` from `3.0.3` to `3.0.7` (latest Node SDK) — includes the transitive axios CVE remediation shipped in `3.0.6` ([#5460](https://github.com/mem0ai/mem0/pull/5460))
- Added pnpm override `uuid@<11.1.1` → `>=11.1.1` to resolve an open MEDIUM Dependabot alert ([#5489](https://github.com/mem0ai/mem0/pull/5489))
**Improvements:**
- **Repo consolidation:** Plugin moved from repo-root `openclaw/` to `integrations/openclaw/`; `package.json` `repository.directory` updated to match so npm provenance links to the correct subdirectory ([#5491](https://github.com/mem0ai/mem0/pull/5491))
**Tests:**
- Added `customCategoryMapToList` unit tests and a `PlatformProvider` test asserting `custom_categories` is passed to the Mem0 SDK as a list ([#5345](https://github.com/mem0ai/mem0/pull/5345))
- Added a regression test asserting `cli-metadata` registration registers only CLI commands and triggers no runtime side effects ([#5383](https://github.com/mem0ai/mem0/pull/5383))
</Update>
<Update label="2026-06-02" description="v1.0.12">
**Docs:**
- **Agent Mode onboarding:** README now documents an autonomous setup path for AI agents — `mem0 init --agent --json` mints an evaluation Mem0 API key with no email, OTP, or browser and exports it as `MEM0_API_KEY` for `openclaw mem0 init`; a human owner can later run `mem0 init --email <email>` to claim ownership without disrupting the agent ([#5123](https://github.com/mem0ai/mem0/pull/5123))
**Security:**
- Added pnpm overrides to remediate advisories in transitive dependencies: `langsmith@<0.6.0` → `^0.6.0`, `picomatch@<2.3.2` → `^2.3.2`, `vite` → `^8.0.5`, and `@qdrant/js-client-rest` → `^1.18.0` ([#5294](https://github.com/mem0ai/mem0/pull/5294))
**Dependencies:**
- Bumped `mem0ai` from `3.0.2` to `3.0.3` ([#5212](https://github.com/mem0ai/mem0/pull/5212))
- Bumped dev dependencies `@vitest/coverage-v8` and `vitest` from `^4.0.18` to `^4.1.7`; added `vite@^8.0.5` and `@qdrant/js-client-rest@^1.18.0` ([#5294](https://github.com/mem0ai/mem0/pull/5294))
</Update>
<Update label="2026-04-29" description="v1.0.11">
**New Features:**
+1 -1
View File
@@ -25,7 +25,7 @@ mode: "wide"
<Update label="2026-04-16" description="">
**Improvements:**
- **UI:** Removed Graph Memory tab, page, and all references from dashboard, sidebar, project settings, playground, and billing
- **UI:** Removed the legacy external-graph-store visualization tab, page, and its references from dashboard, sidebar, project settings, playground, and billing
</Update>
+261 -4
View File
@@ -7,6 +7,143 @@ mode: "wide"
<Tabs>
<Tab title="Python">
<Update label="2026-06-24" description="v2.0.9">
**Bug Fixes:**
- **Memory (OSS):** Improve entity extraction precision by avoiding sentence-start common noun noise, preserving useful topic phrases, and exact-deduplicating entity links before semantic matching ([#5829](https://github.com/mem0ai/mem0/pull/5829))
</Update>
<Update label="2026-06-24" description="v2.0.8">
**New Features:**
- **Embeddings:** Add native `embed_batch` to five embedders — LM Studio, Together, HuggingFace, Vertex AI, and Google GenAI — for batched embedding requests ([#5609](https://github.com/mem0ai/mem0/pull/5609))
**Bug Fixes:**
- **Core:** Guard against malformed `image_url` entries in `parse_vision_messages` to prevent crashes ([#5631](https://github.com/mem0ai/mem0/pull/5631))
- **Core:** Return `attributed_to` from `get()`, `get_all()`, and `search()` ([#5629](https://github.com/mem0ai/mem0/pull/5629))
- **Core:** Fix `reset()` only dropping the history table and leaving stale messages behind ([#5541](https://github.com/mem0ai/mem0/pull/5541))
- **Core:** Guard against an entity `embed_batch` count mismatch in the v3 add pipeline ([#5604](https://github.com/mem0ai/mem0/pull/5604))
- **Core:** Fix an async `delete_all` race condition that corrupted the entity store's `linked_memory_ids` ([#5553](https://github.com/mem0ai/mem0/pull/5553))
- **LLMs:** Skip the JSON `response_format` for Groq compound models that reject it ([#5513](https://github.com/mem0ai/mem0/pull/5513))
- **LLMs:** Preserve reasoning fields during base-to-provider config conversion ([#5638](https://github.com/mem0ai/mem0/pull/5638))
- **LLMs:** Pass the configured `anthropic_base_url` to the Anthropic client ([#5626](https://github.com/mem0ai/mem0/pull/5626))
- **LLMs:** Stop the Azure provider from mutating and corrupting caller messages during content rewrite ([#5731](https://github.com/mem0ai/mem0/pull/5731))
- **LLMs & Embeddings:** Repair HTTP proxy support for `httpx>=0.28` and preserve `proxies` in `LlmFactory` ([#5447](https://github.com/mem0ai/mem0/pull/5447))
- **Embeddings:** Forward `embedding_dims` to Titan V2 in the AWS Bedrock embedder ([#5671](https://github.com/mem0ai/mem0/pull/5671))
- **Rerankers:** Log reranking failures instead of swallowing them silently ([#5717](https://github.com/mem0ai/mem0/pull/5717))
- **Rerankers:** Clamp out-of-range LLM scores instead of mis-parsing them ([#5635](https://github.com/mem0ai/mem0/pull/5635))
- **Rerankers:** Export all five rerankers from the package root ([#5636](https://github.com/mem0ai/mem0/pull/5636))
- **Vector Stores:** Point the FastEmbed-missing warning at `mem0ai[extras]` ([#5622](https://github.com/mem0ai/mem0/pull/5622))
- **Vector Stores:** Preserve empty Azure AI Search update values ([#5524](https://github.com/mem0ai/mem0/pull/5524))
- **Vector Stores:** Add an `auto_refresh` option for OpenSearch Serverless compatibility ([#3893](https://github.com/mem0ai/mem0/pull/3893))
- **Vector Stores:** Wrap a scalar `vector_id` in a list for Chroma `delete()` ([#5703](https://github.com/mem0ai/mem0/pull/5703))
- **Vector Stores:** Wrap Chroma `update()` ids, embeddings, and metadatas in lists ([#5757](https://github.com/mem0ai/mem0/pull/5757))
- **Vector Stores:** Wrap a scalar `vector_id` in a list for Milvus `delete()` ([#5704](https://github.com/mem0ai/mem0/pull/5704))
- **Vector Stores:** Map all comparison operators in the Pinecone `_create_filter()` ([#5707](https://github.com/mem0ai/mem0/pull/5707))
- **Vector Stores:** Return `None` instead of `{}` from Chroma `_generate_where_clause` for empty filters ([#5713](https://github.com/mem0ai/mem0/pull/5713))
- **Vector Stores:** Return `[[]]` from the OpenSearch `list()` error path to honor the `list()` contract ([#5727](https://github.com/mem0ai/mem0/pull/5727))
- **Vector Stores:** Return `[[]]` from the Pinecone `list()` error path instead of a dict ([#5706](https://github.com/mem0ai/mem0/pull/5706))
- **Vector Stores:** Return `[[]]` for an uninitialized FAISS index to honor the `list()` contract ([#5725](https://github.com/mem0ai/mem0/pull/5725))
- **Vector Stores:** Wrap the MongoDB `list()` return in an outer list to match the interface contract ([#5729](https://github.com/mem0ai/mem0/pull/5729))
- **Vector Stores:** Deep-copy Redis `DEFAULT_FIELDS` so instances keep distinct dims ([#5633](https://github.com/mem0ai/mem0/pull/5633))
- **Vector Stores:** Pass the required `vectors` arg in Vertex AI `list()` and similarity search ([#5627](https://github.com/mem0ai/mem0/pull/5627))
- **Vector Stores:** Return `None` from Redis `get()` for missing IDs ([#5625](https://github.com/mem0ai/mem0/pull/5625))
- **Vector Stores:** Drop a stray `print` in Weaviate `list_cols` ([#5637](https://github.com/mem0ai/mem0/pull/5637))
- **Graph:** Keep distinct entities that share a substring prefix ([#5630](https://github.com/mem0ai/mem0/pull/5630))
- **Client:** Check the HTTP status before parsing the ping response in `_validate_api_key` ([#5639](https://github.com/mem0ai/mem0/pull/5639))
- **Server:** Fetch filtered dashboard memories beyond the default page ([#5753](https://github.com/mem0ai/mem0/pull/5753))
- **Server:** Return 404/400 instead of 502 for not-found and invalid input ([#5634](https://github.com/mem0ai/mem0/pull/5634))
- **Server:** Return 404 instead of 500 for a malformed API key id on revoke ([#5640](https://github.com/mem0ai/mem0/pull/5640))
- **Server:** Use `127.0.0.1` in the dashboard healthcheck to avoid IPv6 localhost resolution ([#5612](https://github.com/mem0ai/mem0/pull/5612))
**Improvements:**
- **Vector Stores:** Batch BM25 sparse encoding in Qdrant insert ([#5592](https://github.com/mem0ai/mem0/pull/5592))
**Security:**
- **Vector Stores:** Sanitize Milvus and Baidu filter values to prevent expression injection ([#5746](https://github.com/mem0ai/mem0/pull/5746))
- **Vector Stores:** Reject dict filter values in MongoDB to prevent NoSQL operator injection ([#5748](https://github.com/mem0ai/mem0/pull/5748))
</Update>
<Update label="2026-06-17" description="v2.0.7">
**New Features:**
- **LLMs:** Add Gemini via Vertex AI as LLM provider ([#4030](https://github.com/mem0ai/mem0/pull/4030))
- **Embeddings:** Add native `embed_batch` to `OllamaEmbedding` for batched embedding requests ([#5415](https://github.com/mem0ai/mem0/pull/5415))
**Bug Fixes:**
- **Core:** Fix `api_error_handler` silently dropping return values from async methods ([#5540](https://github.com/mem0ai/mem0/pull/5540))
- **Core:** Fix `AsyncMemory.reset()` not resetting the entity store ([#5535](https://github.com/mem0ai/mem0/pull/5535))
- **Core:** Fix `async delete_all` aborting on first error, leaving partial deletion ([#5529](https://github.com/mem0ai/mem0/pull/5529))
- **Core:** Skip messages without a `content` key in message parsers to prevent `KeyError` crashes ([#5575](https://github.com/mem0ai/mem0/pull/5575))
- **Core:** Preserve custom metadata fields during memory update ([#5480](https://github.com/mem0ai/mem0/pull/5480))
- **LLMs:** Fix Anthropic `tool_choice` format and tool response parsing ([#5537](https://github.com/mem0ai/mem0/pull/5537))
- **LLMs:** Fix Ollama `json` format mutating the caller's messages list in-place ([#5539](https://github.com/mem0ai/mem0/pull/5539))
- **LLMs:** Omit `None` config values from Gemini `GenerateContentConfig` to prevent validation errors ([#5528](https://github.com/mem0ai/mem0/pull/5528))
- **LLMs:** Honor reasoning-model params in `AzureOpenAIStructuredLLM` ([#5548](https://github.com/mem0ai/mem0/pull/5548))
- **LLMs:** Honor reasoning-model params in `OpenAIStructuredLLM` ([#5458](https://github.com/mem0ai/mem0/pull/5458))
- **LLMs:** Send `max_completion_tokens` for the GPT-5 family across all providers ([#5547](https://github.com/mem0ai/mem0/pull/5547))
- **LLMs:** Accept and forward `**kwargs` in Together, LangChain, and Sarvam providers ([#5556](https://github.com/mem0ai/mem0/pull/5556))
- **LLMs:** Fix Bedrock AI21 response parse default using `dict` literal instead of `set` ([#5527](https://github.com/mem0ai/mem0/pull/5527))
- **LLMs:** Fix LiteLLM function-calling check blocking all calls on non-tool models ([#5536](https://github.com/mem0ai/mem0/pull/5536))
- **LLMs:** Fix HuggingFace provider using `self.config` instead of raw `config` parameter ([#5538](https://github.com/mem0ai/mem0/pull/5538))
- **Embeddings:** Honor `aws_session_token` in AWS Bedrock embeddings ([#5566](https://github.com/mem0ai/mem0/pull/5566))
- **Rerankers:** Respect `config.top_k` in Cohere and ZeroEntropy fallback paths ([#5560](https://github.com/mem0ai/mem0/pull/5560))
- **Vector Stores:** Fix FAISS filtered search dropping over-fetched candidates before filtering ([#5453](https://github.com/mem0ai/mem0/pull/5453))
- **Vector Stores:** Fix Weaviate `reset()` crashing with missing `vector_size` argument ([#5531](https://github.com/mem0ai/mem0/pull/5531))
- **Vector Stores:** Pass embedding dims in Weaviate `reset()` to avoid re-init crash ([#5570](https://github.com/mem0ai/mem0/pull/5570))
- **Vector Stores:** Fix MongoDB `reset()` passing wrong argument to `create_col()` ([#5532](https://github.com/mem0ai/mem0/pull/5532))
- **Vector Stores:** Fix Pinecone hybrid search crashing when `filters` is `None` ([#5533](https://github.com/mem0ai/mem0/pull/5533))
- **Vector Stores:** Fix Redis crashing on empty or `None` filters in `search()` and `list()` ([#5446](https://github.com/mem0ai/mem0/pull/5446))
- **Vector Stores:** Return `None` from `get()` for missing IDs in Milvus, Weaviate, and Supabase ([#5562](https://github.com/mem0ai/mem0/pull/5562))
- **Vector Stores:** Return `None` from ChromaDB `get()` for missing IDs ([#5561](https://github.com/mem0ai/mem0/pull/5561))
</Update>
<Update label="2026-06-13" description="v2.0.6">
**New Features:**
- **Memory:** Add a contextual OSS-to-Platform notices system that surfaces occasional, situation-aware messages (first run, scale/performance thresholds, slow queries, and when temporal/decay features are relevant) pointing to the corresponding Mem0 Platform capabilities; disable via `MEM0_TELEMETRY=false` ([#5494](https://github.com/mem0ai/mem0/pull/5494))
**Bug Fixes:**
- **Memory:** Prevent a crash in `parse_vision_messages` when vision support is disabled ([#5487](https://github.com/mem0ai/mem0/pull/5487))
- **Vector Stores:** Expose the `https` option on the Qdrant vector store configuration so TLS endpoints can be targeted explicitly ([#5380](https://github.com/mem0ai/mem0/pull/5380))
- **Vector Stores:** Use valid S3 Vectors entity index names, fixing index operations that failed on invalid names ([#5416](https://github.com/mem0ai/mem0/pull/5416))
- **Vector Stores:** Fix `search()` crashing with a `TypeError` in the LangChain vector store when a result score is `None` ([#5072](https://github.com/mem0ai/mem0/pull/5072))
- **Vector Stores:** Use `is not None` instead of a truthiness check for vector/payload in the PGVector `update()` path, so valid empty/zero values are no longer skipped ([#5488](https://github.com/mem0ai/mem0/pull/5488))
- **Vector Stores:** Index the Valkey `memory` field as `TEXT` rather than `TAG` so full-text search behaves correctly ([#5443](https://github.com/mem0ai/mem0/pull/5443))
- **Vector Stores:** Implement `$not` filter support in the ChromaDB vector store ([#5485](https://github.com/mem0ai/mem0/pull/5485))
</Update>
<Update label="2026-06-10" description="v2.0.5">
**New Features:**
- **Memory:** Warn at init time when hybrid/BM25 search silently degrades to semantic-only because the configured vector store does not implement `keyword_search`. Affected stores: Chroma, FAISS, Cassandra, LangChain, Neptune Analytics, S3 Vectors, Supabase, TurboPuffer, Valkey ([#5444](https://github.com/mem0ai/mem0/pull/5444))
- **Memory:** Add opt-in `explain=True` parameter to `Memory.search()` and `AsyncMemory.search()`. When enabled, each result includes a `score_details` dict with `semantic_score`, `bm25_score`, `entity_boost`, `raw_score`, `max_possible_score`, `final_score`, and `threshold` so callers can understand and tune retrieval ranking ([#5102](https://github.com/mem0ai/mem0/pull/5102))
**Bug Fixes:**
- **Vector Stores:** Normalize similarity scores to `[0, 1]` (higher = better) consistently across all backends. 11 adapters previously returned raw distance metrics (lower = better) — FAISS, Chroma, Milvus, Redis, Cassandra, PGVector, S3 Vectors, Supabase, Valkey, Azure MySQL, and Vertex AI Vector Search — causing incorrect ranking in multi-store setups ([#5391](https://github.com/mem0ai/mem0/pull/5391))
- **Memory:** Parallelize entity boost searches in `Memory.search()` and `AsyncMemory.search()`. Previously up to 8 entities were embedded and queried sequentially (16 serial round-trips with remote embedders); all entity lookups now run concurrently, eliminating multi-second latency on entity-rich queries ([#5377](https://github.com/mem0ai/mem0/pull/5377))
- **Memory:** Reject empty or whitespace-only queries in `Memory.search()`, `AsyncMemory.search()`, `MemoryClient.search()`, and `AsyncMemoryClient.search()` before any embedding or API call is made. Also strips leading/trailing whitespace from valid queries ([#5258](https://github.com/mem0ai/mem0/pull/5258))
- **LLMs:** Add `is_reasoning_model: Optional[bool]` override to `BaseLlmConfig` (surfaced on `OpenAILlmConfig` and `AzureOpenAILlmConfig`). Fixes silent zero-extraction when using Azure deployments with versioned `gpt-5.x` names that the automatic name-based heuristic cannot recognize ([#5327](https://github.com/mem0ai/mem0/pull/5327))
- **LLMs:** Fix xAI LLM provider: add `XAIConfig` with `xai_base_url`, forward `tools`/`tool_choice` in `generate_response()`, and parse `tool_calls` in the response. Previously the provider raised `AttributeError` at init and silently dropped tool results ([#5190](https://github.com/mem0ai/mem0/pull/5190))
- **Vector Stores:** Fix PGVector `ConnectionPool` hang in Docker Compose environments where the app container starts before Postgres is DNS-resolvable — switched to `open=False` to avoid blocking constructor or silent zombie pool ([#5155](https://github.com/mem0ai/mem0/pull/5155))
- **Vector Stores:** Fix PGVector `sslmode` handling for PostgreSQL URIs — the `sslmode` query parameter is now correctly extracted and forwarded when building the async connection pool ([#5308](https://github.com/mem0ai/mem0/pull/5308))
- **Vector Stores:** Fix S3 Vectors `list()` not applying metadata filters — filtering is now done client-side after fetching, with pagination preserved and `top_k` applied after filtering to prevent pre-truncation of matching rows ([#5018](https://github.com/mem0ai/mem0/pull/5018))
- **Vector Stores:** Fix Upstash Vector `search()` routing all queries to the default namespace — `namespace` is now passed as a top-level keyword argument to `query_many()` instead of inside the per-query dict where it was silently ignored ([#5202](https://github.com/mem0ai/mem0/pull/5202))
- **Core:** Replace mutable default arguments with `None` sentinels in embedder configs and the proxy module, preventing cross-request state contamination ([#5302](https://github.com/mem0ai/mem0/pull/5302))
</Update>
<Update label="2026-05-27" description="v2.0.4">
**New Features:**
- **Client:** `delete()` and async `delete()` accept `delete_linked` (default `False`). When `True`, deleting a memory also removes the older memories it superseded (the v3 `linked_memory_ids` chain), transitively — the delete-side counterpart of `latest_only`, so a superseded memory does not resurface after the current one is deleted ([#5270](https://github.com/mem0ai/mem0/pull/5270))
</Update>
<Update label="2026-05-26" description="v2.0.3">
**Bug Fixes:**
@@ -71,8 +208,8 @@ mode: "wide"
- **`messages` in `Memory.add()` rejects invalid types:** Passing `None` or non-`(str | dict | list)` values raises `Mem0ValidationError` (`error_code="VALIDATION_003"`) ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **`qdrant-client>=1.12.0` required** — Upgrade from `>=1.9.1` ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`org_id` and `project_id` removed** — Removed from `MemoryClient` constructor and all method signatures ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **Graph Memory Removed (OSS):** `mem0/memory/graph_memory.py`, `memgraph_memory.py`, `kuzu_memory.py`, `apache_age_memory.py`, and `mem0/graphs/` (Neo4j / Memgraph / Kuzu / Apache AGE / Neptune drivers) deleted — ~4,000 lines. Graph memory is no longer supported in the OSS SDK; graph drivers (neo4j, memgraph, kuzu, etc.) can be uninstalled. Use the Platform API for graph features. Remove `enable_graph` and `graph_store` from your config ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`enable_graph` removed from Client SDK** — Graph memory is now a project-level setting on the Platform. Remove `enable_graph` from `MemoryClient.add()` / `search()` / `get_all()` / `update_project()` calls ([#4776](https://github.com/mem0ai/mem0/pull/4776))
- **External Graph Store Removed (OSS):** `mem0/memory/graph_memory.py`, `memgraph_memory.py`, `kuzu_memory.py`, `apache_age_memory.py`, and `mem0/graphs/` (Neo4j / Memgraph / Kuzu / Apache AGE / Neptune drivers) deleted, about 4,000 lines. The external graph store integration is no longer part of the OSS SDK; graph drivers (neo4j, memgraph, kuzu, etc.) can be uninstalled. Graph memory now runs natively as built-in entity linking. Remove `enable_graph` and `graph_store` from your config ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`enable_graph` removed from Client SDK:** Graph memory now runs automatically and no longer needs a flag. Remove `enable_graph` from `MemoryClient.add()` / `search()` / `get_all()` / `update_project()` calls ([#4776](https://github.com/mem0ai/mem0/pull/4776))
- **`custom_fact_extraction_prompt` renamed to `custom_instructions`** — Update config and memory module references ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **Typed option classes** — Added Pydantic v2 typed classes: `AddMemoryOptions`, `SearchMemoryOptions`, `GetAllMemoryOptions`, `DeleteAllMemoryOptions`, `UpdateMemoryOptions`, `ProjectUpdateOptions` ([#4740](https://github.com/mem0ai/mem0/pull/4740))
@@ -92,7 +229,7 @@ mode: "wide"
**Improvements:**
- **Telemetry:** Sample OSS hot-path events at 10% via PostHog `before_send` hook to reduce event volume ([#4771](https://github.com/mem0ai/mem0/pull/4771))
See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-v2) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions.
See the [OSS v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions.
</Update>
@@ -932,6 +1069,82 @@ See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-
</Tab>
<Tab title="TypeScript">
<Update label="2026-06-24" description="v3.0.11">
**Bug Fixes:**
- **Memory (OSS):** Align entity extraction with Python by reducing generic entity noise, preserving useful topic phrases, and exact-deduplicating entity links before semantic matching ([#5829](https://github.com/mem0ai/mem0/pull/5829))
</Update>
<Update label="2026-06-24" description="v3.0.10">
**Bug Fixes:**
- **Memory (OSS):** Guard against malformed `image_url` entries in `parseVisionMessages` to prevent crashes ([#5631](https://github.com/mem0ai/mem0/pull/5631))
- **Memory (OSS):** Return `attributedTo` from `get()`, `search()`, and `getAll()` ([#5675](https://github.com/mem0ai/mem0/pull/5675))
- **Memory (OSS):** Preserve message roles in the extraction input so assistant facts aren't attributed to the user ([#5643](https://github.com/mem0ai/mem0/pull/5643))
- **Memory (OSS):** Reject empty or blank messages in `Memory.add()` to prevent hallucinated memories ([#5545](https://github.com/mem0ai/mem0/pull/5545))
- **Memory (OSS):** Check `message.role` instead of `content` when detecting system messages ([#3921](https://github.com/mem0ai/mem0/pull/3921))
- **LLMs:** Honor the configured `baseURL` in `AnthropicLLM` ([#5740](https://github.com/mem0ai/mem0/pull/5740))
- **Client:** Preserve `customCategories` names through key conversion ([#5741](https://github.com/mem0ai/mem0/pull/5741))
- **Client:** Prevent hallucinated memories on an empty messages payload ([#5613](https://github.com/mem0ai/mem0/pull/5613))
- **Client:** Preserve user metadata keys across the case-conversion round-trip ([#5515](https://github.com/mem0ai/mem0/pull/5515))
**Security:**
- **Dependencies:** Upgrade `form-data` to `>=4.0.6` across pnpm workspaces to remediate CVE-2026-12143 ([#5618](https://github.com/mem0ai/mem0/pull/5618))
</Update>
<Update label="2026-06-17" description="v3.0.9">
**Bug Fixes:**
- **LLMs:** Fix Anthropic `tool_choice` format — was incorrectly sent as a bare string `"auto"` (rejected by the API); now correctly sent as `{ type: "auto" }`. Also fixes tool response parsing: `tool_use` blocks are now parsed into `toolCalls` objects instead of throwing. Updated default model to `claude-sonnet-4-6` and default `max_tokens` to `2000` to match the Python provider. Added `temperature`, `topP`, and `maxTokens` to `LLMConfig` so Anthropic params can be configured ([#5537](https://github.com/mem0ai/mem0/pull/5537))
- **Memory (OSS):** Preserve custom metadata fields during `update()` — fields such as `category`, `priority`, and other user-defined keys were previously dropped on update; the existing payload is now spread before applying the new data ([#5480](https://github.com/mem0ai/mem0/pull/5480))
- **Client:** Preserve user-defined schema keys in `createMemoryExport` ([#5594](https://github.com/mem0ai/mem0/pull/5594))
**Security:**
- **Dependencies:** Bump `esbuild` to `>=0.28.1` across all npm packages via pnpm overrides to remediate upstream vulnerability ([#5563](https://github.com/mem0ai/mem0/pull/5563))
</Update>
<Update label="2026-06-13" description="v3.0.8">
**New Features:**
- **Memory:** Add a contextual OSS-to-Platform notices system that surfaces occasional, situation-aware messages (first run, scale/performance thresholds, slow queries, and when temporal/decay features are relevant) pointing to the corresponding Mem0 Platform capabilities; disable via `MEM0_TELEMETRY=false` ([#5494](https://github.com/mem0ai/mem0/pull/5494))
**Security:**
- **Dependencies:** Upgrade `@langchain/community` to `^1.1.18` to remediate CVE-2026-27795 and CVE-2026-26019 ([#5510](https://github.com/mem0ai/mem0/pull/5510))
- **Dependencies:** Resolve all open MEDIUM Dependabot alerts via pnpm overrides ([#5489](https://github.com/mem0ai/mem0/pull/5489))
</Update>
<Update label="2026-06-10" description="v3.0.7">
**New Features:**
- **Embeddings:** Add `LMStudioEmbedding` provider for local embeddings via the LM Studio server ([#5377](https://github.com/mem0ai/mem0/pull/5377))
- **Memory:** Add opt-in `explain: true` option to `Memory.search()`. When enabled, each result includes a `scoreBreakdown` object with `semantic`, `keyword`, `entityBoost`, and `temporalBoost` fields so callers can inspect and tune retrieval ranking ([#5102](https://github.com/mem0ai/mem0/pull/5102))
**Bug Fixes:**
- **Memory:** Parallelize entity boost searches in `Memory.search()`. All entity embed + store lookups now run concurrently instead of sequentially, eliminating multi-second latency on entity-rich queries with remote embedding providers ([#5377](https://github.com/mem0ai/mem0/pull/5377))
- **Vector Stores:** Normalize similarity scores to `[0, 1]` (higher = better) — fixed score inversion in the Redis vector store adapter ([#5391](https://github.com/mem0ai/mem0/pull/5391))
- **Embeddings:** Request `encoding_format: "float"` from the OpenAI embedder in both `embed()` and `embedBatch()`. Fixes incorrect vector dimensions when using OpenAI-compatible proxies that default to base64 encoding ([#5170](https://github.com/mem0ai/mem0/pull/5170))
</Update>
<Update label="2026-06-01" description="v3.0.6">
**Security:**
- **Dependencies:** Bumped `axios` to `^1.16.0` to remediate high-severity prototype-pollution CVEs (credential theft, MITM, DoS). Pinned transitive dependencies via pnpm overrides: `jws` → 4.0.1 (CVE-2025-65945), `langsmith` → ^0.6.0 (CVE-2026-45134), `tar-fs` → ^2.1.4 (CVE-2025-48387, CVE-2025-59343), `picomatch` → ^2.3.2 (CVE-2026-33671), `minimatch` → ^3.1.3 / ^5.1.8 / ^9.0.7 (CVE-2026-27903, CVE-2026-27904, CVE-2026-26996), `path-to-regexp` → ^8.4.0 (CVE-2026-4926), `rollup` → ^4.59.0 (CVE-2026-27606), `glob` → ^10.5.0 (CVE-2025-64756), `@modelcontextprotocol/sdk` → ^1.25.4 (CVE-2025-66414, CVE-2026-0621)
</Update>
<Update label="2026-05-27" description="v3.0.5">
**New Features:**
- **Client:** `delete()` accepts an options object with `deleteLinked` (serialized as `delete_linked`, default `false`). When `true`, deleting a memory also removes the older memories it superseded (the v3 linked chain), transitively — the delete-side counterpart of `latestOnly`, so a superseded memory does not resurface after the current one is deleted ([#5270](https://github.com/mem0ai/mem0/pull/5270))
</Update>
<Update label="2026-05-26" description="v3.0.4">
**Bug Fixes:**
@@ -984,7 +1197,7 @@ See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-
- **Default model:** `gpt-5-mini` is now the default in `OpenAI`, `OpenAIStructured`, and `Azure` LLM providers ([#4829](https://github.com/mem0ai/mem0/pull/4829))
**Breaking Changes:**
- **Graph Memory Removed (OSS):** `graph_memory.ts` (675 lines), `graphs/tools.ts` (267 lines), `graphs/utils.ts` (116 lines), `graphs/configs.ts` (30 lines) deleted. Graph memory is no longer supported in the OSS SDK — use Platform API for graph features ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **External Graph Store Removed (OSS):** `graph_memory.ts` (675 lines), `graphs/tools.ts` (267 lines), `graphs/utils.ts` (116 lines), `graphs/configs.ts` (30 lines) deleted. The external graph store integration is no longer part of the OSS SDK; graph memory now runs natively as built-in entity linking ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **camelCase Parameters (Client SDK):** All user-facing parameters converted from snake_case to camelCase. Mapping is transparent at API boundary via `camelToSnakeKeys()` / `snakeToCamelKeys()` ([#4776](https://github.com/mem0ai/mem0/pull/4776))
```typescript
// Before
@@ -1338,6 +1551,13 @@ See the [TypeScript SDK migration guide](https://docs.mem0.ai/migration/ts-v2-to
<Tab title="CLI">
<Update label="2026-06-01" description="Node v0.2.8">
**Security:**
- **Dependencies:** Pinned transitive dependencies via pnpm overrides to remediate high-severity CVEs: `jws` → 4.0.1 (CVE-2025-65945), `langsmith` → ^0.6.0 (CVE-2026-45134), `tar-fs` → ^2.1.4 (CVE-2025-48387, CVE-2025-59343), `picomatch` → ^2.3.2 (CVE-2026-33671), `minimatch` → ^3.1.3 / ^5.1.8 / ^9.0.7 (CVE-2026-27903, CVE-2026-27904, CVE-2026-26996), `path-to-regexp` → ^8.4.0 (CVE-2026-4926), `rollup` → ^4.59.0 (CVE-2026-27606), `glob` → ^10.5.0 (CVE-2025-64756), `@modelcontextprotocol/sdk` → ^1.25.4 (CVE-2025-66414, CVE-2026-0621)
</Update>
<Update label="2026-05-16" description="Python v0.2.6 / Node v0.2.6">
**Bug Fixes:**
@@ -1454,6 +1674,43 @@ A full-featured command-line interface for Mem0, available in both Python and No
<Tab title="Plugins">
<Update label="2026-06-01" description="openclaw-mem0 v1.0.12">
**Security:**
- **Dependencies:** Pinned transitive dependencies via pnpm overrides to remediate high-severity CVEs: `protobufjs` → ^7.5.5, `vite` → ^8.0.5, `langsmith` → ^0.6.0 (CVE-2026-45134), `picomatch` → ^2.3.2 (CVE-2026-33671), `@qdrant/js-client-rest` → ^1.18.0
</Update>
<Update label="2026-06-10" description="Vercel AI SDK v3.0.0">
**Major Release** — Migrated to Vercel AI SDK v6 (`LanguageModelV3` / `ProviderV3`) and Mem0 v3 API.
**Breaking Changes:**
- **AI SDK v6:** Upgraded from AI SDK v5 (`LanguageModelV2`) to v6 (`LanguageModelV3`). Users must upgrade `ai` to `^6.0.199` and all `@ai-sdk/*` provider packages to `^3.x` ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Mem0 v3 API:** Memory endpoints migrated from `/v1/memories/` and `/v2/memories/search/` to `/v3/memories/add/` and `/v3/memories/search/`. Entity IDs (`user_id`, `agent_id`, `run_id`) now go inside the `filters` object for search requests ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Graph memory removed:** All `enable_graph`, graph prompts, and relation-extraction code removed. Graph memory is now a project-level setting on the Platform ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Deprecated params removed:** `org_id`, `project_id`, `org_name`, `project_name`, `output_format`, `filter_memories`, `async_mode`, `enable_graph`, `version`, `api_version` removed from `Mem0ConfigSettings` ([#4741](https://github.com/mem0ai/mem0/pull/4741))
**New Features:**
- **V3 provider contract:** `specificationVersion: 'v3'`, `supportedUrls` property, V3 content array in `doGenerate`, V3 stream lifecycle events in `doStream` ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Mem0 source in responses:** Memories are attached as a `source` in `generateText`/`streamText` responses with `providerMetadata.mem0.memories` for programmatic access ([#4741](https://github.com/mem0ai/mem0/pull/4741))
**Bug Fixes:**
- **Async memory storage:** `addMemories` is now properly `await`ed — memories no longer silently fail to store ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Prompt mutation:** Prompt array is now cloned before injecting memory context, preventing side effects on the caller's array ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Null guard on content:** `doGenerate` guards against null `content` from upstream providers ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Stream response:** `doStream` now returns the full `LanguageModelV3StreamResult` object preserving all V3 fields ([#4741](https://github.com/mem0ai/mem0/pull/4741))
- **Response normalization:** `getMemories` and `retrieveMemories` now handle both array and `{results: [...]}` envelope responses from the v3 API ([#4741](https://github.com/mem0ai/mem0/pull/4741))
</Update>
<Update label="2026-06-01" description="Vercel AI SDK v2.0.6">
**Security:**
- **Dependencies:** Pinned transitive dependencies via pnpm overrides to remediate high-severity CVEs: `glob` → ^10.5.0 (CVE-2025-64756), `minimatch` → ^3.1.3 / ^5.1.8 / ^9.0.7 (CVE-2026-27903, CVE-2026-27904, CVE-2026-26996), `picomatch` → ^2.3.2 (CVE-2026-33671), `rollup` → ^4.59.0 (CVE-2026-27606)
</Update>
<Update label="2026-04-02" description="mem0-plugin v1.0.0">
**Mem0 Plugin for Claude Code, Cursor, and Codex**
@@ -0,0 +1,50 @@
---
title: "FastEmbed"
description: "Configure FastEmbed as an embedding provider in Mem0 to generate embeddings locally using ONNX-based models without a GPU."
---
You can use FastEmbed to run embedding models locally in Mem0. FastEmbed is an ONNX-based embedding library that runs efficiently on CPU without requiring a GPU or an external API key.
### Installation
```bash
pip install fastembed
```
### Usage
<CodeGroup>
```python Python
import os
from mem0 import Memory
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
config = {
"embedder": {
"provider": "fastembed",
"config": {
"model": "thenlper/gte-large"
}
}
}
m = Memory.from_config(config)
messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about 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."}
]
m.add(messages, user_id="john")
```
</CodeGroup>
### Config
Here are the parameters available for configuring FastEmbed embedder:
| Parameter | Description | Default Value |
| --- | --- | --- |
| `model` | The name of the FastEmbed model to use | `thenlper/gte-large` |
| `embedding_dims` | Dimensions of the embedding model (auto-derived from the model if not set) | `None` |
+28 -1
View File
@@ -7,7 +7,8 @@ To use DeepSeek LLM models, you have to set the `DEEPSEEK_API_KEY` environment v
## Usage
```python
<CodeGroup>
```python Python
import os
from mem0 import Memory
@@ -36,6 +37,32 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movies"})
```
```typescript TypeScript
import { Memory } from 'mem0ai/oss';
const config = {
llm: {
provider: 'deepseek',
config: {
apiKey: process.env.DEEPSEEK_API_KEY || '',
model: 'deepseek-chat',
temperature: 0.2,
maxTokens: 2000,
top_p: 1.0,
},
},
};
const memory = new Memory(config);
const messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about 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."}
];
await memory.add(messages, { userId: 'alice', metadata: { category: 'movies' } });
```
</CodeGroup>
You can also configure the API base URL in the config:
```python
+31 -1
View File
@@ -4,9 +4,12 @@ description: "Use LiteLLM as an LLM provider in Mem0 to access over 100 language
---
[Litellm](https://litellm.vercel.app/docs/) is compatible with over 100 large language models (LLMs), all using a standardized input/output format. You can explore the [available models](https://litellm.vercel.app/docs/providers) to use with Litellm. Ensure you set the `API_KEY` for the model you choose to use.
In the TypeScript SDK, run LiteLLM as a [proxy server](https://docs.litellm.ai/docs/simple_proxy) (an OpenAI-compatible endpoint) and point Mem0 at it via `LITELLM_API_BASE` (defaults to `http://localhost:4000`).
## Usage
```python
<CodeGroup>
```python Python
import os
from mem0 import Memory
@@ -33,6 +36,33 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movies"})
```
```typescript TypeScript
import { Memory } from 'mem0ai/oss';
// Point Mem0 at your LiteLLM proxy. apiKey defaults to "sk-anything"
// (the proxy handles real auth); baseURL defaults to http://localhost:4000.
const config = {
llm: {
provider: 'litellm',
config: {
apiKey: process.env.LITELLM_API_KEY || 'sk-anything',
baseURL: process.env.LITELLM_API_BASE || 'http://localhost:4000',
model: 'gpt-5-mini',
},
},
};
const memory = new Memory(config);
const messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about 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."}
];
await memory.add(messages, { userId: 'alice', metadata: { category: 'movies' } });
```
</CodeGroup>
## Config
All available parameters for the `litellm` config are present in [Master List of All Params in Config](../config).
+45 -2
View File
@@ -7,7 +7,8 @@ To use MiniMax LLM models, you have to set the `MINIMAX_API_KEY` environment var
## Usage
```python
<CodeGroup>
```python Python
import os
from mem0 import Memory
@@ -36,9 +37,37 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movies"})
```
```typescript TypeScript
import { Memory } from 'mem0ai/oss';
const config = {
llm: {
provider: 'minimax',
config: {
apiKey: process.env.MINIMAX_API_KEY || '',
model: 'MiniMax-M2.7',
temperature: 0.2,
maxTokens: 2000,
topP: 1.0,
},
},
};
const memory = new Memory(config);
const messages = [
{ role: "user", content: "I'm planning to watch a movie tonight. Any recommendations?" },
{ role: "assistant", content: "How about 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." },
];
await memory.add(messages, { userId: 'alice', metadata: { category: 'movies' } });
```
</CodeGroup>
You can also configure the API base URL in the config:
```python
<CodeGroup>
```python Python
config = {
"llm": {
"provider": "minimax",
@@ -51,6 +80,20 @@ config = {
}
```
```typescript TypeScript
const config = {
llm: {
provider: 'minimax',
config: {
model: 'MiniMax-M2.7',
baseURL: 'https://your-custom-endpoint.com',
apiKey: 'your-api-key', // alternatively to using the environment variable
},
},
};
```
</CodeGroup>
## Config
All available parameters for the `minimax` config are present in [Master List of All Params in Config](../config).
-226
View File
@@ -1,226 +0,0 @@
---
title: LLM as Reranker
description: "Use any LLM as a flexible reranker in Mem0 with custom prompts and domain-specific scoring logic."
---
<Warning>
**This page has been superseded.** Please see [LLM Reranker](/components/rerankers/models/llm_reranker) for the complete and up-to-date documentation on using LLMs for reranking.
</Warning>
LLM-based reranker provides maximum flexibility by using any Large Language Model to score document relevance. This approach allows for custom prompts and domain-specific scoring logic.
## Supported LLM Providers
Any LLM provider supported by Mem0 can be used for reranking:
- **OpenAI**: GPT-4, GPT-3.5-turbo, etc.
- **Anthropic**: Claude models
- **Together**: Open-source models
- **Groq**: Fast inference
- **Ollama**: Local models
- And more...
## Configuration
```python Python
from mem0 import Memory
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "my_memories",
"path": "./chroma_db"
}
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4o-mini"
}
},
"reranker": {
"provider": "llm",
"config": {
"model": "gpt-4o-mini",
"provider": "openai",
"api_key": "your-openai-api-key", # or set OPENAI_API_KEY
"top_k": 5,
"temperature": 0.0
}
}
}
memory = Memory.from_config(config)
```
## Custom Scoring Prompt
You can provide a custom prompt for relevance scoring:
```python Python
custom_prompt = """You are a relevance scoring assistant. Rate how well this document answers the query.
Query: "{query}"
Document: "{document}"
Score from 0.0 to 1.0 where:
- 1.0: Perfect match, directly answers the query
- 0.8-0.9: Highly relevant, good match
- 0.6-0.7: Moderately relevant, partial match
- 0.4-0.5: Slightly relevant, limited useful information
- 0.0-0.3: Not relevant or no useful information
Provide only a single numerical score between 0.0 and 1.0."""
config["reranker"]["config"]["scoring_prompt"] = custom_prompt
```
## Usage Example
```python Python
import os
from mem0 import Memory
# Set API key
os.environ["OPENAI_API_KEY"] = "your-api-key"
# Initialize memory with LLM reranker
config = {
"vector_store": {"provider": "chroma"},
"llm": {"provider": "openai", "config": {"model": "gpt-4o-mini"}},
"reranker": {
"provider": "llm",
"config": {
"model": "gpt-4o-mini",
"provider": "openai",
"temperature": 0.0
}
}
}
memory = Memory.from_config(config)
# Add memories
messages = [
{"role": "user", "content": "I'm learning Python programming"},
{"role": "user", "content": "I find object-oriented programming challenging"},
{"role": "user", "content": "I love hiking in national parks"}
]
memory.add(messages, user_id="david")
# Search with LLM reranking
results = memory.search("What programming topics is the user studying?", filters={"user_id": "david"})
for result in results['results']:
print(f"Memory: {result['memory']}")
print(f"Vector Score: {result['score']:.3f}")
print(f"Rerank Score: {result['rerank_score']:.3f}")
print()
```
```text Output
Memory: I'm learning Python programming
Vector Score: 0.856
Rerank Score: 0.920
Memory: I find object-oriented programming challenging
Vector Score: 0.782
Rerank Score: 0.850
```
## Domain-Specific Scoring
Create specialized scoring for your domain:
```python Python
medical_prompt = """You are a medical relevance expert. Score how relevant this medical record is to the clinical query.
Clinical Query: "{query}"
Medical Record: "{document}"
Consider:
- Clinical relevance and accuracy
- Patient safety implications
- Diagnostic value
- Treatment relevance
Score from 0.0 to 1.0. Provide only the numerical score."""
config = {
"reranker": {
"provider": "llm",
"config": {
"model": "gpt-4o-mini",
"provider": "openai",
"scoring_prompt": medical_prompt,
"temperature": 0.0
}
}
}
```
## Multiple LLM Providers
Use different LLM providers for reranking:
```python Python
# Using Anthropic Claude
anthropic_config = {
"reranker": {
"provider": "llm",
"config": {
"model": "claude-3-haiku-20240307",
"provider": "anthropic",
"temperature": 0.0
}
}
}
# Using local Ollama model
ollama_config = {
"reranker": {
"provider": "llm",
"config": {
"model": "llama2:7b",
"provider": "ollama",
"temperature": 0.0
}
}
}
```
## Configuration Parameters
| Parameter | Description | Type | Default |
|-----------|-------------|------|---------|
| `model` | LLM model to use for scoring | `str` | `"gpt-4o-mini"` |
| `provider` | LLM provider name | `str` | `"openai"` |
| `api_key` | API key for the LLM provider | `str` | `None` |
| `top_k` | Maximum documents to return | `int` | `None` |
| `temperature` | Temperature for LLM generation | `float` | `0.0` |
| `max_tokens` | Maximum tokens for LLM response | `int` | `100` |
| `scoring_prompt` | Custom prompt template | `str` | Default prompt |
## Advantages
- **Maximum Flexibility**: Custom prompts for any use case
- **Domain Expertise**: Leverage LLM knowledge for specialized domains
- **Interpretability**: Understand scoring through prompt engineering
- **Multi-criteria**: Score based on multiple relevance factors
## Considerations
- **Latency**: Higher latency than specialized rerankers
- **Cost**: LLM API costs per reranking operation
- **Consistency**: May have slight variations in scoring
- **Prompt Engineering**: Requires careful prompt design
## Best Practices
1. **Temperature**: Use 0.0 for consistent scoring
2. **Prompt Design**: Be specific about scoring criteria
3. **Token Efficiency**: Keep prompts concise to reduce costs
4. **Caching**: Cache results for repeated queries when possible
5. **Fallback**: Handle API errors gracefully
+1 -1
View File
@@ -46,7 +46,7 @@ Here are the parameters available for configuring Baidu VectorDB:
| `account` | Baidu VectorDB account name | `root` |
| `api_key` | API key for accessing Baidu VectorDB | Required |
| `database_name` | Name of the database | `mem0` |
| `table_name` | Name of the table | `mem0_table` |
| `table_name` | Name of the table | `mem0` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
| `metric_type` | Distance metric for similarity search | `L2` |
@@ -56,6 +56,8 @@ Here are the parameters available for configuring Elasticsearch:
| `api_key` | API key for authentication | `None` |
| `user` | Username for basic authentication | `None` |
| `password` | Password for basic authentication | `None` |
| `use_ssl` | Whether to use SSL for the connection | `True` |
| `ca_certs` | Path to CA bundle for SSL certificate verification | `None` |
| `verify_certs` | Whether to verify SSL certificates | `True` |
| `auto_create_index` | Whether to automatically create the index | `True` |
| `custom_search_query` | Function returning a custom search query | `None` |
+1
View File
@@ -55,6 +55,7 @@ Here are the parameters available for configuring FAISS:
| `path` | Path to store FAISS index and metadata | `/tmp/faiss/<collection_name>` |
| `distance_strategy` | Distance metric strategy to use (options: 'euclidean', 'inner_product', 'cosine') | `euclidean` |
| `normalize_L2` | Whether to normalize L2 vectors (only applicable for euclidean distance) | `False` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
### Performance Considerations
+3 -3
View File
@@ -47,12 +47,12 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
```
```typescript TypeScript
import { Memory } from "mem0ai";
import { Memory } from "mem0ai/oss";
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore as LangchainMemoryStore } from "langchain/vectorstores/memory";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
const embeddings = new OpenAIEmbeddings();
const vectorStore = new LangchainVectorStore(embeddings);
const vectorStore = new MemoryVectorStore(embeddings);
const config = {
"vector_store": {
+3 -3
View File
@@ -42,8 +42,8 @@ Here are the parameters available for configuring MongoDB:
| Parameter | Description | Default Value |
| --- | --- | --- |
| db_name | Name of the MongoDB database | `"mem0_db"` |
| collection_name | Name of the MongoDB collection | `"mem0_collection"` |
| collection_name | Name of the MongoDB collection | `"mem0"` |
| embedding_model_dims | Dimensions of the embedding vectors | `1536` |
| mongo_uri | The MongoDB URI connection string | `mongodb://username:password@localhost:27017` |
| mongo_uri | The MongoDB URI connection string | `mongodb://localhost:27017` |
> **Note**: If `mongo_uri` is not provided, it will default to `mongodb://username:password@localhost:27017`.
> **Note**: If `mongo_uri` is not provided, it will default to `mongodb://localhost:27017`.
+153
View File
@@ -0,0 +1,153 @@
---
title: "Neon"
description: "Use Neon as a vector store in Mem0, powered by PostgreSQL and pgvector."
---
Use [Neon](https://neon.com/) as a vector store in Mem0, powered by PostgreSQL and the
[pgvector extension](https://neon.com/docs/extensions/pgvector).
Neon is a serverless Postgres platform. Since Mem0 supports Postgres through the
`pgvector` provider, Neon can be used with a standard Postgres connection string.
## Usage
<CodeGroup>
```python Python
import os
from dotenv import load_dotenv
from mem0 import Memory
load_dotenv()
config = {
"vector_store": {
"provider": "pgvector",
"config": {
"connection_string": os.environ["DATABASE_URL"],
"collection_name": "memories",
"embedding_model_dims": 1536,
"hnsw": True,
},
},
}
m = Memory.from_config(config)
messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about 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."},
]
m.add(messages, user_id="alice", metadata={"category": "movies"})
results = m.search(
"What movies should I recommend?",
filters={"user_id": "alice"},
)
print(results)
```
```typescript TypeScript
import "dotenv/config";
import { Memory } from "mem0ai/oss";
const m = new Memory({
vectorStore: {
provider: "pgvector",
config: {
connectionString: process.env.DATABASE_URL!,
ssl: {
rejectUnauthorized: false,
},
collectionName: "memories",
dimension: 1536,
embeddingModelDims: 1536,
hnsw: true,
},
},
});
const messages = [
{ role: "user" as const, content: "I'm planning to watch a movie tonight. Any recommendations?" },
{ role: "assistant" as const, content: "How about thriller movies? They can be quite engaging." },
{ role: "user" as const, content: "I'm not a big fan of thriller movies but I love sci-fi movies." },
{ role: "assistant" as const, content: "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future." },
];
await m.add(messages, {
userId: "alice",
metadata: { category: "movies" },
});
const results = await m.search("What movies should I recommend?", {
filters: { user_id: "alice" },
});
console.log(results);
```
</CodeGroup>
## SQL Migration
You don't need to run any SQL migrations. Mem0 creates the collection table when it initializes the `pgvector` store.
## Environment
```env
OPENAI_API_KEY=sk-xx...
DATABASE_URL=postgresql://user:password@ep-example.us-east-2.aws.neon.tech/neondb?sslmode=require
```
## Config
<Tabs>
<Tab title="Python">
| Parameter | Description | Default Value |
| --- | --- | --- |
| `connection_string` | Neon Postgres connection string. | Required |
| `collection_name` | Name for the vector collection. | `mem0` |
| `embedding_model_dims` | Embedding model dimensions. | `1536` |
| `hnsw` | Enables HNSW indexing. | `False` |
| `sslmode` | PostgreSQL SSL mode. Use `require` for Neon. | Driver default |
</Tab>
<Tab title="TypeScript">
Use the Neon `DATABASE_URL` directly with `connectionString`. Set `ssl` if your runtime needs an explicit TLS config object.
| Parameter | Description | Default |
| -------------------- | ---------------------------------------------- | -------------- |
| `connectionString` | Neon Postgres connection string. | Required |
| `ssl` | Optional TLS settings passed directly to `pg`. | Driver default |
| `collectionName` | Name for the vector collection. | `memories` |
| `dimension` | Vector dimension for Mem0 config. | Auto-detected |
| `embeddingModelDims` | Embedding model dimensions for table creation. | Required |
| `hnsw` | Enables HNSW indexing. | `false` |
**TLS note:** `ssl: true` is sufficient for most Neon connections since Neon uses valid certificates. Use `ssl: { rejectUnauthorized: false }` only when connecting through Neon's connection pooler on certain edge runtimes (e.g. Cloudflare Workers) that require it, or when your environment does not trust the Neon CA chain.
</Tab>
</Tabs>
### Indexing
The `pgvector` provider can create an HNSW index for faster vector search.
- Set `hnsw` to `true` to enable a Hierarchical Navigable Small World index.
- Leave `hnsw` as `false` if you want to create or manage indexes yourself.
### Similarity Search
The `pgvector` provider uses cosine similarity for vector search. Make sure your
embedding dimensions match the configured `embedding_model_dims` value.
### Best Practices
1. **Index Selection**:
- Use `hnsw` for faster search performance when memory usage is not a constraint
- Manage indexes manually if you need a different pgvector index strategy
2. **Connection String**:
- Always use environment variables or even better, a secret manager for sensitive information in the connection string
- Format: `postgresql://user:password@host:port/database`
@@ -10,7 +10,7 @@ description: "Use AWS Neptune Analytics as a vector store in Mem0, combining gra
## Installation
```bash
pip install mem0ai[vector_stores]
pip install mem0ai[vector-stores]
```
## Usage
@@ -56,6 +56,30 @@ config = {
}
```
### Configuration Options
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `collection_name` | string | required | Name of the OpenSearch index |
| `host` | string | required | OpenSearch endpoint URL |
| `port` | int | 9200 | Port number |
| `http_auth` | object | None | Authentication credentials (e.g., AWSV4SignerAuth) |
| `embedding_model_dims` | int | 1536 | Dimension of embedding vectors |
| `use_ssl` | bool | False | Enable SSL/TLS connection |
| `verify_certs` | bool | False | Verify SSL certificates |
| `auto_refresh` | bool | False | Automatically refresh index after insert. OpenSearch refreshes every ~1 second by default, so this is rarely needed. |
<Note>
The defaults above match a local OpenSearch instance. The AWS OpenSearch Serverless
example earlier on this page intentionally overrides them with `port=443`, `use_ssl=True`,
and `verify_certs=True`, which are required when connecting to a Serverless collection.
</Note>
<Note>
For **AWS OpenSearch Serverless**, keep `auto_refresh=False` (the default).
The `indices.refresh()` API is not supported on Serverless collections.
</Note>
### Add Memories
```python
+37 -32
View File
@@ -2,6 +2,7 @@
title: "pgvector"
description: "Use pgvector as a vector store in Mem0 for PostgreSQL-based vector similarity search with open-source simplicity."
---
[pgvector](https://github.com/pgvector/pgvector) is an open-source vector similarity search extension for Postgres. After connecting to Postgres, run `CREATE EXTENSION IF NOT EXISTS vector;` to create the vector extension.
### Usage
@@ -21,7 +22,7 @@ config = {
"password": "123",
"host": "127.0.0.1",
"port": "5432",
}
},
}
}
@@ -30,25 +31,22 @@ messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about 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."}
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."},
]
m.add(messages, user_id="alice", metadata={"category": "movies"})
```
```typescript TypeScript
import { Memory } from 'mem0ai/oss';
import { Memory } from "mem0ai/oss";
const config = {
vectorStore: {
provider: 'pgvector',
provider: "pgvector",
config: {
collectionName: 'memories',
collectionName: "memories",
embeddingModelDims: 1536,
user: 'test',
password: '123',
host: '127.0.0.1',
port: 5432,
dbname: 'vector_store', // Optional; TypeScript OSS defaults to `vector_store` when omitted
connectionString: "postgresql://test:123@localhost:5432/vector_store",
diskann: false, // Optional, requires pgvectorscale extension
hnsw: false, // Optional, for HNSW indexing
},
@@ -57,37 +55,44 @@ const config = {
const memory = new Memory(config);
const messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about 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."}
]
{ role: "user", content: "I'm planning to watch a movie tonight. Any recommendations?" },
{ role: "assistant", content: "How about 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." },
];
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
```
</CodeGroup>
### Config
Here are the parameters available for configuring pgvector:
| Parameter | Description | Default Value |
| --- | --- | --- |
| `dbname` | The name of the database | `postgres` |
| `collection_name` | The name of the collection | `mem0` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
| `user` | User name to connect to the database | `None` |
| `password` | Password to connect to the database | `None` |
| `host` | The host where the Postgres server is running | `None` |
| `port` | The port where the Postgres server is running | `None` |
| `diskann` | Whether to use diskann for vector similarity search (requires pgvectorscale) | `True` |
| `hnsw` | Whether to use hnsw for vector similarity search | `False` |
| `sslmode` | SSL mode for PostgreSQL connection (e.g., 'require', 'prefer', 'disable') | `None` |
| `connection_string` | PostgreSQL connection string (overrides individual connection parameters) | `None` |
| `connection_pool` | psycopg2 connection pool object (overrides connection string and individual parameters) | `None` |
| Parameter | SDK | Description | Default Value |
| -------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `connectionString` | TypeScript OSS | PostgreSQL connection string for direct connections. When set, Mem0 connects to the target database directly and skips the bootstrap `postgres` database flow. | `None` |
| `ssl` | TypeScript OSS | SSL option passed directly to `pg`, either `true` or an SSL config object, for both `connectionString` and split-field connections. | `None` |
| `dbname` | TypeScript OSS | Split-field database name. This is only used when `connectionString` is absent. | `vector_store` |
| `collectionName` | TypeScript OSS | Collection name. | `memories` |
| `embeddingModelDims` | TypeScript OSS | Dimensions of the embedding model. | Required |
| `user` | TypeScript OSS + Python | Database user for split-field connections. | `None` |
| `password` | TypeScript OSS + Python | Database password for split-field connections. | `None` |
| `host` | TypeScript OSS + Python | Database host for split-field connections. | `None` |
| `port` | TypeScript OSS + Python | Database port for split-field connections. | `None` |
| `diskann` | TypeScript OSS + Python | Whether to use DiskANN for vector similarity search, requires pgvectorscale. | `False` |
| `hnsw` | TypeScript OSS + Python | Whether to use HNSW for vector similarity search. | TypeScript OSS: `False`, Python: `True` |
| `connection_string` | Python only | PostgreSQL connection string, overrides individual connection parameters. | `None` |
| `sslmode` | Python only | SSL mode for PostgreSQL connections, such as `require`, `prefer`, or `disable`. | `None` |
| `connection_pool` | Python only | psycopg connection pool object, overrides connection string and individual connection parameters. | `None` |
**Note (TypeScript OSS):** If you omit `dbname`, the TypeScript client uses the database name `vector_store`. Python defaults to `postgres` for `dbname`, as in the table above.
**TypeScript OSS:** Use `connectionString` plus optional `ssl` for managed Postgres setups. If you omit `connectionString`, Mem0 falls back to split fields and uses `dbname`, `user`, `password`, `host`, `port`, and optional `ssl`.
**Python:** The Python SDK uses snake_case keys such as `connection_string`, `sslmode`, `collection_name`, and `embedding_model_dims`.
**Python connection priority**:
**Note**: The connection parameters have the following priority:
1. `connection_pool` (highest priority)
2. `connection_string`
3. Individual connection parameters (`user`, `password`, `host`, `port`, `sslmode`)
3. Individual connection parameters (`user`, `password`, `host`, `port`, `sslmode`)
+2 -1
View File
@@ -76,6 +76,7 @@ Let's see the available parameters for the `qdrant` config:
| `path` | Path for the qdrant database | `/tmp/qdrant` |
| `url` | Full URL for the qdrant server | `None` |
| `api_key` | API key for the qdrant server | `None` |
| `https` | Whether to force HTTPS on or off. `None` lets the client decide; set `False` for plain HTTP Qdrant with API key authentication. | `None` |
| `on_disk` | For enabling persistent storage | `False` |
</Tab>
<Tab title="TypeScript">
@@ -90,4 +91,4 @@ Let's see the available parameters for the `qdrant` config:
| `apiKey` | API key for the Qdrant server | `None` |
| `onDisk` | For enabling persistent storage | `False` |
</Tab>
</Tabs>
</Tabs>
@@ -18,7 +18,9 @@ os.environ["UPSTASH_VECTOR_REST_TOKEN"] = "..."
config = {
"vector_store": {
"provider": "upstash_vector",
"enable_embeddings": True,
"config": {
"enable_embeddings": True,
}
}
}
+2 -2
View File
@@ -9,7 +9,7 @@ description: "Use Valkey as an open-source vector store in Mem0 for high-perform
## Installation
```bash
pip install mem0ai[vector_stores]
pip install mem0ai[vector-stores]
```
## Usage
@@ -51,7 +51,7 @@ Here are the parameters available for configuring Valkey:
| `hnsw_ef_construction` | Size of dynamic candidate list for HNSW | `200` |
| `hnsw_ef_runtime` | Size of dynamic candidate list for search | `10` |
| `cluster_mode` | Enable cluster mode for Valkey cluster (CME) deployments | `false` |
| `distance_metric` | Distance metric for vector similarity | `cosine` |
| `timezone` | Timezone for timestamp handling | `UTC` |
## Cluster Mode
+3 -2
View File
@@ -24,7 +24,7 @@ config = {
"deployment_index_id": "YOUR_DEPLOYMENT_INDEX_ID", # Required: Deployment-specific ID
"project_id": "YOUR_PROJECT_ID", # Required: Google Cloud project ID
"project_number": "YOUR_PROJECT_NUMBER", # Required: Google Cloud project number
"region": "YOUR_REGION", # Optional: Defaults to GOOGLE_CLOUD_REGION
"region": "YOUR_REGION", # Required: Google Cloud region
"credentials_path": "path/to/credentials.json", # Optional: Defaults to GOOGLE_APPLICATION_CREDENTIALS
"vector_search_api_endpoint": "YOUR_API_ENDPOINT" # Required for get operations
}
@@ -45,5 +45,6 @@ m.add("Your text here", user_id="user", metadata={"category": "example"})
| `project_id` | Google Cloud project ID | Yes |
| `project_number` | Google Cloud project number | Yes |
| `vector_search_api_endpoint` | Vector search API endpoint | Yes (for get operations) |
| `region` | Google Cloud region | No (defaults to GOOGLE_CLOUD_REGION) |
| `region` | Google Cloud region | Yes |
| `credentials_path` | Path to service account credentials | No (defaults to GOOGLE_APPLICATION_CREDENTIALS) |
| `service_account_json` | Service account credentials as a dictionary (alternative to `credentials_path`) | `None` |
+3 -2
View File
@@ -7,7 +7,7 @@ description: "Use Weaviate as an open-source vector search engine in Mem0 for st
### Installation
```bash
pip install weaviate weaviate-client
pip install weaviate-client
```
### Usage
@@ -48,4 +48,5 @@ Here are the parameters available for configuring Weaviate:
| `collection_name` | The name of the collection to store the vectors | `mem0` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
| `cluster_url` | URL for the Weaviate server | `None` |
| `auth_client_secret` | API key for Weaviate authentication | `None` |
| `auth_client_secret` | API key for Weaviate authentication | `None` |
| `additional_headers` | Additional headers to include in requests (`Dict[str, str]`) | `None` |
+1 -1
View File
@@ -10,7 +10,7 @@ Mem0 includes built-in support for various popular databases. Memory can utilize
See the list of supported vector databases below.
<Note>
The following vector databases are supported in the Python implementation. The TypeScript implementation currently only supports Qdrant, Redis, Valkey, Vectorize and in-memory vector database.
The following vector databases are supported in the Python implementation. The TypeScript implementation currently supports Qdrant, Redis, PGVector, Supabase, LangChain, Azure AI Search, Vectorize, and an in-memory store.
</Note>
<CardGroup cols={3}>
+84 -18
View File
@@ -1,32 +1,65 @@
---
title: Development
description: "Guide to contributing code to Mem0, covering the fork and clone workflow, PR submission, and code quality checks."
description: "Guide to contributing code to Mem0, covering the issue-first workflow, the CLA, environment setup for the Python and TypeScript SDKs, and code quality checks."
icon: "code"
---
# Development Contributions
We strive to make contributions **easy, collaborative, and enjoyable**. Follow the steps below to ensure a smooth contribution process.
We strive to make contributions **easy, collaborative, and enjoyable**. Mem0 is a
polyglot monorepo containing the **Python SDK** (`mem0/`), the **TypeScript SDK**
(`mem0-ts/`), CLIs, integrations, the self-hosted server, and the docs site.
Follow the steps below for a smooth contribution process.
## Submitting Your Contribution through PR
<Note>
For the complete contributor checklist, see
[CONTRIBUTING.md](https://github.com/mem0ai/mem0/blob/main/CONTRIBUTING.md) in
the repository root.
</Note>
To contribute, follow these steps:
## Before You Start
### 1. Open an Issue First
**Always open an issue before opening a pull request.** This lets us discuss the
change, avoid duplicate work, and agree on the approach before you write code.
- Search [existing issues](https://github.com/mem0ai/mem0/issues) first.
- If none match, open a
[bug report](https://github.com/mem0ai/mem0/issues/new?template=bug_report.yml)
or [feature request](https://github.com/mem0ai/mem0/issues/new?template=feature_request.yml).
- For anything beyond a trivial fix, wait for a maintainer to confirm the approach.
Every pull request must link to an issue using `Closes #<issue-number>`.
### 2. Sign the Contributor License Agreement (CLA)
**We cannot merge any pull request until you have signed our Contributor License
Agreement (CLA).** When you open your first PR, the CLA bot will comment with a
link to sign — it takes less than a minute and only needs to be done once.
## Submitting Your Contribution through a PR
1. **Fork & Clone** the repository: [Mem0 on GitHub](https://github.com/mem0ai/mem0)
2. **Create a Feature Branch**: Use a dedicated branch for your changes, e.g., `feature/my-new-feature`
3. **Implement Changes**: If adding a feature or fixing a bug, ensure to:
2. **Create a Feature Branch**: Use a dedicated branch, e.g., `feature/my-new-feature`
3. **Implement Changes**: If adding a feature or fixing a bug, be sure to:
- Write necessary **tests**
- Add **documentation, docstrings, and runnable examples**
4. **Code Quality Checks**:
- Run **linting** to catch style issues
- Ensure **all tests pass**
5. **Submit a Pull Request**
5. **Commit** using [Conventional Commits](https://www.conventionalcommits.org/)
(`feat:`, `fix:`, `docs:`, `refactor:`, `test:`)
6. **Submit a Pull Request** against `main`, linking the issue and filling out the
PR template.
For detailed guidance on pull requests, refer to [GitHub's documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
---
## Dependency Management
## Python SDK (`mem0/`)
### Dependency Management
We use `hatch` as our package manager. Install it by following the [official instructions](https://hatch.pypa.io/latest/install/).
@@ -44,13 +77,9 @@ hatch -e dev_py_3_11 shell # For dev_py_3_11 (differences are mentioned in pypr
make install_all
```
---
## Development Standards
### Pre-commit Hooks
Ensure `pre-commit` is installed before contributing:
Ensure `pre-commit` is installed before contributing (hooks run ruff + isort):
```bash
pre-commit install
@@ -58,7 +87,7 @@ pre-commit install
### Linting with `ruff`
Run the linter and fix any reported issues before submitting your PR:
Run the linter and fix any reported issues before submitting your PR (line length **120**):
```bash
make lint
@@ -66,10 +95,11 @@ make lint
### Code Formatting
To maintain a consistent code style, format your code:
To maintain a consistent code style, format your code and sort imports (isort, `profile = "black"`):
```bash
make format
make sort
```
### Testing with `pytest`
@@ -84,10 +114,46 @@ make test
---
## Release Process
## TypeScript SDK (`mem0-ts/`)
Currently, releases are handled manually. We aim for frequent releases, typically when new features or bug fixes are introduced.
We use [`pnpm`](https://pnpm.io/) (v10+) for all TypeScript packages. **Do NOT use
`npm` or `yarn`.**
```bash
cd mem0-ts
pnpm install
pnpm run build # tsup (CJS + ESM)
pnpm run test # jest (all tests)
pnpm run test:unit # unit tests with coverage
```
### Standards
- **Build:** tsup
- **Formatter:** Prettier
- **Tests:** jest
- Always run type checking after changes: `pnpm run typecheck` (or `tsc --noEmit`)
- Use ES module `import` syntax — never `require()`
---
Thank you for contributing to Mem0!
## Reporting Security Issues
**Do not report security vulnerabilities through public issues or pull requests.**
Please follow our [Security Policy](https://github.com/mem0ai/mem0/blob/main/SECURITY.md)
to report them privately.
---
## Release Process
Packages are published automatically via GitHub Actions when a GitHub Release is
created with the correct tag prefix (e.g. `v*` for the Python SDK, `ts-v*` for the
TypeScript SDK). See
[CONTRIBUTING.md](https://github.com/mem0ai/mem0/blob/main/CONTRIBUTING.md#releasing)
for the full tag-prefix table and publishing details.
---
Thank you for contributing to Mem0!
@@ -323,10 +323,6 @@ Metadata: {'verified': True, 'updated_date': '2025-04-02'}
That “no duplicates” promise comes from the inference pipeline. Keep `infer=True` when you rely on automatic updates. Raw imports (`infer=False`) skip conflict checks, so mixing the two modes for the same fact will create duplicates.
</Warning>
**Maintains relationships:**
- If using graph memory, connections to other entities persist
### Pick the right inference mode
| Mode | What it does | Best for | Watch out for |
@@ -216,7 +216,6 @@ This information was retrieved from your memory history where you previously men
- **Smart Memory Management** - Organizes memories into searchable information *without setting up vector databases*
- **Fast Retrieval** - Instant lookups with *sub-millisecond ping*, handles large datasets
- **Graph Capabilities** - Builds knowledge *automatically* as you push information
- **Simple Integration** - Uses Mem0 API in the backend, works with *any MCP client* with just a few lines of code
### Gemini 3 + Mem0 Benefits
+1 -8
View File
@@ -156,14 +156,7 @@ Here are some examples of how Mem0 can be integrated into various applications:
icon="aws"
href="/cookbooks/integrations/aws-bedrock"
>
Mem0 with AWS Bedrock and Neptune.
</Card>
<Card
title="Graph Memory on Neptune"
icon="network-wired"
href="/cookbooks/integrations/neptune-analytics"
>
Graph memory with Neptune Analytics.
Mem0 with AWS Bedrock.
</Card>
</CardGroup>
+6 -6
View File
@@ -17,7 +17,7 @@ Some benchmarks today — particularly smaller ones like LoCoMo and LongMemEval
## Architecture Overview
Mem0's memory system operates across two phases — **extraction** (writing) and **retrieval** (reading) — with an entity linking layer connecting them.
Mem0's memory system operates across two phases, **extraction** (writing) and **retrieval** (reading), with a graph memory layer (entity linking) connecting them.
### Memory Extraction (Distillation)
@@ -27,14 +27,14 @@ When new conversations arrive, the extraction pipeline processes them through fi
2. **Context Lookup** — Find related existing memories to avoid duplicates
3. **Distill Memories** — Single-pass LLM extraction produces ADD-only facts from input + context
4. **Deduplicate + Embed** — Hash-based deduplication, then vectorize new memories
5. **Entity Linking** — Identify entities (proper nouns, quoted text, compound noun phrases) and link them across memories
5. **Graph Memory (Entity Linking)**: Identify entities (proper nouns, quoted text, compound noun phrases) and link them across memories into a graph
Memories are distributed across three storage layers, each tuned for a specific retrieval pattern:
| Store | Contents | Purpose |
|---|---|---|
| **Vector Database** | Memory text, embeddings, metadata (timestamps, hash, categories, attributed_to) | Primary fact storage + semantic retrieval |
| **Entity Store** | Entities + embeddings + linked memory IDs | Entity-based retrieval boost |
| **Graph / Entity Store** | Entities + embeddings + linked memory IDs | Graph connections across memories + entity-based retrieval boost |
| **SQL Database** | History log (ADD events) + rolling message window | Audit trail + extraction dedup context |
<Info>
@@ -47,7 +47,7 @@ When a query arrives, the retrieval pipeline scores candidates across three sign
1. **Semantic Search** — Vector similarity scoring against memory embeddings
2. **Keyword Search** — Normalized term matching via BM25 with verb-form lemmatization
3. **Entity Search** — Entity graph matching boosts memories linked to query entities
3. **Entity Search** — Entity matching boosts memories linked to query entities
Results are fused via rank scoring into a final top-K set. Different query types lean on different signals:
@@ -76,7 +76,7 @@ The combined score outperformed every individual signal across every category te
*Mean tokens: 6,956*
The two largest gains are **temporal queries (+29.6)** and **multi-hop reasoning (+23.1)**. Both categories directly test the ADD-only architecture (preserving temporal context) and entity linking (connecting facts across memories).
The two largest gains are **temporal queries (+29.6)** and **multi-hop reasoning (+23.1)**. Both categories directly test the ADD-only architecture (preserving temporal context) and graph memory / entity linking (connecting facts across memories).
### LongMemEval
@@ -345,7 +345,7 @@ When evaluating memory systems, keep these considerations in mind:
<Card title="Research" icon="flask" href="https://mem0.ai/research">
Published research papers and technical reports
</Card>
<Card title="Blog Post" icon="newspaper" href="https://mem0.ai/blog/new-algorithm">
<Card title="Blog Post" icon="newspaper" href="https://mem0.ai/blog/the-token-efficient-memory-algorithm-now-has-temporal-reasoning">
Detailed writeup of the new algorithm design and results
</Card>
<Card title="Platform Migration" icon="arrow-right" href="/migration/platform-v2-to-v3">
+13 -17
View File
@@ -21,35 +21,31 @@ Adding memory is how Mem0 captures useful details from a conversation so your ag
- **Messages** – The ordered list of user/assistant turns you send to `add`.
- **Infer** – Controls whether Mem0 extracts structured memories (`infer=True`, default) or stores raw messages.
- **Metadata** – Optional filters (e.g., `{"category": "movie_recommendations"}`) that improve retrieval later.
- **User / Session identifiers** – `user_id`, `agent_id`, or `run_id` that scope the memory for future searches.
- **User / Session identifiers** – `user_id`, `agent_id`, `app_id`, or `run_id` that scope the memory for future searches.
## How does it work?
Mem0 offers two flows:
- **Mem0 Platform** – Fully managed API with dashboard, scaling, and graph features.
- **Mem0 Platform** – Fully managed API with dashboard and scaling.
- **Mem0 Open Source** – Local SDK that you run in your own environment.
Both flows take the same payload and pass it through the same pipeline.
<Frame caption="Architecture diagram illustrating the process of adding memories.">
<img src="../../images/add_architecture.png" />
</Frame>
Both flows take the same payload and add memories through an additive pipeline.
<Steps>
<Step title="Information extraction">
Mem0 sends the messages through an LLM that pulls out key facts, decisions, or preferences to remember.
</Step>
<Step title="Conflict resolution">
Existing memories are checked for duplicates or contradictions so the latest truth wins.
<Step title="Additive storage">
New memories are added without overwriting or deleting existing memories.
</Step>
<Step title="Storage">
The resulting memories land in managed vector storage (and optional graph storage) so future searches return them quickly.
<Step title="Retrieval">
Future searches rank the most relevant memories for the query.
</Step>
</Steps>
<Warning>
Duplicate protection only runs during that conflict-resolution step when you let Mem0 infer memories (`infer=True`, the default). If you switch to `infer=False`, Mem0 stores your payload exactly as provided, so duplicates will land. Mixing both modes for the same fact will save it twice.
When you switch to `infer=False`, Mem0 stores your payload exactly as provided, so duplicates can land. Mixing both modes for the same fact can save it twice.
</Warning>
You trigger this pipeline with a single `add` call—no manual orchestration needed.
@@ -84,13 +80,13 @@ const messages = [
];
await client.add(messages, {
user_id: "alice",
userId: "alice",
});
```
</CodeGroup>
<Info icon="check">
Expect a `memory_id` (or list of IDs) in the response. Check the Mem0 dashboard to confirm the new entry under the correct user.
Expect a `status: "PENDING"` response with an `event_id`. Poll `GET /v1/event/{event_id}/` to confirm completion.
</Info>
## Add with Mem0 Open Source
@@ -142,7 +138,7 @@ const result = memory.add(messages, {
</Tip>
<Warning>
If you do choose `infer=False`, keep it consistent. Raw inserts skip conflict resolution, so a later `infer=True` call with the same content will create a second memory instead of updating the first.
If you do choose `infer=False`, keep it consistent. Raw inserts skip inference, so a later `infer=True` call with the same content can create a second memory.
</Warning>
## When Should You Add Memory?
@@ -171,13 +167,13 @@ For full list of supported fields, required formats, and advanced options, see t
| Capability | Mem0 Platform | Mem0 OSS |
| --- | --- | --- |
| Conflict resolution | Automatic with dashboard visibility | SDK handles merges locally; you control storage |
| Add behavior | ADD-only; memories accumulate | ADD-only; you control storage |
| Rate limits | Managed quotas per workspace | Limited by your hardware and provider APIs |
| Dashboard visibility | Yes — inspect memories visually | Inspect via CLI, logs, or custom UI |
## Put it into practice
- Review the <Link href="/platform/advanced-memory-operations">Advanced Memory Operations</Link> guide to layer metadata, rerankers, and graph toggles.
- Review the <Link href="/platform/advanced-memory-operations">Advanced Memory Operations</Link> guide to layer metadata and rerankers.
- Explore the <Link href="/api-reference/memory/add-memories">Add Memories API reference</Link> for every request/response field.
## See it live
@@ -25,10 +25,6 @@ Mem0's search operation lets agents ask natural-language questions and get back
## Architecture
<Frame caption="Architecture diagram illustrating the memory search process.">
<img src="../../images/search_architecture.png" />
</Frame>
<Steps>
<Step title="Query processing">
Mem0 cleans and enriches your natural-language query so the downstream embedding search is accurate.
@@ -160,6 +156,33 @@ const memories = memory.search("food preferences", {
On Mem0 Platform v3, time-aware queries use Temporal Reasoning internally while preserving the normal search response shape. See <Link href="/platform/features/temporal-reasoning">Temporal Reasoning</Link>.
</Note>
### Explain OSS search scores
OSS search combines semantic similarity with optional keyword and entity signals. Pass `explain=True` when tuning retrieval quality or debugging why a memory ranked where it did:
<CodeGroup>
```python Python
results = m.search(
"food preferences",
filters={"user_id": "alice"},
explain=True,
)
print(results["results"][0]["score_details"])
```
```javascript JavaScript
const results = await memory.search("food preferences", {
filters: { user_id: "alice" },
explain: true,
});
console.log(results.results[0].score_details);
```
</CodeGroup>
Each result includes `score_details` with the semantic score, normalized BM25 score, entity boost, raw combined score, maximum possible score, final score, and threshold used for filtering. The field is omitted unless `explain` is enabled, so existing response shapes stay unchanged.
## Filter patterns
Filters help narrow down search results. Common use cases:
+1 -1
View File
@@ -104,7 +104,7 @@ results = memory.search(
## Put it into practice
- Use the <Link href="/core-concepts/memory-operations/add">Add Memory</Link> guide to persist user preferences.
- Follow <Link href="/platform/advanced-memory-operations">Advanced Memory Operations</Link> to tune metadata and graph writes.
- Follow <Link href="/platform/advanced-memory-operations">Advanced Memory Operations</Link> to tune metadata and retrieval.
## See it live
+29 -13
View File
@@ -71,6 +71,7 @@
"pages": [
"platform/features/v2-memory-filters",
"platform/features/entity-scoped-memory",
"platform/features/graph-memory",
"platform/features/async-client",
"platform/features/multimodal-support",
"platform/features/custom-categories",
@@ -122,8 +123,7 @@
"icon": "arrow-right",
"pages": [
"migration/platform-v2-to-v3",
"migration/oss-to-platform",
"migration/api-changes"
"migration/oss-to-platform"
]
},
{
@@ -143,7 +143,8 @@
"icon": "robot",
"pages": [
"integrations/openclaw",
"integrations/hermes"
"integrations/hermes",
"integrations/pi-agent"
]
}
]
@@ -245,6 +246,7 @@
"components/vectordbs/dbs/cassandra",
"components/vectordbs/dbs/s3_vectors",
"components/vectordbs/dbs/databricks",
"components/vectordbs/dbs/neon",
"components/vectordbs/dbs/neptune_analytics",
"components/vectordbs/dbs/turbopuffer"
]
@@ -270,7 +272,8 @@
"components/embedders/models/lmstudio",
"components/embedders/models/together",
"components/embedders/models/langchain",
"components/embedders/models/aws_bedrock"
"components/embedders/models/aws_bedrock",
"components/embedders/models/fastembed"
]
}
]
@@ -302,7 +305,8 @@
"group": "Migration",
"icon": "arrow-right",
"pages": [
"migration/oss-v2-to-v3"
"migration/oss-v2-to-v3",
"migration/server-pgvector-upgrade"
]
},
{
@@ -437,7 +441,7 @@
"integrations/flowise",
"integrations/langchain-tools",
"integrations/agentops",
"integrations/keywords",
"integrations/respan",
"integrations/raycast"
]
}
@@ -452,7 +456,9 @@
"pages": [
"integrations/claude-code",
"integrations/cursor",
"integrations/codex"
"integrations/codex",
"integrations/opencode",
"integrations/antigravity"
]
},
{
@@ -460,7 +466,8 @@
"icon": "robot",
"pages": [
"integrations/openclaw",
"integrations/hermes"
"integrations/hermes",
"integrations/pi-agent"
]
}
]
@@ -526,6 +533,8 @@
"api-reference/organization/get-org",
"api-reference/organization/get-org-members",
"api-reference/organization/add-org-member",
"api-reference/organization/update-org-member",
"api-reference/organization/remove-org-member",
"api-reference/organization/delete-org"
]
},
@@ -538,6 +547,9 @@
"api-reference/project/get-project",
"api-reference/project/get-project-members",
"api-reference/project/add-project-member",
"api-reference/project/update-project",
"api-reference/project/update-project-member",
"api-reference/project/remove-project-member",
"api-reference/project/delete-project"
]
},
@@ -617,6 +629,10 @@
]
},
"redirects": [
{
"source": "/components/rerankers/models/llm",
"destination": "/components/rerankers/models/llm_reranker"
},
{
"source": "/migration/breaking-changes",
"destination": "/"
@@ -625,6 +641,10 @@
"source": "/migration/v0-to-v1",
"destination": "/"
},
{
"source": "/migration/api-changes",
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/platform/features/expiration-date",
"destination": "/"
@@ -641,10 +661,6 @@
"source": "/open-source/features/custom-fact-extraction-prompt",
"destination": "/open-source/features/custom-instructions"
},
{
"source": "/platform/features/graph-memory",
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/cookbooks/essentials/choosing-memory-architecture-vector-vs-graph",
"destination": "/migration/oss-v2-to-v3"
@@ -1019,7 +1035,7 @@
},
{
"source": "/features/graph-memory",
"destination": "/migration/oss-v2-to-v3"
"destination": "/platform/features/graph-memory"
},
{
"source": "/features/:slug",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

+6 -4
View File
@@ -309,19 +309,21 @@ Here are the available integrations for Mem0:
</Card>
<Card
title="Keywords AI"
title="Respan"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
viewBox="0 0 200 200"
fill="none"
>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.07513 1.1863C9.21663 1.07722 9.39144 1.01009 9.56624 1.01009C9.83261 1.01009 10.0823 1.12756 10.2405 1.33734L15.0101 7.4964V12.4136L16.4335 13.8401C16.7582 14.1673 16.7582 14.7043 16.4335 15.0316C16.1089 15.3588 15.5762 15.3588 15.2515 15.0316L13.3453 13.1016V8.07538L8.92529 2.36944V2.36105C8.64228 2.00024 8.70887 1.4716 9.07513 1.1863ZM18.976 14.4133C18.8344 14.3778 18.7003 14.3042 18.5894 14.1925L16.9163 12.5059C16.7249 12.3129 16.6416 12.0528 16.6749 11.8094V6.88385H16.6499L11.8553 0.691225C11.7282 0.529117 11.6716 0.333133 11.6803 0.140562C11.134 0.0481292 10.5726 0 10 0C4.47715 0 0 4.47715 0 10C0 15.5228 4.47715 20 10 20C13.9387 20 17.3456 17.7229 18.976 14.4133Z" fill="currentColor"></path>
<path d="M2.00635 190.234V9.76584H53.3558V29.5101H26.7223V170.562H53.3558V190.234H2.00635Z" fill="currentColor"></path>
<path d="M120.692 160.902C116.383 160.902 112.691 159.387 109.612 156.357C106.535 153.327 105.02 149.633 105.067 145.277C105.02 141.016 106.535 137.37 109.612 134.34C112.691 131.309 116.383 129.794 120.692 129.794C124.859 129.794 128.481 131.309 131.559 134.34C134.684 137.37 136.27 141.016 136.317 145.277C136.27 148.166 135.512 150.793 134.045 153.161C132.624 155.528 130.73 157.422 128.362 158.842C126.042 160.216 123.486 160.902 120.692 160.902Z" fill="currentColor"></path>
<path d="M197.993 9.76584V190.234H146.643V170.562H173.278V29.5101H146.643V9.76584H197.993Z" fill="currentColor"></path>
</svg>
}
href="/integrations/keywords"
href="/integrations/respan"
>
Build AI applications with persistent memory and comprehensive LLM observability.
</Card>
+1 -1
View File
@@ -73,7 +73,7 @@ client = MemoryClient()
# Define the agent
agent = Agent(
name="Personal Agent",
model=OpenAIChat(id="gpt-4"),
model=OpenAIChat(id="gpt-5-mini"),
description="You are a helpful personal agent that helps me with day to day activities."
"You can process both text and images.",
markdown=True
+83
View File
@@ -0,0 +1,83 @@
---
title: Antigravity
description: "Add persistent memory to Google Antigravity with the Mem0 plugin — MCP server, lifecycle hooks, and slash commands."
---
Add persistent memory to [**Google Antigravity**](https://antigravity.google) (`agy` CLI and Desktop IDE) with the Mem0 plugin. Your agent forgets everything between sessions — Mem0 fixes that by storing decisions, preferences, and learnings so they carry over automatically.
## Prerequisites
1. A Mem0 API key (starts with `m0-`):
- <a href="https://app.mem0.ai/dashboard/api-keys?utm_source=oss&utm_medium=integration-antigravity" rel="nofollow">Get your API key</a> (free sign-up at <a href="https://app.mem0.ai?utm_source=oss&utm_medium=integration-antigravity" rel="nofollow">app.mem0.ai</a>)
2. Add it to your shell profile so it persists across sessions:
<CodeGroup>
```bash zsh
echo 'export MEM0_API_KEY="m0-your-api-key"' >> ~/.zshrc && source ~/.zshrc
```
```bash bash
echo 'export MEM0_API_KEY="m0-your-api-key"' >> ~/.bashrc && source ~/.bashrc
```
</CodeGroup>
## Installation
**Option A — degit** (recommended):
```bash
# Install the plugin (MCP server, hooks, scripts)
npx degit mem0ai/mem0/integrations/mem0-plugin ~/.gemini/config/plugins/mem0
```
This installs the MCP server, lifecycle hooks, and shared scripts.
## What's Included
| Component | Included |
|-----------|:--------:|
| MCP Server (9 memory tools) | Yes |
| Lifecycle Hooks | Yes |
| 16 Slash Commands | Yes |
## Available MCP Tools
| Tool | Description |
|------|-------------|
| `add_memory` | Save text or conversation history for a user/agent |
| `search_memories` | Semantic search across memories with filters |
| `get_memories` | List memories with filters and pagination |
| `get_memory` | Retrieve a specific memory by ID |
| `update_memory` | Overwrite a memory's text by ID |
| `delete_memory` | Delete a single memory by ID |
| `delete_all_memories` | Bulk delete all memories in scope |
| `delete_entities` | Delete a user/agent/app/run entity and its memories |
| `list_entities` | List users/agents/apps/runs stored in Mem0 |
## Lifecycle Hooks
The plugin uses the same shell scripts as Claude Code, Cursor, and Codex — hooks bridge environment variables using `${extensionPath}` (Antigravity's plugin-root token).
| Hook | Event | What it does |
|------|-------|-------------|
| **Session start** | `SessionStart` | Loads prior memories and displays status banner |
| **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message |
| **Pre-tool** | `PreToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tools |
| **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories |
| **Stop** | `Stop` | Stores a session summary when the session ends |
## Troubleshooting
- **No tools appearing** — Restart your Antigravity session after installation
- **"Connection failed"** — Verify your key is set: `echo $MEM0_API_KEY`
- **MCP 401 Unauthorized** — If `${MEM0_API_KEY}` interpolation doesn't work in your `agy` version, replace with your literal key in `mcp_config.json`
<CardGroup cols={2}>
<Card title="Mem0 MCP Setup" icon="puzzle-piece" href="/platform/mem0-mcp">
Detailed MCP configuration for all clients
</Card>
<Card title="OpenCode Integration" icon="code" href="/integrations/opencode">
Add Mem0 memory to OpenCode workflows
</Card>
</CardGroup>

Some files were not shown because too many files have changed in this diff Show More