From 492e09bae21a3502272c3e2e61a6e9651f694e95 Mon Sep 17 00:00:00 2001 From: Dhravya Shah Date: Fri, 17 Jul 2026 15:54:30 -0700 Subject: [PATCH] =?UTF-8?q?docs:=20staleness=20sweep=20=E2=80=94=20current?= =?UTF-8?q?=20model=20IDs,=20AI=20SDK=20APIs,=20one=20search=20signature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes across existing pages: stale claude-3-sonnet -> current models, deprecated ai/react + toAIStreamResponse -> current AI SDK APIs, five divergent search signatures unified to client.search.memories (v4) / client.search.documents (v3), singular containerTag in v4 contexts, from-zep containerTag type error, canonical processing-status enum, corrected 'v4 has no SDK' claim, internal links re-pointed at final destinations. Co-Authored-By: Claude Fable 5 --- apps/docs/add-memories.mdx | 4 +- apps/docs/add-memories/examples/basic.mdx | 278 ------- .../add-memories/examples/file-upload.mdx | 195 ----- apps/docs/add-memories/overview.mdx | 249 ------- apps/docs/add-memories/parameters.mdx | 156 ---- apps/docs/ai-sdk/infinite-chat.mdx | 216 ------ apps/docs/ai-sdk/memory-tools.mdx | 147 ---- apps/docs/ai-sdk/overview.mdx | 93 --- apps/docs/ai-sdk/user-profiles.mdx | 357 --------- apps/docs/concepts/container-tags.mdx | 176 ----- apps/docs/concepts/content-types.mdx | 4 +- apps/docs/concepts/filtering.mdx | 359 --------- apps/docs/concepts/memory-vs-rag.mdx | 8 +- apps/docs/concepts/super-rag.mdx | 12 +- apps/docs/cookbook/ai-sdk-integration.mdx | 20 +- apps/docs/cookbook/customer-support.mdx | 8 +- apps/docs/cookbook/document-qa.mdx | 8 +- apps/docs/cookbook/personal-assistant.mdx | 10 +- apps/docs/document-operations.mdx | 3 +- apps/docs/integrations/agno.mdx | 1 - apps/docs/integrations/ai-sdk.mdx | 14 +- apps/docs/integrations/convex.mdx | 1 - apps/docs/integrations/crewai.mdx | 1 - apps/docs/integrations/hermes.mdx | 2 +- apps/docs/integrations/langchain.mdx | 1 - apps/docs/integrations/langgraph.mdx | 1 - apps/docs/integrations/memory-graph.mdx | 2 +- apps/docs/integrations/openai-agents-sdk.mdx | 1 - apps/docs/integrations/openclaw.mdx | 2 +- apps/docs/integrations/supermemory-sdk.mdx | 8 +- apps/docs/list-memories/examples/basic.mdx | 87 --- .../docs/list-memories/examples/filtering.mdx | 506 ------------- .../list-memories/examples/monitoring.mdx | 119 --- .../list-memories/examples/pagination.mdx | 110 --- apps/docs/list-memories/overview.mdx | 153 ---- apps/docs/memory-operations.mdx | 2 +- apps/docs/memory-review.mdx | 2 +- apps/docs/migration/from-mem0.mdx | 14 +- apps/docs/migration/from-zep.mdx | 40 +- apps/docs/migration/tools-v2-upgrade.mdx | 6 +- apps/docs/n8n.mdx | 92 --- apps/docs/search.mdx | 4 +- apps/docs/search/examples/document-search.mdx | 588 --------------- apps/docs/search/examples/memory-search.mdx | 695 ------------------ apps/docs/search/overview.mdx | 493 ------------- apps/docs/search/parameters.mdx | 264 ------- apps/docs/search/query-rewriting.mdx | 440 ----------- apps/docs/search/reranking.mdx | 387 ---------- apps/docs/search/response-schema.mdx | 354 --------- apps/docs/update-delete-memories/overview.mdx | 523 ------------- apps/docs/user-profiles.mdx | 2 +- apps/docs/user-profiles/api.mdx | 226 ------ apps/docs/user-profiles/examples.mdx | 370 ---------- apps/docs/user-profiles/overview.mdx | 135 ---- apps/docs/user-profiles/use-cases.mdx | 153 ---- apps/docs/vibe-coding.mdx | 11 +- apps/docs/zapier.mdx | 64 -- 57 files changed, 95 insertions(+), 8082 deletions(-) delete mode 100644 apps/docs/add-memories/examples/basic.mdx delete mode 100644 apps/docs/add-memories/examples/file-upload.mdx delete mode 100644 apps/docs/add-memories/overview.mdx delete mode 100644 apps/docs/add-memories/parameters.mdx delete mode 100644 apps/docs/ai-sdk/infinite-chat.mdx delete mode 100644 apps/docs/ai-sdk/memory-tools.mdx delete mode 100644 apps/docs/ai-sdk/overview.mdx delete mode 100644 apps/docs/ai-sdk/user-profiles.mdx delete mode 100644 apps/docs/concepts/container-tags.mdx delete mode 100644 apps/docs/concepts/filtering.mdx delete mode 100644 apps/docs/list-memories/examples/basic.mdx delete mode 100644 apps/docs/list-memories/examples/filtering.mdx delete mode 100644 apps/docs/list-memories/examples/monitoring.mdx delete mode 100644 apps/docs/list-memories/examples/pagination.mdx delete mode 100644 apps/docs/list-memories/overview.mdx delete mode 100644 apps/docs/n8n.mdx delete mode 100644 apps/docs/search/examples/document-search.mdx delete mode 100644 apps/docs/search/examples/memory-search.mdx delete mode 100644 apps/docs/search/overview.mdx delete mode 100644 apps/docs/search/parameters.mdx delete mode 100644 apps/docs/search/query-rewriting.mdx delete mode 100644 apps/docs/search/reranking.mdx delete mode 100644 apps/docs/search/response-schema.mdx delete mode 100644 apps/docs/update-delete-memories/overview.mdx delete mode 100644 apps/docs/user-profiles/api.mdx delete mode 100644 apps/docs/user-profiles/examples.mdx delete mode 100644 apps/docs/user-profiles/overview.mdx delete mode 100644 apps/docs/user-profiles/use-cases.mdx delete mode 100644 apps/docs/zapier.mdx diff --git a/apps/docs/add-memories.mdx b/apps/docs/add-memories.mdx index 7d34221f..e8f02878 100644 --- a/apps/docs/add-memories.mdx +++ b/apps/docs/add-memories.mdx @@ -385,7 +385,7 @@ When you add content, Supermemory: Track progress with `GET /v3/documents/{id}`: ```typescript const doc = await client.documents.get("abc123"); -console.log(doc.status); // "queued" | "processing" | "done" +console.log(doc.status); // "queued" | "extracting" | "chunking" | "embedding" | "indexing" | "done" | "failed" ``` @@ -479,4 +479,4 @@ console.log(doc.status); // "queued" | "processing" | "done" - [Search Memories](/search) — Query your content - [User Profiles](/user-profiles) — Get user context -- [Organizing & Filtering](/concepts/filtering) — Container tags and metadata +- [Organizing & Filtering](/concepts/hybrid-search) — Container tags and metadata diff --git a/apps/docs/add-memories/examples/basic.mdx b/apps/docs/add-memories/examples/basic.mdx deleted file mode 100644 index 02cac11e..00000000 --- a/apps/docs/add-memories/examples/basic.mdx +++ /dev/null @@ -1,278 +0,0 @@ ---- -title: "Basic Usage" -description: "Simple examples of adding text content to Supermemory" ---- - -Learn how to add basic text content to Supermemory with simple, practical examples. - -## Add Simple Text - -The most basic operation - adding plain text content. - - - -```typescript TypeScript -const response = await client.add({ - content: "Artificial intelligence is transforming how we work and live" -}); - -console.log(response); -// Output: { id: "abc123", status: "queued" } -``` - -```python Python -response = client.add( - content="Artificial intelligence is transforming how we work and live" -) - -print(response) -# Output: {"id": "abc123", "status": "queued"} -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "Artificial intelligence is transforming how we work and live" - }' -``` - - - -## Add with Container Tags - -Group related content using container tags. - - - -```typescript TypeScript -const response = await client.add({ - content: "Q4 2024 revenue exceeded projections by 15%", - containerTag: "financial_reports" -}); - -console.log(response.id); -// Output: xyz789 -``` - -```python Python -response = client.add( - content="Q4 2024 revenue exceeded projections by 15%", - container_tag="financial_reports" -) - -print(response['id']) -# Output: xyz789 -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "Q4 2024 revenue exceeded projections by 15%", - "containerTag": "financial_reports" - }' - -# Response: {"id": "xyz789", "status": "queued"} -``` - - - -## Add with Metadata - -Attach metadata for better search and filtering. - - - -```typescript TypeScript -await client.add({ - content: "New onboarding flow reduces drop-off by 30%", - containerTag: "product_updates", - metadata: { - impact: "high", - team: "product" - } -}); -``` - -```python Python -client.add( - content="New onboarding flow reduces drop-off by 30%", - container_tag="product_updates", - metadata={ - "impact": "high", - "team": "product" - } -) -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "New onboarding flow reduces drop-off by 30%", - "containerTag": "product_updates", - "metadata": {"impact": "high", "team": "product"} - }' -``` - - - -## Add Multiple Documents - -Process multiple related documents. - - - -```typescript TypeScript -const notes = [ - "API redesign discussion", - "Security audit next month", - "New hire starting Monday" -]; - -const results = await Promise.all( - notes.map(note => - client.add({ - content: note, - containerTag: "meeting_2024_01_15" - }) - ) -); -``` - -```python Python -notes = [ - "API redesign discussion", - "Security audit next month", - "New hire starting Monday" -] - -for note in notes: - client.add( - content=note, - container_tag="meeting_2024_01_15" - ) -``` - -```bash cURL -# Add each note with separate requests -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"content": "API redesign discussion", "containerTag": "meeting_2024_01_15"}' -``` - - - -## Add URLs - -Process web pages, YouTube videos, and other URLs automatically. - - - -```typescript TypeScript -// Web page -await client.add({ - content: "https://example.com/article", - containerTag: "articles" -}); - -// YouTube video (auto-transcribed) -await client.add({ - content: "https://youtube.com/watch?v=dQw4w9WgXcQ", - containerTag: "videos" -}); - -// Google Docs -await client.add({ - content: "https://docs.google.com/document/d/abc123/edit", - containerTag: "docs" -}); -``` - -```python Python -# Web page -client.add( - content="https://example.com/article", - container_tag="articles" -) - -# YouTube video (auto-transcribed) -client.add( - content="https://youtube.com/watch?v=dQw4w9WgXcQ", - container_tag="videos" -) - -# Google Docs -client.add( - content="https://docs.google.com/document/d/abc123/edit", - container_tag="docs" -) -``` - -```bash cURL -# Web page -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"content": "https://example.com/article", "containerTag": "articles"}' - -# YouTube video -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"content": "https://youtube.com/watch?v=dQw4w9WgXcQ", "containerTag": "videos"}' -``` - - - -## Add Markdown Content - -Supermemory preserves markdown formatting. - - - -```typescript TypeScript -const markdown = ` -# Project Documentation - -## Features -- **Real-time sync** -- **AI search** -- **Enterprise security** -`; - -await client.add({ - content: markdown, - containerTag: "docs" -}); -``` - -```python Python -markdown = """ -# Project Documentation - -## Features -- **Real-time sync** -- **AI search** -- **Enterprise security** -""" - -client.add( - content=markdown, - container_tag="docs" -) -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"content": "# Project Documentation\n\n## Features\n- **Real-time sync**\n- **AI search**", "containerTag": "docs"}' -``` - - diff --git a/apps/docs/add-memories/examples/file-upload.mdx b/apps/docs/add-memories/examples/file-upload.mdx deleted file mode 100644 index 7d79d36e..00000000 --- a/apps/docs/add-memories/examples/file-upload.mdx +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: "File Upload" -description: "Upload PDFs, images, and other files to Supermemory" ---- - -Upload files directly to Supermemory for automatic content extraction and processing. - -## Upload a PDF - -Extract text from PDFs with OCR support. - - - -```typescript TypeScript -const file = fs.createReadStream('document.pdf'); - -const response = await client.documents.uploadFile({ - file: file, - containerTags: 'documents' -}); - -console.log(response.id); -// Output: pdf_123 -``` - -```python Python -with open('document.pdf', 'rb') as file: - response = client.documents.upload_file( - file=file, - container_tags='documents' - ) - -print(response['id']) -# Output: pdf_123 -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents/file" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -F "file=@document.pdf" \ - -F "containerTags=documents" - -# Response: {"id": "pdf_123", "status": "processing"} -``` - - - -## Upload Images with OCR - -Extract text from images. - - - -```typescript TypeScript -const image = fs.createReadStream('screenshot.png'); - -await client.documents.uploadFile({ - file: image, - containerTags: 'images' -}); -``` - -```python Python -with open('screenshot.png', 'rb') as file: - client.documents.upload_file( - file=file, - container_tags='images' - ) -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents/file" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -F "file=@screenshot.png" \ - -F "containerTags=images" -``` - - - -## Browser File Upload - -Handle browser file uploads. - - - -```javascript JavaScript -const formData = new FormData(); -formData.append('file', fileInput.files[0]); -formData.append('containerTags', 'uploads'); - -const response = await fetch('https://api.supermemory.ai/v3/documents/file', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${API_KEY}` - }, - body: formData -}); - -const result = await response.json(); -console.log(result.id); -``` - -```typescript React -function handleUpload(file: File) { - const formData = new FormData(); - formData.append('file', file); - formData.append('containerTags', 'uploads'); - - return fetch('https://api.supermemory.ai/v3/documents/file', { - method: 'POST', - headers: { 'Authorization': `Bearer ${API_KEY}` }, - body: formData - }); -} -``` - -```bash cURL -# Browser uploads use FormData, same as file upload -curl -X POST "https://api.supermemory.ai/v3/documents/file" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -F "file=@document.pdf" \ - -F "containerTags=uploads" -``` - - - -## Upload Multiple Files - -Batch upload with rate limiting. - - - -```typescript TypeScript -for (const file of files) { - const stream = fs.createReadStream(file); - - await client.documents.uploadFile({ - file: stream, - containerTags: 'batch' - }); - - // Rate limit - await new Promise(r => setTimeout(r, 1000)); -} -``` - -```python Python -import time - -for file_path in files: - with open(file_path, 'rb') as file: - client.documents.upload_file( - file=file, - container_tags='batch' - ) - - time.sleep(1) # Rate limit -``` - -```bash cURL -# Upload each file separately with delays -for file in *.pdf; do - curl -X POST "https://api.supermemory.ai/v3/documents/file" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -F "file=@$file" \ - -F "containerTags=batch" - - sleep 1 # Rate limit -done -``` - - - -## Supported File Types - -### Documents -| Format | Extensions | Processing | -|--------|------------|------------| -| PDF | .pdf | Text extraction, OCR for scanned pages | -| Microsoft Word | .doc, .docx | Full text and formatting extraction | -| Plain Text | .txt, .md | Direct text processing | -| CSV | .csv | Structured data extraction | - -### Images -| Format | Extensions | Processing | -|--------|------------|------------| -| JPEG | .jpg, .jpeg | OCR text extraction | -| PNG | .png | OCR text extraction | -| GIF | .gif | OCR for static images | -| WebP | .webp | OCR text extraction | - -### Size Limits -- **Maximum file size**: 50MB -- **Recommended size**: < 10MB for optimal processing -- **Large files**: May take longer to process diff --git a/apps/docs/add-memories/overview.mdx b/apps/docs/add-memories/overview.mdx deleted file mode 100644 index be96185a..00000000 --- a/apps/docs/add-memories/overview.mdx +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Add Memories Overview" -description: "Add content to Supermemory through text, files, or URLs" -sidebarTitle: "Overview" ---- - -Add any type of content to Supermemory - text, files, URLs, images, videos, and more. Everything is automatically processed into searchable memories that form part of your intelligent knowledge graph. - -## Prerequisites - -Before adding memories, you need to set up the Supermemory client: - -- **Install the SDK** for your language -- **Get your API key** from [Supermemory Console](https://console.supermemory.ai) -- **Initialize the client** with your API key - - - -```bash npm -npm install supermemory -``` - -```bash pip -pip install supermemory -``` - - - - - -```typescript TypeScript -import Supermemory from 'supermemory'; - -const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! -}); -``` - -```python Python -from supermemory import Supermemory -import os - -client = Supermemory( - api_key=os.environ.get("SUPERMEMORY_API_KEY") -) -``` - - - -## Quick Start - - - -```typescript TypeScript -// Add text content -const result = await client.add({ - content: "Machine learning enables computers to learn from data", - containerTag: "ai-research", - metadata: { priority: "high" } -}); - -console.log(result); -// Output: { id: "abc123", status: "queued" } -``` - -```python Python -# Add text content -result = client.add( - content="Machine learning enables computers to learn from data", - container_tags=["ai-research"], - metadata={"priority": "high"} -) - -print(result) -# Output: {"id": "abc123", "status": "queued"} -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "Machine learning enables computers to learn from data", - "containerTag": "ai-research", - "metadata": {"priority": "high"} - }' - -# Response: {"id": "abc123", "status": "queued"} -``` - - - -## Key Concepts - - -**New to Supermemory?** Read [How Supermemory Works](/how-it-works) to understand the knowledge graph architecture and the distinction between documents and memories. - - -### Quick Overview -- **Documents**: Raw content you upload (PDFs, URLs, text) -- **Memories**: Searchable chunks created automatically with relationships -- **Container Tags**: Group related content for better context -- **Metadata**: Additional information for filtering - -### Content Sources - -Add content through three methods: - -1. **Direct Text**: Send text content directly via API -2. **File Upload**: Upload PDFs, images, videos for extraction -3. **URL Processing**: Automatic extraction from web pages and platforms - -## Endpoints - - -Remember, these endpoints add documents. Memories are inferred by Supermemory. - - -### Add Content - -`POST /v3/documents` - -Add text content, URLs, or any supported format. - - - -```typescript TypeScript -await client.add({ - content: "Your content here", - containerTag: "project" -}); -``` - -```python Python -client.add( - content="Your content here", - container_tags=["project"] -) -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"content": "Your content here", "containerTag": "project"}' -``` - - - -### Upload File - -`POST /v3/documents/file` - -Upload files directly for processing. - - - -```typescript TypeScript -await client.documents.uploadFile({ - file: fileStream, - containerTag: "project" -}); -``` - -```python Python -client.documents.upload_file( - file=open('file.pdf', 'rb'), - container_tags='project' -) -``` - -```bash cURL -curl -X POST "https://api.supermemory.ai/v3/documents/file" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -F "file=@document.pdf" \ - -F "containerTags=project" -``` - - - -### Update Memory - -`PATCH /v3/documents/{id}` - -Update existing document content or metadata. Content changes trigger reindexing; metadata-only updates do not. - - - -```typescript TypeScript -await client.documents.update("doc_id", { - content: "Updated content" -}); -``` - -```python Python -client.documents.update("doc_id", { - "content": "Updated content" -}) -``` - -```bash cURL -curl -X PATCH "https://api.supermemory.ai/v3/documents/doc_id" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"content": "Updated content"}' -``` - - - -## Supported Content Types - -### Documents -- PDF with OCR support -- Google Docs, Sheets, Slides -- Notion pages -- Microsoft Office files - -### Media -- Images (JPG, PNG, GIF, WebP) with OCR - -### Web Content -- Twitter/X posts -- YouTube videos with captions - -### Text Formats -- Plain text -- Markdown -- CSV files - - Refer to the [connectors guide](/connectors/overview) to learn how you can connect Google Drive, Notion, and OneDrive and sync files in real-time. - -## Response Format - -```json -{ - "id": "D2Ar7Vo7ub83w3PRPZcaP1", - "status": "queued" -} -``` - -- **`id`**: Unique document identifier -- **`status`**: Processing state (`queued`, `processing`, `done`) - - - -## Next Steps - -- [Memory Operations](/memory-operations) - Track status, list, update, and delete memories -- [Search Memories](/search) - Search your content diff --git a/apps/docs/add-memories/parameters.mdx b/apps/docs/add-memories/parameters.mdx deleted file mode 100644 index dedfad0e..00000000 --- a/apps/docs/add-memories/parameters.mdx +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: "Parameters" -description: "Complete reference for add memory parameters" ---- - -Detailed parameter documentation for adding memories to Supermemory. - -## Request Parameters - -### Required Parameters - - - The content to process into memories. Can be: - - Plain text content - - URL to process - - HTML content - - Markdown text - - ```json - { - "content": "Machine learning is a subset of AI..." - } - ``` - - **URL Examples:** - ```json - { - "content": "https://youtube.com/watch?v=dQw4w9WgXcQ" - } - ``` - - -### Optional Parameters - - - **Recommended.** Single tag to group related memories. Improves search performance. - - Default: `"sm_project_default"` - - ```json - { - "containerTag": "project_alpha" - } - ``` - - - Use `containerTag` (singular) for better performance than `containerTags` (array). - - - - - Additional metadata as key-value pairs. Values must be strings, numbers, or booleans. - - ```json - { - "metadata": { - "source": "research-paper", - "author": "John Doe", - "priority": 1, - "reviewed": true - } - } - ``` - - **Restrictions:** - - No nested objects - - No arrays as values - - Keys must be strings - - Values: string, number, or boolean only - - - - Your own identifier for the document. Enables deduplication and updates. - - **Maximum length:** 255 characters - - ```json - { - "customId": "doc_2024_01_research_ml" - } - ``` - - **Use cases:** - - Prevent duplicate uploads - - Update existing documents - - Sync with external systems - - - - Raw content to store alongside processed content. Useful for preserving original formatting. - - ```json - { - "content": "# Machine Learning\n\nML is a subset of AI...", - "raw": "# Machine Learning\n\nML is a subset of AI..." - } - ``` - - -## File Upload Parameters - -For `POST /v3/documents/file` endpoint: - - - The file to upload. Supported formats: - - **Documents:** PDF, DOC, DOCX, TXT, MD - - **Images:** JPG, PNG, GIF, WebP - - **Videos:** MP4, WebM, AVI - - **Maximum size:** 50MB - - - - Container tag for the uploaded file (sent as form field). - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/file" \ - -F "file=@document.pdf" \ - -F "containerTags=research" - ``` - - - -## Container Tag Patterns - -### Recommended Patterns - -```typescript -// By user -"user_123" - -// By project -"project_alpha" - -// By organization and type -"org_456_research" - -// By time period -"2024_q1_reports" - -// By data source -"slack_channel_general" -``` - -### Performance Considerations - -```typescript -// ✅ FAST: Single tag -{ "containerTag": "project_alpha" } - -// ⚠️ SLOWER: Multiple tags -{ "containerTags": ["project_alpha", "backend", "auth"] } - -// ❌ AVOID: Too many tags -{ "containerTags": ["tag1", "tag2", "tag3", "tag4", "tag5"] } -``` diff --git a/apps/docs/ai-sdk/infinite-chat.mdx b/apps/docs/ai-sdk/infinite-chat.mdx deleted file mode 100644 index 4d67a86d..00000000 --- a/apps/docs/ai-sdk/infinite-chat.mdx +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: "Infinite Chat" -description: "Unlimited context for chat applications with automatic memory management" -sidebarTitle: "Infinite Chat" ---- - -Infinite Chat provides unlimited context for chat applications with automatic memory management. - -## Setup - -```typescript -import { streamText } from "ai" - -const infiniteChat = createAnthropic({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.anthropic.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) - -const result = await streamText({ - model: infiniteChat("claude-3-sonnet"), - messages: [ - { role: "user", content: "Hello! Remember that I love TypeScript." } - ] -}) -``` - -## Provider Configuration - -### Named Providers - - - -```typescript OpenAI -const infiniteChat = createOpenAI({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.openai.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) - -const result = await streamText({ - model: infiniteChat("gpt-5"), - messages: [...] -}) -``` - -```typescript Anthropic -const infiniteChat = createAnthropic({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.anthropic.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) - -const result = await streamText({ - model: infiniteChat("claude-3-sonnet"), - messages: [...] -}) -``` - -```typescript Google -const infiniteChat = createGoogleGenerativeAI({ - baseUrl: 'https://api.supermemory.ai/v3/https://generativelanguage.googleapis.com/v1beta', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) - -const result = await streamText({ - model: infiniteChat("gemini-pro"), - messages: [...] -}) -``` - -```typescript Groq -const infiniteChat = createGroq({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.groq.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) - -const result = await streamText({ - model: infiniteChat("mixtral-8x7b"), - messages: [...] -}) -``` - - - -### Custom Provider URL - -```typescript -const infiniteChat = createOpenAI({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.openai.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) -``` - -## Example Usage - -```typescript -import { streamText } from "ai" - -const infiniteChat = createOpenAI({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.openai.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) - -const result = await streamText({ - model: infiniteChat("gpt-5"), - messages: [ - { role: "user", content: "What did we discuss yesterday?" } - ] -}) - -return result.toAIStreamResponse() -``` - -## Configuration Options - -```typescript -interface ConfigWithProviderName { - providerName: 'openai' | 'anthropic' | 'openrouter' | - 'deepinfra' | 'groq' | 'google' | 'cloudflare' - providerApiKey: string - headers?: Record -} - -interface ConfigWithProviderUrl { - providerUrl: string - providerApiKey: string - headers?: Record -} -``` - -### Custom Headers - -Add user IDs, conversation IDs, or other metadata: - -```typescript -const infiniteChat = createOpenAI({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.openai.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) -``` - -## Comparison with Memory Tools - -| Feature | Infinite Chat | Memory Tools | -|---------|--------------|--------------| -| Memory Management | Automatic | Manual | -| Context Handling | Automatic | Manual | -| Tool Calls | None | searchMemories, addMemory, fetchMemory | -| Best For | Chat apps | AI agents | -| Setup Complexity | Simple | Moderate | - -## Headers - -Add user and conversation context: - -```typescript -const infiniteChat = createOpenAI({ - baseUrl: 'https://api.supermemory.ai/v3/https://api.openai.com/v1', - apiKey: 'your-provider-api-key', - headers: { - 'x-supermemory-api-key': 'supermemory-api-key', - 'x-sm-conversation-id': 'conversation-id' - } -}) -``` - -## Comparison - -| Feature | Infinite Chat | Memory Tools | -|---------|--------------|-------------| -| Memory Management | Automatic | Manual | -| Context Handling | Automatic | Manual | -| Tool Calls | None | searchMemories, addMemory, fetchMemory | -| Best For | Chat apps | AI agents | - -## Next Steps - - - - Explore explicit memory control - - - - See complete implementations - - diff --git a/apps/docs/ai-sdk/memory-tools.mdx b/apps/docs/ai-sdk/memory-tools.mdx deleted file mode 100644 index f48d04f7..00000000 --- a/apps/docs/ai-sdk/memory-tools.mdx +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: "Memory Tools" -description: "Add memory capabilities to your AI agents with Vercel AI SDK tools" -sidebarTitle: "Memory Tools" ---- - -Memory tools allow AI agents to search, add, and fetch memories. - -## Setup - -```typescript -import { streamText } from "ai" -import { createOpenAI } from "@ai-sdk/openai" -import { supermemoryTools } from "@supermemory/tools/ai-sdk" - -const openai = createOpenAI({ - apiKey: "YOUR_OPENAI_KEY" -}) - -const result = await streamText({ - model: openai("gpt-5"), - prompt: "Remember that my name is Alice", - tools: supermemoryTools("YOUR_SUPERMEMORY_KEY") -}) -``` - -## Available Tools - -### Search Memories - -Semantic search through user memories: - -```typescript -const result = await streamText({ - model: openai("gpt-5"), - prompt: "What are my dietary preferences?", - tools: supermemoryTools("API_KEY") -}) - -// The AI will automatically call searchMemories tool -// Example tool call: -// searchMemories({ informationToGet: "dietary preferences and restrictions" }) -``` - -### Add Memory - -Store new information: - -```typescript -const result = await streamText({ - model: anthropic("claude-3-sonnet"), - prompt: "Remember that I'm allergic to peanuts", - tools: supermemoryTools("API_KEY") -}) - -// The AI will automatically call addMemory tool -// Example tool call: -// addMemory({ memory: "User is allergic to peanuts" }) -``` - -### Fetch Memory - -Retrieve specific memory by ID: - -```typescript -const result = await streamText({ - model: openai("gpt-5"), - prompt: "Get the details of memory abc123", - tools: supermemoryTools("API_KEY") -}) - -// The AI will automatically call fetchMemory tool -// Example tool call: -// fetchMemory({ memoryId: "abc123" }) -``` - -## Using Individual Tools - -For more control, import tools separately: - -```typescript -import { - searchMemoriesTool, - addMemoryTool, - fetchMemoryTool -} from "@supermemory/tools/ai-sdk" - -// Use only search tool -const result = await streamText({ - model: openai("gpt-5"), - prompt: "What do you know about me?", - tools: { - searchMemories: searchMemoriesTool("API_KEY", { - projectId: "personal" - }) - } -}) - -// Combine with custom tools -const result = await streamText({ - model: anthropic("claude-3"), - prompt: "Help me with my calendar", - tools: { - searchMemories: searchMemoriesTool("API_KEY"), - // Your custom tools - createEvent: yourCustomTool, - sendEmail: anotherCustomTool - } -}) -``` - -## Tool Results - -Each tool returns a result object: - -```typescript -// searchMemories result -{ - success: true, - results: [...], // Array of memories - count: 5 -} - -// addMemory result -{ - success: true, - memory: { id: "mem_123", ... } -} - -// fetchMemory result -{ - success: true, - memory: { id: "mem_123", content: "...", ... } -} -``` - -## Next Steps - - - - Automatic personalization with profiles - - - - See more complete examples - - diff --git a/apps/docs/ai-sdk/overview.mdx b/apps/docs/ai-sdk/overview.mdx deleted file mode 100644 index b4d6aad9..00000000 --- a/apps/docs/ai-sdk/overview.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "AI SDK Integration" -description: "Use Supermemory with Vercel AI SDK for seamless memory management" -sidebarTitle: "Overview" ---- - -The Supermemory AI SDK provides native integration with Vercel's AI SDK through two approaches: **User Profiles** for automatic personalization and **Memory Tools** for agent-based interactions. - - - Check out the NPM page for more details - - -## Installation - -```bash -npm install @supermemory/tools -``` - -## User Profiles with Middleware - -Automatically inject user profiles into every LLM call for instant personalization. Customize how memories are formatted with the `promptTemplate` option for XML-based prompting, custom branding, or model-specific formatting. - -```typescript -import { generateText } from "ai" -import { withSupermemory } from "@supermemory/tools/ai-sdk" -import { openai } from "@ai-sdk/openai" - -// Wrap your model with Supermemory - profiles are automatically injected -const modelWithMemory = withSupermemory(openai("gpt-5"), { - containerTag: "user-123", - customId: "conversation-456", -}) - -const result = await generateText({ - model: modelWithMemory, - messages: [{ role: "user", content: "What do you know about me?" }] -}) -// The model automatically has the user's profile context! -``` - - - **Memory saving is enabled by default** (`addMemory: "always"`). New conversations are persisted automatically. To opt out, set `addMemory: "never"`: - - ```typescript - const modelWithMemory = withSupermemory(openai("gpt-5"), { - containerTag: "user-123", - customId: "conversation-456", - addMemory: "never", - }) - ``` - - -```typescript -``` - -## Memory Tools - -Add memory capabilities to AI agents with search, add, and fetch operations. - -```typescript -import { streamText } from "ai" -import { createAnthropic } from "@ai-sdk/anthropic" -import { supermemoryTools } from "@supermemory/tools/ai-sdk" - -const anthropic = createAnthropic({ - apiKey: "YOUR_ANTHROPIC_KEY" -}) - -const result = await streamText({ - model: anthropic("claude-3-sonnet"), - prompt: "Remember that my name is Alice", - tools: supermemoryTools("YOUR_SUPERMEMORY_KEY") -}) -``` - -## When to Use - -| Approach | Use Case | -|----------|----------| -| User Profiles | Personalized LLM responses with automatic user context | -| Memory Tools | AI agents that need explicit memory control | - -## Next Steps - - - - Automatic personalization with profiles - - - - Agent-based memory management - - diff --git a/apps/docs/ai-sdk/user-profiles.mdx b/apps/docs/ai-sdk/user-profiles.mdx deleted file mode 100644 index c0027aa2..00000000 --- a/apps/docs/ai-sdk/user-profiles.mdx +++ /dev/null @@ -1,357 +0,0 @@ ---- -title: "User Profiles with AI SDK" -description: "Automatically inject user profiles into LLM calls for instant personalization" -sidebarTitle: "User Profiles" ---- - -## Overview - -The `withSupermemory` middleware automatically injects user profiles into your LLM calls, providing instant personalization without manual prompt engineering or API calls. - - - **New to User Profiles?** Read the [conceptual overview](/user-profiles) to understand what profiles are and why they're powerful for LLM personalization. - - -## Quick Start - -```typescript -import { generateText } from "ai" -import { withSupermemory } from "@supermemory/tools/ai-sdk" -import { openai } from "@ai-sdk/openai" - -// Wrap any model with Supermemory middleware -const modelWithMemory = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conversation-456", -}) - -// Use normally - profiles are automatically injected! -const result = await generateText({ - model: modelWithMemory, - messages: [{ role: "user", content: "Help me with my current project" }] -}) - -// The model knows about the user's background, skills, and current work! -``` - -## How It Works - -The `withSupermemory` middleware: - -1. **Intercepts** your LLM calls before they reach the model -2. **Fetches** the user's profile based on the container tag -3. **Injects** profile data into the system prompt automatically -4. **Forwards** the enhanced prompt to your LLM - -All of this happens transparently - you write code as if using a normal model, but get personalized responses. - - - **Memory saving is enabled by default** (`addMemory: "always"`). New conversations are persisted automatically. To opt out, set `addMemory: "never"`: - - ```typescript - const model = withSupermemory(openai("gpt-5"), { - containerTag: "user-123", - customId: "conversation-456", - addMemory: "never", - }) - ``` - - -## Memory Search Modes - -Configure how the middleware retrieves and uses memory: - -### Profile Mode (Default) - -Retrieves the user's complete profile without query-specific search. Best for general personalization. - -```typescript -// Default behavior - profile mode -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", -}) - -// Or explicitly specify -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - mode: "profile", -}) - -const result = await generateText({ - model, - messages: [{ role: "user", content: "What do you know about me?" }] -}) -// Response uses full user profile for context -``` - -### Query Mode - -Searches memories based on the user's specific message. Best for finding relevant information. - -```typescript -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - mode: "query", -}) - -const result = await generateText({ - model, - messages: [{ - role: "user", - content: "What was that Python script I wrote last week?" - }] -}) -// Searches for memories about Python scripts from last week -``` - -### Full Mode - -Combines profile AND query-based search for comprehensive context. Best for complex interactions. - -```typescript -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - mode: "full", -}) - -const result = await generateText({ - model, - messages: [{ - role: "user", - content: "Help me debug this similar to what we did before" - }] -}) -// Uses both profile (user's expertise) AND search (previous debugging sessions) -``` - -## Custom Prompt Templates - -Customize how memories are formatted and injected into the system prompt using the `promptTemplate` option. This is useful for: -- Using XML-based prompting (e.g., for Claude models) -- Custom branding (removing "supermemories" references) -- Controlling how your agent describes where information comes from - -```typescript -import { generateText } from "ai" -import { withSupermemory, type MemoryPromptData } from "@supermemory/tools/ai-sdk" -import { openai } from "@ai-sdk/openai" - -const customPrompt = (data: MemoryPromptData) => ` - -Here is some information about your past conversations with the user: -${data.userMemories} -${data.generalSearchMemories} - -`.trim() - -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - mode: "full", - promptTemplate: customPrompt, -}) - -const result = await generateText({ - model, - messages: [{ role: "user", content: "What do you know about me?" }] -}) -``` - -### MemoryPromptData Interface - -The `MemoryPromptData` object passed to your template function provides: - -- `userMemories`: Pre-formatted markdown combining static profile facts (name, preferences, goals) and dynamic context (current projects, recent interests) -- `generalSearchMemories`: Pre-formatted search results based on semantic similarity to the current query (empty string if mode is "profile") -- `searchResults`: Raw search results array (`Array<{ memory: string; metadata?: Record }>`) for traversing, filtering, or selectively including results based on metadata - -### XML-Based Prompting for Claude - -Claude models perform better with XML-structured prompts: - -```typescript -const claudePrompt = (data: MemoryPromptData) => ` - - - ${data.userMemories} - - - ${data.generalSearchMemories} - - - -Use the above context to provide personalized responses. -`.trim() - -const model = withSupermemory(anthropic("claude-3-sonnet"), { - containerTag: "user-123", - customId: "conv-1", - mode: "full", - promptTemplate: claudePrompt, -}) -``` - -### Filtering Search Results - -Use `searchResults` to traverse the raw data and pick what's important: - -```typescript -const selectivePrompt = (data: MemoryPromptData) => { - const relevant = data.searchResults.filter( - (r) => (r.metadata?.score as number) > 0.7 - ) - return ` - -${data.userMemories} - - -${relevant.map((r) => `- ${r.memory}`).join("\n")} - -`.trim() -} - -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - mode: "full", - promptTemplate: selectivePrompt, -}) -``` - -### Custom Branding - -Remove "supermemories" references and use your own branding: - -```typescript -const brandedPrompt = (data: MemoryPromptData) => ` -You are an AI assistant with access to the user's personal knowledge base. - -User Profile: -${data.userMemories} - -Relevant Context: -${data.generalSearchMemories} - -Use this information to provide personalized and contextually relevant responses. -`.trim() - -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - promptTemplate: brandedPrompt, -}) -``` - -### Default Template - -If no `promptTemplate` is provided, the default format is used: - -```typescript -const defaultPrompt = (data: MemoryPromptData) => - `User Supermemories: \n${data.userMemories}\n${data.generalSearchMemories}`.trim() -``` - -## Verbose Logging - -Enable detailed logging to see exactly what's happening: - -```typescript -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - verbose: true, // Enable detailed logging -}) - -const result = await generateText({ - model, - messages: [{ role: "user", content: "Where do I live?" }] -}) - -// Console output: -// [supermemory] Searching memories for container: user-123 -// [supermemory] User message: Where do I live? -// [supermemory] System prompt exists: false -// [supermemory] Found 3 memories -// [supermemory] Memory content: You live in San Francisco, California... -// [supermemory] Creating new system prompt with memories -``` - -## Comparison with Direct API - -The AI SDK middleware abstracts away the complexity of manual profile management: - - - - ```typescript - // Simple setup - const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", - }) - - // Use normally - const result = await generateText({ - model, - messages: [{ role: "user", content: "Help me" }] - }) - ``` - - - - ```typescript - // Manual profile fetching - const profileRes = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { /* ... */ }, - body: JSON.stringify({ containerTag: "user-123" }) - }) - const profile = await profileRes.json() - - // Manual prompt construction - const systemPrompt = `User Profile:\n${profile.profile.static?.join('\n')}` - - // Manual LLM call with profile - const result = await generateText({ - model: openai("gpt-4"), - messages: [ - { role: "system", content: systemPrompt }, - { role: "user", content: "Help me" } - ] - }) - ``` - - - -## Limitations - -- **Beta Feature**: The `withSupermemory` middleware is currently in beta -- **Container Tag Required**: You must provide a valid container tag -- **API Key Required**: Ensure `SUPERMEMORY_API_KEY` is set in your environment - -## Next Steps - - - - Understand how profiles work conceptually - - - - Add explicit memory operations to your agents - - - - Explore the underlying profile API - - - - View the package on NPM - - - - - **Pro Tip**: Start with profile mode for general personalization, then experiment with query and full modes as you understand your use case better. - diff --git a/apps/docs/concepts/container-tags.mdx b/apps/docs/concepts/container-tags.mdx deleted file mode 100644 index 71b8b0d7..00000000 --- a/apps/docs/concepts/container-tags.mdx +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: "Container Tags" -sidebarTitle: "Container Tags" -description: "The isolation boundary that groups and partitions memories by user, project, or any logical scope" -icon: "folder" ---- - -A **container tag** is the primary way you organize and isolate memories in Supermemory. It's a simple string identifier you attach to content when you add it — and that you pass back when you search, list, or update it. - -Think of a container tag as a **namespace**: every memory tagged with `user_alex` lives in its own isolated space, completely separate from memories tagged `user_jordan`. This is what makes Supermemory safe to use in multi-tenant applications — one user can never see another user's memories unless you explicitly query across both tags. - - - - Bucket memories by user, project, agent, workspace, or any boundary that makes sense for your app. - - - Each container tag maps to its own vector namespace, so search and retrieval never leak across boundaries. - - - ---- - -## How it works - -When you add a memory with a container tag, Supermemory automatically creates a **space** for that tag (scoped to your organization) if one doesn't already exist. You don't need to provision anything ahead of time — the first write with a new tag creates the container, and subsequent writes reuse it. - -```typescript -// First call auto-creates the "user_alex" container -await client.add({ - content: "Alex prefers dark mode and concise answers", - containerTag: "user_alex", -}); - -// Later, retrieve only Alex's memories -const results = await client.search.memories({ - q: "what are the user's UI preferences?", - containerTag: "user_alex", -}); -``` - -Under the hood, each container tag is hashed into a dedicated vector namespace. Embeddings, chunks, and memory entries for one tag are stored and searched independently of every other tag — there is no shared index to filter through, which is why isolation is strict rather than best-effort. - - -A container tag is an **opaque identifier you choose**. Supermemory does not parse meaning out of it — `user_123`, `project_mobile`, and `org:acme:team:growth` are all equally valid. Pick a convention that mirrors the access boundaries in your own application. - - ---- - -## Naming rules - -Container tags are validated on every request. A tag must: - -- Be **100 characters or less** -- Contain only **alphanumeric characters, hyphens (`-`), underscores (`_`), and colons (`:`)** - -Matching pattern: `^[a-zA-Z0-9_:-]+$` - -```typescript -// ✅ Valid -"user_123" -"project-mobile-app" -"org:acme:user:john" -"tenant_42_workspace_7" - -// ❌ Invalid — spaces, slashes, and other symbols are rejected -"user 123" -"project/mobile" -"team@acme" -``` - -The colon is intentionally allowed so you can build **hierarchical** tags (for example `org:acme:user:john`) that encode several levels of structure in a single identifier. - ---- - -## `containerTag` vs `containerTags` - -Supermemory's current API uses a **single** `containerTag` string per request. - - -The plural `containerTags` array field is **deprecated**. It still works for backward compatibility on older (`/v3`) endpoints, but new integrations should use the singular `containerTag` string. The `/v4` API only accepts `containerTag`. - - -| API field | Type | Status | -|-----------|------|--------| -| `containerTag` | `string` | ✅ Current — use this | -| `containerTags` | `string[]` | ⚠️ Deprecated | - ---- - -## Where container tags are used - -The same tag flows through the entire lifecycle of a memory. Pass it consistently and your data stays neatly partitioned. - -| Operation | Behavior | -|-----------|----------| -| **Add** | Writes the memory into the tag's container (auto-creating the space). | -| **Search** | Restricts retrieval to the given tag's namespace. | -| **List** | Returns only memories belonging to the tag(s). | -| **Update / Delete** | Targets the memory inside the specified tag's container. | - -```typescript -// Add -await client.add({ content: "Q1 planning notes", containerTag: "project_q1" }); - -// Search within the same container -await client.search.memories({ q: "planning", containerTag: "project_q1" }); - -// List everything in the container -await client.documents.list({ containerTags: ["project_q1"] }); -``` - ---- - -## Access control - -Container tags are also an **authorization boundary**, not just an organizational one. Two mechanisms can restrict which tags a given caller may touch: - -- **API key scopes** — an API key can be limited to a specific set of container tags, with read or write permission per tag. -- **Member restrictions** — an organization member can be granted access to only certain container tags. - -When a request is restricted, Supermemory validates the requested tag against the caller's allowed set: - -- Requesting a tag outside the allowed set returns `403 Forbidden`. -- A write (add/update/delete) to a read-only tag returns `403 Forbidden`. -- If no tag is supplied by a restricted caller, the request is automatically scoped to their allowed tag(s). - -This means you can hand out an API key that is physically incapable of reading or writing another tenant's data, enforced at the data layer rather than in your application code. - ---- - -## Per-container settings - -Each container tag can carry its own configuration, independent of other tags in the same organization: - -| Setting | Purpose | -|---------|---------| -| `name` | A human-friendly display name for the container. | -| `entityContext` | A custom context prompt applied when processing documents in this container — useful for steering extraction and summarization per project or tenant. | - -```typescript -await client.containerTags.update("project_research", { - entityContext: "This project contains research papers about machine learning.", -}); -``` - -Container tags can also be **merged** when you need to consolidate two buckets of memories into one. - ---- - -## Choosing a convention - -Pick a tagging scheme that maps onto the isolation boundaries your application actually needs. - -| Pattern | Example | Use case | -|---------|---------|----------| -| User isolation | `user_{userId}` | Per-user memory in a consumer app | -| Project grouping | `project_{projectId}` | Project- or workspace-scoped content | -| Agent scoping | `agent_{agentId}` | Separate long-term memory per AI agent | -| Hierarchical | `org:{orgId}:user:{userId}` | Multi-level, multi-tenant SaaS | - - -Keep tags **deterministic** — derive them directly from IDs you already have (a user ID, a tenant ID) so you can always reconstruct the right tag at query time without a lookup. - - ---- - -## Next steps - - - - Combine container tags with metadata filters for precise retrieval. - - - See container tags in action across the add API. - - diff --git a/apps/docs/concepts/content-types.mdx b/apps/docs/concepts/content-types.mdx index 473fad67..25aabba0 100644 --- a/apps/docs/concepts/content-types.mdx +++ b/apps/docs/concepts/content-types.mdx @@ -14,7 +14,7 @@ Raw text, conversations, notes, or any string content. ```typescript await client.add({ content: "User prefers dark mode and uses vim keybindings", - containerTags: ["user_123"] + containerTag: "user_123" }); ``` @@ -29,7 +29,7 @@ Send a URL and Supermemory fetches, extracts, and indexes the content. ```typescript await client.add({ content: "https://docs.example.com/api-reference", - containerTags: ["documentation"] + containerTag: "documentation" }); ``` diff --git a/apps/docs/concepts/filtering.mdx b/apps/docs/concepts/filtering.mdx deleted file mode 100644 index d222e849..00000000 --- a/apps/docs/concepts/filtering.mdx +++ /dev/null @@ -1,359 +0,0 @@ ---- -title: "Organizing & Filtering Memories" -sidebarTitle: "Multi-Tenancy / Filtering" -description: "Use container tags and metadata to organize and retrieve memories" -icon: "users" ---- - -Supermemory provides two ways to organize your memories: - - - - **Organize memories** into isolated spaces by user, project, or workspace - - - **Query memories** by custom properties like category, status, or date - - - -Both can be used independently or together for precise filtering. - ---- - -## Container Tags - -Container tags create isolated memory spaces. Use them to separate memories by user, project, or any logical boundary. - -### Adding Memories with Tags - -```typescript -await client.add({ - content: "Meeting notes from Q1 planning", - containerTags: ["user_123"] -}); -``` - -### Searching with Tags - -```typescript -const results = await client.search.documents({ - q: "planning notes", - containerTags: ["user_123"] -}); -``` - - -Container tags use **exact array matching**. A memory tagged `["user_123", "project_a"]` won't match a search for just `["user_123"]`. - - -### Recommended Patterns - -| Pattern | Example | Use Case | -|---------|---------|----------| -| User isolation | `user_{userId}` | Per-user memories | -| Project grouping | `project_{projectId}` | Project-specific content | -| Hierarchical | `org_{orgId}_team_{teamId}` | Multi-level organization | - - - - ```typescript - // Multi-tenant SaaS - isolate by organization and user - await client.add({ - content: "Company policy document", - containerTags: ["org_acme_user_john"] - }); - - // Search only within that user's org context - const results = await client.search.documents({ - q: "vacation policy", - containerTags: ["org_acme_user_john"] - }); - - // Project-based isolation - await client.add({ - content: "Sprint 5 retrospective notes", - containerTags: ["project_mobile_app"] - }); - - // Time-based segmentation - await client.add({ - content: "Q1 2024 financial report", - containerTags: ["user_cfo_2024_q1"] - }); - ``` - - **API field differences:** - | Endpoint | Field | Type | - |----------|-------|------| - | `/v3/search` | `containerTags` | Array | - | `/v4/search` | `containerTag` | String | - | `/v3/documents/list` | `containerTags` | Array | - - - ---- - -## Metadata - -Metadata lets you attach custom properties to memories and filter by them later. - -### Adding Memories with Metadata - -```typescript -await client.add({ - content: "Technical design document for auth system", - containerTags: ["user_123"], - metadata: { - category: "engineering", - priority: "high", - year: 2024 - } -}); -``` - -### Searching with Metadata Filters - -Filters must be wrapped in `AND` or `OR` arrays: - -```typescript -const results = await client.search.documents({ - q: "design document", - containerTags: ["user_123"], - filters: { - AND: [ - { key: "category", value: "engineering" }, - { key: "priority", value: "high" } - ] - } -}); -``` - -### Filter Types - -| Type | Example | Description | -|------|---------|-------------| -| String equality | `{ key: "status", value: "published" }` | Exact match | -| String contains | `{ filterType: "string_contains", key: "title", value: "react" }` | Substring match | -| Numeric | `{ filterType: "numeric", key: "priority", value: "5", numericOperator: ">=" }` | Number comparison | -| Array contains | `{ filterType: "array_contains", key: "tags", value: "important" }` | Check array membership | - -### Combining Filters - -Use `AND` and `OR` for complex queries: - -```typescript -const results = await client.search.documents({ - q: "meeting notes", - filters: { - AND: [ - { key: "type", value: "meeting" }, - { - OR: [ - { key: "team", value: "engineering" }, - { key: "team", value: "product" } - ] - } - ] - } -}); -``` - -### Excluding Results - -Use `negate: true` to exclude matches: - -```typescript -const results = await client.search.documents({ - q: "documentation", - filters: { - AND: [ - { key: "status", value: "draft", negate: true } - ] - } -}); -``` - - - - **String contains (substring search):** - ```typescript - // Find documents with "machine learning" in the description - const results = await client.search.documents({ - q: "AI research", - filters: { - AND: [ - { - filterType: "string_contains", - key: "description", - value: "machine learning", - ignoreCase: true - } - ] - } - }); - ``` - - **Numeric comparisons:** - ```typescript - // Find high-priority items created after a specific date - const results = await client.search.documents({ - q: "tasks", - filters: { - AND: [ - { - filterType: "numeric", - key: "priority", - value: "7", - numericOperator: ">=" - }, - { - filterType: "numeric", - key: "created_timestamp", - value: "1704067200", // Unix timestamp - numericOperator: ">=" - } - ] - } - }); - ``` - - **Array contains (check array membership):** - ```typescript - // Find documents where a specific user is a participant - const results = await client.search.documents({ - q: "meeting notes", - filters: { - AND: [ - { - filterType: "array_contains", - key: "participants", - value: "alice@company.com" - } - ] - } - }); - ``` - - **Complex nested filters:** - ```typescript - // (category = "tech" OR category = "science") AND status != "archived" - const results = await client.search.documents({ - q: "research papers", - filters: { - AND: [ - { - OR: [ - { key: "category", value: "tech" }, - { key: "category", value: "science" } - ] - }, - { key: "status", value: "archived", negate: true } - ] - } - }); - ``` - - **Numeric operator negation mapping:** - When using `negate: true`, operators flip: - - `<` becomes `>=` - - `<=` becomes `>` - - `>` becomes `<=` - - `>=` becomes `<` - - `=` becomes `!=` - - - - **User's work documents from 2024:** - ```typescript - const results = await client.search.documents({ - q: "quarterly report", - containerTags: ["user_123"], - filters: { - AND: [ - { key: "category", value: "work" }, - { key: "type", value: "report" }, - { filterType: "numeric", key: "year", value: "2024", numericOperator: "=" } - ] - } - }); - ``` - - **Team meeting notes with specific participants:** - ```typescript - const results = await client.search.documents({ - q: "sprint planning", - containerTags: ["project_alpha"], - filters: { - AND: [ - { key: "type", value: "meeting" }, - { - OR: [ - { filterType: "array_contains", key: "participants", value: "alice" }, - { filterType: "array_contains", key: "participants", value: "bob" } - ] - } - ] - } - }); - ``` - - **Exclude drafts and deprecated content:** - ```typescript - const results = await client.search.documents({ - q: "documentation", - filters: { - AND: [ - { key: "status", value: "draft", negate: true }, - { filterType: "string_contains", key: "content", value: "deprecated", negate: true }, - { filterType: "array_contains", key: "tags", value: "archived", negate: true } - ] - } - }); - ``` - - - ---- - -## Quick Reference - -### When Adding Memories - -```typescript -await client.add({ - content: "Your content here", - containerTags: ["user_123"], // Isolation - metadata: { key: "value" } // Custom properties -}); -``` - -### When Searching - -```typescript -const results = await client.search.documents({ - q: "search query", - containerTags: ["user_123"], // Must match exactly - filters: { // Optional metadata filters - AND: [{ key: "status", value: "published" }] - } -}); -``` - -### Metadata Key Rules - -- Allowed characters: `a-z`, `A-Z`, `0-9`, `_`, `-`, `.` -- Max length: 64 characters -- No spaces or special characters - ---- - -## Next Steps - - - - Apply filters in search queries - - - Add content with container tags and metadata - - diff --git a/apps/docs/concepts/memory-vs-rag.mdx b/apps/docs/concepts/memory-vs-rag.mdx index bc08e94f..5171e663 100644 --- a/apps/docs/concepts/memory-vs-rag.mdx +++ b/apps/docs/concepts/memory-vs-rag.mdx @@ -205,7 +205,7 @@ client.add( # Add a user-specific memory client.add( content="User prefers Android over iOS", - container_tags=["user_123"], # User-specific + container_tag="user_123", # User-specific metadata={ "type": "preference", "confidence": "high" @@ -216,9 +216,9 @@ client.add( ### 3. Hybrid Retrieval ```python # Search combines both approaches -results = client.documents.search( - query="What phone should I recommend?", - container_tags=["user_123"], # Gets user memories +results = client.search.memories( + q="What phone should I recommend?", + container_tag="user_123", # Gets user memories # Also searches general knowledge ) diff --git a/apps/docs/concepts/super-rag.mdx b/apps/docs/concepts/super-rag.mdx index ebe538bf..9d2761c1 100644 --- a/apps/docs/concepts/super-rag.mdx +++ b/apps/docs/concepts/super-rag.mdx @@ -95,13 +95,13 @@ Supermemory combines the best of both approaches in every search: -With `searchMode: "hybrid"` (the default), you get both: +Search memories and include the matching documents, and you get both: ```typescript -const results = await client.search({ +const results = await client.search.memories({ q: "how do I deploy the app?", containerTag: "user_123", - searchMode: "hybrid" + include: { documents: true } }); // Returns: @@ -121,8 +121,9 @@ Two flags give you fine-grained control over result quality: Re-scores results using a cross-encoder model for better relevance: ```typescript -const results = await client.search({ +const results = await client.search.memories({ q: "complex technical question", + containerTag: "user_123", rerank: true // +~100ms, significantly better ranking }); ``` @@ -134,8 +135,9 @@ const results = await client.search({ Expands your query to capture more relevant results: ```typescript -const results = await client.search({ +const results = await client.search.memories({ q: "how to auth", + containerTag: "user_123", rewriteQuery: true // Expands to "authentication login oauth jwt..." }); ``` diff --git a/apps/docs/cookbook/ai-sdk-integration.mdx b/apps/docs/cookbook/ai-sdk-integration.mdx index d6853210..34b80cea 100644 --- a/apps/docs/cookbook/ai-sdk-integration.mdx +++ b/apps/docs/cookbook/ai-sdk-integration.mdx @@ -24,7 +24,7 @@ export async function POST(request: Request) { const { messages } = await request.json() const result = await streamText({ - model: anthropic('claude-3-sonnet-20240229'), + model: anthropic('claude-sonnet-4-5'), messages, tools: supermemoryTools(process.env.SUPERMEMORY_API_KEY!), system: `You are a helpful personal assistant. When users share information about themselves, @@ -32,14 +32,14 @@ export async function POST(request: Request) { personalized responses. Always be proactive about remembering important details.` }) - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() } ``` ```typescript Client Component 'use client' -import { useChat } from 'ai/react' +import { useChat } from '@ai-sdk/react' export default function PersonalAssistant() { const { messages, input, handleInputChange, handleSubmit } = useChat() @@ -109,7 +109,7 @@ export async function POST(request: Request) { 4. Always be empathetic and solution-focused` }) - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() } ``` @@ -130,7 +130,7 @@ export async function POST(request: Request) { const { messages, userId, courseId } = await request.json() const result = await streamText({ - model: anthropic('claude-3-haiku-20240307'), + model: anthropic('claude-haiku-4-5'), messages, tools: supermemoryTools(process.env.SUPERMEMORY_API_KEY!, { containerTags: [userId] @@ -142,7 +142,7 @@ export async function POST(request: Request) { 4. Tracking topics they've mastered vs topics they need more help with` }) - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() } ``` @@ -177,7 +177,7 @@ export async function POST(request: Request) { 4. Track research progress and important discoveries` }) - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() } ``` @@ -230,7 +230,7 @@ export async function POST(request: Request) { const { messages, repositoryId } = await request.json() const result = await streamText({ - model: anthropic('claude-3-sonnet-20240229'), + model: anthropic('claude-sonnet-4-5'), messages, tools: { // Use individual tools for more control @@ -262,7 +262,7 @@ export async function POST(request: Request) { 4. Learn from debugging sessions and common issues` }) - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() } ``` @@ -313,7 +313,7 @@ export async function POST(request: Request) { 3. Search for conflicts using searchMemories` }) - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() } ``` diff --git a/apps/docs/cookbook/customer-support.mdx b/apps/docs/cookbook/customer-support.mdx index 01ad0e8e..a9b8fa27 100644 --- a/apps/docs/cookbook/customer-support.mdx +++ b/apps/docs/cookbook/customer-support.mdx @@ -480,12 +480,12 @@ If you cannot resolve the issue completely, prepare a clear summary for escalati } }) - return result.toAIStreamResponse({ - data: { + return result.toUIMessageStreamResponse({ + messageMetadata: () => ({ needsEscalation, customerTier: customer.tier, contextCount: contextResults.length - } + }) }) } catch (error) { @@ -724,7 +724,7 @@ If you cannot resolve the issue completely, prepare a clear summary for escalati 'use client' import { useState, useEffect } from 'react' -import { useChat } from 'ai/react' +import { useChat } from '@ai-sdk/react' import { CustomerContextManager } from '@/lib/customer-context' interface Customer { diff --git a/apps/docs/cookbook/document-qa.mdx b/apps/docs/cookbook/document-qa.mdx index 5aa071eb..3d5e8b16 100644 --- a/apps/docs/cookbook/document-qa.mdx +++ b/apps/docs/cookbook/document-qa.mdx @@ -369,12 +369,12 @@ If the question cannot be answered from the provided documents, respond with: "I maxTokens: 1000 }) - return result.toAIStreamResponse({ - data: { + return result.toUIMessageStreamResponse({ + messageMetadata: () => ({ sources, searchResultsCount: searchResults.results.length, totalResults: searchResults.total - } + }) }) } catch (error) { @@ -525,7 +525,7 @@ If the question cannot be answered from the provided documents, respond with: "I 'use client' import { useState, useRef } from 'react' -import { useChat } from 'ai/react' +import { useChat } from '@ai-sdk/react' import { DocumentProcessor } from '@/lib/document-processor' interface Document { diff --git a/apps/docs/cookbook/personal-assistant.mdx b/apps/docs/cookbook/personal-assistant.mdx index 59c3e057..2d96266b 100644 --- a/apps/docs/cookbook/personal-assistant.mdx +++ b/apps/docs/cookbook/personal-assistant.mdx @@ -610,10 +610,10 @@ Later: #### Return Streaming Response ```typescript - return result.toAIStreamResponse() + return result.toUIMessageStreamResponse() ``` -`toAIStreamResponse()` converts the streaming result into a format the frontend can consume. It: +`toUIMessageStreamResponse()` converts the streaming result into a format the frontend can consume. It: - Sets appropriate headers for streaming - Formats data for the `useChat` hook - Handles errors gracefully @@ -643,7 +643,7 @@ Catches any errors (API failures, tool errors, etc.) and returns a clean error r | **Memory Search** | Manual `search_user_memories()` call | AI SDK calls `searchMemories` tool automatically | | **Memory Add** | Manual `add_user_memory()` call | AI SDK calls `addMemory` tool automatically | | **Tool Decision** | You decide when to search/add | AI decides based on conversation context | -| **Streaming** | Manual SSE formatting | `toAIStreamResponse()` handles it | +| **Streaming** | Manual SSE formatting | `toUIMessageStreamResponse()` handles it | | **Error Handling** | Try/catch in each function | AI SDK handles tool errors | **Python = Manual Control** @@ -660,7 +660,7 @@ Replace `app/page.tsx`: ```typescript 'use client' -import { useChat } from 'ai/react' +import { useChat } from '@ai-sdk/react' import { useState } from 'react' export default function ChatPage() { @@ -824,7 +824,7 @@ Create `scripts/check-memories.ts`: const userId = "your_user_id_here" const containerTag = `user_${userId}` -const response = await fetch('https://api.supermemory.ai/v3/memories', { +const response = await fetch('https://api.supermemory.ai/v3/documents/list', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, diff --git a/apps/docs/document-operations.mdx b/apps/docs/document-operations.mdx index ecf4c54d..e6870e4a 100644 --- a/apps/docs/document-operations.mdx +++ b/apps/docs/document-operations.mdx @@ -125,7 +125,7 @@ Get a specific document with its processing status. ```typescript const doc = await client.documents.get("doc_abc123"); - console.log(doc.status); // "queued" | "processing" | "done" | "failed" + console.log(doc.status); // "queued" | "extracting" | "chunking" | "embedding" | "indexing" | "done" | "failed" console.log(doc.content); ``` @@ -153,6 +153,7 @@ Get a specific document with its processing status. | `extracting` | Extracting content (OCR, transcription) | | `chunking` | Breaking into searchable pieces | | `embedding` | Creating vector representations | +| `indexing` | Indexing for retrieval | | `done` | Ready for search | | `failed` | Processing failed | diff --git a/apps/docs/integrations/agno.mdx b/apps/docs/integrations/agno.mdx index eeeb621e..7f171354 100644 --- a/apps/docs/integrations/agno.mdx +++ b/apps/docs/integrations/agno.mdx @@ -136,7 +136,6 @@ Look up past interactions: results = memory.search.memories( q="pasta recipes we discussed", container_tag="user_123", - search_mode="hybrid", limit=5 ) diff --git a/apps/docs/integrations/ai-sdk.mdx b/apps/docs/integrations/ai-sdk.mdx index eede8429..89efd93c 100644 --- a/apps/docs/integrations/ai-sdk.mdx +++ b/apps/docs/integrations/ai-sdk.mdx @@ -74,19 +74,19 @@ Both `containerTag` and `customId` are required. **Profile Mode (Default)** - Retrieves the user's complete profile: ```typescript -const model = withSupermemory(openai("gpt-4"), { containerTag: "user-123", customId: "conv-1", mode: "profile" }) +const model = withSupermemory(openai("gpt-4o"), { containerTag: "user-123", customId: "conv-1", mode: "profile" }) ``` **Query Mode** - Searches memories based on the user's message: ```typescript -const model = withSupermemory(openai("gpt-4"), { containerTag: "user-123", customId: "conv-1", mode: "query" }) +const model = withSupermemory(openai("gpt-4o"), { containerTag: "user-123", customId: "conv-1", mode: "query" }) ``` **Full Mode** - Combines profile AND query-based search: ```typescript -const model = withSupermemory(openai("gpt-4"), { containerTag: "user-123", customId: "conv-1", mode: "full" }) +const model = withSupermemory(openai("gpt-4o"), { containerTag: "user-123", customId: "conv-1", mode: "full" }) ``` ### Custom Prompt Templates @@ -107,7 +107,7 @@ const claudePrompt = (data: MemoryPromptData) => ` `.trim() -const model = withSupermemory(anthropic("claude-3-sonnet"), { +const model = withSupermemory(anthropic("claude-sonnet-4-5"), { containerTag: "user-123", customId: "conv-1", mode: "full", @@ -118,7 +118,7 @@ const model = withSupermemory(anthropic("claude-3-sonnet"), { ### Verbose Logging ```typescript -const model = withSupermemory(openai("gpt-4"), { +const model = withSupermemory(openai("gpt-4o"), { containerTag: "user-123", customId: "conv-1", verbose: true, @@ -166,7 +166,7 @@ import { supermemoryTools } from "@supermemory/tools/ai-sdk" const anthropic = createAnthropic({ apiKey: "YOUR_ANTHROPIC_KEY" }) const result = await streamText({ - model: anthropic("claude-3-sonnet"), + model: anthropic("claude-sonnet-4-5"), prompt: "Remember that my name is Alice", tools: supermemoryTools("YOUR_SUPERMEMORY_KEY") }) @@ -189,7 +189,7 @@ const result = await streamText({ ```typescript const result = await streamText({ - model: anthropic("claude-3-sonnet"), + model: anthropic("claude-sonnet-4-5"), prompt: "Remember that I'm allergic to peanuts", tools: supermemoryTools("API_KEY") }) diff --git a/apps/docs/integrations/convex.mdx b/apps/docs/integrations/convex.mdx index 37130a84..0a0ce125 100644 --- a/apps/docs/integrations/convex.mdx +++ b/apps/docs/integrations/convex.mdx @@ -77,7 +77,6 @@ export const searchMemories = action({ return await memory.search.memories({ q: query, containerTag: userId, - searchMode: "hybrid", limit: limit ?? 10, }); }, diff --git a/apps/docs/integrations/crewai.mdx b/apps/docs/integrations/crewai.mdx index f4fdc9c4..2b44cf4b 100644 --- a/apps/docs/integrations/crewai.mdx +++ b/apps/docs/integrations/crewai.mdx @@ -122,7 +122,6 @@ Pull up past interactions before running a crew: results = memory.search.memories( q="previous project recommendations", container_tag="user_abc", - search_mode="hybrid", limit=10 ) diff --git a/apps/docs/integrations/hermes.mdx b/apps/docs/integrations/hermes.mdx index 0b8efea5..b307f216 100644 --- a/apps/docs/integrations/hermes.mdx +++ b/apps/docs/integrations/hermes.mdx @@ -148,4 +148,4 @@ If you run your own supermemory API, set **`base_url`** (and any other host-spec -Questions about the API or product? [Discord](https://supermemory.link/discord) · [support@supermemory.com](mailto:support@supermemory.com) · [Developer docs](/intro) +Questions about the API or product? [Discord](https://supermemory.link/discord) · [support@supermemory.ai](mailto:support@supermemory.ai) · [Developer docs](/intro) diff --git a/apps/docs/integrations/langchain.mdx b/apps/docs/integrations/langchain.mdx index 6c9eee9a..ca877536 100644 --- a/apps/docs/integrations/langchain.mdx +++ b/apps/docs/integrations/langchain.mdx @@ -137,7 +137,6 @@ Search returns both extracted memories and document chunks: results = memory.search.memories( q="async programming", container_tag="user_123", - search_mode="hybrid", # Searches memories + document chunks limit=5 ) diff --git a/apps/docs/integrations/langgraph.mdx b/apps/docs/integrations/langgraph.mdx index e67cdaec..57035d41 100644 --- a/apps/docs/integrations/langgraph.mdx +++ b/apps/docs/integrations/langgraph.mdx @@ -154,7 +154,6 @@ Search returns both extracted memories and document chunks: results = memory.search.memories( q="graph algorithms", container_tag="user_123", - search_mode="hybrid", limit=5 ) diff --git a/apps/docs/integrations/memory-graph.mdx b/apps/docs/integrations/memory-graph.mdx index decd5f52..101a617a 100644 --- a/apps/docs/integrations/memory-graph.mdx +++ b/apps/docs/integrations/memory-graph.mdx @@ -289,7 +289,7 @@ interface DocumentWithMemories { url?: string | null; source?: string | null; type?: string | null; - status: 'pending' | 'processing' | 'done' | 'failed'; + status: 'unknown' | 'queued' | 'extracting' | 'chunking' | 'embedding' | 'indexing' | 'done' | 'failed'; metadata?: Record | null; createdAt: string | Date; updatedAt: string | Date; diff --git a/apps/docs/integrations/openai-agents-sdk.mdx b/apps/docs/integrations/openai-agents-sdk.mdx index ebd59863..262d8f24 100644 --- a/apps/docs/integrations/openai-agents-sdk.mdx +++ b/apps/docs/integrations/openai-agents-sdk.mdx @@ -135,7 +135,6 @@ Look up past interactions before running an agent: results = memory.search.memories( q="previous travel recommendations", container_tag="user_123", - search_mode="hybrid", limit=5 ) diff --git a/apps/docs/integrations/openclaw.mdx b/apps/docs/integrations/openclaw.mdx index aacc7ef0..b60132c4 100644 --- a/apps/docs/integrations/openclaw.mdx +++ b/apps/docs/integrations/openclaw.mdx @@ -269,7 +269,7 @@ openclaw supermemory wipe # Delete all memories (requires confirma Automatic per-channel separation is not supported yet. If you need this, let us know — with enough requests, we'll implement it right away. - + Email us with your use case. diff --git a/apps/docs/integrations/supermemory-sdk.mdx b/apps/docs/integrations/supermemory-sdk.mdx index 474976d5..7f9bce4a 100644 --- a/apps/docs/integrations/supermemory-sdk.mdx +++ b/apps/docs/integrations/supermemory-sdk.mdx @@ -36,7 +36,7 @@ Both SDKs also work against [self-hosted Supermemory](/self-hosting/overview) }); // Add a memory - await client.add({ content: "Meeting notes from Q1 planning", containerTags: ["user_123"] }); + await client.add({ content: "Meeting notes from Q1 planning", containerTag: "user_123" }); // Search memories const response = await client.search.documents({ @@ -57,7 +57,7 @@ Both SDKs also work against [self-hosted Supermemory](/self-hosting/overview) // Add with metadata await client.add({ content: "Technical design doc", - containerTags: ["user_123"], + containerTag: "user_123", metadata: { category: "engineering", priority: "high" } }); @@ -98,7 +98,7 @@ Both SDKs also work against [self-hosted Supermemory](/self-hosting/overview) ) # Add a memory - client.add(content="Meeting notes from Q1 planning", container_tags=["user_123"]) + client.add(content="Meeting notes from Q1 planning", container_tag="user_123") # Search memories response = client.search.documents( @@ -119,7 +119,7 @@ Both SDKs also work against [self-hosted Supermemory](/self-hosting/overview) # Add with metadata client.add( content="Technical design doc", - container_tags=["user_123"], + container_tag="user_123", metadata={"category": "engineering", "priority": "high"} ) diff --git a/apps/docs/list-memories/examples/basic.mdx b/apps/docs/list-memories/examples/basic.mdx deleted file mode 100644 index e0fa40dc..00000000 --- a/apps/docs/list-memories/examples/basic.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "Basic Listing" -description: "Simple memory retrieval across languages" ---- - -Simple memory retrieval examples for getting started with the list memories endpoint. - -## Basic Usage - - - - ```typescript - import Supermemory from 'supermemory'; - - const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! - }); - - const response = await client.documents.list({ limit: 10 }); - console.log(response); - ``` - - - ```python - from supermemory import Supermemory - import os - - client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - response = client.documents.list(limit=10) - print(response) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 10}' - ``` - - - -## With Custom Parameters - - - - ```typescript - const response = await client.documents.list({ - containerTags: ["user_123"], - limit: 20, - sort: "updatedAt", - order: "desc" - }); - - console.log(`Found ${response.memories.length} memories`); - ``` - - - ```python - response = client.documents.list( - container_tags=["user_123"], - limit=20, - sort="updatedAt", - order="desc" - ) - - print(f"Found {len(response.memories)} memories") - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "containerTags": ["user_123"], - "limit": 20, - "sort": "updatedAt", - "order": "desc" - }' - ``` - - - - - Start with small `limit` values (10-20) when testing to avoid overwhelming responses. - diff --git a/apps/docs/list-memories/examples/filtering.mdx b/apps/docs/list-memories/examples/filtering.mdx deleted file mode 100644 index d159fb55..00000000 --- a/apps/docs/list-memories/examples/filtering.mdx +++ /dev/null @@ -1,506 +0,0 @@ ---- -title: "Filtering Memories" -description: "Filter memories by container tags and metadata using SQL-based filtering" ---- - -Filter memories using container tags and metadata. The filtering system uses SQL query construction, so you need to structure your filters like database queries. - -## Filter by Container Tags - -Container tags use exact array matching - memories must have the exact same tags in the same order. - - - - ```typescript - // Single tag - matches memories with exactly ["user_123"] - const userMemories = await client.documents.list({ - containerTags: ["user_123"] - }); - - // Multiple tags - matches memories with exactly ["user_123", "project_ai"] - const projectMemories = await client.documents.list({ - containerTags: ["user_123", "project_ai"] - }); - ``` - - - ```python - # Single tag - user_memories = client.documents.list(container_tags=["user_123"]) - - # Multiple tags (exact match) - project_memories = client.documents.list( - container_tags=["user_123", "project_ai"] - ) - ``` - - - ```bash - # Single tag - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"containerTags": ["user_123"]}' - - # Multiple tags - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"containerTags": ["user_123", "project_ai"]}' - ``` - - - -## Metadata Filtering with SQL Logic - -The `filters` parameter allows filtering by metadata fields using SQL-like query structures. Since we use SQL query construction in the backend, you need to structure your filters like database queries with explicit AND/OR logic. - -### Why This Structure? - -In SQL databases, `AND` has higher precedence than `OR`. Without explicit grouping, a query like: -``` -category = 'programming' OR framework = 'react' AND difficulty = 'advanced' -``` - -Is interpreted as: -``` -category = 'programming' OR (framework = 'react' AND difficulty = 'advanced') -``` - -The JSON structure forces explicit grouping to prevent unexpected results. - - -**Filter Structure Rules:** -- Always wrap conditions in `AND` or `OR` arrays (even single conditions) -- Pass the filter as an object (TypeScript/Python) or JSON string (cURL) -- Each condition needs `key`, `value`, and `negate` properties -- `negate: false` for normal matching, `negate: true` for exclusion - - -### Simple Metadata Filter - - - - ```typescript - // Filter by single metadata field - const programmingMemories = await client.documents.list({ - filters: { - AND: [ - { key: "category", value: "programming", negate: false } - ] - } - }); - ``` - - - ```python - # Filter by single metadata field - programming_memories = client.documents.list( - filters={ - "AND": [ - {"key": "category", "value": "programming", "negate": False} - ] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"AND\":[{\"key\":\"category\",\"value\":\"programming\",\"negate\":false}]}" - }' - ``` - - - -### Multiple Conditions (AND Logic) - - - - ```typescript - // All conditions must match - const reactTutorials = await client.documents.list({ - filters: { - AND: [ - { key: "category", value: "tutorial", negate: false }, - { key: "framework", value: "react", negate: false }, - { key: "difficulty", value: "beginner", negate: false } - ] - } - }); - ``` - - - ```python - # All conditions must match - react_tutorials = client.documents.list( - filters={ - "AND": [ - {"key": "category", "value": "tutorial", "negate": False}, - {"key": "framework", "value": "react", "negate": False}, - {"key": "difficulty", "value": "beginner", "negate": False} - ] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"AND\":[{\"key\":\"category\",\"value\":\"tutorial\",\"negate\":false},{\"key\":\"framework\",\"value\":\"react\",\"negate\":false}]}" - }' - ``` - - - -### Alternative Conditions (OR Logic) - - - - ```typescript - // Any condition can match - const frontendMemories = await client.documents.list({ - filters: { - OR: [ - { key: "framework", value: "react", negate: false }, - { key: "framework", value: "vue", negate: false }, - { key: "framework", value: "angular", negate: false } - ] - } - }); - ``` - - - ```python - # Any condition can match - frontend_memories = client.documents.list( - filters={ - "OR": [ - {"key": "framework", "value": "react", "negate": False}, - {"key": "framework", "value": "vue", "negate": False}, - {"key": "framework", "value": "angular", "negate": False} - ] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"OR\":[{\"key\":\"framework\",\"value\":\"react\",\"negate\":false},{\"key\":\"framework\",\"value\":\"vue\",\"negate\":false}]}" - }' - ``` - - - -### Complex Nested Logic - - - - ```typescript - // Complex logic: programming AND (react OR advanced difficulty) - const advancedContent = await client.documents.list({ - filters: { - AND: [ - { key: "category", value: "programming", negate: false }, - { - OR: [ - { key: "framework", value: "react", negate: false }, - { key: "difficulty", value: "advanced", negate: false } - ] - } - ] - } - }); - ``` - - - ```python - # Complex logic: programming AND (react OR advanced difficulty) - advanced_content = client.documents.list( - filters={ - "AND": [ - {"key": "category", "value": "programming", "negate": False}, - { - "OR": [ - {"key": "framework", "value": "react", "negate": False}, - {"key": "difficulty", "value": "advanced", "negate": False} - ] - } - ] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"AND\":[{\"key\":\"category\",\"value\":\"programming\",\"negate\":false},{\"OR\":[{\"key\":\"framework\",\"value\":\"react\",\"negate\":false},{\"key\":\"difficulty\",\"value\":\"advanced\",\"negate\":false}]}]}" - }' - ``` - - - -## Array Contains Filtering - -Filter memories that contain specific values in array fields like participants, tags, or team members. - -### Basic Array Contains - - - - ```typescript - // Find memories where john.doe participated - const meetingMemories = await client.documents.list({ - filters: { - AND: [ - { - key: "participants", - value: "john.doe", - filterType: "array_contains", - negate: false - } - ] - } - }); - ``` - - - ```python - # Find memories where john.doe participated - meeting_memories = client.documents.list( - filters={ - "AND": [ - { - "key": "participants", - "value": "john.doe", - "filterType": "array_contains", - "negate": False - } - ] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"AND\":[{\"key\":\"participants\",\"value\":\"john.doe\",\"filterType\":\"array_contains\",\"negate\":false}]}" - }' - ``` - - - -### Array Contains with Exclusion - - - - ```typescript - // Find memories that don't include a specific team member - const filteredMemories = await client.documents.list({ - filters: { - AND: [ - { - key: "reviewers", - value: "external.consultant", - filterType: "array_contains", - negate: true // Exclude memories with external consultants - }, - { - key: "project_tags", - value: "internal-only", - filterType: "array_contains", - negate: false - } - ] - } - }); - ``` - - - ```python - # Find memories that don't include a specific team member - filtered_memories = client.documents.list( - filters={ - "AND": [ - { - "key": "reviewers", - "value": "external.consultant", - "filterType": "array_contains", - "negate": True # Exclude memories with external consultants - }, - { - "key": "project_tags", - "value": "internal-only", - "filterType": "array_contains", - "negate": False - } - ] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"AND\":[{\"key\":\"reviewers\",\"value\":\"external.consultant\",\"filterType\":\"array_contains\",\"negate\":true},{\"key\":\"project_tags\",\"value\":\"internal-only\",\"filterType\":\"array_contains\",\"negate\":false}]}" - }' - ``` - - - -### Multiple Array Contains (OR Logic) - - - - ```typescript - // Find memories involving any of several team leads - const leadershipMemories = await client.documents.list({ - filters: { - OR: [ - { - key: "attendees", - value: "engineering.lead", - filterType: "array_contains" - }, - { - key: "attendees", - value: "product.lead", - filterType: "array_contains" - }, - { - key: "attendees", - value: "design.lead", - filterType: "array_contains" - } - ] - }, - sort: "updatedAt", - order: "desc" - }); - ``` - - - ```python - # Find memories involving any of several team leads - leadership_memories = client.documents.list( - filters={ - "OR": [ - { - "key": "attendees", - "value": "engineering.lead", - "filterType": "array_contains" - }, - { - "key": "attendees", - "value": "product.lead", - "filterType": "array_contains" - }, - { - "key": "attendees", - "value": "design.lead", - "filterType": "array_contains" - } - ] - }, - sort="updatedAt", - order="desc" - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "filters": "{\"OR\":[{\"key\":\"attendees\",\"value\":\"engineering.lead\",\"filterType\":\"array_contains\"},{\"key\":\"attendees\",\"value\":\"product.lead\",\"filterType\":\"array_contains\"},{\"key\":\"attendees\",\"value\":\"design.lead\",\"filterType\":\"array_contains\"}]}", - "sort": "updatedAt", - "order": "desc" - }' - ``` - - - -## Combined Container Tags + Metadata Filtering - - - - ```typescript - const filteredMemories = await client.documents.list({ - containerTags: ["user_123"], - filters: { - AND: [ - { key: "category", value: "tutorial", negate: false }, - { key: "framework", value: "react", negate: false } - ] - }, - sort: "updatedAt", - order: "desc", - limit: 50 - }); - ``` - - - ```python - filtered_memories = client.documents.list( - container_tags=["user_123"], - filters={ - "AND": [ - {"key": "category", "value": "tutorial", "negate": False}, - {"key": "framework", "value": "react", "negate": False} - ] - }, - sort="updatedAt", - order="desc", - limit=50 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "containerTags": ["user_123"], - "filters": "{\"AND\":[{\"key\":\"category\",\"value\":\"tutorial\",\"negate\":false},{\"key\":\"framework\",\"value\":\"react\",\"negate\":false}]}", - "sort": "updatedAt", - "order": "desc", - "limit": 50 - }' - ``` - - - - -**Common Mistakes:** -- Using bare condition objects: `{"key": "category", "value": "programming"}` without wrapping in `AND` or `OR` -- Missing negate property: always include `"negate": false` or `"negate": true` -- For cURL requests: forgetting to properly escape the JSON string - - - -**Container Tags vs Metadata Filtering:** -- Container tags: Exact array matching for organizational grouping -- Metadata filters: SQL-like queries on custom metadata fields with complex logic -- Both can be combined for powerful filtering capabilities - diff --git a/apps/docs/list-memories/examples/monitoring.mdx b/apps/docs/list-memories/examples/monitoring.mdx deleted file mode 100644 index 7c373d3c..00000000 --- a/apps/docs/list-memories/examples/monitoring.mdx +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: "Status Monitoring" -description: "Monitor memory processing status and completion rates" ---- - -Monitor memory processing status and track completion rates using the list endpoint. - -## Status Overview - - - - ```typescript - const response = await client.documents.list({ limit: 100 }); - - const statusCounts = response.memories.reduce((acc: any, memory) => { - acc[memory.status] = (acc[memory.status] || 0) + 1; - return acc; - }, {}); - - console.log('Status breakdown:', statusCounts); - ``` - - - ```python - response = client.documents.list(limit=100) - - status_counts = {} - for memory in response.memories: - status = memory.status - status_counts[status] = status_counts.get(status, 0) + 1 - - print("Status breakdown:", status_counts) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 100}' | \ - jq '.memories | group_by(.status) | map({status: .[0].status, count: length})' - ``` - - - -## Filter Processing Memories - - - - ```typescript - const response = await client.documents.list({ limit: 100 }); - - const processing = response.memories.filter(m => - ['queued', 'extracting', 'chunking', 'embedding', 'indexing'].includes(m.status) - ); - - console.log(`${processing.length} memories currently processing`); - ``` - - - ```python - response = client.documents.list(limit=100) - - processing_statuses = ['queued', 'extracting', 'chunking', 'embedding', 'indexing'] - processing = [m for m in response.memories if m.status in processing_statuses] - - print(f"{len(processing)} memories currently processing") - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 100}' | \ - jq '.memories[] | select(.status | IN("queued", "extracting", "chunking", "embedding", "indexing"))' - ``` - - - -## Failed Memories - - - - ```typescript - const response = await client.documents.list({ limit: 100 }); - - const failedMemories = response.memories.filter(m => m.status === 'failed'); - - failedMemories.forEach(memory => { - console.log(`Failed: ${memory.id} - ${memory.title || 'Untitled'}`); - }); - ``` - - - ```python - response = client.documents.list(limit=100) - - failed_memories = [m for m in response.memories if m.status == 'failed'] - - for memory in failed_memories: - title = memory.title or 'Untitled' - print(f"Failed: {memory.id} - {title}") - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 100}' | \ - jq '.memories[] | select(.status == "failed") | {id, title, status}' - ``` - - - - - For real-time monitoring of individual memories, use the [Track Processing Status](/memory-api/track-progress) guide. - diff --git a/apps/docs/list-memories/examples/pagination.mdx b/apps/docs/list-memories/examples/pagination.mdx deleted file mode 100644 index 9a975acc..00000000 --- a/apps/docs/list-memories/examples/pagination.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: "Pagination" -description: "Handle large memory collections with pagination" ---- - -Handle large memory collections efficiently using pagination to process data in manageable chunks. - -## Basic Pagination - - - - ```typescript - // Get first page - const page1 = await client.documents.list({ - limit: 20, - page: 1 - }); - - // Get next page - const page2 = await client.documents.list({ - limit: 20, - page: 2 - }); - - console.log(`Page 1: ${page1.memories.length} memories`); - console.log(`Page 2: ${page2.memories.length} memories`); - ``` - - - ```python - # Get first page - page1 = client.documents.list(limit=20, page=1) - - # Get next page - page2 = client.documents.list(limit=20, page=2) - - print(f"Page 1: {len(page1.memories)} memories") - print(f"Page 2: {len(page2.memories)} memories") - ``` - - - ```bash - # Get first page - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 20, "page": 1}' - - # Get next page - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 20, "page": 2}' - ``` - - - -## Loop Through Pages - - - - ```typescript - let currentPage = 1; - let hasMore = true; - - while (hasMore) { - const response = await client.documents.list({ - page: currentPage, - limit: 50 - }); - - console.log(`Page ${currentPage}: ${response.memories.length} memories`); - - hasMore = currentPage < response.pagination.totalPages; - currentPage++; - } - ``` - - - ```python - current_page = 1 - has_more = True - - while has_more: - response = client.documents.list(page=current_page, limit=50) - - print(f"Page {current_page}: {len(response.memories)} memories") - - has_more = current_page < response.pagination.total_pages - current_page += 1 - ``` - - - ```bash - # Manual pagination with bash loop - for page in {1..5}; do - echo "=== Page $page ===" - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d "{\"page\": $page, \"limit\": 20}" | \ - jq '.memories | length' - done - ``` - - - - - Use larger `limit` values (50-100) for pagination to reduce the number of API calls needed. - diff --git a/apps/docs/list-memories/overview.mdx b/apps/docs/list-memories/overview.mdx deleted file mode 100644 index 13976fe7..00000000 --- a/apps/docs/list-memories/overview.mdx +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: "List Memories" -description: "Retrieve paginated memories with filtering and sorting options" -sidebarTitle: "Overview" ---- - - -Retrieve paginated memories with filtering and sorting options from your Supermemory account. - -## Quick Start - - - - ```typescript - import Supermemory from 'supermemory'; - - const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! - }); - - const memories = await client.documents.list({ limit: 10 }); - console.log(memories); - ``` - - - ```python - from supermemory import Supermemory - import os - - client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - memories = client.documents.list(limit=10) - print(f"Found {len(memories.memories)} memories") - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/documents/list" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"limit": 10}' - ``` - - - -## Response Schema - -The endpoint returns a structured response containing your memories and pagination information: - -```json -{ - "memories": [ - { - "id": "abc123", - "connectionId": null, - "createdAt": "2024-01-15T10:30:00.000Z", - "updatedAt": "2024-01-15T10:35:00.000Z", - "customId": "ml-basics-001", - "title": "Introduction to Machine Learning", - "summary": "This document introduces machine learning as a subset of artificial intelligence...", - "status": "done", - "type": "text", - "metadata": { - "category": "education", - "priority": "high", - "source": "research-notes" - }, - "containerTags": ["user_123", "ai-research"] - } - ], - "pagination": { - "currentPage": 1, - "totalPages": 3, - "totalItems": 25, - "limit": 10 - } -} -``` - -### Memory Object Fields - - - -| Field | Type | Description | -|-------|------|-------------| -| `id` | string | Unique identifier for the memory | -| `status` | ProcessingStatus | Current processing status (`queued`, `extracting`, `chunking`, `embedding`, `indexing`, `done`, `failed`) | -| `type` | MemoryType | Content type (`text`, `pdf`, `webpage`, `video`, `image`, etc.) | -| `title` | string \| null | Auto-generated or custom title | -| `summary` | string \| null | AI-generated summary of content | -| `createdAt` | string | ISO 8601 creation timestamp | -| `updatedAt` | string | ISO 8601 last update timestamp | - - - - - -| Field | Type | Description | -|-------|------|-------------| -| `customId` | string \| null | Your custom identifier for the memory | -| `connectionId` | string \| null | ID of connector that created this memory | -| `metadata` | object \| null | Custom key-value metadata you provided | -| `containerTags` | string[] | Tags for organizing and filtering memories | - - - -## Key Parameters - -All parameters are optional and sent in the request body since this endpoint uses `POST`: - - - **Number of items per page.** Controls how many memories are returned in a single request. Maximum recommended: 200 for optimal performance. - - - - **Page number to fetch (1-indexed).** Use with `limit` to paginate through large result sets. - - - - **Filter by tags.** Memories must match ALL provided tags. Use for filtering by user ID, project, or custom organization tags. - - - - **Sort field.** Options: `"createdAt"` (when memory was added) or `"updatedAt"` (when memory was last modified). - - - - **Sort direction.** Use `"desc"` for newest first, `"asc"` for oldest first. - - - - **Advanced filtering.** Filter based on metadata with advanced SQL logic. - - -## Examples - - - - Simple memory retrieval with default settings - - - Filter by tags, status, and other criteria - - - Handle large datasets with pagination - - - Track processing status across memories - - - - - The `/v3/documents/list` endpoint uses **POST** method, not GET. This allows for complex filtering parameters in the request body. - diff --git a/apps/docs/memory-operations.mdx b/apps/docs/memory-operations.mdx index f70a9b16..3c9ed8a8 100644 --- a/apps/docs/memory-operations.mdx +++ b/apps/docs/memory-operations.mdx @@ -6,7 +6,7 @@ icon: "database" --- -These v4 endpoints operate on extracted memories (not raw documents). SDK support coming soon — use fetch or cURL for now. +These v4 endpoints operate on extracted memories (not raw documents). The SDK already covers the v4 read surface — `client.search.memories` and `client.profile` — while the memory create/update/forget endpoints on this page are called with fetch or cURL for now. For document management (list, get, update, delete), see [Document Operations](/document-operations). For ingesting raw content (text, files, URLs) through the processing pipeline, see [Add Context](/add-memories). diff --git a/apps/docs/memory-review.mdx b/apps/docs/memory-review.mdx index 84fda2fa..017dc613 100644 --- a/apps/docs/memory-review.mdx +++ b/apps/docs/memory-review.mdx @@ -15,7 +15,7 @@ inferred memories awaiting review, then **approve**, **decline**, or **undo** a decision on each one. -These endpoints are scoped to a single [container tag](/concepts/container-tags) +These endpoints are scoped to a single [container tag](/concepts/permissioning) (space), under `/v3/container-tags/{containerTag}`. diff --git a/apps/docs/migration/from-mem0.mdx b/apps/docs/migration/from-mem0.mdx index 6903379e..d662a6f3 100644 --- a/apps/docs/migration/from-mem0.mdx +++ b/apps/docs/migration/from-mem0.mdx @@ -38,7 +38,7 @@ for memory in data["memories"]: if memory.get("content"): supermemory.memories.add( content=memory["content"], - container_tags=["imported_from_mem0"] + container_tag="imported_from_mem0" ) print(f"✅ {memory['content'][:50]}...") @@ -142,7 +142,7 @@ print("Migration complete!") try: result = client.add( content=content, - container_tags=["imported_from_mem0"], + container_tag="imported_from_mem0", metadata={ "source": "mem0", "created_at": memory.get("created_at"), @@ -182,7 +182,7 @@ from supermemory import Supermemory client = Supermemory(api_key="...") client.add( content="User prefers dark mode", - container_tags=["user_alice"] + container_tag="user_alice" ) ``` @@ -200,9 +200,9 @@ results = client.search( ``` ```python Supermemory -results = client.documents.search( - query="user preferences", - container_tags=["user_alice"] +results = client.search.memories( + q="user preferences", + container_tag="user_alice" ) ``` @@ -247,6 +247,6 @@ For enterprise migrations, [contact us](mailto:support@supermemory.ai) for assis ## Next Steps -1. [Explore](/how-it-works) how Supermemory works +1. [Explore](/concepts/how-it-works) how Supermemory works 2. Read the [quickstart](/quickstart) and add and retrieve your first memories 3. [Connect](/connectors/overview) to Google Drive, Notion, and OneDrive with automatic syncing diff --git a/apps/docs/migration/from-zep.mdx b/apps/docs/migration/from-zep.mdx index f6585605..c6e099ef 100644 --- a/apps/docs/migration/from-zep.mdx +++ b/apps/docs/migration/from-zep.mdx @@ -9,9 +9,9 @@ sidebarTitle: "From Zep" | Zep AI | Supermemory | |--------|-------------| | Sessions & Messages | Documents & Container Tags | -| `session.create()` | Use `containerTags` parameter | -| `memory.add(session_id, ...)` | `add({containerTag: [...]})` | -| `memory.search(session_id, {text: ...})` | `search.execute({q: ..., containerTags: [...]})` | +| `session.create()` | Use `containerTag` parameter | +| `memory.add(session_id, ...)` | `add({containerTag: "..."})` | +| `memory.search(session_id, {text: ...})` | `search.memories({q: ..., containerTag: "..."})` | ## Installation @@ -56,7 +56,7 @@ session = client.session.create( ```python Supermemory # No explicit session creation - use containerTag -containerTag = ["user_123"] +containerTag = "user_123" ``` @@ -75,7 +75,7 @@ client.memory.add( ```python Supermemory client.add({ "content": "User prefers dark mode", - "containerTag": ["user_123"] + "containerTag": "user_123" }) ``` @@ -93,9 +93,9 @@ results = client.memory.search( ``` ```python Supermemory -results = client.search.execute({ +results = client.search.memories({ "q": "preferences", - "containerTag": ["user_123"], + "containerTag": "user_123", "limit": 5 }) ``` @@ -112,7 +112,7 @@ memories = client.memory.get(session_id="user_123") ```python Supermemory documents = client.documents.list({ - "containerTag": ["user_123"], + "containerTags": ["user_123"], "limit": 100 }) ``` @@ -122,8 +122,8 @@ documents = client.documents.list({ ## Migration Steps 1. **Replace client initialization** - Use Supermemory client instead of Zep -2. **Map sessions to container tags** - Replace `session_id="user_123"` with `containerTag: ["user_123"]` -3. **Update method calls** - Use `add()` and `search.execute()` instead of `memory.add()` and `memory.search()` +2. **Map sessions to container tags** - Replace `session_id="user_123"` with `containerTag: "user_123"` +3. **Update method calls** - Use `add()` and `search.memories()` instead of `memory.add()` and `memory.search()` 4. **Change search parameter** - Use `q` instead of `text` 5. **Handle async processing** - Documents process asynchronously (status: `queued` → `done`) @@ -152,7 +152,7 @@ results = client.memory.search("user_123", { from supermemory import Supermemory client = Supermemory(api_key="...") -containerTag = ["user_123"] +containerTag = "user_123" client.add({ "content": "I love Python", @@ -160,7 +160,7 @@ client.add({ "metadata": {"role": "user"} }) -results = client.search.execute({ +results = client.search.memories({ "q": "programming", "containerTag": containerTag, "limit": 3 @@ -203,10 +203,11 @@ for (const sessionId of sessionIds) { if (mem.content) { await supermemory.add({ content: mem.content, - containerTag: [`session_${sessionId}`, `user_${memory.user_id || "unknown"}`], + containerTag: `user_${memory.user_id || "unknown"}`, metadata: { role: mem.role, type: "message", + session_id: sessionId, original_uuid: mem.uuid, ...mem.metadata } @@ -238,10 +239,11 @@ for session_id in session_ids: if mem.content: supermemory.add({ "content": mem.content, - "containerTag": [f"session_{session_id}", f"user_{memory.user_id or 'unknown'}"], + "containerTag": f"user_{memory.user_id or 'unknown'}", "metadata": { "role": mem.role, "type": "message", + "session_id": session_id, "original_uuid": mem.uuid, **(mem.metadata or {}) } @@ -315,10 +317,9 @@ async function migrateFromZep( // Import to Supermemory let totalMemories = 0; for (const [sessionId, data] of Object.entries(exportedData) as any) { - const containerTag = ["imported_from_zep", `session_${sessionId}`]; - if (data.session.user_id) { - containerTag.push(`user_${data.session.user_id}`); - } + const containerTag = data.session.user_id + ? `user_${data.session.user_id}` + : `session_${sessionId}`; for (const memory of data.memories) { totalMemories++; @@ -335,6 +336,7 @@ async function migrateFromZep( source: "zep_migration", role: memory.role, type: "message", + session_id: sessionId, original_uuid: memory.uuid, ...memory.metadata, }, @@ -368,5 +370,5 @@ migrateFromZep( ## Resources - [Supermemory SDKs](/integrations/supermemory-sdk) -- [API Reference](/memory-api/overview) +- [API Reference](/add-memories) - [Search Documentation](/search) diff --git a/apps/docs/migration/tools-v2-upgrade.mdx b/apps/docs/migration/tools-v2-upgrade.mdx index a948da52..0c22492a 100644 --- a/apps/docs/migration/tools-v2-upgrade.mdx +++ b/apps/docs/migration/tools-v2-upgrade.mdx @@ -34,7 +34,7 @@ npm install @supermemory/tools@^2.0.0 // v1.4.x import { withSupermemory } from '@supermemory/tools/ai-sdk'; -const model = withSupermemory(openai('gpt-4'), 'user-123', { +const model = withSupermemory(openai('gpt-4o'), 'user-123', { conversationId: 'conv-456', mode: 'full', }); @@ -44,7 +44,7 @@ const model = withSupermemory(openai('gpt-4'), 'user-123', { // v2.0.0 import { withSupermemory } from '@supermemory/tools/ai-sdk'; -const model = withSupermemory(openai('gpt-4'), { +const model = withSupermemory(openai('gpt-4o'), { containerTag: 'user-123', customId: 'conv-456', mode: 'full', @@ -139,7 +139,7 @@ If you were relying on `verbose: false` implicitly while passing `verbose: true` Across all four integrations, `addMemory` now defaults to `"always"`. If your v1.4.x code relied on the old default of `"never"`, set it explicitly: ```typescript -const model = withSupermemory(openai('gpt-4'), { +const model = withSupermemory(openai('gpt-4o'), { containerTag: 'user-123', customId: 'conv-456', addMemory: 'never', // preserve v1.4.x behavior diff --git a/apps/docs/n8n.mdx b/apps/docs/n8n.mdx deleted file mode 100644 index 9eb10a25..00000000 --- a/apps/docs/n8n.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "n8n Integration" -description: "Automate knowledge management with Supermemory in n8n workflows" -sidebarTitle: "n8n" ---- - -Connect Supermemory to your n8n workflows to build intelligent automation workflows and agents that leverage your full knowledge base. - -## Quick Start - -### Prerequisites - -- n8n instance (self-hosted or cloud) -- Supermemory API key ([get one here](https://console.supermemory.ai/settings)) -- Basic understanding of n8n workflows - -### Setting Up the HTTP Request Node - -The Supermemory integration in n8n uses the HTTP Request node to interact with the Supermemory API. Here's how to configure it: - -1. Add an **HTTP Request** node to your workflow (Core > HTTP Request) -![](/images/core-http-req.png) -2. Set the **Method** to `POST` -3. Set the **URL** to the appropriate Supermemory API endpoint: - - Add memory: `https://api.supermemory.ai/v3/documents` - - Search memories: `https://api.supermemory.ai/v4/search` -4. For authentication, select **Generic Credential Type** and then **Bearer Auth** -5. Click on **Create New Credential** and paste the Supermemory API Key in the Bearer Token field. -![](/images/bearer-auth-add-n8n.png) -6. Check **Send Body** and select **JSON** as the Body Content Type. The fields depend on what API endpoint you're sending the request to. You can find detailed step-by-step examples below. - -## Step-by-Step Tutorial - -In this tutorial, we'll create a workflow that automatically adds every email from Gmail to your Supermemory knowledge base. We'll use the HTTP Request node to send email data to Supermemory's API, creating a searchable archive of all your communications. - -### Adding Gmail Emails to Supermemory - -Follow these steps to build a workflow that captures and stores your Gmail messages: - -#### Step 1: Set Up Gmail Trigger - -![](/images/gmail-trigger.png) - -1. **Add a Gmail Trigger node** to your workflow -2. Configure your Gmail credentials (OAuth2 recommended) -3. Set the trigger to **Message Received** -4. Optional: Add labels or filters to process specific emails only - -#### Step 2: Configure HTTP Request Node - -1. **Add an HTTP Request node** after the Gmail Trigger -2. **Method**: `POST` -3. **URL**: `https://api.supermemory.ai/v3/documents` -4. Select your auth credentials you created with the Supermemory API Key. - -#### Step 3: Format Email Data for Supermemory - -In the HTTP Request node's **Body**, select **JSON** and **Using Fields Below** - -And create 2 fields: - -1. name: `content`, value: `{{ $json.snippet }}` -2. name: `containerTag`, value: gmail - - -![](/images/gmail-content.png) - -#### Step 4: Handle Attachments (Optional) - -If you want to process attachments: - -1. **Add a Loop node** after the Gmail Trigger -2. Loop through `{{$json.attachments}}` -3. **Add a Gmail node** to download each attachment -4. **Add another HTTP Request node** to store attachment metadata - - -#### Step 5: Add Error Handling - -1. **Add an Error Trigger node** connected to your workflow -2. Configure it to catch errors from the HTTP Request node -3. **Add a notification node** (Email, Slack, etc.) to alert you of failures -4. Optional: Add a **Wait node** with retry logic - -#### Step 6: Test Your Workflow - -1. **Activate the workflow** in test mode -2. Send a test email to your Gmail account -3. Check the execution to ensure the email was captured -4. Verify in Supermemory that the email appears in search results - -Refer to the API Reference tab to learn more about other supermemory API endpoints. \ No newline at end of file diff --git a/apps/docs/search.mdx b/apps/docs/search.mdx index 15f4861d..90469607 100644 --- a/apps/docs/search.mdx +++ b/apps/docs/search.mdx @@ -165,7 +165,7 @@ const results = await client.search.memories({ - **Array contains:** `{ filterType: "array_contains", key: "tags", value: "important" }` - **Negate:** `{ key: "status", value: "draft", negate: true }` - See [Organizing & Filtering](/concepts/filtering) for full syntax. + See [Organizing & Filtering](/concepts/hybrid-search) for full syntax. --- @@ -244,4 +244,4 @@ async function getContext(userId: string, message: string) { - [Ingesting Content](/add-memories) — Add content to search - [User Profiles](/user-profiles) — Get user context with search -- [Organizing & Filtering](/concepts/filtering) — Container tags and metadata +- [Organizing & Filtering](/concepts/hybrid-search) — Container tags and metadata diff --git a/apps/docs/search/examples/document-search.mdx b/apps/docs/search/examples/document-search.mdx deleted file mode 100644 index 4ef11070..00000000 --- a/apps/docs/search/examples/document-search.mdx +++ /dev/null @@ -1,588 +0,0 @@ ---- -title: "Documents Search (/v3/search)" -description: "Full-featured search with extensive control over ranking, filtering, and results" ---- - -Documents search (`POST /v3/search`) provides maximum control over search behavior with extensive parameters for fine-tuning results. - -## Basic Implementation - - - - ```typescript - import Supermemory from 'supermemory'; - - const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! - }); - - const results = await client.search.documents({ - q: "machine learning neural networks", - limit: 5 - }); - - console.log(`Found ${results.total} documents in ${results.timing}ms`); - - // Sample output structure - results.results.forEach((doc, i) => { - console.log(`${i + 1}. ${doc.title} (Score: ${doc.score})`); - console.log(` ${doc.chunks.length} chunks found`); - }); - ``` - - - ```python - from supermemory import Supermemory - import os - - client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - - results = client.search.documents( - q="machine learning neural networks", - limit=5 - ) - - print(f"Found {results.total} documents in {results.timing}ms") - - # Sample output structure - for i, doc in enumerate(results.results): - print(f"{i + 1}. {doc.title} (Score: {doc.score})") - print(f" {len(doc.chunks)} chunks found") - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning neural networks", - "limit": 5 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "documentId": "doc_ml_guide_2024", - "title": "Machine Learning with Neural Networks: A Comprehensive Guide", - "score": 0.89, - "chunks": [ - { - "content": "Neural networks are computational models inspired by biological neural networks. They consist of interconnected nodes (neurons) that process information through weighted connections...", - "score": 0.92, - "isRelevant": true - }, - { - "content": "Deep learning, a subset of machine learning, uses neural networks with multiple hidden layers to learn complex patterns in data...", - "score": 0.87, - "isRelevant": true - } - ], - "createdAt": "2024-01-15T10:30:00Z", - "metadata": { - "category": "ai", - "difficulty": "intermediate" - } - } - ], - "total": 12, - "timing": 156 -} -``` - -## Container Tags Filtering - -Container tags are the primary way to isolate search results by user, project, or organization. - -**Key behaviors:** -- **Array-based**: Unlike `/v4/search`, this endpoint accepts multiple container tags as an array -- **Exact array matching**: Documents must have the EXACT same container tags array to match - - - - ```typescript - const results = await client.search.documents({ - q: "quarterly reports", - containerTags: ["user_123"], - limit: 10 - }); - ``` - - - ```python - results = client.search.documents( - q="quarterly reports", - container_tags=["user_123"], - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "quarterly reports", - "containerTags": ["user_123"], - "limit": 10 - }' - ``` - - - -## Metadata Filtering - -Metadata filtering allows complex conditions on structured data attached to your documents. This uses SQL-like query construction in the backend, requiring explicit AND/OR structures. - -**Filter structure rules:** -- **Must wrap conditions** in AND or OR arrays, even for single conditions -- **Supports string matching** (exact), numeric operators, and array contains -- **Negate any condition** with `negate: true` -- **Combines with container tags** - both filters are applied - - - - ```typescript - const results = await client.search.documents({ - q: "machine learning", - filters: { - AND: [ - { - key: "category", - value: "technology", - negate: false - }, - { - filterType: "numeric", - key: "readingTime", - value: "5", - negate: false, - numericOperator: "<=" - } - ] - }, - limit: 10 - }); - ``` - - - ```python - results = client.search.documents( - q="machine learning", - filters={ - "AND": [ - { - "key": "category", - "value": "technology", - "negate": False - }, - { - "filterType": "numeric", - "key": "readingTime", - "value": "5", - "negate": False, - "numericOperator": "<=" - } - ] - }, - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning", - "filters": { - "AND": [ - { - "key": "category", - "value": "technology", - "negate": false - }, - { - "filterType": "numeric", - "key": "readingTime", - "value": "5", - "negate": false, - "numericOperator": "<=" - } - ] - }, - "limit": 10 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "documentId": "doc_tech_trends_2024", - "title": "Technology Trends in Machine Learning", - "score": 0.91, - "chunks": [ - { - "content": "Machine learning continues to evolve with new architectures and optimization techniques. Reading time for this comprehensive overview is approximately 8 minutes...", - "score": 0.88, - "isRelevant": true - } - ], - "metadata": { - "category": "technology", - "readingTime": 8, - "difficulty": "intermediate", - "published": true - } - } - ], - "total": 6, - "timing": 189 -} -``` - -## Array Contains Filtering - -When your metadata includes arrays (like participant lists, tags, or categories), use `array_contains` to check if the array includes a specific value. - - - - ```typescript - const results = await client.search.documents({ - q: "meeting discussion", - filters: { - AND: [ - { - key: "participants", - value: "john.doe", - filterType: "array_contains" - } - ] - }, - limit: 5 - }); - ``` - - - ```python - results = client.search.documents( - q="meeting discussion", - filters={ - "AND": [ - { - "key": "participants", - "value": "john.doe", - "filterType": "array_contains" - } - ] - }, - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "meeting discussion", - "filters": { - "AND": [ - { - "key": "participants", - "value": "john.doe", - "filterType": "array_contains" - } - ] - }, - "limit": 5 - }' - ``` - - - -## Threshold Control - -Control result quality with sensitivity thresholds: - - - - ```typescript - const results = await client.search.documents({ - q: "artificial intelligence", - documentThreshold: 0.7, // Higher = fewer, more relevant documents - chunkThreshold: 0.8, // Higher = fewer, more relevant chunks - limit: 10 - }); - ``` - - - ```python - results = client.search.documents( - q="artificial intelligence", - document_threshold=0.7, # Higher = fewer, more relevant documents - chunk_threshold=0.8, # Higher = fewer, more relevant chunks - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "artificial intelligence", - "documentThreshold": 0.7, - "chunkThreshold": 0.8, - "limit": 10 - }' - ``` - - - -## Query Rewriting - -Improve search accuracy with automatic query rewriting: - - - - ```typescript - const results = await client.search.documents({ - q: "What is the capital of France?", - rewriteQuery: true, // +400ms latency but better results - limit: 5 - }); - ``` - - - ```python - results = client.search.documents( - q="What is the capital of France?", - rewrite_query=True, # +400ms latency but better results - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "What is the capital of France?", - "rewriteQuery": true, - "limit": 5 - }' - ``` - - - - -Query rewriting generates multiple query variations and searches through all of them, then merges results. No additional cost but adds ~400ms latency. - - -## Reranking - -Improve result quality with secondary ranking: - - - - ```typescript - const results = await client.search.documents({ - q: "machine learning applications", - rerank: true, // Apply secondary ranking algorithm - limit: 10 - }); - ``` - - - ```python - results = client.search.documents( - q="machine learning applications", - rerank=True, # Apply secondary ranking algorithm - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning applications", - "rerank": true, - "limit": 10 - }' - ``` - - - -## Document-Specific Search - -Search within a specific large document: - - - - ```typescript - const results = await client.search.documents({ - q: "neural networks", - docId: "doc_123", // Search only within this document - limit: 10 - }); - ``` - - - ```python - results = client.search.documents( - q="neural networks", - doc_id="doc_123", # Search only within this document - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "neural networks", - "docId": "doc_123", - "limit": 10 - }' - ``` - - - -## Full Context Options - -Include complete document content and summaries: - - - - ```typescript - const results = await client.search.documents({ - q: "research findings", - includeFullDocs: true, // Include complete document content - includeSummary: true, // Include document summaries - onlyMatchingChunks: false, // Include all chunks, not just matching ones - limit: 5 - }); - ``` - - - ```python - results = client.search.documents( - q="research findings", - include_full_docs=True, # Include complete document content - include_summary=True, # Include document summaries - only_matching_chunks=False, # Include all chunks, not just matching ones - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "research findings", - "includeFullDocs": true, - "includeSummary": true, - "onlyMatchingChunks": false, - "limit": 5 - }' - ``` - - - -## Complete Advanced Example - -Combining all features for maximum control: - - - - ```typescript - const results = await client.search.documents({ - q: "machine learning performance metrics", - containerTags: ["research_project"], - filters: { - AND: [ - { key: "category", value: "ai", negate: false }, - { key: "status", value: "published", negate: false } - ] - }, - documentThreshold: 0.6, - chunkThreshold: 0.7, - rewriteQuery: true, - rerank: true, - includeFullDocs: false, - includeSummary: true, - onlyMatchingChunks: true, - limit: 10 - }); - ``` - - - ```python - results = client.search.documents( - q="machine learning performance metrics", - container_tags=["research_project"], - filters={ - "AND": [ - {"key": "category", "value": "ai", "negate": False}, - {"key": "status", "value": "published", "negate": False} - ] - }, - document_threshold=0.6, - chunk_threshold=0.7, - rewrite_query=True, - rerank=True, - include_full_docs=False, - include_summary=True, - only_matching_chunks=True, - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning performance metrics", - "containerTags": ["research_project"], - "filters": { - "AND": [ - {"key": "category", "value": "ai", "negate": false}, - {"key": "status", "value": "published", "negate": false} - ] - }, - "documentThreshold": 0.6, - "chunkThreshold": 0.7, - "rewriteQuery": true, - "rerank": true, - "includeFullDocs": false, - "includeSummary": true, - "onlyMatchingChunks": true, - "limit": 10 - }' - ``` - - diff --git a/apps/docs/search/examples/memory-search.mdx b/apps/docs/search/examples/memory-search.mdx deleted file mode 100644 index c6d18b6e..00000000 --- a/apps/docs/search/examples/memory-search.mdx +++ /dev/null @@ -1,695 +0,0 @@ ---- -title: "Memories Search (/v4/search)" -description: "Minimal-latency search optimized for chatbots and conversational AI" ---- - - -Memories search (`POST /v4/search`) provides minimal-latency search optimized for real-time interactions. This endpoint prioritizes speed over extensive control, making it perfect for chatbots, Q&A systems, and any application where users expect immediate responses. - -## Basic Search - - - - ```typescript - import Supermemory from 'supermemory'; - - const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! - }); - - const results = await client.search.memories({ - q: "machine learning applications", - limit: 5 - }); - - console.log(results) - ``` - - - ```python - from supermemory import Supermemory - import os - - client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - - results = client.search.memories( - q="machine learning applications", - limit=5 - ) - - console.log(results) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning applications", - "limit": 5 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "id": "mem_ml_apps_2024", - "memory": "Machine learning applications span numerous industries including healthcare (diagnostic imaging, drug discovery), finance (fraud detection, algorithmic trading), autonomous vehicles (computer vision, path planning), and natural language processing (chatbots, translation services).", - "similarity": 0.92, - "title": "Machine Learning Industry Applications", - "type": "text", - "metadata": { - "topic": "machine-learning", - "industry": "technology", - "created": "2024-01-10" - } - }, - { - "id": "mem_ml_healthcare", - "memory": "In healthcare, machine learning enables early disease detection through medical imaging analysis, personalized treatment recommendations, and drug discovery acceleration by predicting molecular behavior.", - "similarity": 0.89, - "title": "ML in Healthcare", - "type": "text" - } - ], - "total": 8, - "timing": 87 -} -``` - -## Container Tag Filtering - -Filter by user, project, or organization: - - - - ```typescript - const results = await client.search.memories({ - q: "project updates", - containerTag: "user_123", // Note: singular, not plural - limit: 10 - }); - ``` - - - ```python - results = client.search.memories( - q="project updates", - container_tag="user_123", # Note: singular, not plural - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "project updates", - "containerTag": "user_123", - "limit": 10 - }' - ``` - - - -## Threshold Control - -Control result quality with similarity threshold: - - - - ```typescript - const results = await client.search.memories({ - q: "artificial intelligence research", - threshold: 0.7, // Higher = fewer, more similar results - limit: 10 - }); - ``` - - - ```python - results = client.search.memories( - q="artificial intelligence research", - threshold=0.7, # Higher = fewer, more similar results - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "artificial intelligence research", - "threshold": 0.7, - "limit": 10 - }' - ``` - - - -## Reranking - -Improve result quality with secondary ranking: - - - - ```typescript - const results = await client.search.memories({ - q: "quantum computing breakthrough", - rerank: true, // Better relevance, slight latency increase - limit: 5 - }); - ``` - - - ```python - results = client.search.memories( - q="quantum computing breakthrough", - rerank=True, # Better relevance, slight latency increase - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "quantum computing breakthrough", - "rerank": true, - "limit": 5 - }' - ``` - - - -## Query Rewriting - -Improve search accuracy with automatic query expansion: - - - - ```typescript - const results = await client.search.memories({ - q: "How do neural networks learn?", - rewriteQuery: true, // +400ms latency but better results - limit: 5 - }); - ``` - - - ```python - results = client.search.memories( - q="How do neural networks learn?", - rewrite_query=True, # +400ms latency but better results - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "How do neural networks learn?", - "rewriteQuery": true, - "limit": 5 - }' - ``` - - - -## Include Related Content - -Include documents, related memories, and summaries: - - - - ```typescript - const results = await client.search.memories({ - q: "machine learning trends", - include: { - documents: true, // Include source documents - relatedMemories: true, // Include related memory entries - summaries: true // Include memory summaries - }, - limit: 5 - }); - ``` - - - ```python - results = client.search.memories( - q="machine learning trends", - include={ - "documents": True, # Include source documents - "relatedMemories": True, # Include related memory entries - "summaries": True # Include memory summaries - }, - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning trends", - "include": { - "documents": true, - "relatedMemories": true, - "summaries": true - }, - "limit": 5 - }' - ``` - - - -## Metadata Filtering - -Simple metadata filtering for Memories search: - - - - ```typescript - const results = await client.search.memories({ - q: "research findings", - filters: { - AND: [ - { key: "category", value: "science", negate: false }, - { key: "status", value: "published", negate: false } - ] - }, - limit: 10 - }); - ``` - - - ```python - results = client.search.memories( - q="research findings", - filters={ - "AND": [ - {"key": "category", "value": "science", "negate": False}, - {"key": "status", "value": "published", "negate": False} - ] - }, - limit=10 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "research findings", - "filters": { - "AND": [ - {"key": "category", "value": "science", "negate": false}, - {"key": "status", "value": "published", "negate": false} - ] - }, - "limit": 10 - }' - ``` - - - -## Chatbot Example - -Optimal configuration for conversational AI: - - - - ```typescript - // Optimized for chatbot responses - const results = await client.search.memories({ - q: userMessage, - containerTag: userId, - threshold: 0.6, // Balanced relevance - rerank: false, // Skip for speed - rewriteQuery: false, // Skip for speed - limit: 3 // Few, relevant results - }); - - // Quick response for chat - const context = results.results - .map(r => r.memory) - .join('\n\n'); - ``` - - - ```python - # Optimized for chatbot responses - results = client.search.memories( - q=user_message, - container_tag=user_id, - threshold=0.6, # Balanced relevance - rerank=False, # Skip for speed - rewrite_query=False, # Skip for speed - limit=3 # Few, relevant results - ) - - # Quick response for chat - context = '\n\n'.join([r.memory for r in results.results]) - ``` - - - ```bash - # Optimized for chatbot responses - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "user question here", - "containerTag": "user_123", - "threshold": 0.6, - "rerank": false, - "rewriteQuery": false, - "limit": 3 - }' - ``` - - - -## Complete Memories Search Example - -Combining features for comprehensive results: - - - - ```typescript - const results = await client.search.memories({ - q: "machine learning model performance", - containerTag: "research_team", - filters: { - AND: [ - { key: "topic", value: "ai", negate: false } - ] - }, - threshold: 0.7, - rerank: true, - rewriteQuery: false, // Skip for speed - include: { - documents: true, - relatedMemories: false, - summaries: true - }, - limit: 5 - }); - ``` - - - ```python - results = client.search.memories( - q="machine learning model performance", - container_tag="research_team", - filters={ - "AND": [ - {"key": "topic", "value": "ai", "negate": False} - ] - }, - threshold=0.7, - rerank=True, - rewrite_query=False, # Skip for speed - include={ - "documents": True, - "relatedMemories": False, - "summaries": True - }, - limit=5 - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning model performance", - "containerTag": "research_team", - "filters": { - "AND": [ - {"key": "topic", "value": "ai", "negate": false} - ] - }, - "threshold": 0.7, - "rerank": true, - "rewriteQuery": false, - "include": { - "documents": true, - "relatedMemories": false, - "summaries": true - }, - "limit": 5 - }' - ``` - - - -## Hybrid Search Mode - -Hybrid search mode allows you to search both memories and document chunks in a single request. When `searchMode="hybrid"`, results contain objects with either a `memory` key (for memory results) or a `chunk` key (for chunk results). - -### Basic Hybrid Search - - - - ```typescript - const results = await client.search.memories({ - q: "machine learning best practices", - searchMode: "hybrid", // Search memories + chunks - limit: 10 - }); - - // Handle mixed results - results.results.forEach(result => { - if ('memory' in result) { - console.log('Memory:', result.memory); - } else if ('chunk' in result) { - console.log('Chunk:', result.chunk); - console.log('From document:', result.documents?.[0]?.title); - } - }); - ``` - - - ```python - results = client.search.memories( - q="machine learning best practices", - search_mode="hybrid", # Search memories + chunks - limit=10 - ) - - # Handle mixed results - for result in results.results: - if 'memory' in result: - print('Memory:', result['memory']) - elif 'chunk' in result: - print('Chunk:', result['chunk']) - print('From document:', result.get('documents', [{}])[0].get('title')) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning best practices", - "searchMode": "hybrid", - "limit": 10 - }' - ``` - - - -### When to Use Hybrid Mode - -Use hybrid mode when: -- You want comprehensive search across both memories and documents -- Memories might not exist for certain queries but document content is available -- You need flexibility to get either memory or document chunk results -- You want a single search endpoint that covers all content types - -Use memories-only mode (`searchMode="memories"`) when: -- You only need user memories and preferences -- You want faster, more focused results -- You're building a personalized chatbot that relies on user context - -### Handling Mixed Results - -When using hybrid mode, you'll receive mixed results. Here's how to process them: - - - - ```typescript - const results = await client.search.memories({ - q: "quantum computing applications", - searchMode: "hybrid", - limit: 10 - }); - - // Separate memory and chunk results - const memoryResults = results.results.filter(r => 'memory' in r); - const chunkResults = results.results.filter(r => 'chunk' in r); - - console.log(`Found ${memoryResults.length} memories and ${chunkResults.length} chunks`); - - // Process memories - memoryResults.forEach(mem => { - console.log('Memory:', mem.memory); - console.log('Similarity:', mem.similarity); - }); - - // Process chunks - chunkResults.forEach(chunk => { - console.log('Chunk:', chunk.chunk); - console.log('Document:', chunk.documents?.[0]?.title); - console.log('Similarity:', chunk.similarity); - }); - ``` - - - ```python - results = client.search.memories( - q="quantum computing applications", - search_mode="hybrid", - limit=10 - ) - - # Separate memory and chunk results - memory_results = [r for r in results.results if 'memory' in r] - chunk_results = [r for r in results.results if 'chunk' in r] - - print(f"Found {len(memory_results)} memories and {len(chunk_results)} chunks") - - # Process memories - for mem in memory_results: - print('Memory:', mem['memory']) - print('Similarity:', mem['similarity']) - - # Process chunks - for chunk in chunk_results: - print('Chunk:', chunk['chunk']) - print('Document:', chunk.get('documents', [{}])[0].get('title')) - print('Similarity:', chunk['similarity']) - ``` - - - -### Hybrid Search with All Features - -Combining hybrid mode with other features: - - - - ```typescript - const results = await client.search.memories({ - q: "research findings on AI", - searchMode: "hybrid", - containerTag: "research_team", - threshold: 0.7, - rerank: true, - include: { - documents: true, - relatedMemories: true, - summaries: true - }, - limit: 10 - }); - - // Results are automatically sorted by similarity - // Memory results have 'memory' field, chunk results have 'chunk' field - results.results.forEach(result => { - if ('memory' in result) { - // Memory result - console.log('Memory:', result.memory); - console.log('Context:', result.context); - } else { - // Chunk result - console.log('Chunk:', result.chunk); - console.log('Document:', result.documents?.[0]); - } - }); - ``` - - - ```python - results = client.search.memories( - q="research findings on AI", - search_mode="hybrid", - container_tag="research_team", - threshold=0.7, - rerank=True, - include={ - "documents": True, - "relatedMemories": True, - "summaries": True - }, - limit=10 - ) - - # Results are automatically sorted by similarity - # Memory results have 'memory' field, chunk results have 'chunk' field - for result in results.results: - if 'memory' in result: - # Memory result - print('Memory:', result['memory']) - print('Context:', result.get('context')) - else: - # Chunk result - print('Chunk:', result['chunk']) - print('Document:', result.get('documents', [{}])[0]) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "research findings on AI", - "searchMode": "hybrid", - "containerTag": "research_team", - "threshold": 0.7, - "rerank": true, - "include": { - "documents": true, - "relatedMemories": true, - "summaries": true - }, - "limit": 10 - }' - ``` - - - - - **Important**: In hybrid mode, results are automatically merged and sorted by similarity score. Memory results and chunk results are deduplicated - if a chunk is already associated with a memory result, it won't appear as a separate chunk result. - - -## Common Use Cases - -- **Chatbots**: Basic search with container tag and low threshold -- **Q&A Systems**: Add reranking for better relevance -- **Knowledge Retrieval**: Include documents and summaries -- **Real-time Search**: Skip rewriting and reranking for maximum speed -- **Hybrid Search**: Use `searchMode="hybrid"` when you need comprehensive search across both memories and documents diff --git a/apps/docs/search/overview.mdx b/apps/docs/search/overview.mdx deleted file mode 100644 index 32c2d7da..00000000 --- a/apps/docs/search/overview.mdx +++ /dev/null @@ -1,493 +0,0 @@ ---- -title: "Search with Filters & Scoring" -description: "Semantic and hybrid search with metadata filters, scoring, and precise result control" -sidebarTitle : "Overview" ---- - -## Prerequisites - -Before searching memories, you need to set up the Supermemory client: - -- **Install the SDK** for your language -- **Get your API key** from [Supermemory Console](https://console.supermemory.ai) -- **Initialize the client** with your API key - - - -```bash npm -npm install supermemory -``` - -```bash pip -pip install supermemory -``` - - - - - -```typescript TypeScript -import Supermemory from 'supermemory'; - -const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! -}); -``` - -```python Python -from supermemory import Supermemory -import os - -client = Supermemory( - api_key=os.environ.get("SUPERMEMORY_API_KEY") -) -``` - - - -## Search Endpoints Overview - - - - **POST /v3/search** - - Full-featured search with extensive control over ranking, filtering, thresholds, and result structure. Searches through and returns relevant documents. More flexibility. - - - - **POST /v4/search** - - Minimal-latency search optimized for chatbots and conversational AI. Searches through and returns memories. Simple parameters, fast responses, easy to use. - - - -## Documents vs Memories Search: What's the Difference? - -The key difference between `/v3/search` and `/v4/search` is **documents vs memories**. `/v3/search` searches through the documents and returns matching chunks, whereas `/v4/search` searches through user's memories, preferences and history. - -- **Documents:** Refer to the data you ingest like text, pdfs, videos, images, etc. They are sources of ground truth. -- **Memories:** They are automatically extracted from your documents by Supermemory. Smaller information chunks inferred from documents and related to each other. - -Refer to the [ingestion guide](/memory-api/ingesting) to learn more about the difference between documents and memories. - -### Documents Search (`/v3/search`) -**High quality documents search** - extensive parameters for fine-tuning search behavior: - -- **Use cases**: Use this endpoint for use cases where "literal" document search is required. - - Looking through legal/finance documents - - Searching through items in google drive - - Chat with documentation -- With this endpoint, you get **Full Control** over - - Thresholds, - - Filtering - - Reranking - - Query rewriting - - - - ```typescript - // Documents search - const results = await client.search.documents({ - q: "machine learning accuracy", - limit: 10, - documentThreshold: 0.7, - chunkThreshold: 0.8, - rerank: true, - rewriteQuery: true, - includeFullDocs: true, - includeSummary: true, - onlyMatchingChunks: false, - containerTags: ["research"], - filters: { - AND: [{ key: "category", value: "ai", negate: false }] - } - }); - ``` - - - ```python - # Documents search - results = client.search.documents( - q="machine learning accuracy", - limit=10, - document_threshold=0.7, - chunk_threshold=0.8, - rerank=True, - rewrite_query=True, - include_full_docs=True, - include_summary=True, - only_matching_chunks=False, - container_tags=["research"], - filters={ - "AND": [{"key": "category", "value": "ai", "negate": False}] - } - ) - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning accuracy", - "limit": 10, - "documentThreshold": 0.7, - "chunkThreshold": 0.8, - "rerank": true, - "rewriteQuery": true, - "includeFullDocs": true, - "includeSummary": true, - "onlyMatchingChunks": false, - "containerTags": ["research"], - "filters": { - "AND": [{"key": "category", "value": "ai", "negate": false}] - } - }' - ``` - - - -```json Sample Response - -{ - "results": [ - { - "documentId": "doc_abc123", - "title": "Machine Learning Fundamentals", - "type": "pdf", - "score": 0.89, - "chunks": [ - { - "content": "Machine learning is a subset of artificial intelligence...", - "score": 0.95, - "isRelevant": true - } - ], - "metadata": { - "category": "education", - "author": "Dr. Smith", - "difficulty": "beginner" - }, - "createdAt": "2024-01-15T10:30:00Z", - "updatedAt": "2024-01-20T14:45:00Z" - } - ], - "timing": 187, - "total": 1 -} -``` - -The `/v3/search` endpoint returns the most relevant documents and chunks from those documents. Head over to the [response schema](/search/response-schema) page to understand more about the response structure. - -### Memories Search (`/v4/search`) -**Search through user memories**: - -- **Use cases**: Use this endpoint for use cases where understanding user context / preferences / memories is more important than literal document search. - - Personalized chatbots (AI Companions) - - Auto selecting based on what the user wants - - Setting the tone of the conversation - -Companies like Composio [Rube.app](https://rube.app) use memories search for letting the MCP automate better based on the user prompts before. - - - This endpoint works best for conversational AI use cases like chatbots. - - -**Hybrid Search Mode:** - -The `/v4/search` endpoint supports a `searchMode` parameter with two options: - -- **`"memories"`** (default): Searches only memory entries. Returns results with a `memory` key containing the memory content. -- **`"hybrid"`**: Searches memories first, then falls back to document chunks if needed. Returns mixed results where each result object has either a `memory` key (for memory results) or a `chunk` key (for chunk results from documents). - - - In hybrid mode, results are automatically merged by similarity score and deduplicated. Check for the presence of `memory` or `chunk` keys to distinguish result types. - - - - - ```typescript - // Memories search (default mode) - const results = await client.search.memories({ - q: "machine learning accuracy", - limit: 5, - containerTag: "research", - threshold: 0.7, - rerank: true, - searchMode: "memories" // Default: only search memories - }); - - // Hybrid search (memories + chunks) - const hybridResults = await client.search.memories({ - q: "machine learning accuracy", - limit: 5, - containerTag: "research", - threshold: 0.7, - searchMode: "hybrid" // Search memories + fallback to chunks - }); - ``` - - - ```python - # Memories search (default mode) - results = client.search.memories( - q="machine learning accuracy", - limit=5, - container_tag="research", - threshold=0.7, - rerank=True, - search_mode="memories" # Default: only search memories - ) - - # Hybrid search (memories + chunks) - hybrid_results = client.search.memories( - q="machine learning accuracy", - limit=5, - container_tag="research", - threshold=0.7, - search_mode="hybrid" # Search memories + fallback to chunks - ) - ``` - - - ```bash - # Memories search (default mode) - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning accuracy", - "limit": 5, - "containerTag": "research", - "threshold": 0.7, - "rerank": true, - }' - - # Hybrid search (memories + chunks) - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning accuracy", - "limit": 5, - "containerTag": "research", - "threshold": 0.7, - "rerank": true, - "searchMode": "hybrid" - }' - ``` - - - - -```json Sample Response -{ - "results": [ - { - "id": "mem_xyz789", - "memory": "Complete memory content about quantum computing applications...", - "similarity": 0.87, - "metadata": { - "category": "research", - "topic": "quantum-computing" - }, - "updatedAt": "2024-01-18T09:15:00Z", - "version": 3, - "context": { - "parents": [ - { - "memory": "Earlier discussion about quantum theory basics...", - "relation": "extends", - "version": 2, - "updatedAt": "2024-01-17T16:30:00Z" - } - ], - "children": [ - { - "memory": "Follow-up questions about quantum algorithms...", - "relation": "derives", - "version": 4, - "updatedAt": "2024-01-19T11:20:00Z" - } - ] - }, - "documents": [ - { - "id": "doc_quantum_paper", - "title": "Quantum Computing Applications", - "type": "pdf", - "createdAt": "2024-01-10T08:00:00Z" - } - ] - } - ], - "timing": 156, - "total": 1 -} - -``` - -The `/v4/search` endpoint searches through and returns memories. With `searchMode="hybrid"`, it can also return document chunks when memories aren't found, providing comprehensive search coverage. - -## Direct Document Retrieval - -If you don't need semantic search and just want to retrieve a specific document you've uploaded by its ID, use the GET document endpoint: - -`GET /v3/documents/{id}` - -This is useful when: -- You know the exact document ID -- You want to retrieve the full document content and metadata -- You need to check processing status or document details - - - -```typescript TypeScript -// Get a specific document by ID -const document = await client.documents.get("doc_abc123"); - -console.log(document.content); // Full document content -console.log(document.status); // Processing status -console.log(document.metadata); // Document metadata -console.log(document.summary); // AI-generated summary -``` - -```python Python -# Get a specific document by ID -document = client.documents.get("doc_abc123") - -print(document.content) # Full document content -print(document.status) # Processing status -``` - -```bash cURL -curl -X GET "https://api.supermemory.ai/v3/documents/{YOUR-DOCUMENT-ID}" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" -``` - - - - -This endpoint returns the complete document with all fields including content, metadata, containerTags, summary, and processing status. For more details, see the API Reference tab. - - -## Search Flow Architecture - -### Document Search (`/v3/search`) Flow - -```mermaid -graph TD - A[Query Input] --> B{Rewrite Query?} - B -->|Yes| C[Query Rewriting +400ms] - B -->|No| D[Generate Embeddings] - C --> E[Generate Rewritten Embeddings] - D --> F[Search Execution] - E --> F - F --> G[Apply Filtering
metadata, categories, containerTags] - G --> H{Rerank?} - H -->|Yes| I[Apply Reranking] - H -->|No| J[Build Results with Chunks] - I --> J - J --> K[Return Documents + Chunks + Scores] -``` - -### Memory Search (`/v4/search`) Flow - -```mermaid -graph TD - A[Query Input] --> B[Query Rewriting + Embedding] - B --> C[Parallel Search Execution] - C --> D[Apply Filtering] - D --> E[Merge Results] - E --> F[Deduplication] - F --> G{Rerank?} - G -->|Yes| H[Apply Reranking] - G -->|No| I[Return Memories + Similarity] - H --> I -``` - -## Key Concepts You Need to Understand - -### 1. Thresholds (Sensitivity Control) - -Thresholds control result quality vs quantity: - -- **0.0** = Least sensitive (more results, lower quality) -- **1.0** = Most sensitive (fewer results, higher quality) - -```typescript -// Different threshold strategies -const broadSearch = await client.search.documents({ - q: "machine learning", - chunkThreshold: 0.2, // Return more chunks - documentThreshold: 0.1 // From more documents -}); - -const preciseSearch = await client.search.documents({ - q: "machine learning", - chunkThreshold: 0.8, // Only highly relevant chunks - documentThreshold: 0.7 // From closely matching documents -}); -``` - -### 2. Chunk Context vs Exact Matching - -By default, Supermemory returns chunks **with context** (surrounding text): - -```typescript -// Default: includes surrounding chunks for context -const contextualResults = await client.search.documents({ - q: "neural networks", - onlyMatchingChunks: false // Default -}); - -// Precise: only the exact matching text -const exactResults = await client.search.documents({ - q: "neural networks", - onlyMatchingChunks: true -}); -``` - -### 3. Query Rewriting & Reranking - -**Query Rewriting** (+400ms latency): -- Expands your query to find more relevant results -- "ML" becomes "machine learning artificial intelligence" -- Useful for abbreviations and domain-specific terms - -**Reranking**: -- Re-scores results using a different algorithm -- More accurate but slower -- Recommended for critical searches - -### 4. Container Tags vs Metadata Filters - -Two different filtering mechanisms: - -When to use container tags: - - The user understanding graph is built on top of container tags. **The graph is formed on top of container tags.** - - Container tags are used for organizational grouping and exact matching. - - They are useful for categorizing content and ensuring precise results. -When to use metadata filters: - - When you need flexible conditions beyond exact matches. - - Useful for filtering by attributes like date, author, or category. - -```typescript -// Container tags: Organizational grouping (exact array matching) -const userContent = await client.search.documents({ - q: "python tutorial", - containerTag "user_123" // Must match exactly -}); - -// Metadata filters: SQL-based queries (flexible conditions) -const filteredContent = await client.search.documents({ - q: "python tutorial", - filters: JSON.stringify({ - AND: [ - { key: "language", value: "python", negate: false }, - { key: "difficulty", value: "beginner", negate: false } - ] - }) -}); -``` diff --git a/apps/docs/search/parameters.mdx b/apps/docs/search/parameters.mdx deleted file mode 100644 index f9df18da..00000000 --- a/apps/docs/search/parameters.mdx +++ /dev/null @@ -1,264 +0,0 @@ ---- -title: "Search Parameters" -description: "Complete reference for all search parameters and their effects" ---- - - -Complete parameter reference for all three search endpoints: document search, memory search, and execute search. - -## Common Parameters - -These parameters work across all search endpoints: - - - **Search query string** - - The text you want to search for. Can be natural language, keywords, or questions. - - ```typescript - q: "machine learning neural networks" - q: "What are the applications of quantum computing?" - q: "python tutorial beginner" - ``` - - - - **Maximum number of results to return** - - Controls how many results you get back. Higher limits increase response time and size. - - ```typescript - limit: 5 // Fast, focused results - limit: 20 // Comprehensive results - limit: 100 // Maximum recommended - ``` - - - - **Filter by container tags** - - Organizational tags for filtering results. Uses **exact array matching** - must match all tags in the same order. - - ```typescript - containerTags: ["user_123"] // Single tag - containerTags: ["user_123", "project_ai"] // Multiple tags (exact match) - ``` - - - - **Metadata filtering with SQL-like structure** - - JSON string containing AND/OR logic for filtering by metadata fields. Uses the same structure as memory listing filters. - - ```typescript - filters: JSON.stringify({ - AND: [ - { key: "category", value: "tutorial", negate: false }, - { key: "difficulty", value: "beginner", negate: false } - ] - }) - ``` - - - See [Metadata Filtering Guide](/concepts/filtering) for complete syntax and examples. - - - - - **Re-score results for better relevance** - - Applies a secondary ranking algorithm to improve result quality. Adds ~100-200ms latency but increases accuracy. - - ```typescript - rerank: true // Better accuracy, slower - rerank: false // Faster, standard accuracy - ``` - - - - **Expand and improve the query** - - Rewrites your query to find more relevant results. Particularly useful for abbreviations and domain-specific terms. **Adds ~400ms latency**. - - ```typescript - // Query rewriting examples: - "ML" → "machine learning artificial intelligence" - "JS" → "JavaScript programming language" - "API" → "application programming interface REST" - ``` - - - Query rewriting significantly increases latency. Only use when search quality is more important than speed. - - - -## Document Search Parameters (POST `/v3/search`) - -These parameters are specific to `client.search.documents()`: - - - **Sensitivity for chunk selection** - - Controls which text chunks are included in results: - - **0.0** = Least sensitive (more chunks, more results) - - **1.0** = Most sensitive (fewer chunks, higher quality) - - ```typescript - chunkThreshold: 0.2 // Broad search, many chunks - chunkThreshold: 0.8 // Precise search, only relevant chunks - ``` - - - - **Sensitivity for document selection** - - Controls which documents are considered for search: - - **0.0** = Search more documents (comprehensive) - - **1.0** = Search only highly relevant documents (focused) - - ```typescript - documentThreshold: 0.1 // Cast wide net - documentThreshold: 0.9 // Only very relevant documents - ``` - - - - **Search within a specific document** - - Limit search to chunks within a single document. Useful for finding content in large documents. - - ```typescript - docId: "doc_abc123" // Only search this document - ``` - - - - **Return only exact matching chunks** - - By default, Supermemory includes surrounding chunks for context. Set to `true` to get only the exact matching text. - - ```typescript - onlyMatchingChunks: false // Include context chunks (default) - onlyMatchingChunks: true // Only matching chunks - ``` - - - Context chunks help LLMs understand the full meaning. Only disable if you need precise text extraction. - - - - - **Include complete document content** - - Adds the full document text to each result. Useful for chatbots that need complete context. - - ```typescript - includeFullDocs: true // Full document in response - includeFullDocs: false // Only chunks and metadata - ``` - - - Including full documents can make responses very large. Use sparingly and with appropriate limits. - - - - - **Include document summaries** - - Adds AI-generated document summaries to results. Good middle-ground between chunks and full documents. - - ```typescript - includeSummary: true // Include document summaries - includeSummary: false // No summaries - ``` - - - - **Filter by metadata using SQL queries** - - ```typescript - - // Use this instead: - filters: JSON.stringify({ - OR: [ - { key: "category", value: "technology", negate: false }, - { key: "category", value: "science", negate: false } - ] - }) - ``` - - -## Memory Search Parameters (POST `/v4/search`) - -These parameters are specific to `client.search.memories()`: - - - **Sensitivity for memory selection** - - Controls which memories are returned based on similarity: - - **0.0** = Return more memories (broad search) - - **1.0** = Return only highly similar memories (precise search) - - ```typescript - threshold: 0.3 // Broader memory search - threshold: 0.8 // Only very similar memories - ``` - - - - **Search mode - memories only or hybrid search** - - Controls whether to search only memories or also include document chunks: - - **`"memories"`** (default): Searches only memory entries. Returns results with `memory` field. - - **`"hybrid"`**: Searches memories first, then falls back to document chunks if needed. Returns mixed results with either `memory` field (for memory results) or `chunk` field (for chunk results). - - - In hybrid mode, results are automatically merged and deduplicated. Results contain objects with either a `memory` key (for memory results) or a `chunk` key (for chunk results from document search). - - - ```typescript - searchMode: "memories" // Only search memories (default) - searchMode: "hybrid" // Search memories + fallback to chunks - ``` - - **When to use hybrid mode:** - - When you want comprehensive search across both memories and documents - - When memories might not exist for certain queries but document content is available - - When you need the flexibility to get either memory or document chunk results - - - - **Filter by single container tag** - - Note: Memory search uses `containerTag` (singular) while document search uses `containerTags` (plural array). - - ```typescript - containerTag: "user_123" // Single tag for memory search - ``` - - - - **Control what additional data to include** - - Object specifying what contextual information to include with memory results. - - - Include associated documents for each memory - - - - Include parent and child memories (contextual relationships) - - - - Include memory summaries - - - ```typescript - include: { - documents: true, // Show related documents - relatedMemories: true, // Show parent/child memories - summaries: true // Include summaries - } - ``` - diff --git a/apps/docs/search/query-rewriting.mdx b/apps/docs/search/query-rewriting.mdx deleted file mode 100644 index 114af692..00000000 --- a/apps/docs/search/query-rewriting.mdx +++ /dev/null @@ -1,440 +0,0 @@ ---- -title: "Query Rewriting" -description: "Improve search accuracy with automatic query expansion and rewriting" ---- - - -![query rewriting](/images/query-rewriting.png) - -Query rewriting automatically generates multiple variations of your search query to improve result coverage and accuracy. Supermemory creates several rewrites, searches through all of them, then merges and deduplicates the results. - -## How Query Rewriting Works - -When you enable `rewriteQuery: true`, Supermemory: - -1. **Analyzes your original query** for intent and key concepts -2. **Generates multiple rewrites** with different phrasings and synonyms -3. **Executes searches** for both original and rewritten queries in parallel -4. **Merges and deduplicates** results from all queries -5. **Returns unified results** ranked by relevance - -This process adds ~400ms latency but significantly improves result quality, especially for: -- **Natural language questions** ("How do neural networks learn?") -- **Ambiguous terms** that could have multiple meanings -- **Complex queries** with multiple concepts -- **Domain-specific terminology** that might have synonyms - -## Basic Query Rewriting - - - - ```typescript - import Supermemory from 'supermemory'; - - const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! - }); - - // Without query rewriting - const basicResults = await client.search.documents({ - q: "How do transformers work in AI?", - rewriteQuery: false, - limit: 5 - }); - - // With query rewriting - generates multiple query variations - const rewrittenResults = await client.search.documents({ - q: "How do transformers work in AI?", - rewriteQuery: true, - limit: 5 - }); - - console.log(`Basic search: ${basicResults.total} results`); - console.log(`Rewritten search: ${rewrittenResults.total} results`); - ``` - - - ```python - from supermemory import Supermemory - import os - - client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - - # Without query rewriting - basic_results = client.search.documents( - q="How do transformers work in AI?", - rewrite_query=False, - limit=5 - ) - - # With query rewriting - generates multiple query variations - rewritten_results = client.search.documents( - q="How do transformers work in AI?", - rewrite_query=True, - limit=5 - ) - - print(f"Basic search: {basic_results.total} results") - print(f"Rewritten search: {rewritten_results.total} results") - ``` - - - ```bash - # Without query rewriting - echo "Basic search:" - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "How do transformers work in AI?", - "rewriteQuery": false, - "limit": 5 - }' | jq '.total' - - # With query rewriting - echo "Rewritten search:" - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "How do transformers work in AI?", - "rewriteQuery": true, - "limit": 5 - }' | jq '.total' - ``` - - - -**Sample Output Comparison:** -```json -// Without rewriting: 3 results -{ - "results": [...], - "total": 3, - "timing": 120 -} - -// With rewriting: 8 results (found more relevant content) -{ - "results": [...], - "total": 8, - "timing": 520 // +400ms for query processing -} -``` - -## Natural Language Questions - -Query rewriting excels at converting conversational questions into effective search queries: - - - - ```typescript - // Natural language question - const results = await client.search.documents({ - q: "What are the best practices for training deep learning models?", - rewriteQuery: true, - limit: 10 - }); - - // The system might generate rewrites like: - // - "deep learning model training best practices" - // - "neural network training optimization techniques" - // - "machine learning model training guidelines" - // - "deep learning training methodology" - ``` - - - ```python - # Natural language question - results = client.search.documents( - q="What are the best practices for training deep learning models?", - rewrite_query=True, - limit=10 - ) - - # The system might generate rewrites like: - # - "deep learning model training best practices" - # - "neural network training optimization techniques" - # - "machine learning model training guidelines" - # - "deep learning training methodology" - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "What are the best practices for training deep learning models?", - "rewriteQuery": true, - "limit": 10 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "documentId": "doc_123", - "title": "Deep Learning Training Guide", - "score": 0.92, - "chunks": [ - { - "content": "Best practices for training deep neural networks include proper weight initialization, learning rate scheduling, and regularization techniques...", - "score": 0.89, - "isRelevant": true - } - ] - }, - { - "documentId": "doc_456", - "title": "Neural Network Optimization", - "score": 0.87, - "chunks": [ - { - "content": "Effective training methodologies involve batch normalization, dropout, and gradient clipping to prevent overfitting...", - "score": 0.85, - "isRelevant": true - } - ] - } - ], - "total": 12, - "timing": 445 -} -``` - -## Technical Term Expansion - -Query rewriting helps find content using different technical terminologies: - - - - ```typescript - // Original query with specific terminology - const results = await client.search.documents({ - q: "CNN architecture patterns", - rewriteQuery: true, - containerTags: ["research"], - limit: 8 - }); - - // System expands to include: - // - "convolutional neural network architecture" - // - "CNN design patterns" - // - "convolutional network structures" - // - "CNN architectural components" - ``` - - - ```python - # Original query with specific terminology - results = client.search.documents( - q="CNN architecture patterns", - rewrite_query=True, - container_tags=["research"], - limit=8 - ) - - # System expands to include: - # - "convolutional neural network architecture" - # - "CNN design patterns" - # - "convolutional network structures" - # - "CNN architectural components" - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "CNN architecture patterns", - "rewriteQuery": true, - "containerTags": ["research"], - "limit": 8 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "documentId": "doc_789", - "title": "Convolutional Neural Network Architectures", - "score": 0.94, - "chunks": [ - { - "content": "Modern CNN architectures like ResNet and DenseNet utilize skip connections to address the vanishing gradient problem...", - "score": 0.91, - "isRelevant": true - } - ] - }, - { - "documentId": "doc_101", - "title": "Deep Learning Design Patterns", - "score": 0.88, - "chunks": [ - { - "content": "Convolutional layers followed by pooling operations form the fundamental building blocks of CNN architectures...", - "score": 0.86, - "isRelevant": true - } - ] - } - ], - "total": 15, - "timing": 478 -} -``` - -## Memory Search with Query Rewriting - -Query rewriting works with both document and memory search: - - - - ```typescript - // Memory search with query rewriting - const memoryResults = await client.search.memories({ - q: "explain quantum entanglement simply", - rewriteQuery: true, - containerTag: "physics_notes", - limit: 5 - }); - - // Generates variations like: - // - "quantum entanglement explanation" - // - "what is quantum entanglement" - // - "quantum entanglement basics" - // - "simple quantum entanglement description" - ``` - - - ```python - # Memory search with query rewriting - memory_results = client.search.memories( - q="explain quantum entanglement simply", - rewrite_query=True, - container_tag="physics_notes", - limit=5 - ) - - # Generates variations like: - # - "quantum entanglement explanation" - # - "what is quantum entanglement" - # - "quantum entanglement basics" - # - "simple quantum entanglement description" - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "explain quantum entanglement simply", - "rewriteQuery": true, - "containerTag": "physics_notes", - "limit": 5 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "id": "mem_456", - "memory": "Quantum entanglement is a phenomenon where two particles become connected in such a way that measuring one instantly affects the other, regardless of distance. Think of it like having two magical coins that always land on opposite sides.", - "similarity": 0.91, - "title": "Simple Quantum Entanglement Explanation", - "metadata": { - "topic": "quantum-physics", - "difficulty": "beginner" - } - }, - { - "id": "mem_789", - "memory": "Einstein called quantum entanglement 'spooky action at a distance' because entangled particles seem to communicate instantaneously across vast distances, challenging our understanding of locality in physics.", - "similarity": 0.87, - "title": "Einstein's View on Entanglement" - } - ], - "total": 7, - "timing": 412 -} -``` - -## Complex Multi-Concept Queries - -Query rewriting excels at handling queries with multiple concepts: - - - - ```typescript - const results = await client.search.documents({ - q: "machine learning bias fairness algorithmic discrimination", - rewriteQuery: true, - filters: { - AND: [ - { key: "category", value: "ethics", negate: false } - ] - }, - limit: 10 - }); - - // Breaks down into focused rewrites: - // - "machine learning bias detection" - // - "algorithmic fairness in AI" - // - "discrimination in machine learning algorithms" - // - "bias mitigation techniques ML" - ``` - - - ```python - results = client.search.documents( - q="machine learning bias fairness algorithmic discrimination", - rewrite_query=True, - filters={ - "AND": [ - {"key": "category", "value": "ethics", "negate": False} - ] - }, - limit=10 - ) - - # Breaks down into focused rewrites: - # - "machine learning bias detection" - # - "algorithmic fairness in AI" - # - "discrimination in machine learning algorithms" - # - "bias mitigation techniques ML" - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "machine learning bias fairness algorithmic discrimination", - "rewriteQuery": true, - "filters": { - "AND": [ - {"key": "category", "value": "ethics", "negate": false} - ] - }, - "limit": 10 - }' - ``` - - diff --git a/apps/docs/search/reranking.mdx b/apps/docs/search/reranking.mdx deleted file mode 100644 index 7d2e017a..00000000 --- a/apps/docs/search/reranking.mdx +++ /dev/null @@ -1,387 +0,0 @@ ---- -title: "Reranking" -description: "Improve result relevance with secondary ranking algorithms" ---- - - -Reranking applies a secondary ranking algorithm to improve the relevance order of search results. After the initial search returns results, the reranker analyzes the relationship between your query and each result to provide better ordering. - -## How Reranking Works - -Supermemory's reranking process: - -1. **Initial search** returns results using standard semantic similarity -2. **Reranker model** analyzes query-result pairs -3. **Scores are recalculated** based on deeper semantic understanding -4. **Results are reordered** by the new relevance scores -5. **Final results** maintain the same structure but with improved ordering - -The reranker is particularly effective at: -- **Understanding context** and nuanced relationships -- **Handling ambiguous queries** with multiple possible meanings -- **Improving precision** for complex technical topics -- **Better ranking** when results have similar initial scores - -## Basic Reranking Comparison - - - - ```typescript - import Supermemory from 'supermemory'; - - const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! - }); - - // Search without reranking - const standardResults = await client.search.documents({ - q: "neural network optimization techniques", - rerank: false, - limit: 5 - }); - - // Search with reranking - const rerankedResults = await client.search.documents({ - q: "neural network optimization techniques", - rerank: true, - limit: 5 - }); - - console.log("Standard top result:", standardResults.results[0].score); - console.log("Reranked top result:", rerankedResults.results[0].score); - ``` - - - ```python - from supermemory import Supermemory - import os - - client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - - # Search without reranking - standard_results = client.search.documents( - q="neural network optimization techniques", - rerank=False, - limit=5 - ) - - # Search with reranking - reranked_results = client.search.documents( - q="neural network optimization techniques", - rerank=True, - limit=5 - ) - - print("Standard top result:", standard_results.results[0].score) - print("Reranked top result:", reranked_results.results[0].score) - ``` - - - ```bash - # Without reranking - echo "Standard ranking:" - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "neural network optimization techniques", - "rerank": false, - "limit": 3 - }' | jq '.results[0] | {title, score}' - - # With reranking - echo "Reranked results:" - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "neural network optimization techniques", - "rerank": true, - "limit": 3 - }' | jq '.results[0] | {title, score}' - ``` - - - -**Sample Output Comparison:** - -```json -// Without reranking - results ordered by semantic similarity -{ - "results": [ - { - "title": "Deep Learning Optimization Methods", - "score": 0.82, - "chunks": [ - { - "content": "Various optimization algorithms like Adam, RMSprop, and SGD are used in neural network training...", - "score": 0.79 - } - ] - }, - { - "title": "Neural Network Training Techniques", - "score": 0.81, - "chunks": [ - { - "content": "Batch normalization and dropout are common regularization techniques for neural networks...", - "score": 0.78 - } - ] - } - ], - "timing": 145 -} - -// With reranking - results reordered by contextual relevance -{ - "results": [ - { - "title": "Neural Network Training Techniques", - "score": 0.89, // Boosted by reranker - "chunks": [ - { - "content": "Batch normalization and dropout are common regularization techniques for neural networks...", - "score": 0.85 - } - ] - }, - { - "title": "Deep Learning Optimization Methods", - "score": 0.86, // Slightly adjusted - "chunks": [ - { - "content": "Various optimization algorithms like Adam, RMSprop, and SGD are used in neural network training...", - "score": 0.83 - } - ] - } - ], - "timing": 267 // Additional ~120ms for reranking -} -``` - -## Complex Query Reranking - -Reranking excels with complex, multi-faceted queries: - - - - ```typescript - const results = await client.search.documents({ - q: "sustainable machine learning carbon footprint energy efficiency", - rerank: true, - containerTags: ["research", "sustainability"], - limit: 8 - }); - - // Reranker understands the connection between: - // - Machine learning computational costs - // - Environmental impact of AI training - // - Energy-efficient model architectures - // - Green computing practices in ML - ``` - - - ```python - results = client.search.documents( - q="sustainable machine learning carbon footprint energy efficiency", - rerank=True, - container_tags=["research", "sustainability"], - limit=8 - ) - - # Reranker understands the connection between: - # - Machine learning computational costs - # - Environmental impact of AI training - # - Energy-efficient model architectures - # - Green computing practices in ML - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "sustainable machine learning carbon footprint energy efficiency", - "rerank": true, - "containerTags": ["research", "sustainability"], - "limit": 8 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "documentId": "doc_green_ai", - "title": "Green AI: Reducing the Carbon Footprint of Machine Learning", - "score": 0.94, // Highly relevant after reranking - "chunks": [ - { - "content": "Training large neural networks can consume as much energy as several cars over their lifetime. Sustainable ML practices focus on model efficiency, pruning, and quantization to reduce computational demands...", - "score": 0.92, - "isRelevant": true - } - ] - }, - { - "documentId": "doc_efficient_models", - "title": "Energy-Efficient Neural Network Architectures", - "score": 0.91, // Boosted for strong topical relevance - "chunks": [ - { - "content": "MobileNets and EfficientNets are designed specifically for energy-constrained environments, achieving high accuracy with minimal computational overhead...", - "score": 0.88, - "isRelevant": true - } - ] - } - ], - "total": 12, - "timing": 298 -} -``` - -## Memory Search Reranking - -Reranking also improves memory search results: - - - - ```typescript - const memoryResults = await client.search.memories({ - q: "explain transformer architecture attention mechanism", - rerank: true, - containerTag: "ai_notes", - threshold: 0.6, - limit: 5 - }); - - // Reranker identifies memories that best explain - // the relationship between transformers and attention - ``` - - - ```python - memory_results = client.search.memories( - q="explain transformer architecture attention mechanism", - rerank=True, - container_tag="ai_notes", - threshold=0.6, - limit=5 - ) - - # Reranker identifies memories that best explain - # the relationship between transformers and attention - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v4/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "explain transformer architecture attention mechanism", - "rerank": true, - "containerTag": "ai_notes", - "threshold": 0.6, - "limit": 5 - }' - ``` - - - -**Sample Output:** -```json -{ - "results": [ - { - "id": "mem_transformer_intro", - "memory": "The transformer architecture revolutionized NLP by replacing recurrent layers with self-attention mechanisms. The attention mechanism allows the model to focus on different parts of the input sequence when processing each token, enabling parallel processing and better long-range dependency modeling.", - "similarity": 0.93, // Reranked higher for comprehensive explanation - "title": "Transformer Architecture Overview", - "metadata": { - "topic": "deep-learning", - "subtopic": "transformers" - } - }, - { - "id": "mem_attention_detail", - "memory": "Self-attention computes attention weights by taking dot products between query, key, and value vectors derived from the input embeddings. This allows each position to attend to all positions in the previous layer, capturing complex relationships in the data.", - "similarity": 0.91, // Boosted for technical detail - "title": "Self-Attention Mechanism Details" - } - ], - "total": 8, - "timing": 198 -} -``` - -## Domain-Specific Reranking - -Reranking understands domain-specific relationships: - - - - ```typescript - // Medical domain query - const medicalResults = await client.search.documents({ - q: "diabetes treatment insulin resistance metformin", - rerank: true, - filters: { - AND: [ - { key: "domain", value: "medical", negate: false } - ] - }, - limit: 10 - }); - - // Reranker understands medical relationships: - // - Diabetes types and treatments - // - Insulin resistance mechanisms - // - Metformin's role in diabetes management - ``` - - - ```python - # Medical domain query - medical_results = client.search.documents( - q="diabetes treatment insulin resistance metformin", - rerank=True, - filters={ - "AND": [ - {"key": "domain", "value": "medical", "negate": False} - ] - }, - limit=10 - ) - - # Reranker understands medical relationships: - # - Diabetes types and treatments - # - Insulin resistance mechanisms - # - Metformin's role in diabetes management - ``` - - - ```bash - curl -X POST "https://api.supermemory.ai/v3/search" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "q": "diabetes treatment insulin resistance metformin", - "rerank": true, - "filters": { - "AND": [ - {"key": "domain", "value": "medical", "negate": false} - ] - }, - "limit": 10 - }' - ``` - - diff --git a/apps/docs/search/response-schema.mdx b/apps/docs/search/response-schema.mdx deleted file mode 100644 index b4f43ff4..00000000 --- a/apps/docs/search/response-schema.mdx +++ /dev/null @@ -1,354 +0,0 @@ ---- -title: "Response Schema" -description: "Complete response structure for all search endpoints with scoring details" ---- - - -## Document Search Response (POST `/v3/search`) - -Response from `client.search.documents()` and `client.search.execute()`: - -```json -{ - "results": [ - { - "documentId": "doc_abc123", - "title": "Machine Learning Fundamentals", - "type": "pdf", - "score": 0.89, - "chunks": [ - { - "content": "Machine learning is a subset of artificial intelligence...", - "score": 0.95, - "isRelevant": true - } - ], - "metadata": { - "category": "education", - "author": "Dr. Smith", - "difficulty": "beginner" - }, - "createdAt": "2024-01-15T10:30:00Z", - "updatedAt": "2024-01-20T14:45:00Z" - } - ], - "timing": 187, - "total": 1 -} -``` - -### Document Result Fields - - - Unique identifier for the document containing the matching chunks. - - - - Document title if available. May be null for documents without titles. - - - - Document type (e.g., "pdf", "text", "webpage", "notion_doc"). May be null if not specified. - - - - **Overall document relevance score**. Combines semantic similarity, keyword matching, and metadata relevance. - - - **0.9-1.0**: Extremely relevant - - **0.7-0.9**: Highly relevant - - **0.5-0.7**: Moderately relevant - - **0.3-0.5**: Somewhat relevant - - **0.0-0.3**: Marginally relevant - - - - Array of matching text chunks from the document. Each chunk represents a portion of the document that matched your query. - - - The actual text content of the matching chunk. May include context from surrounding chunks unless `onlyMatchingChunks=true`. - - - - **Chunk-specific similarity score**. How well this specific chunk matches your query. - - - - Whether this chunk passed the `chunkThreshold`. `true` means the chunk is above the threshold, `false` means it's included for context only. - - - - - Document metadata as key-value pairs. Structure depends on what was stored with the document. - - ```json - { - "category": "tutorial", - "language": "python", - "difficulty": "intermediate", - "tags": "web-development,backend" - } - ``` - - - - ISO 8601 timestamp when the document was created. - - - - ISO 8601 timestamp when the document was last updated. - - - - **Full document content**. Only included when `includeFullDocs=true`. Can be very large. - - - Full document content can make responses extremely large. Use with appropriate limits and only when necessary. - - - - - **AI-generated document summary**. Only included when `includeSummary=true`. Provides a concise overview of the document. - - -## Memory Search Response - -Response from `client.search.memories()`: - -When `searchMode="memories"` (default), all results are memory entries: - -```json -{ - "results": [ - { - "id": "mem_xyz789", - "memory": "Complete memory content about quantum computing applications...", - "similarity": 0.87, - "metadata": { - "category": "research", - "topic": "quantum-computing" - }, - "updatedAt": "2024-01-18T09:15:00Z", - "version": 3, - "context": { - "parents": [ - { - "memory": "Earlier discussion about quantum theory basics...", - "relation": "extends", - "version": 2, - "updatedAt": "2024-01-17T16:30:00Z" - } - ], - "children": [ - { - "memory": "Follow-up questions about quantum algorithms...", - "relation": "derives", - "version": 4, - "updatedAt": "2024-01-19T11:20:00Z" - } - ] - }, - "documents": [ - { - "id": "doc_quantum_paper", - "title": "Quantum Computing Applications", - "type": "pdf", - "createdAt": "2024-01-10T08:00:00Z" - } - ] - } - ], - "timing": 156, - "total": 1 -} -``` - -When `searchMode="hybrid"`, results can contain both memory entries and document chunks. **Memory results have a `memory` key, chunk results have a `chunk` key:** - -```json -{ - "results": [ - { - "id": "mem_xyz789", - "memory": "Complete memory content about quantum computing applications...", - "similarity": 0.87, - "metadata": { - "category": "research", - "topic": "quantum-computing" - }, - "updatedAt": "2024-01-18T09:15:00Z", - "version": 3, - "context": { - "parents": [], - "children": [] - }, - "documents": [ - { - "id": "doc_quantum_paper", - "title": "Quantum Computing Applications", - "type": "pdf", - "createdAt": "2024-01-10T08:00:00Z", - "updatedAt": "2024-01-10T08:00:00Z" - } - ] - }, - { - "id": "chunk_abc123", - "chunk": "This is a chunk of content from a document about quantum computing...", - "similarity": 0.82, - "metadata": { - "category": "research", - "source": "document" - }, - "updatedAt": "2024-01-15T10:30:00Z", - "version": 1, - "context": { - "parents": [], - "children": [] - }, - "documents": [ - { - "id": "doc_quantum_research", - "title": "Quantum Computing Research Paper", - "type": "pdf", - "metadata": { - "author": "Dr. Smith" - }, - "createdAt": "2024-01-15T10:30:00Z", - "updatedAt": "2024-01-15T10:30:00Z" - } - ] - } - ], - "timing": 198, - "total": 2 -} -``` - - - **Distinguishing Memory vs Chunk Results:** - - In hybrid mode, check which key exists on the result object: - - **Memory results**: Have a `memory` key (no `chunk` key) - - **Chunk results**: Have a `chunk` key (no `memory` key) - - ```typescript - // TypeScript example - results.results.forEach(result => { - if ('memory' in result) { - // This is a memory result - console.log('Memory:', result.memory); - } else if ('chunk' in result) { - // This is a chunk result - console.log('Chunk:', result.chunk); - } - }); - ``` - - -### Memory Result Fields - - - Unique identifier for the memory entry or chunk ID. In hybrid mode, can be either a memory ID (e.g., `mem_xyz789`) or a chunk ID (e.g., `chunk_abc123`). - - - - **Complete memory content**. Only present for memory results (when `searchMode="memories"` or when a memory result is returned in hybrid mode). This field is not present for chunk results. - - - - **Chunk content from a document**. Only present for chunk results when `searchMode="hybrid"`. This field is not present for memory results. Contains the actual text content from the document chunk. - - - - **Similarity score** between your query and this memory. Higher scores indicate better matches. - - - **0.9-1.0**: Extremely similar - - **0.8-0.9**: Very similar - - **0.7-0.8**: Similar - - **0.6-0.7**: Somewhat similar - - **0.5-0.6**: Marginally similar - - - - Memory metadata as key-value pairs. Structure depends on what was stored with the memory. - - - - ISO 8601 timestamp when the memory was last updated. - - - - Version number of this memory entry. Used for tracking memory evolution and relationships. For chunk results, this is typically `1`. - - - - Root memory ID for memory entries. Only present for memory results. Always `null` for chunk results. - - - - **Contextual memory relationships**. Only included when `include.relatedMemories=true`. - - - Array of parent memories that this memory extends or derives from. - - - - Array of child memories that extend or derive from this memory. - - - ### Context Memory Structure - - - Content of the related memory. - - - - Relationship type: `"updates"`, `"extends"`, or `"derives"`. - - - **updates**: This memory updates/replaces the related memory - - **extends**: This memory builds upon the related memory - - **derives**: This memory is derived from the related memory - - - - Relative version distance: - - **Negative values** for parents (-1 = direct parent, -2 = grandparent) - - **Positive values** for children (+1 = direct child, +2 = grandchild) - - - - When the related memory was last updated. - - - - Metadata of the related memory. - - - - - **Associated documents**. Only included when `include.documents=true`. - - - Document identifier. - - - - Document title. - - - - Document type. - - - - Document metadata. - - - - Document creation timestamp. - - - - Document update timestamp. - - diff --git a/apps/docs/update-delete-memories/overview.mdx b/apps/docs/update-delete-memories/overview.mdx deleted file mode 100644 index 033f6c33..00000000 --- a/apps/docs/update-delete-memories/overview.mdx +++ /dev/null @@ -1,523 +0,0 @@ ---- -title: "Update & Delete Memories" -description: "Safely update and delete memories with upsert patterns and idempotency" -icon: "delete" ---- - -Choose from direct updates, idempotent upserts, single deletions, and powerful bulk operations. - -## Direct Updates - -Update existing memories by their ID when you know the specific memory you want to modify. - -- **Content changes** — Trigger full reprocessing (reindexing) through the pipeline. Response status is `"queued"`. -- **Metadata-only changes** — Update the document row only; no reindexing. Response status stays `"done"`. Use this when updating fields like `accepted`, `version`, or other filter metadata without changing the document content. - - - -```typescript Typescript -import Supermemory from 'supermemory'; - -const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! -}); - -// Update by memory ID -const updated = await client.documents.update('memory_id_123', { - content: 'Updated content here', - metadata: { version: 2, updated: true } -}); - -console.log(updated.status); // "queued" when content changed; "done" when metadata-only -console.log(updated.id); // "memory_id_123" -``` - -```python Python -from supermemory import Supermemory -import os - -client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - -# Update by memory ID -updated = client.documents.update( - 'memory_id_123', - content='Updated content here', - metadata={'version': 2, 'updated': True} -) - -print(f"Status: {updated.status}") # "queued" when content changed; "done" when metadata-only -print(f"ID: {updated.id}") # "memory_id_123" -``` - -```bash cURL -curl -X PATCH "https://api.supermemory.ai/v3/documents/memory_id_123" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "Updated content here", - "metadata": {"version": 2, "updated": true} - }' -``` - - - - -**Metadata-only updates:** If you omit `content` or send the same content and only change `metadata` (e.g. `accepted: false` → `accepted: true`), the document is updated in place with no reindexing. Works with both internal `id` and `customId`—no special setup required. - - -## Upserts Using customId - -Use `customId` for idempotent operations where the same `customId` with `add()` will update existing memory instead of creating duplicates. - - - -```typescript Typescript -import Supermemory from 'supermemory'; - -const client = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY! -}); - -const customId = 'user-note-001'; - -// First call creates memory -const created = await client.add({ - content: 'Initial content', - customId: customId, - metadata: { version: 1 } -}); - -console.log('Created memory:', created.id); - -// Second call with same customId updates existing -const updated = await client.add({ - content: 'Updated content', - customId: customId, // Same customId = upsert - metadata: { version: 2 } -}); -``` - -```python Python -from supermemory import Supermemory -import os - -client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY")) - -custom_id = 'user-note-001' - -# First call creates memory -created = client.add( - content='Initial content', - custom_id=custom_id, - metadata={'version': 1} -) - -print(f'Created memory: {created.id}') - -# Second call with same customId updates existing -updated = client.add( - content='Updated content', - custom_id=custom_id, # Same customId = upsert - metadata={'version': 2} -) - -print(f'Updated memory: {updated.id}') -print(f'Same memory? {created.id == updated.id}') # True -``` - -```bash cURL -# First call - creates memory -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "Initial content", - "customId": "user-note-001", - "metadata": {"version": 1} - }' - -# Response: {"id": "mem_abc123", "status": "queued", "customId": "user-note-001"} - -# Second call - updates existing (same customId) -curl -X POST "https://api.supermemory.ai/v3/documents" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "content": "Updated content", - "customId": "user-note-001", - "metadata": {"version": 2} - }' - -# Response: {"id": "mem_abc123", "status": "queued", "customId": "user-note-001"} -# Note: Same ID returned - memory was updated, not created -``` - - - - -The `customId` enables idempotency across all endpoints. The `memoryId` doesn't support idempotency, only the `customId` does. - - - - -The `customId` can have a maximum length of 100 characters. - - - -## Single Delete - -Delete individual memories by their ID. This is a permanent hard delete with no recovery mechanism. - - - -```typescript Typescript -// Hard delete - permanently removes memory -await client.documents.delete('memory_id_123'); -console.log('Memory deleted successfully'); -``` - -```python Python -# Hard delete - permanently removes memory -client.documents.delete('memory_id_123') -print('Memory deleted successfully') - -# Error handling for single delete -try: - client.documents.delete('memory_id_123') - print('Delete successful') -except NotFoundError: - print('Memory not found or already deleted') -except AuthenticationError: - print('Authentication failed') -except Exception as e: - print(f'Delete failed: {e}') -``` - -```bash cURL -curl -X DELETE "https://api.supermemory.ai/v3/documents/memory_id_123" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" - -# Response: 204 No Content (success) -# Response: 404 Not Found (memory doesn't exist) -``` - - - -## Bulk Delete by IDs - -Delete multiple memories at once by providing an array of memory IDs. Maximum of 100 IDs per request. - - - -```typescript Typescript -// Bulk delete by memory IDs -const result = await client.documents.deleteBulk({ - ids: [ - 'memory_id_1', - 'memory_id_2', - 'memory_id_3', - 'non_existent_id' // This will be reported in errors - ] -}); - -console.log('Bulk delete result:', result); -// Output: { -// success: true, -// deletedCount: 3, -// errors: [ -// { id: "non_existent_id", error: "Memory not found" } -// ] -// } -``` - -```python Python -# Bulk delete by memory IDs -result = client.documents.delete_bulk( - ids=[ - 'memory_id_1', - 'memory_id_2', - 'memory_id_3', - 'non_existent_id' # This will be reported in errors - ] -) - -print(f'Bulk delete result: {result}') -# Output: { -# 'success': True, -# 'deletedCount': 3, -# 'errors': [ -# {'id': 'non_existent_id', 'error': 'Memory not found'} -# ] -# } -``` - -```bash cURL -curl -X DELETE "https://api.supermemory.ai/v3/documents/bulk" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "ids": [ - "memory_id_1", - "memory_id_2", - "memory_id_3", - "non_existent_id" - ] - }' - -# Response: { -# "success": true, -# "deletedCount": 3, -# "errors": [ -# {"id": "non_existent_id", "error": "Memory not found"} -# ] -# } -``` - - - -## Bulk Delete by Container Tags - -Delete all memories within specific container tags. This is useful for cleaning up entire projects or user data. - - - -```typescript Typescript -// Delete all memories in specific container tags -const result = await client.documents.deleteBulk({ - containerTags: ['user-123', 'project-old', 'archived-content'] -}); - -console.log('Bulk delete by tags result:', result); -// Output: { -// success: true, -// deletedCount: 45, -// containerTags: ["user-123", "project-old", "archived-content"] -// } -``` - -```python Python -# Delete all memories in specific container tags -result = client.documents.delete_bulk( - container_tags=['user-123', 'project-old', 'archived-content'] -) - -print(f'Bulk delete by tags result: {result}') -# Output: { -# 'success': True, -# 'deletedCount': 45, -# 'containerTags': ['user-123', 'project-old', 'archived-content'] -# } -``` - -```bash cURL -curl -X DELETE "https://api.supermemory.ai/v3/documents/bulk" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "containerTags": ["user-123", "project-old", "archived-content"] - }' - -# Response: { -# "success": true, -# "deletedCount": 45, -# "containerTags": ["user-123", "project-old", "archived-content"] -# } -``` - - - -## Advanced Patterns - -### Soft Delete Implementation - -For applications requiring audit trails or recovery mechanisms, implement soft delete patterns using metadata: - - - -```typescript Typescript -// Soft delete pattern using metadata -await client.documents.update('memory_id', { - metadata: { - deleted: true, - deletedAt: new Date().toISOString(), - deletedBy: 'user_123' - } -}); - -// Filter out deleted memories in searches -const activeMemories = await client.documents.list({ - filters: { - AND: [ - { key: "deleted", value: "true", negate: true } - ] - } -}); - -console.log('Active memories:', activeMemories.memories.length); -``` - -```python Python -from datetime import datetime - -# Soft delete pattern using metadata -client.documents.update( - 'memory_id', - metadata={ - 'deleted': True, - 'deletedAt': datetime.now().isoformat(), - 'deletedBy': 'user_123' - } -) - -# Filter out deleted memories -active_memories = client.documents.list( - filters={ - "AND": [ - {"key": "deleted", "value": "true", "negate": True} - ] - } -) - -print(f'Active memories: {len(active_memories.memories)}') -``` - -```bash cURL -# Soft delete using metadata -curl -X PATCH "https://api.supermemory.ai/v3/documents/memory_id" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "metadata": { - "deleted": true, - "deletedAt": "2024-01-15T10:30:00Z", - "deletedBy": "user_123" - } - }' - -# Response: {"id": "memory_id", "status": "queued"} -``` - - - -### Batch Processing for Large Operations - - - -```typescript Typescript -// Batch delete large numbers of memories safely -async function batchDeleteMemories(memoryIds: string[], batchSize = 100) { - const results = []; - - for (let i = 0; i < memoryIds.length; i += batchSize) { - const batch = memoryIds.slice(i, i + batchSize); - - console.log(`Processing batch ${Math.floor(i/batchSize) + 1} of ${Math.ceil(memoryIds.length/batchSize)}`); - - try { - const result = await client.documents.deleteBulk({ ids: batch }); - results.push(result); - - // Brief delay between batches to avoid rate limiting - if (i + batchSize < memoryIds.length) { - await new Promise(resolve => setTimeout(resolve, 1000)); - } - } catch (error) { - console.error(`Batch ${Math.floor(i/batchSize) + 1} failed:`, error); - results.push({ success: false, error: error.message, batch }); - } - } - - // Aggregate results - const totalDeleted = results - .filter(r => r.success) - .reduce((sum, r) => sum + (r.deletedCount || 0), 0); - - console.log(`Total deleted: ${totalDeleted} out of ${memoryIds.length}`); - return { totalDeleted, results }; -} -``` - -```python Python -import time -import math - -def batch_delete_memories(memory_ids, batch_size=100): - """Batch delete large numbers of memories safely""" - results = [] - - for i in range(0, len(memory_ids), batch_size): - batch = memory_ids[i:i + batch_size] - batch_num = i // batch_size + 1 - total_batches = math.ceil(len(memory_ids) / batch_size) - - print(f'Processing batch {batch_num} of {total_batches}') - - try: - result = client.documents.delete_bulk(ids=batch) - results.append(result) - - # Brief delay between batches to avoid rate limiting - if i + batch_size < len(memory_ids): - time.sleep(1) - except Exception as error: - print(f'Batch {batch_num} failed: {error}') - results.append({'success': False, 'error': str(error), 'batch': batch}) - - # Aggregate results - total_deleted = sum( - r.get('deletedCount', 0) for r in results if r.get('success') - ) - - print(f'Total deleted: {total_deleted} out of {len(memory_ids)}') - return {'totalDeleted': total_deleted, 'results': results} -``` - -```bash cURL -# Batch processing script example -#!/bin/bash - -MEMORY_IDS=("id1" "id2" "id3") # Your memory IDs array -BATCH_SIZE=100 -TOTAL_DELETED=0 - -# Process in batches -for ((i=0; i<${#MEMORY_IDS[@]}; i+=BATCH_SIZE)); do - batch=("${MEMORY_IDS[@]:i:BATCH_SIZE}") - batch_json=$(printf '%s\n' "${batch[@]}" | jq -R . | jq -s .) - - echo "Processing batch $((i/BATCH_SIZE + 1))" - - response=$(curl -s -X DELETE \ - "https://api.supermemory.ai/v3/documents/bulk" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d "{\"ids\": $batch_json}") - - deleted_count=$(echo "$response" | jq -r '.deletedCount // 0') - TOTAL_DELETED=$((TOTAL_DELETED + deleted_count)) - - echo "Batch deleted: $deleted_count memories" - sleep 1 # Rate limiting protection -done - -echo "Total deleted: $TOTAL_DELETED memories" -``` - - - -## Best Practices - -### Update Operations - -1. **Use customId for idempotent updates** - Prevents duplicate memories and enables safe retries -2. **Monitor processing status** - Content changes trigger full reprocessing; metadata-only updates do not reindex -3. **Handle metadata carefully** - Updates replace specified metadata keys -4. **Implement proper error handling** - Memory may be deleted between operations - -### Delete Operations - -1. **Hard delete is permanent** - No recovery mechanism exists -2. **Use bulk operations efficiently** - Maximum 100 IDs per bulk delete request -3. **Consider soft delete patterns** - Use metadata flags for recoverable deletion -4. **Batch large operations** - Avoid rate limits with proper batching -5. **Clean up application state** - Update your UI/cache after deletions diff --git a/apps/docs/user-profiles.mdx b/apps/docs/user-profiles.mdx index cb5c7cd1..9687a28a 100644 --- a/apps/docs/user-profiles.mdx +++ b/apps/docs/user-profiles.mdx @@ -367,7 +367,7 @@ a vague one. `static` and `dynamic` are reserved and can't be used as bucket key import { openai } from "@ai-sdk/openai" // Profiles automatically injected - const model = withSupermemory(openai("gpt-4"), { + const model = withSupermemory(openai("gpt-4o"), { containerTag: "user-123", customId: "conv-1", }) diff --git a/apps/docs/user-profiles/api.mdx b/apps/docs/user-profiles/api.mdx deleted file mode 100644 index 7501e791..00000000 --- a/apps/docs/user-profiles/api.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: "Profile API" -description: "Endpoint details and response structure for user profiles" -sidebarTitle: "API Reference" -icon: "code" ---- - -## Endpoint - -**`POST /v4/profile`** - -Retrieves a user's profile, optionally combined with search results. - -## Request - -### Headers - -| Header | Required | Description | -|--------|----------|-------------| -| `Authorization` | Yes | Bearer token with your API key | -| `Content-Type` | Yes | `application/json` | - -### Body Parameters - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `containerTag` | string | Yes | The container tag (usually user ID) to get profiles for | -| `threshold` | float | No | Threshold for filtering search results. Only results with a score above this threshold will be included. | -| `q` | string | No | Optional search query to include search results with the profile | - -## Response - -```json -{ - "profile": { - "static": [ - "User is a software engineer", - "User specializes in Python and React", - "User prefers dark mode interfaces" - ], - "dynamic": [ - "User is working on Project Alpha", - "User recently started learning Rust", - "User is debugging authentication issues" - ] - }, - "searchResults": { - "results": [...], // Only if 'q' parameter was provided - "total": 15, - "timing": 45.2 - } -} -``` - -### Response Fields - -| Field | Type | Description | -|-------|------|-------------| -| `profile.static` | string[] | Long-term, stable facts about the user | -| `profile.dynamic` | string[] | Recent context and temporary information | -| `searchResults` | object | Only present if `q` parameter was provided | -| `searchResults.results` | array | Matching memory results | -| `searchResults.total` | number | Total number of matches | -| `searchResults.timing` | number | Query execution time in milliseconds | - -## Basic Request - - - -```typescript TypeScript -const response = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - containerTag: 'user_123' - }) -}); - -const data = await response.json(); - -console.log("Static facts:", data.profile.static); -console.log("Dynamic context:", data.profile.dynamic); -``` - -```python Python -import requests -import os - -response = requests.post( - 'https://api.supermemory.ai/v4/profile', - headers={ - 'Authorization': f'Bearer {os.getenv("SUPERMEMORY_API_KEY")}', - 'Content-Type': 'application/json' - }, - json={ - 'containerTag': 'user_123' - } -) - -data = response.json() - -print("Static facts:", data['profile']['static']) -print("Dynamic context:", data['profile']['dynamic']) -``` - -```bash cURL -curl -X POST https://api.supermemory.ai/v4/profile \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "containerTag": "user_123" - }' -``` - - - -## Profile with Search - -Include a search query to get both profile data and relevant memories in one call: - - - -```typescript TypeScript -const response = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - containerTag: 'user_123', - q: 'deployment errors yesterday' - }) -}); - -const data = await response.json(); - -// Profile data -const profile = data.profile; - -// Search results (only present because we passed 'q') -const searchResults = data.searchResults?.results || []; -``` - -```python Python -response = requests.post( - 'https://api.supermemory.ai/v4/profile', - headers={ - 'Authorization': f'Bearer {os.getenv("SUPERMEMORY_API_KEY")}', - 'Content-Type': 'application/json' - }, - json={ - 'containerTag': 'user_123', - 'q': 'deployment errors yesterday' - } -) - -data = response.json() - -profile = data['profile'] -search_results = data.get('searchResults', {}).get('results', []) -``` - - - -## Profile with Threshold - -Use the optional `threshold` parameter to filter search results by relevance score: - - - -```typescript TypeScript -const response = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - containerTag: 'user_123', - threshold: 0.7, // Only include results with score > 0.7 - q: 'deployment errors yesterday' - }) -}); - -const data = await response.json(); -``` - -```python Python -response = requests.post( - 'https://api.supermemory.ai/v4/profile', - headers={ - 'Authorization': f'Bearer {os.getenv("SUPERMEMORY_API_KEY")}', - 'Content-Type': 'application/json' - }, - json={ - 'containerTag': 'user_123', - 'threshold': 0.7, # Only include results with score > 0.7 - 'q': 'deployment errors yesterday' - } -) - -data = response.json() -``` - - - -## Error Responses - -| Status | Description | -|--------|-------------| -| `400` | Missing or invalid `containerTag` or `threshold` | -| `401` | Invalid or missing API key | -| `404` | Container not found | -| `500` | Internal server error | - -## Rate Limits - -Profile requests count toward your standard API rate limits. Since profiles are cached, repeated requests for the same user are efficient. - - - View complete integration examples for chat apps, support systems, and more - diff --git a/apps/docs/user-profiles/examples.mdx b/apps/docs/user-profiles/examples.mdx deleted file mode 100644 index bd64b9da..00000000 --- a/apps/docs/user-profiles/examples.mdx +++ /dev/null @@ -1,370 +0,0 @@ ---- -title: "Profile Examples" -description: "Complete code examples for integrating user profiles" -sidebarTitle: "Examples" -icon: "laptop-code" ---- - -## Building a Personalized Prompt - -The most common use case: inject profile data into your LLM's system prompt. - - - -```typescript TypeScript -async function handleChatMessage(userId: string, message: string) { - // Get user profile - const profileResponse = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ containerTag: userId }) - }); - - const { profile } = await profileResponse.json(); - - // Build personalized system prompt - const systemPrompt = `You are assisting a user with the following context: - -ABOUT THE USER: -${profile.static?.join('\n') || 'No profile information yet.'} - -CURRENT CONTEXT: -${profile.dynamic?.join('\n') || 'No recent activity.'} - -Provide responses personalized to their expertise level and preferences.`; - - // Send to your LLM - const response = await llm.chat({ - messages: [ - { role: "system", content: systemPrompt }, - { role: "user", content: message } - ] - }); - - return response; -} -``` - -```python Python -import requests -import os - -async def handle_chat_message(user_id: str, message: str): - # Get user profile - response = requests.post( - 'https://api.supermemory.ai/v4/profile', - headers={ - 'Authorization': f'Bearer {os.getenv("SUPERMEMORY_API_KEY")}', - 'Content-Type': 'application/json' - }, - json={'containerTag': user_id} - ) - - profile = response.json()['profile'] - - # Build personalized system prompt - static_facts = '\n'.join(profile.get('static', ['No profile information yet.'])) - dynamic_context = '\n'.join(profile.get('dynamic', ['No recent activity.'])) - - system_prompt = f"""You are assisting a user with the following context: - -ABOUT THE USER: -{static_facts} - -CURRENT CONTEXT: -{dynamic_context} - -Provide responses personalized to their expertise level and preferences.""" - - # Send to your LLM - llm_response = await llm.chat( - messages=[ - {"role": "system", "content": system_prompt}, - {"role": "user", "content": message} - ] - ) - - return llm_response -``` - - - -## Full Context Mode - -Combine profile data with query-specific search for comprehensive context: - - - -```typescript TypeScript -async function getFullContext(userId: string, userQuery: string) { - // Single call gets both profile and search results - const response = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - containerTag: userId, - q: userQuery // Include the user's query - }) - }); - - const data = await response.json(); - - return { - // Static background about the user - userBackground: data.profile.static, - // Current activities and context - currentContext: data.profile.dynamic, - // Query-specific memories - relevantMemories: data.searchResults?.results || [] - }; -} - -// Usage -const context = await getFullContext('user_123', 'deployment error last week'); - -const systemPrompt = ` -User Background: -${context.userBackground.join('\n')} - -Current Context: -${context.currentContext.join('\n')} - -Relevant Information: -${context.relevantMemories.map(m => m.content).join('\n')} -`; -``` - -```python Python -async def get_full_context(user_id: str, user_query: str): - # Single call gets both profile and search results - response = requests.post( - 'https://api.supermemory.ai/v4/profile', - headers={ - 'Authorization': f'Bearer {os.getenv("SUPERMEMORY_API_KEY")}', - 'Content-Type': 'application/json' - }, - json={ - 'containerTag': user_id, - 'q': user_query # Include the user's query - } - ) - - data = response.json() - - return { - 'user_background': data['profile'].get('static', []), - 'current_context': data['profile'].get('dynamic', []), - 'relevant_memories': data.get('searchResults', {}).get('results', []) - } - -# Usage -context = await get_full_context('user_123', 'deployment error last week') - -system_prompt = f""" -User Background: -{chr(10).join(context['user_background'])} - -Current Context: -{chr(10).join(context['current_context'])} - -Relevant Information: -{chr(10).join(m['content'] for m in context['relevant_memories'])} -""" -``` - - - -## Filtering with Threshold - -Use the optional `threshold` parameter to filter search results by relevance score: - - - -```typescript TypeScript -async function getHighQualityContext(userId: string, userQuery: string) { - const response = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - containerTag: userId, - threshold: 0.7, // Only include high-confidence results - q: userQuery - }) - }); - - const data = await response.json(); - - // Only highly relevant memories are included - return data; -} -``` - -```python Python -async def get_high_quality_context(user_id: str, user_query: str): - response = requests.post( - 'https://api.supermemory.ai/v4/profile', - headers={ - 'Authorization': f'Bearer {os.getenv("SUPERMEMORY_API_KEY")}', - 'Content-Type': 'application/json' - }, - json={ - 'containerTag': user_id, - 'threshold': 0.7, # Only include high-confidence results - 'q': user_query - } - ) - - data = response.json() - - # Only highly relevant memories are included - return data -``` - - - -## Separate Profile and Search - -For more control, you can call profile and search endpoints separately: - -```typescript TypeScript -async function advancedContext(userId: string, query: string) { - // Parallel requests for profile and search - const [profileRes, searchRes] = await Promise.all([ - fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ containerTag: userId }) - }), - fetch('https://api.supermemory.ai/v3/search', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - q: query, - containerTag: userId, - limit: 5 - }) - }) - ]); - - const profile = await profileRes.json(); - const search = await searchRes.json(); - - return { profile: profile.profile, searchResults: search.results }; -} -``` - -## Express.js Middleware - -Add profile context to all authenticated requests: - -```typescript TypeScript -import express from 'express'; - -// Middleware to fetch user profile -async function withUserProfile(req, res, next) { - if (!req.user?.id) { - return next(); - } - - try { - const response = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ containerTag: req.user.id }) - }); - - req.userProfile = await response.json(); - } catch (error) { - console.error('Failed to fetch profile:', error); - req.userProfile = null; - } - - next(); -} - -const app = express(); - -// Apply to all routes -app.use(withUserProfile); - -app.post('/chat', async (req, res) => { - const { message } = req.body; - - // Profile is automatically available - const profile = req.userProfile?.profile; - - // Use in your LLM call... -}); -``` - -## Next.js API Route - -```typescript TypeScript -// app/api/chat/route.ts -import { NextRequest, NextResponse } from 'next/server'; - -export async function POST(req: NextRequest) { - const { userId, message } = await req.json(); - - // Fetch profile - const profileRes = await fetch('https://api.supermemory.ai/v4/profile', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ containerTag: userId }) - }); - - const { profile } = await profileRes.json(); - - // Build context and call your LLM... - const response = await generateResponse(message, profile); - - return NextResponse.json({ response }); -} -``` - -## AI SDK Integration - -For the cleanest integration, use the Supermemory AI SDK middleware: - -```typescript TypeScript -import { generateText } from "ai" -import { withSupermemory } from "@supermemory/tools/ai-sdk" -import { openai } from "@ai-sdk/openai" - -// Simple setup - profiles automatically injected -const model = withSupermemory(openai("gpt-4"), { - containerTag: "user-123", - customId: "conv-1", -}) - -const result = await generateText({ - model, - messages: [{ role: "user", content: "Help me with my current project" }] -}) -// Model automatically has access to user's profile! -``` - - - Learn more about automatic profile injection with the AI SDK - diff --git a/apps/docs/user-profiles/overview.mdx b/apps/docs/user-profiles/overview.mdx deleted file mode 100644 index 160807fa..00000000 --- a/apps/docs/user-profiles/overview.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: "User Profiles" -description: "Automatically maintained user context that gives your LLMs instant, comprehensive knowledge about each user" -sidebarTitle: "Overview" -icon: "user" ---- - -User profiles are **automatically maintained collections of facts about your users** that Supermemory builds from all their interactions and content. Think of it as a persistent "about me" document that's always up-to-date and instantly accessible. - - - - No search queries needed - comprehensive user information is always ready - - - Profiles update automatically as users interact with your system - - - Static facts + dynamic context for perfect personalization - - - Just ingest content normally - profiles build themselves - - - -## Why Profiles? - -Traditional memory systems rely entirely on search, which has fundamental limitations: - -| Problem | With Search Only | With Profiles | -|---------|-----------------|---------------| -| **Context retrieval** | 3-5 search queries | 1 profile call | -| **Response time** | 200-500ms | 50-100ms | -| **Consistency** | Varies by search quality | Always comprehensive | -| **Basic user info** | Requires specific queries | Always available | - -**Search is too narrow**: When you search for "project updates", you miss that the user prefers bullet points, works in PST timezone, and uses specific terminology. - -**Profiles provide the foundation**: Instead of repeatedly searching for basic context, profiles give your LLM a complete picture of who the user is. - -## Static vs Dynamic - -Profiles intelligently separate two types of information: - -![](/images/static-dynamic-profile.png) - -### Static Profile - -Long-term, stable facts that rarely change: - -- "Sarah Chen is a senior software engineer at TechCorp" -- "Sarah specializes in distributed systems and Kubernetes" -- "Sarah has a PhD in Computer Science from MIT" -- "Sarah prefers technical documentation over video tutorials" - -### Dynamic Profile - -Recent context and temporary states: - -- "Sarah is currently migrating the payment service to microservices" -- "Sarah recently started learning Rust for a side project" -- "Sarah is preparing for a conference talk next month" -- "Sarah is debugging a memory leak in the authentication service" - -## How It Works - -Profiles are **automatically built and maintained** through Supermemory's ingestion pipeline: - - - - When users add documents, chat, or any content to Supermemory, it goes through the standard ingestion workflow. - - - - AI analyzes the content to extract not just memories, but also facts about the user themselves. - - - - The system generates profile operations (add, update, or remove facts) based on the new information. - - - - Profiles are updated in real-time, ensuring they always reflect the latest information. - - - - - You don't need to manually manage profiles - they build themselves as users interact with your system. - - -## Profiles + Search - -Profiles don't replace search - they complement it: - - - - The user's profile gives your LLM comprehensive background context about who they are, what they know, and what they're working on. - - - - When you need specific information (like "error in deployment yesterday"), search finds those exact memories. - - - - Your LLM gets both the broad understanding from profiles AND the specific details from search. - - - -### Example - -User asks: **"Can you help me debug this?"** - -**Without profiles**: The LLM has no context about the user's expertise level, current projects, or debugging preferences. - -**With profiles**: The LLM knows: -- The user is a senior engineer (adjust technical level) -- They're working on a payment service migration (likely context) -- They prefer command-line tools over GUIs (tool suggestions) -- They recently had issues with memory leaks (possible connection) - -## Next Steps - - - - Learn how to fetch and use profiles via the API - - - See complete integration examples - - - Use the AI SDK for automatic profile injection - - - Common patterns and applications - - diff --git a/apps/docs/user-profiles/use-cases.mdx b/apps/docs/user-profiles/use-cases.mdx deleted file mode 100644 index db383513..00000000 --- a/apps/docs/user-profiles/use-cases.mdx +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: "Profile Use Cases" -description: "Common patterns and applications for user profiles" -sidebarTitle: "Use Cases" -icon: "lightbulb" ---- - -## Personalized AI Assistants - -The most common use case: building AI assistants that truly know your users. - -**What profiles provide:** -- User's expertise level (adjust technical depth) -- Communication preferences (brief vs detailed, formal vs casual) -- Tools and technologies they use -- Current projects and priorities - -**Example prompt enhancement:** - -```typescript -const systemPrompt = `You are assisting ${userName}. - -Their background: -${profile.static.join('\n')} - -Current focus: -${profile.dynamic.join('\n')} - -Adjust your responses to match their expertise level and preferences.`; -``` - -**Result:** An assistant that explains React hooks differently to a junior developer vs a senior architect. - -## Customer Support Systems - -Give support agents (or AI) instant context about customers. - -**What profiles provide:** -- Customer's product usage history -- Previous issues and resolutions -- Preferred communication channels -- Technical proficiency level - -**Benefits:** -- No more "let me look up your account" -- Agents immediately understand customer context -- AI support can reference past interactions naturally - -```typescript -// Support agent dashboard -async function loadCustomerContext(customerId: string) { - const { profile } = await getProfile(customerId); - - return { - summary: profile.static, // Long-term customer info - recentIssues: profile.dynamic // Current tickets, recent problems - }; -} -``` - -## Educational Platforms - -Adapt learning content to each student's level and progress. - -**What profiles provide:** -- Learning style preferences -- Completed courses and topics -- Areas of strength and weakness -- Current learning goals - -**Example adaptation:** - -```typescript -// Profile might contain: -// static: ["Visual learner", "Strong in algebra, struggles with geometry"] -// dynamic: ["Currently studying calculus", "Preparing for AP exam"] - -const tutorPrompt = `You're helping a student with: -${profile.static.join('\n')} - -Current focus: ${profile.dynamic.join('\n')} - -Adapt explanations to their learning style and build on their strengths.`; -``` - -## Development Tools - -IDE assistants and coding tools that understand your codebase and habits. - -**What profiles provide:** -- Preferred languages and frameworks -- Coding style and conventions -- Current project context -- Frequently used patterns - -**Example:** - -```typescript -// Profile for a developer: -// static: ["Prefers TypeScript", "Uses functional patterns", "Senior engineer"] -// dynamic: ["Working on auth refactor", "Recently learning Rust"] - -// Code assistant knows to: -// - Suggest TypeScript solutions -// - Use functional patterns in examples -// - Provide senior-level explanations -// - Connect suggestions to the auth refactor when relevant -``` - -## Knowledge Base Assistants - -Internal tools that understand each employee's role and responsibilities. - -**What profiles provide:** -- Department and role -- Projects they're involved in -- Access level and permissions context -- Areas of expertise (for routing questions) - -**Example:** - -```typescript -// HR assistant that knows: -// - Employee's team and manager -// - Their location/timezone -// - Recent PTO requests -// - Benefits elections - -const response = await hrAssistant.answer( - "When is my next performance review?", - { profile: employeeProfile } -); -// Can answer with specific dates, manager name, etc. -``` - -## E-commerce Recommendations - -Personalized shopping experiences beyond basic recommendation engines. - -**What profiles provide:** -- Style preferences -- Size information -- Past purchases and returns -- Budget range -- Occasions they shop for - -**Example conversation:** - -``` -User: "I need something for a wedding next month" - -// Profile knows: prefers classic styles, size M, budget-conscious, -// previously bought navy suits \ No newline at end of file diff --git a/apps/docs/vibe-coding.mdx b/apps/docs/vibe-coding.mdx index 6a5c3279..5d59bf46 100644 --- a/apps/docs/vibe-coding.mdx +++ b/apps/docs/vibe-coding.mdx @@ -171,17 +171,17 @@ import { supermemoryTools } from '@supermemory/tools/ai-sdk' // Option 1: Agent tools (recommended for agentic flows) const result = await streamText({ - model: anthropic('claude-3-5-sonnet-20241022'), + model: anthropic('claude-sonnet-4-5'), prompt: userMessage, tools: supermemoryTools(process.env.SUPERMEMORY_API_KEY, { - containerTag: userId // singular string — never an array + containerTags: [userId] // the tools config takes an array; API bodies use singular containerTag }) }) // Agent gets searchMemories, addMemory, fetchMemory tools // Option 2: Profile middleware (automatic context injection) import { withSupermemory } from '@supermemory/tools/ai-sdk' -const modelWithMemory = withSupermemory(anthropic('claude-3-5-sonnet-20241022'), { +const modelWithMemory = withSupermemory(anthropic('claude-sonnet-4-5'), { containerTag: userId, customId: 'conversation-1', }) @@ -236,15 +236,14 @@ import Supermemory from 'supermemory' const client = new Supermemory() // Search for relevant memories -const results = await client.search({ +const results = await client.search.memories({ q: userMessage, containerTag: userId, - searchMode: 'hybrid', // Searches memories + document chunks limit: 5 }) // Build context -const context = results.results.map(r => r.memory || r.chunk).join('\n') +const context = results.results.map(r => r.memory).join('\n') // Send to LLM with context const messages = [ diff --git a/apps/docs/zapier.mdx b/apps/docs/zapier.mdx deleted file mode 100644 index d7398ab4..00000000 --- a/apps/docs/zapier.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: "Integrate supermemory in your Zapier workflows" -sidebarTitle: "Zapier" -description: "Learn how to use the code block to integrate supermemory with Zapier and add memory to your automations." ---- - -With Supermemory you can now easily add memory to your Zapier workflow steps. Here's how: - -## Prerequisites -- A Supermemory API Key. Get yours [here](https://console.supermemory.ai) - -## Step-by-step tutorial - -For this tutorial, we're building a simple flow that adds incoming emails in Gmail to Supermemory. - - - - Open your Zapier account and click on 'Zap' to make a new automation. - ![make a zap - annotated](/images/make-zap.png) - - - Add a new Gmail node that gets triggered on every new email. Connect to your Google account. - ![add gmail](/images/add-gmail-node-zapier.png) - - - Now, add a new 'Code by Zapier' block. Set it up to run Python. - - In the **Input Data** section, map the content field to the Gmail raw snippet. - - ![](/images/map-content-to-gmail.png) - - - Since we're ingesting data here, we'll use the add documents endpoint. - - Add the following code block: - - ```python - import requests - - url = "https://api.supermemory.ai/v3/documents" - - payload = { "content": inputData['content'], "containerTag": "gmail" } - headers = { - "Authorization": "Bearer YOUR_SM_API_KEY", - "Content-Type": "application/json" - } - - response = requests.post(url, json=payload, headers=headers) - - print(response.json()) - ``` - - The `inputData['content']` field maps to the Gmail content fetched from Zapier. - - ![](/images/zapier-output.png) - - - - - Sometimes Zapier might show an error on the first test run. It usually works right after. Weird bug, we know. - - - -You can perform other operations like search, filtering, user profiles, etc., by using other Supermemory API endpoints which can be found in our API Reference tab. \ No newline at end of file