{"_id":"@mongodb-developer/vercel-ai-memory","_rev":"7-636d96d4ce6e3ad35c0c21deb188b4cc","name":"@mongodb-developer/vercel-ai-memory","dist-tags":{"latest":"0.4.2"},"versions":{"0.1.0":{"name":"@mongodb-developer/vercel-ai-memory","version":"0.1.0","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","_id":"@mongodb-developer/vercel-ai-memory@0.1.0","maintainers":[{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"dist":{"shasum":"3d1c7e3a811b81f54096a246ecaef9ba93b94d79","tarball":"https://registry.npmjs.org/@mongodb-developer/vercel-ai-memory/-/vercel-ai-memory-0.1.0.tgz","fileCount":9,"integrity":"sha512-fJ2Wg9tJaqIPYLBBd00tjLg6WKCWgbzvyMNXoWcgQ+CnOOOcTZfkzBMk7phffZtnxeuZWZObfVaPoNeB/eeLtQ==","signatures":[{"sig":"MEYCIQDxHLClWet/HfWB6t3rjm2ddbGYK+PMiZZQx5piheijcgIhANAadRGZb5fe+ZfIYq6UQ/zfDYeFHDjdEQIh/lewocgb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mongodb-developer%2fvercel-ai-memory@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":344127},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"d2d924479f81cc1bc6c57253e2efc65a4981a105","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run --config vitest.config.ts","build":"tsup","test:all":"npm test && npm run test:integration","test:watch":"vitest --config vitest.config.ts","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"pash1986","email":"pavel.duchovny@mongodb.com"},"repository":{"url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git","type":"git"},"_npmVersion":"10.8.2","description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"^6.0.0","zod":"^3.24.0","tsup":"^8.0.0","vitest":"^4.1.4","mongodb":"^6.12.0","typescript":"^5.7.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.1.4"},"peerDependencies":{"ai":"^4.0.0 || ^5.0.0 || ^6.0.0","zod":"^3.0.0","mongodb":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vercel-ai-memory_0.1.0_1776927935830_0.7244950020496812","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@mongodb-developer/vercel-ai-memory","version":"0.2.0","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","_id":"@mongodb-developer/vercel-ai-memory@0.2.0","maintainers":[{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"dist":{"shasum":"e30da89a986aa9f2983c077acf8cbd3ff27c845a","tarball":"https://registry.npmjs.org/@mongodb-developer/vercel-ai-memory/-/vercel-ai-memory-0.2.0.tgz","fileCount":10,"integrity":"sha512-92gClRHjS0SmURiHIaHimO2Lf5uLw8NNH3yv4gpy1CqyIDlOlf1bPxQpG+SvEzvzyQ+5S5ESSp7b7LDetX/wTw==","signatures":[{"sig":"MEQCIDs+Z+JyF2rf+KwNjiIMlgUbCIqunqSaKTEGBQi49nVhAiAJgdFP7D9Y3JFSylmxXJ+YfKwuNtOFwREbESa/AxUw/w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mongodb-developer%2fvercel-ai-memory@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":415740},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"155dc44512b68afb632f7a92224fa0d12910af07","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run --config vitest.config.ts","build":"tsup","test:all":"npm test && npm run test:integration","test:watch":"vitest --config vitest.config.ts","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"pash1986","email":"pavel.duchovny@mongodb.com"},"repository":{"url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git","type":"git"},"_npmVersion":"10.8.2","description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"^6.0.0","zod":"^3.24.0","tsup":"^8.0.0","vitest":"^4.1.4","mongodb":"^6.12.0","typescript":"^5.7.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.1.4"},"peerDependencies":{"ai":"^4.0.0 || ^5.0.0 || ^6.0.0","zod":"^3.0.0","mongodb":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vercel-ai-memory_0.2.0_1777271897611_0.08458304106168923","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@mongodb-developer/vercel-ai-memory","version":"0.3.0","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","_id":"@mongodb-developer/vercel-ai-memory@0.3.0","maintainers":[{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"dist":{"shasum":"a2da269839ad29cb9812c7235e9ba8e69a463950","tarball":"https://registry.npmjs.org/@mongodb-developer/vercel-ai-memory/-/vercel-ai-memory-0.3.0.tgz","fileCount":10,"integrity":"sha512-Yqyb1b3TtqQJlLwBR3a4quRouG1E8wAaqlq9QnF4gKVanMkg+M//AHxZYQZiX/CdlVtfW3q0CkTOmw330InhFQ==","signatures":[{"sig":"MEUCIQDEyjLAHdYPphDXnnipIvKzFhV82KC6RQDMcIcbvAoizwIgXkuBH8jd6pm2ANtCFkSWE8gxZ7s4/vMlUHCEpblMJaM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mongodb-developer%2fvercel-ai-memory@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":434611},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"91fdf0041b69d3d62f36573812521566b903f5f1","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run --config vitest.config.ts","build":"tsup","test:all":"npm test && npm run test:integration","test:watch":"vitest --config vitest.config.ts","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"pash1986","email":"pavel.duchovny@mongodb.com"},"repository":{"url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git","type":"git"},"_npmVersion":"10.8.2","description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"^6.0.0","zod":"^3.24.0","tsup":"^8.0.0","vitest":"^4.1.4","mongodb":"^6.12.0","typescript":"^5.7.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.1.4"},"peerDependencies":{"ai":"^6.0.0","zod":"^3.0.0","mongodb":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vercel-ai-memory_0.3.0_1779619096061_0.8768558730477289","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@mongodb-developer/vercel-ai-memory","version":"0.4.0","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","_id":"@mongodb-developer/vercel-ai-memory@0.4.0","maintainers":[{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"dist":{"shasum":"74aafb1642fca913635889790f7d1463520f8931","tarball":"https://registry.npmjs.org/@mongodb-developer/vercel-ai-memory/-/vercel-ai-memory-0.4.0.tgz","fileCount":10,"integrity":"sha512-J+cWtXePkAvUtchJoiszWr1Aap70ddi1ViCazn19ErFu+ecycKH4Ja0Lelh5Omgbil9C2IUQ4vtSMhBb0mqgqw==","signatures":[{"sig":"MEUCIQCG9TGsj75djvgEQ5/JeWlaLakE7VzWSfhIfjBhm47W8gIgcTMOjpTycx9KrPyu7DWLKVZlxN1aOhcYdDcwD1fM77c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mongodb-developer%2fvercel-ai-memory@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":435052},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"976aa8b5b17123820bf3cd692649e49fec4cbd96","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run --config vitest.config.ts","build":"tsup","test:all":"npm test && npm run test:integration","test:watch":"vitest --config vitest.config.ts","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"pash1986","email":"pavel.duchovny@mongodb.com"},"repository":{"url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git","type":"git"},"_npmVersion":"10.8.2","description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"^6.0.0","zod":"^3.24.0","tsup":"^8.0.0","vitest":"^4.1.4","mongodb":"^6.12.0","typescript":"^5.7.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.1.4"},"peerDependencies":{"ai":"^6.0.0 || ^7.0.0","zod":"^3.0.0","mongodb":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vercel-ai-memory_0.4.0_1781773828071_0.33255754251284375","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@mongodb-developer/vercel-ai-memory","version":"0.4.1","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","_id":"@mongodb-developer/vercel-ai-memory@0.4.1","maintainers":[{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"dist":{"shasum":"ef7fc0361cfa1e380e4486c698e38abbefdcb19a","tarball":"https://registry.npmjs.org/@mongodb-developer/vercel-ai-memory/-/vercel-ai-memory-0.4.1.tgz","fileCount":10,"integrity":"sha512-c5o0a+amNYisCiw0Mo1D1g1oBlyvPc0wQkVl8IwH8J5KGSfIQsIyVhlxwihKV98gbWsz8oCmJOGqRScBOGj02A==","signatures":[{"sig":"MEUCIQCAPm4+Nr0NopJiLtoF7CvGd4G+2YA7EqdK2W/Lygcz9gIgBK0rvm+J8113UTPHTBHUl0f1LAManDWoNuyOKQ4f5YY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mongodb-developer%2fvercel-ai-memory@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":436044},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"54485dd8bdf5929460206c5576349d56c0f0e047","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run --config vitest.config.ts","build":"tsup","test:all":"npm test && npm run test:integration","test:watch":"vitest --config vitest.config.ts","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"pash1986","email":"pavel.duchovny@mongodb.com"},"repository":{"url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git","type":"git"},"_npmVersion":"10.8.2","description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"^6.0.0","zod":"^3.25.76","tsup":"^8.0.0","vitest":"^4.1.4","mongodb":"^7.3.0","typescript":"^5.7.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.1.4"},"peerDependencies":{"ai":"^6.0.0 || ^7.0.0","zod":"^3.25.76 || ^4.1.8","mongodb":"^6.0.0 || ^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vercel-ai-memory_0.4.1_1781794096422_0.2998565008489047","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@mongodb-developer/vercel-ai-memory","version":"0.4.2","description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git"},"publishConfig":{"access":"public"},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsup","dev":"tsup --watch","lint":"tsc --noEmit","prepublishOnly":"npm run build","test":"vitest run --config vitest.config.ts","test:integration":"vitest run --config vitest.integration.config.ts","test:all":"npm test && npm run test:integration","test:watch":"vitest --config vitest.config.ts"},"peerDependencies":{"ai":"^6.0.0 || ^7.0.0","mongodb":"^6.0.0 || ^7.0.0","zod":"^3.25.76 || ^4.1.8"},"devDependencies":{"@types/node":"^22.0.0","@vitest/coverage-v8":"^4.1.4","ai":"^6.0.0","mongodb":"^7.3.0","tsup":"^8.0.0","typescript":"^5.7.0","vitest":"^4.1.4","zod":"^3.25.76"},"_id":"@mongodb-developer/vercel-ai-memory@0.4.2","gitHead":"0275b398ff1c86c4d952542f8f992f4b77ad67be","bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-211mDBX9wz76klE37MiA3RMZZ0U2j1kgGKiS7TtMG0XxdHGAPbO+X16VB/wjzuB3lECUBwTu4HLhJezc3l8q3w==","shasum":"c091adbd524310c63f6465fc5dccebd41f78e678","tarball":"https://registry.npmjs.org/@mongodb-developer/vercel-ai-memory/-/vercel-ai-memory-0.4.2.tgz","fileCount":10,"unpackedSize":436449,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mongodb-developer%2fvercel-ai-memory@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGWVeA02pBk+mr7bYILEbIMXbUt9lfogtXkJKLCotYfwAiEA5wTpje/CA5yyPs1CZRz47ol2U4Pc+jF3For8hn6geCg="}]},"_npmUser":{"name":"pash1986","email":"pavel.duchovny@mongodb.com"},"directories":{},"maintainers":[{"name":"mira_mongodb","email":"stanimira.vlaeva@mongodb.com"},{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vercel-ai-memory_0.4.2_1782375033784_0.8549038744558941"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-23T07:05:35.753Z","modified":"2026-06-25T08:10:34.370Z","0.1.0":"2026-04-23T07:05:35.954Z","0.2.0":"2026-04-27T06:38:17.774Z","0.3.0":"2026-05-24T10:38:16.232Z","0.4.0":"2026-06-18T09:10:28.260Z","0.4.1":"2026-06-18T14:48:16.617Z","0.4.2":"2026-06-25T08:10:34.017Z"},"bugs":{"url":"https://github.com/mongodb-developer/vercel-ai-memory/issues"},"author":{"name":"Pavel Duchovny"},"license":"Apache-2.0","homepage":"https://github.com/mongodb-developer/vercel-ai-memory#readme","keywords":["mongodb","vercel-ai","ai-sdk","memory","agent-memory","vector-search","atlas","llm","rag"],"repository":{"type":"git","url":"git+https://github.com/mongodb-developer/vercel-ai-memory.git"},"description":"MongoDB-backed persistent memory provider for the Vercel AI SDK — Session, Semantic, Procedural, Episodic, and Scratchpad memory with Atlas Vector Search.","maintainers":[{"name":"mira_mongodb","email":"stanimira.vlaeva@mongodb.com"},{"name":"pash1986","email":"pavel.duchovny@mongodb.com"}],"readme":"# `@mongodb-developer/vercel-ai-memory`\n\nMongoDB-backed persistent memory for the [Vercel AI SDK](https://sdk.vercel.ai). Gives your agent five structured memory tiers — **Session**, **Semantic**, **Procedural**, **Episodic**, and **Scratchpad** — all stored in MongoDB Atlas with automatic vector search indexes and per-type retention policies.\n\n## Features\n\n- 🧠 **5 memory types** — session history, entity knowledge, how-to procedures, event episodes, and a temporary scratchpad\n- 🔍 **Atlas Vector Search** — semantic retrieval powered by any Vercel AI SDK embedding model\n- 📏 **Auto-detected dimensions** — no need to configure vector dimensions; the package probes them at startup\n- ⏱️ **Flexible retention** — per-type policies: `none`, `ttl`, `ttl+importance`, or fully `dynamic` (forgetting curve)\n- 🗑️ **Agent-driven `memory_forget`** — let the model mark individual memories for immediate deletion\n- 🧩 **Multi-tenant ready** — custom collection/index names, extra filter fields (e.g. `tenant_id`), or disable types entirely\n- 🔄 **Temporal versioning** — semantic and procedural memories are versioned; history is preserved\n- 🏗️ **Zero lock-in** — works with any AI SDK model and any embedding provider (VoyageAI, OpenAI, Cohere, Google, etc.)\n- 🔌 **Lazy connection** — MongoDB connects on first tool use; call `.connect()` early if you prefer\n\n## Installation\n\n```bash\nnpm install @mongodb-developer/vercel-ai-memory\n# or\npnpm add @mongodb-developer/vercel-ai-memory\n```\n\n**Peer dependencies** (install separately):\n\n```bash\nnpm install ai mongodb zod\n```\n\nThis package supports **AI SDK v6 and v7** (`ai@^6.0.0 || ^7.0.0`). The examples\nuse APIs such as `ToolLoopAgent` and `isLoopFinished()` that are available in\nboth major versions.\n\n## Quick Start\n\n```ts\nimport { createMongoDBMemory } from '@mongodb-developer/vercel-ai-memory'\nimport { openai } from '@ai-sdk/openai'\nimport { ToolLoopAgent } from 'ai'\n\n// ── 1. Create the memory instance (once, at module/server level) ──────────────\nconst mongodbMemory = createMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n})\n\n// ── 2. Use per-request, scoped to a user and session ─────────────────────────\nconst agent = new ToolLoopAgent({\n  model: openai('gpt-4.1'),\n  tools: mongodbMemory({ userId: 'alice', sessionId: 'sess-001' }),\n})\n\nconst result = await agent.generate({\n  prompt: 'My name is Alice and I love hiking. Remember that.',\n})\n```\n\n`mongodbMemory({ userId, sessionId })` returns the tools record directly — no spreading needed.\n\n## Session memory: two modes\n\nThe package exposes session (short-term conversation) memory in **two modes**, both backed by the same Mongo collection. Pick based on how much determinism you need — they can't be combined for the same session.\n\n### Mode A — Tool-driven (LLM-controlled)\n\nShown in the Quick Start above. The LLM sees `memory` with `session_append` / `session_recent` commands and decides when to call them. This is the simplest setup but **not deterministic**: the model sometimes skips writes (only user or only assistant turns get persisted) or skips reads (agent forgets earlier turns).\n\nUse this for demos, prototypes, or agents where the LLM genuinely curates what belongs in the transcript.\n\n### Mode B — Hook-driven (runtime-controlled) ✅ recommended for production\n\nHide the session tool commands from the LLM and let the runtime read/write the transcript on every turn via Vercel AI SDK hooks. Every user, assistant, and tool turn is captured **exactly once per generation**, regardless of what the LLM decides.\n\n```ts\nimport { createMongoDBMemory } from '@mongodb-developer/vercel-ai-memory'\nimport { openai } from '@ai-sdk/openai'\nimport { ToolLoopAgent, isLoopFinished } from 'ai'\nimport { z } from 'zod'\n\nconst mongodbMemory = createMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n  // Hide session_append / session_recent from the LLM tool surface, but keep\n  // the session collection + store methods live for the runtime hooks below.\n  // (Use `disable: ['session']` instead if you want the collection entirely off.)\n  topology: { hideToolCommands: ['session'] },\n})\n\nconst agent = new ToolLoopAgent({\n  model: openai('gpt-4o-mini'),\n\n  callOptionsSchema: z.object({\n    userId: z.string(),\n    sessionId: z.string(),\n    prompt: z.string(),\n  }),\n\n  // ── PRE hook: read history + scope onFinish ─────────────────────────────────\n  // Strip `prompt` / `messages` from the incoming settings — the AI SDK enforces\n  // `prompt` XOR `messages`, and we're replacing them with our restored history.\n  prepareCall: async ({ options, prompt: _p, messages: _m, ...settings }) => {\n    const { userId, sessionId, prompt } = options!\n    const history = await mongodbMemory.loadSession({ userId, sessionId })\n\n    return {\n      ...settings,\n      tools: mongodbMemory({ userId, sessionId }),\n      messages: [...history, { role: 'user', content: prompt }],\n      // per-call state flows to onFinish via experimental_context\n      experimental_context: { userId, sessionId, prompt },\n    }\n  },\n\n  // ── POST hook: write every turn exactly once ────────────────────────────────\n  onFinish: mongodbMemory.onFinish(),\n\n  stopWhen: isLoopFinished(),\n})\n\n// Usage\nawait agent.generate({\n  prompt: 'Hi! My name is Alex.',\n  options: { userId: 'alice', sessionId: 'sess-001', prompt: 'Hi! My name is Alex.' },\n})\n```\n\n**What the hooks do:**\n\n| Hook | Method | When it runs | What it does |\n|------|--------|-------------|--------------|\n| Pre  | `mongodbMemory.loadSession({ userId, sessionId })` | Inside `prepareCall`, before every LLM call | Reads prior turns from Mongo, returns `ModelMessage[]` you prepend to `messages`. |\n| Post | `mongodbMemory.onFinish()` | After the full tool loop finishes | Persists the user prompt + every assistant & tool message across all steps. |\n\n`loadSession()` restores user/assistant turns only. Tool turns remain stored in Mongo as\ntranscript/audit records, but they are not replayed as provider `tool-result` blocks because\nOpenAI Responses and Anthropic Messages reject orphan tool results without the matching prior\nassistant tool call.\n\n**Why `experimental_context`?** `ToolLoopAgent` only accepts `onFinish` at construction time, but you still need per-call scope (`userId`, `sessionId`, `prompt`). The hook reads those from `event.experimental_context`, which you set inside `prepareCall`. You can also call `mongodbMemory.onFinish({ userId, sessionId, prompt })` with a baked-in closure when using one-shot `generateText` / `streamText`.\n\nSee `examples/deterministic-agent.ts` for the full runnable example.\n\n> **Note:** The other memory tiers (semantic, procedural, episodic, scratchpad) are intentionally left under LLM control — they should be selective and content-dependent, not every-turn.\n\n## Configuration\n\nAll options are passed to `createMongoDBMemory(options)`.\n\n### Top-level\n\n| Option | Type | Required | Default | Description |\n|--------|------|----------|---------|-------------|\n| `uri` | `string` | ✅ | — | MongoDB Atlas connection string |\n| `embedder` | `EmbeddingModel` | ✅ | — | Any Vercel AI SDK embedding model |\n| `userId` | `string` | — | `'default'` | Default userId (override per-call) |\n| `sessionId` | `string` | — | `'default'` | Default sessionId (override per-call) |\n| `dbName` | `string` | — | `'agent_memory'` | Database name. *(Deprecated — prefer `topology.dbName`.)* |\n| `topology` | `TopologyOptions` | — | `{}` | Where data lives — db, collections, indexes, disabled types |\n| `retention` | `RetentionOptions` | — | see below | Per-type decay / TTL policies |\n| `filtering` | `FilteringOptions` | — | see below | Retrieval-time filters on vector search results |\n| `defaults` | `DefaultsOptions` | — | see below | Small defaults (importance, limits, similarity) |\n\n### `topology` — data location & layout\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `topology.dbName` | `string` | `'agent_memory'` | Database name (takes precedence over the legacy top-level `dbName`) |\n| `topology.collections` | `Partial<Record<MemoryType, string>>` | see **Collection defaults** below | Override collection names per memory type |\n| `topology.vectorIndexNames` | `Partial<Record<VectorMemoryType, string>>` | see **Index defaults** below | Override Atlas Vector Search index names |\n| `topology.disable` | `MemoryType[]` | `[]` | Disable memory types entirely — no bootstrap, tool commands removed, store methods throw |\n| `topology.hideToolCommands` | `MemoryType[]` | `[]` | Hide a memory type's commands from the tool schema, but keep its collection + store methods live (use with runtime hooks) |\n| `topology.extraFilterFields` | `Partial<Record<VectorMemoryType, string[]>>` | `{}` | Extra scalar fields to index as Atlas Search filters (e.g. `['tenant_id']`) |\n\n**Collection defaults:**\n\n| Memory type | Default collection name |\n|---|---|\n| `session` | `session_memory` |\n| `semantic` | `semantic_memory` |\n| `procedural` | `procedural_memory` |\n| `episodic` | `episodic_memory` |\n| `scratchpad` | `scratchpad_memory` |\n\n**Index defaults:**\n\n| Memory type | Default vector index name |\n|---|---|\n| `semantic` | `semantic_vector_index` |\n| `procedural` | `procedural_vector_index` |\n| `episodic` | `episodic_vector_index` |\n\n### `retention` — how each memory type decays\n\nEvery memory type accepts a `DecayPolicy`, one of four modes:\n\n| Mode | Shape | What it does |\n|------|-------|--------------|\n| `none` | `{ mode: 'none' }` | Memories never auto-expire. |\n| `ttl` | `{ mode: 'ttl', ttlSeconds, field? }` | Classic Mongo TTL index on a `Date` field. |\n| `ttl+importance` | `{ mode: 'ttl+importance', ttlSeconds, minImportance, field? }` | TTL only applies to docs with `importance < minImportance` — important memories are immune. |\n| `dynamic` | `{ mode: 'dynamic', computeExpireAt, refreshOnRead? }` | Per-doc `expire_at` computed on write (and recomputed on read when `refreshOnRead: true`, default). Backed by an `expireAfterSeconds: 0` TTL index — perfect for **forgetting-curve** semantics. |\n\n**`computeExpireAt(input)`** receives `{ importance, stats, createdAt }` and returns a `Date` (or `null` to never expire).\n\n**Default retention policies:**\n\n| Memory type | Default policy |\n|---|---|\n| `session` | `{ mode: 'ttl', ttlSeconds: 86_400 }` — 24 h on `created_at` |\n| `scratchpad` | `{ mode: 'ttl', ttlSeconds: 3_600 }` — 1 h on `created_at` |\n| `episodic` | `{ mode: 'ttl', ttlSeconds: 31_536_000, field: 'stats.last_retrieved' }` — 1 yr of inactivity |\n| `semantic` | `{ mode: 'none' }` |\n| `procedural` | `{ mode: 'none' }` |\n\n**Examples:**\n\n```ts\nretention: {\n  // Keep only important semantic facts after a week\n  semantic: { mode: 'ttl+importance', ttlSeconds: 604_800, minImportance: 7 },\n\n  // Forgetting curve — important episodes live longer, rarely-read ones decay fast\n  episodic: {\n    mode: 'dynamic',\n    refreshOnRead: true,\n    computeExpireAt: ({ importance, stats, createdAt }) => {\n      const hoursFromNow = Math.pow(2, importance) // 2^importance hours\n      return new Date(Date.now() + hoursFromNow * 3600 * 1000)\n    },\n  },\n\n  // Disable session auto-expiry entirely\n  session: { mode: 'none' },\n}\n```\n\n### `filtering` — retrieval-time filters\n\nApplied to every `*_search` vector query.\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `filtering.minImportance` | `number` (1–10) | `0` | Drop results with `importance < minImportance` |\n| `filtering.recencyWindowHours` | `number` | `0` (disabled) | Only return memories retrieved within the last N hours |\n| `filtering.numCandidatesMultiplier` | `number` | `10` | `$vectorSearch.numCandidates = limit * multiplier`. Higher → better recall, slower query. |\n\n### `defaults` — small knobs\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `defaults.importance` | `number` (1–10) | `5` | Default importance when the agent doesn't supply one |\n| `defaults.sessionRecentLimit` | `number` | `40` | Default `limit` for `session_recent` |\n| `defaults.searchLimit` | `number` | `5` | Default `limit` for all `*_search` commands |\n| `defaults.similarity` | `'cosine' \\| 'dotProduct' \\| 'euclidean'` | `'cosine'` | Vector similarity used when creating Atlas Search indexes |\n\n## Configuration Recipes\n\n### Minimal — just point it at Mongo\n\n```ts\ncreateMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n})\n```\n\n### Multi-tenant — add a `tenant_id` filter field\n\n```ts\ncreateMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n  topology: {\n    extraFilterFields: {\n      semantic: ['tenant_id'],\n      procedural: ['tenant_id'],\n      episodic: ['tenant_id'],\n    },\n  },\n})\n```\n\n### Session-only — disable everything else\n\n```ts\ncreateMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n  topology: {\n    disable: ['semantic', 'procedural', 'episodic', 'scratchpad'],\n  },\n})\n```\n\n### Custom collection names (existing schema)\n\n```ts\ncreateMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n  topology: {\n    dbName: 'my_app',\n    collections: {\n      session: 'agent_sessions',\n      semantic: 'agent_facts',\n    },\n    vectorIndexNames: {\n      semantic: 'agent_facts_vs',\n    },\n  },\n})\n```\n\n### Aggressive cleanup — keep only high-value semantic facts\n\n```ts\ncreateMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n  retention: {\n    semantic: { mode: 'ttl+importance', ttlSeconds: 30 * 86_400, minImportance: 6 },\n  },\n  filtering: {\n    minImportance: 3,        // never surface low-importance memories\n    recencyWindowHours: 24 * 30, // only last 30 days of reads\n  },\n})\n```\n\n### Forgetting curve — dynamic decay\n\n```ts\ncreateMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n  retention: {\n    episodic: {\n      mode: 'dynamic',\n      refreshOnRead: true,\n      computeExpireAt: ({ importance, stats }) => {\n        // Half-life grows with importance and retrieval count\n        const baseHours = 24 * Math.pow(1.5, importance)\n        const boost = (stats?.retrieval_ct ?? 0) * 12\n        return new Date(Date.now() + (baseHours + boost) * 3600 * 1000)\n      },\n    },\n  },\n})\n```\n\n### Tune recall vs. latency\n\n```ts\nfiltering: {\n  numCandidatesMultiplier: 25, // higher recall, slower\n}\n```\n\n## Supported Embedding Providers\n\nAny model that implements the Vercel AI SDK `EmbeddingModel` interface. Dimensions are **auto-detected**.\n\n```ts\nimport { openai } from '@ai-sdk/openai'\nimport { cohere } from '@ai-sdk/cohere'\nimport { google } from '@ai-sdk/google'\n\nembedder: openai.embedding('text-embedding-3-small')        // 1536\nembedder: cohere.embedding('embed-english-v3.0')            // 1024\nembedder: google.textEmbeddingModel('text-embedding-004')   // 768\n```\n\n## API\n\n### `createMongoDBMemory(options)`\n\nCreates a MongoDB memory provider. Returns a callable `MongoDBMemoryInstance`.\n\n### `mongodbMemory(callOptions?)`\n\nCallable — returns a `{ memory: Tool }` record scoped to the given `userId` and `sessionId`.\n\n```ts\ntools: mongodbMemory({ userId: req.userId, sessionId: req.sessionId })\ntools: mongodbMemory() // use defaults set at creation time\n```\n\n### `mongodbMemory.connect()`\n\nExplicitly connect and bootstrap indexes. Called automatically on first tool use.\n\n```ts\nawait mongodbMemory.connect() // pre-warm on server startup\n```\n\n### `mongodbMemory.close()`\n\nGracefully close the MongoDB connection.\n\n```ts\nprocess.on('SIGTERM', () => mongodbMemory.close())\n```\n\n### `mongodbMemory.store`\n\nRaw `MongoMemoryStore` for advanced direct access:\n\n```ts\nawait mongodbMemory.store.semanticSave('alice', 'Preference', 'Loves hiking', { importance: 8 })\nconst results = await mongodbMemory.store.semanticSearch('alice', 'outdoor activities')\nawait mongodbMemory.store.forget('semantic', someMemoryId) // immediate agent-driven delete\n```\n\n## Memory Types & Tool Commands\n\nThe single `memory` tool accepts a `command` field and routes to the right memory type.\n\n### Session Memory\nPer-session conversation turns.\n```\nsession_append {role, content}  — Save a turn\nsession_recent {limit?}         — Get last N turns (default: defaults.sessionRecentLimit)\n```\n\n### Semantic Memory\nLong-term knowledge about people, entities, and user preferences. **Temporally versioned**.\n```\nsemantic_save {name, content, importance?, tags?}  — Save/update entity knowledge\nsemantic_search {query, limit?}                    — Vector search\n```\n\n### Procedural Memory\nHow-to knowledge: tasks, workflows, agent instructions. **Temporally versioned**.\n```\nprocedural_save {task, content, importance?, source?}  — Save/update a procedure\nprocedural_search {query, limit?}                      — Vector search\n```\n\n### Episodic Memory\nRecords of key events and outcomes.\n```\nepisodic_save {event_type, content, importance?, context?}  — Record an event\nepisodic_search {query, limit?}                             — Vector search\n```\n\n### Scratchpad Memory\nTemporary working notes. Can be promoted to Episodic memory.\n```\nscratchpad_write {content}                         — Write a temporary note\nscratchpad_read                                    — Read current session notes\nscratchpad_promote {scratchpad_id, event_type}     — Promote note → Episodic\n```\n\n### `memory_forget` — agent-driven deletion\n\nAlways available; lets the LLM explicitly forget a specific memory (e.g. when the user says \"forget that\").\n\n```\nmemory_forget {memory_type, id, reason?}\n```\n\nInternally sets `expire_at` to \"now\", leveraging the `expire_at` TTL index. The doc is removed on the next TTL sweep (usually within ~60 s).\n\n> **Disabled types** are removed from the tool's command enum *and* skipped during bootstrap, so the agent can't attempt to use them.\n\n## MongoDB Collections & Indexes\n\nWith defaults, the package creates:\n\n| Collection | Retention | Vector Index |\n|---|---|---|\n| `session_memory` | 24 h on `created_at` | — |\n| `semantic_memory` | none | ✅ cosine (auto-dims) |\n| `procedural_memory` | none | ✅ cosine (auto-dims) |\n| `episodic_memory` | 1 yr on `stats.last_retrieved` | ✅ cosine (auto-dims) |\n| `scratchpad_memory` | 1 h on `created_at` | — |\n\nAll collections also get an `expire_at` TTL index (`expireAfterSeconds: 0`) to power `memory_forget` and `dynamic` retention.\n\n> **Note**: Atlas Vector Search indexes are created asynchronously. Allow a few seconds for them to build on a fresh database.\n\n## Usage in Next.js (App Router)\n\n```ts\n// app/api/chat/route.ts\nimport { createMongoDBMemory } from '@mongodb-developer/vercel-ai-memory'\nimport { openai } from '@ai-sdk/openai'\nimport { ToolLoopAgent, createAgentUIStreamResponse } from 'ai'\n\nconst mongodbMemory = createMongoDBMemory({\n  uri: process.env.MONGODB_URI!,\n  embedder: openai.embedding('text-embedding-3-small'),\n})\n\nexport async function POST(req: Request) {\n  const { messages, userId, sessionId } = await req.json()\n\n  const agent = new ToolLoopAgent({\n    model: openai('gpt-4.1'),\n    tools: mongodbMemory({ userId, sessionId }),\n    instructions: `You are a helpful assistant with persistent memory.\n    At the start of each session, call session_recent to restore context.\n    Save important facts with semantic_save. If the user asks you to forget\n    something, call memory_forget with the matching memory_type + id.`,\n  })\n\n  return createAgentUIStreamResponse({ agent, uiMessages: messages })\n}\n```\n\n## Advanced: Direct Store Access\n\n```ts\nconst { store } = mongodbMemory\n\n// Seed procedural knowledge\nawait store.proceduralSave(\n  'system',\n  'Onboarding Flow',\n  '1. Greet user by name. 2. Ask about their goals. 3. Set up preferences.',\n  { source: 'human_expert', importance: 9 }\n)\n\n// Promote a scratchpad note to episodic memory\nconst scratchId = await store.scratchpadWrite('alice', 'sess-001', 'User mentioned they dislike emails')\nawait store.scratchpadPromote(scratchId.toString(), 'alice', 'preference', { importance: 7 })\n\n// Immediately forget a memory\nawait store.forget('semantic', '507f1f77bcf86cd799439011')\n```\n\n## Environment Variables\n\n```bash\nMONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/?retryWrites=true&w=majority\nOPENAI_API_KEY=sk-...   # or whichever embedding provider you use\n```\n\n## License\n\nApache 2.0 — see [LICENSE](./LICENSE)\n","readmeFilename":"README.md"}