diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c0b65f9c..e4ae3bf4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -34,30 +34,22 @@ jobs: fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- + - name: Install uv + uses: astral-sh/setup-uv@v3 - name: Install MkDocs and dependencies - run: | - pip install mkdocs-material - pip install mkdocs-minify-plugin - pip install mkdocs-git-revision-date-localized-plugin + run: uv sync --group docs - name: Setup Pages if: github.ref == 'refs/heads/main' uses: actions/configure-pages@v4 - name: Build documentation - run: mkdocs build --clean --strict + run: uv run mkdocs build --clean --strict - name: Upload artifact if: github.ref == 'refs/heads/main' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3ba0052e..4dcf2cef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + args: [--unsafe] - id: check-added-large-files - repo: https://github.com/crate-ci/typos diff --git a/README.md b/README.md index 2c1f39a1..8557cc5b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@
-# Redis Agent Memory Server +# Agent Memory Server -A memory layer for AI agents. +Session Memory and Long-Term Memory for AI Agents. - **[Documentation](https://redis.github.io/agent-memory-server/)** β€’ **[GitHub](https://github.com/redis/agent-memory-server)** β€’ **[Docker](https://hub.docker.com/r/redislabs/agent-memory-server)** + **[Documentation](https://ai.redis.io/agent-memory/)** β€’ **[GitHub](https://github.com/redis/agent-memory-server)** β€’ **[Docker](https://hub.docker.com/r/redislabs/agent-memory-server)**
@@ -144,7 +144,7 @@ results = await client.search_long_term_memory( ) ``` -> **Note**: While you can call client functions directly as shown above, using **MCP or SDK-provided tool calls** is recommended for AI agents as it provides better integration, automatic context management, and follows AI-native patterns. For the best performance, you can add messages to working memory and allow the server to extract memories in the background. See **[Memory Integration Patterns](https://redis.github.io/agent-memory-server/memory-integration-patterns/)** for guidance on when to use each approach. +> **Note**: While you can call client functions directly as shown above, using **MCP or SDK-provided tool calls** is recommended for AI agents as it provides better integration, automatic context management, and follows AI-native patterns. For the best performance, you can add messages to working memory and allow the server to extract memories in the background. See **[Memory Integration Patterns](https://ai.redis.io/agent-memory/user_guide/how_to_guides/integration_patterns/)** for guidance on when to use each approach. #### LangChain Integration @@ -244,24 +244,24 @@ export EMBEDDING_MODEL=ollama/nomic-embed-text export REDISVL_VECTOR_DIMENSIONS=768 # Required for Ollama ``` -See **[LLM Providers](https://redis.github.io/agent-memory-server/llm-providers/)** for complete configuration options. +See **[LLM Providers](https://ai.redis.io/agent-memory/user_guide/how_to_guides/llm_providers/)** for complete configuration options. ## Documentation -πŸ“š **[Full Documentation](https://redis.github.io/agent-memory-server/)** - Complete guides, API reference, and examples +πŸ“š **[Full Documentation](https://ai.redis.io/agent-memory/)** - Complete guides, API reference, and examples ### Key Documentation Sections: -- **[Quick Start Guide](https://redis.github.io/agent-memory-server/quick-start/)** - Get up and running in minutes -- **[Python SDK](https://redis.github.io/agent-memory-server/python-sdk/)** - Complete SDK reference with examples -- **[LangChain Integration](https://redis.github.io/agent-memory-server/langchain-integration/)** - Automatic tool conversion for LangChain -- **[LLM Providers](https://redis.github.io/agent-memory-server/llm-providers/)** - Configure OpenAI, Anthropic, AWS Bedrock, Ollama, and more -- **[Embedding Providers](https://redis.github.io/agent-memory-server/embedding-providers/)** - Configure embedding models for semantic search -- **[Custom Memory Vector Databases](https://redis.github.io/agent-memory-server/custom-memory-vector-db/)** - Configure custom memory vector databases -- **[Authentication](https://redis.github.io/agent-memory-server/authentication/)** - OAuth2/JWT setup for production -- **[Memory Types](https://redis.github.io/agent-memory-server/long-term-memory/#memory-types)** - Understanding semantic vs episodic memory -- **[API Reference](https://redis.github.io/agent-memory-server/api/)** - REST API endpoints -- **[MCP Protocol](https://redis.github.io/agent-memory-server/mcp/)** - Model Context Protocol integration +- **[Quick Start Guide](https://ai.redis.io/agent-memory/user_guide/01_quick_start/)** - Get up and running in minutes +- **[Python SDK](https://ai.redis.io/agent-memory/api/python_sdk/)** - Complete SDK reference with examples +- **[LangChain Integration](https://ai.redis.io/agent-memory/examples/langchain/)** - Automatic tool conversion for LangChain +- **[LLM Providers](https://ai.redis.io/agent-memory/user_guide/how_to_guides/llm_providers/)** - Configure OpenAI, Anthropic, AWS Bedrock, Ollama, and more +- **[Embedding Providers](https://ai.redis.io/agent-memory/user_guide/how_to_guides/embedding_providers/)** - Configure embedding models for semantic search +- **[Custom Memory Vector Databases](https://ai.redis.io/agent-memory/user_guide/how_to_guides/custom_vector_db/)** - Configure custom memory vector databases +- **[Authentication](https://ai.redis.io/agent-memory/user_guide/how_to_guides/authentication/)** - OAuth2/JWT setup for production +- **[Memory Types](https://ai.redis.io/agent-memory/concepts/long_term_memory/#memory-types)** - Understanding semantic vs episodic memory +- **[API Reference](https://ai.redis.io/agent-memory/api/rest/)** - REST API endpoints +- **[MCP Protocol](https://ai.redis.io/agent-memory/api/mcp/)** - Model Context Protocol integration ## Architecture diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index b2df1c31..00000000 --- a/docs/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# Redis Agent Memory Server Documentation - -Comprehensive documentation for building AI agents with persistent, intelligent memory. - -## πŸš€ Getting Started - -**New to Redis Agent Memory Server?** Start here: - -- **[Quick Start Guide](quick-start.md)** - Get up and running in 5 minutes -- **[Getting Started](getting-started.md)** - Complete installation and setup guide -- **[Use Cases](use-cases.md)** - Real-world examples and implementation patterns - -## 🧠 Core Concepts - -Understand the fundamentals: - -- **[Memory Types](long-term-memory.md#memory-types)** - Working vs Long-term memory explained with examples -- **[Authentication](authentication.md)** - OAuth2/JWT, token-based, and development setup -- **[Configuration](configuration.md)** - Environment variables, settings, and deployment options - -## ✨ Advanced Features - -Powerful features for intelligent memory management: - -- **[Query Optimization](query-optimization.md)** - AI-powered query refinement for better search accuracy -- **[Contextual Grounding](contextual-grounding.md)** - Resolve pronouns and references in extracted memories -- **[Memory Editing](memory-lifecycle.md#memory-editing)** - Update, correct, and enrich existing memories -- **[Recency Boost](recency-boost.md)** - Time-aware memory ranking and intelligent scoring -- **[Custom Memory Vector Databases](custom-memory-vector-db.md)** - Custom memory vector database implementations - -## πŸ”Œ API Reference - -Choose your integration approach: - -- **[REST API](api.md)** - HTTP endpoints with complete examples and curl commands -- **[MCP Server](mcp.md)** - Model Context Protocol tools for AI agents (Claude, etc.) -- **[CLI](cli.md)** - Command-line interface for server management and administration - -## πŸ› οΈ Development - -For contributors and advanced users: - -- **[Development Guide](development.md)** - Local setup, testing, and contributing guidelines -- **[System Architecture](../diagram.png)** - Visual overview of system components - -## πŸ“š Additional Resources - -- **[Manual OAuth Testing](../manual_oauth_qa/README.md)** - Comprehensive Auth0 testing guide -- **[Main Project README](../README.md)** - Project overview and quick reference -- **[Examples Directory](../examples/)** - Complete working examples and demos - -## Navigation Tips - -### By Experience Level - -**πŸ‘‹ New Users**: Quick Start β†’ Use Cases β†’ Memory Types -**πŸ”§ Developers**: Getting Started β†’ REST API β†’ Configuration -**πŸ€– AI Agent Builders**: MCP Server β†’ Memory Editing β†’ Query Optimization -**πŸ—οΈ System Admins**: Authentication β†’ Configuration β†’ CLI - -### By Use Case - -**Building a chatbot?** β†’ Quick Start β†’ Memory Types β†’ MCP Server -**Adding memory to existing app?** β†’ REST API β†’ Authentication β†’ Configuration -**Research/content assistant?** β†’ Use Cases β†’ Query Optimization β†’ Contextual Grounding -**Production deployment?** β†’ Authentication β†’ Custom Memory Vector Databases β†’ Development - -### By Interface Preference - -**REST API users** β†’ [API Documentation](api.md) β†’ [Authentication](authentication.md) -**MCP/Claude users** β†’ [MCP Server](mcp.md) β†’ [Memory Editing](memory-lifecycle.md#memory-editing) -**CLI management** β†’ [CLI Reference](cli.md) β†’ [Configuration](configuration.md) - -## Feature Cross-Reference - -| Feature | REST API | MCP Server | CLI | Documentation | -|---------|----------|------------|-----|---------------| -| **Memory Search** (semantic, keyword, hybrid) | βœ… `/v1/long-term-memory/search` | βœ… `search_long_term_memory` | βœ… `agent-memory search` | [REST API](api.md), [MCP](mcp.md), [CLI](cli.md) | -| **Memory Editing** | βœ… `PATCH /v1/long-term-memory/{id}` | βœ… `edit_long_term_memory` | ❌ | [Memory Editing](memory-lifecycle.md#memory-editing) | -| **Query Optimization** | βœ… `optimize_query` param | βœ… `optimize_query` param | ❌ | [Query Optimization](query-optimization.md) | -| **Recency Boost** | βœ… Default enabled | βœ… Available | ❌ | [Recency Boost](recency-boost.md) | -| **Authentication** | βœ… JWT/Token | βœ… Inherited | βœ… Token management | [Authentication](authentication.md) | -| **Background Tasks** | βœ… Automatic | βœ… Automatic | βœ… Worker management | [Configuration](configuration.md) | - ---- - -**Need help?** Check the [Quick Start Guide](quick-start.md) or explore [real-world examples](use-cases.md) to see Redis Agent Memory Server in action! 🧠✨ diff --git a/docs/advanced-topics-index.md b/docs/advanced-topics-index.md deleted file mode 100644 index 992f00b3..00000000 --- a/docs/advanced-topics-index.md +++ /dev/null @@ -1,48 +0,0 @@ -# Advanced Topics - -Optimize memory search, tune ranking algorithms, and configure advanced memory vector database features. - -
- -- πŸ” **Query Optimization** - - --- - - Improve search accuracy with query expansion and rewriting - - [Query Optimization β†’](query-optimization.md) - -- ⏱️ **Recency Boost** - - --- - - Time-aware memory ranking for more relevant results - - [Recency Boost β†’](recency-boost.md) - -- πŸ—„οΈ **Advanced Memory Vector Database Config** - - --- - - Fine-tune vector indexing, distance metrics, and performance - - [Memory Vector Database Config β†’](advanced-memory-vector-db.md) - -- 🎯 **Contextual Grounding** - - --- - - Resolve pronouns and references in extracted memories - - [Contextual Grounding β†’](contextual-grounding.md) - -
- -## When to Use These Features - -| Feature | Use When | -|---------|----------| -| Query Optimization | Search results aren't matching user intent well | -| Recency Boost | Recent memories should rank higher than older ones | -| Advanced Vector Config | You need to tune performance or use custom distance metrics | -| Contextual Grounding | Extracted memories contain unresolved pronouns like "he" or "it" | diff --git a/docs/agent-examples.md b/docs/agent-examples.md deleted file mode 100644 index c0af0efa..00000000 --- a/docs/agent-examples.md +++ /dev/null @@ -1,499 +0,0 @@ -# Agent Examples - -This section provides comprehensive working examples that demonstrate real-world usage patterns of the Redis Agent Memory Server. Each example showcases different aspects of memory management, from basic conversation storage to advanced memory editing workflows. - -## Interactive Technical Guide (Notebook) - -**File:** `examples/agent_memory_server_interactive_guide.ipynb` - -The Interactive Technical Guide is a comprehensive, cell-by-cell walkthrough of the -Agent Memory Server. Unlike the standalone scripts below, this notebook is designed -for hands-on exploration in an interactive environment β€” each section builds on the -previous one, with executable code cells and inline explanations. - -### Format - -The notebook uses the [Jupytext percent format](https://jupytext.readthedocs.io/en/latest/formats-scripts.html), -where cells are delimited by `# %%` markers. You can open it directly in: - -- **VS Code** (with the Jupyter extension) -- **JetBrains IDEs** (PyCharm, DataSpell) -- **JupyterLab** (via `jupytext --to notebook` conversion) - -### Prerequisites - -Before running the notebook, ensure the following services are available: - -1. **Redis 8** running locally (via `docker-compose up redis -d`) -2. **Agent Memory Server** running in development mode: - ```bash - DISABLE_AUTH=true uv run agent-memory api --task-backend=asyncio - ``` -3. **Environment variables** configured: - ```bash - export OPENAI_API_KEY= - export DISABLE_AUTH=true - ``` -4. **Python dependencies** installed: - ```bash - pip install agent-memory-client httpx openai - ``` - -### Sections - -The guide is organized into twelve sections, each covering a distinct aspect of the -memory system: - -| Section | Topic | Description | -|---------|-------|-------------| -| 1 | Problem & Solution | Introduces the statelessness problem and the two-tier memory architecture (working memory and long-term memory). | -| 2 | Quick Start | Configures the SDK client, verifies server connectivity, and explains the Redis key structure used internally. | -| 3 | Integration Patterns Overview | Describes the three integration patterns β€” Code-Driven, LLM-Driven, and Background Extraction β€” and when to use each. | -| 4 | Pattern 1: Code-Driven (SDK) | Demonstrates deterministic memory operations using the `agent_memory_client` SDK: creating sessions, seeding long-term memories, retrieving context with `memory_prompt()`, and storing conversations. | -| 5 | Pattern 2: LLM-Driven (Tools) | Shows how to expose memory operations as OpenAI-compatible tool schemas, let the model decide when to store or retrieve memories, and resolve tool calls with `resolve_tool_call()`. | -| 6 | Pattern 3: Background Extraction | Covers automatic memory extraction from conversations using discrete and custom extraction strategies, including debounce configuration. | -| 7 | Combining Patterns | Discusses how production applications typically combine multiple patterns (e.g., code-driven context hydration with LLM-driven storage). | -| 8 | Working Memory Deep Dive | Explores session management, working memory summarization (trigger conditions, token allocation, progressive summarization), and structured data storage. | -| 9 | Long-Term Memory Deep Dive | Covers semantic, keyword, and hybrid search modes; `hybrid_alpha` tuning; recency boost configuration; and filtered search by topics, entities, or timestamps. | -| 10 | Memory Types & Contextual Grounding | Explains semantic vs. episodic memory types, event dating, and how contextual grounding enriches stored memories. | -| 11 | Extraction Strategy Comparison | Provides a side-by-side comparison of discrete (default) and custom extraction strategies using a vehicle rental scenario. | -| 12 | Production Considerations | Covers authentication, background task workers, and LLM provider configuration for deployment. | - -### Key concepts demonstrated - -- **Two-tier memory architecture**: Working memory (session-scoped, ephemeral) automatically promotes structured memories to long-term storage (persistent, searchable). -- **Search mode comparison**: Executable cells that run the same query across `semantic`, `keyword`, and `hybrid` search modes, illustrating how each mode surfaces different results. -- **Recency boost tuning**: Shows how to adjust or disable the recency weight to control whether newer memories are prioritized over older, semantically relevant ones. -- **Tool schema integration**: Generates OpenAI-compatible function schemas from the SDK and demonstrates the full tool-call lifecycle (schema β†’ LLM decision β†’ execution β†’ response). -- **Extraction strategy configuration**: Compares what discrete vs. custom extraction strategies produce from the same input conversation. - -### Running the guide - -```bash -cd examples - -# VS Code: open the file directly β€” the Jupyter extension recognizes percent-format cells -code agent_memory_server_interactive_guide.ipynb - -# JupyterLab: convert to standard notebook format first -jupytext --to notebook agent_memory_server_interactive_guide.ipynb -jupyter lab agent_memory_server_interactive_guide.ipynb -``` - ---- - -## 🧳 Travel Agent - -**File**: [`examples/travel_agent.py`](https://github.com/redis/agent-memory-server/blob/main/examples/travel_agent.py) - -A comprehensive travel assistant that demonstrates the most complete integration patterns. - -### Key Features - -- **Automatic Tool Discovery**: Uses `MemoryAPIClient.get_all_memory_tool_schemas()` to automatically discover and integrate all available memory tools -- **Unified Tool Resolution**: Leverages `client.resolve_tool_call()` to handle all memory tool calls uniformly across different LLM providers -- **Working Memory Management**: Session-based conversation state and structured memory storage -- **Long-term Memory**: Persistent memory storage with semantic, keyword, and hybrid search capabilities -- **Optional Web Search**: Cached web search using Tavily API with Redis caching - -### Available Tools - -The travel agent automatically discovers and uses all memory tools: - -1. **search_memory** - Search through previous conversations and stored information (supports `semantic`, `keyword`, and `hybrid` search modes) -2. **get_or_create_working_memory** - Check current working memory session -3. **lazily_create_long_term_memory** - Store important information as structured memories (promoted to long-term storage later) -4. **update_working_memory_data** - Store/update session-specific data like trip plans -5. **get_long_term_memory** - Retrieve a specific long-term memory by ID -6. **eagerly_create_long_term_memory** - Create long-term memories directly for immediate storage -7. **edit_long_term_memory** - Update existing long-term memories -8. **delete_long_term_memories** - Remove long-term memories -9. **get_current_datetime** - Get current UTC datetime for grounding relative time expressions -10. **web_search** (optional) - Search the internet for current travel information - -### Usage Examples - -```bash -# Basic interactive usage -cd examples -python travel_agent.py - -# Automated demo showing capabilities -python travel_agent.py --demo - -# With custom configuration -python travel_agent.py --session-id my_trip --user-id john_doe --memory-server-url http://localhost:8001 -``` - -### Environment Setup - -```bash -# Required -export OPENAI_API_KEY="your-openai-key" - -# Optional (for web search) -export TAVILY_API_KEY="your-tavily-key" -export REDIS_URL="redis://localhost:6379" -``` - -### Key Implementation Patterns - -```python -# Tool auto-discovery -memory_tools = MemoryAPIClient.get_all_memory_tool_schemas() - -# Unified tool resolution for any provider -result = await client.resolve_tool_call( - tool_call=provider_tool_call, - session_id=session_id -) - -if result["success"]: - print(result["formatted_response"]) -``` - -## 🧠 Memory Prompt Agent - -**File**: [`examples/memory_prompt_agent.py`](https://github.com/redis/agent-memory-server/blob/main/examples/memory_prompt_agent.py) - -Demonstrates the simplified memory prompt feature for context-aware conversations without manual tool management. - -### Core Concept - -Uses `client.memory_prompt()` to automatically retrieve relevant memories and enrich prompts with contextual information. - -### How It Works - -1. **Store Messages**: All conversation messages stored in working memory -2. **Memory Prompt**: `memory_prompt()` retrieves relevant context automatically -3. **Enriched Context**: Memory context combined with system prompt -4. **LLM Generation**: Enhanced context sent to LLM for personalized responses - -### Usage Examples - -```bash -cd examples -python memory_prompt_agent.py - -# With custom session -python memory_prompt_agent.py --session-id my_session --user-id jane_doe -``` - -### Key Implementation Pattern - -```python -# Automatic memory retrieval and context enrichment -context = await client.memory_prompt( - query=user_message, - session_id=session_id, - long_term_search={ - "text": user_message, - "limit": 5, - "user_id": user_id - } -) - -# Enhanced prompt with memory context -response = await openai_client.chat.completions.create( - model="gpt-4o", - messages=context["messages"] -) -``` - -## ✏️ Memory Editing Agent - -**File**: [`examples/memory_editing_agent.py`](https://github.com/redis/agent-memory-server/blob/main/examples/memory_editing_agent.py) - -Demonstrates comprehensive memory editing capabilities through natural conversation patterns. - -### Core Features - -- **Memory Editing Workflow**: Complete lifecycle of creating, searching, editing, and deleting memories -- **All Memory Tools**: Uses all available memory management tools including editing capabilities -- **Realistic Scenarios**: Common patterns like corrections, updates, and information cleanup -- **Interactive Demo**: Both automated demo and interactive modes - -### Memory Operations Demonstrated - -1. **search_memory** - Find existing memories using natural language (supports `semantic`, `keyword`, and `hybrid` search modes) -2. **get_long_term_memory** - Retrieve specific memories by ID -3. **lazily_create_long_term_memory** - Store new information (promoted to long-term storage later) -4. **eagerly_create_long_term_memory** - Create long-term memories directly for immediate storage -5. **edit_long_term_memory** - Update existing memories -6. **delete_long_term_memories** - Remove outdated information -7. **get_or_create_working_memory** - Check current working memory session -8. **update_working_memory_data** - Store/update session-specific data -9. **get_current_datetime** - Get current UTC datetime for grounding relative time expressions - -### Common Editing Scenarios - -```python -# Correction scenario -"Actually, I work at Microsoft, not Google" -# β†’ Search for job memory, edit company name - -# Update scenario -"I got promoted to Senior Engineer" -# β†’ Find job memory, update title and add promotion date - -# Preference change -"I prefer tea over coffee now" -# β†’ Search beverage preferences, update from coffee to tea - -# Information cleanup -"Delete that old job information" -# β†’ Search and remove outdated employment data -``` - -### Usage Examples - -```bash -cd examples - -# Interactive mode (explore memory editing) -python memory_editing_agent.py - -# Automated demo (see complete workflow) -python memory_editing_agent.py --demo - -# Custom configuration -python memory_editing_agent.py --session-id alice_session --user-id alice -``` - -### Demo Conversation Flow - -The automated demo shows a realistic conversation: - -1. **Initial Information**: User shares profile (name, job, preferences) -2. **Corrections**: User corrects information (job company change) -3. **Updates**: User provides updates (promotion, new title) -4. **Multiple Changes**: User updates location and preferences -5. **Information Retrieval**: User asks what agent remembers -6. **Ongoing Updates**: Continued information updates -7. **Memory Management**: Specific memory operations (show/delete) - -## 🏫 AI Tutor - -**File**: [`examples/ai_tutor.py`](https://github.com/redis/agent-memory-server/blob/main/examples/ai_tutor.py) - -A functional tutoring system that demonstrates episodic memory for learning tracking and semantic memory for concept management. - -### Core Features - -- **Quiz Management**: Runs interactive quizzes and stores results -- **Learning Tracking**: Stores quiz results as episodic memories with timestamps -- **Concept Tracking**: Tracks weak concepts as semantic memories -- **Progress Analysis**: Provides summaries and personalized practice suggestions - -### Memory Patterns Used - -```python -# Episodic: Per-question results with event dates -{ - "text": "User answered 'photosynthesis' question incorrectly", - "memory_type": "episodic", - "event_date": "2024-01-15T10:30:00Z", - "topics": ["quiz", "biology", "photosynthesis"] -} - -# Semantic: Weak concepts for targeted practice -{ - "text": "User struggles with photosynthesis concepts", - "memory_type": "semantic", - "topics": ["weak_concept", "biology", "photosynthesis"] -} -``` - -### Usage Examples - -```bash -cd examples - -# Interactive tutoring session -python ai_tutor.py - -# Demo with sample quiz flow -python ai_tutor.py --demo - -# Custom student session -python ai_tutor.py --user-id student123 --session-id bio_course -``` - -### Key Commands - -- **Practice**: Start a quiz on specific topics -- **Summary**: Get learning progress summary -- **Practice-next**: Get personalized practice recommendations based on weak areas - -## πŸ”— LangChain Integration Example - -**File**: [`examples/langchain_integration_example.py`](https://github.com/redis/agent-memory-server/blob/main/examples/langchain_integration_example.py) - -Demonstrates how to use the `agent_memory_client` LangChain integration to create memory-enabled agents **without manual tool wrapping**. - -### Core Concept - -Uses `get_memory_tools()` from `agent_memory_client.integrations.langchain` to automatically generate LangChain-compatible tools, then creates an agent with `create_agent` (LangGraph-based). - -### Key Features - -- **Automatic Tool Generation**: No manual `@tool` wrappers needed β€” `get_memory_tools()` handles it -- **Modern LangGraph Agent**: Uses `create_agent` from `langchain.agents` (not the deprecated `AgentExecutor`) -- **State Persistence**: Demonstrates `MemorySaver` checkpointer for multi-turn conversations -- **Search Modes**: Supports `semantic`, `keyword`, and `hybrid` search via `search_memory` - -### Usage Examples - -```bash -cd examples -python langchain_integration_example.py -``` - -### Key Implementation Pattern - -```python -from agent_memory_client import create_memory_client -from agent_memory_client.integrations.langchain import get_memory_tools -from langchain.agents import create_agent - -memory_client = await create_memory_client("http://localhost:8000") -tools = get_memory_tools(memory_client=memory_client, session_id="session", user_id="user") - -agent = create_agent( - ChatOpenAI(model="gpt-4o"), tools, - system_prompt="You are a helpful assistant with persistent memory." -) - -result = await agent.ainvoke({"messages": [("human", "Remember I love pizza")]}) -print(result["messages"][-1].content) -``` - ---- - -## πŸ“Š Recent Messages Limit Demo - -**File**: [`examples/recent_messages_limit_demo.py`](https://github.com/redis/agent-memory-server/blob/main/examples/recent_messages_limit_demo.py) - -Demonstrates the `recent_messages_limit` parameter for efficiently retrieving only the most recent N messages from working memory. - -### Core Concept - -When working memory grows large, retrieving all messages is expensive. The `recent_messages_limit` parameter lets you fetch only the N most recent messages, useful for context windows and UI displays. - -### Key Features - -- **Efficient Retrieval**: Fetch only the messages you need instead of the full history -- **SDK & HTTP Integration**: Uses `agent_memory_client` to store working memory and raw HTTP requests to retrieve it -- **Multiple Scenarios**: Tests various limits (3, 5, 20, 2) to show how `recent_messages_limit` changes the results -- **Direct API Verification**: Uses the raw HTTP API for retrieval so you can inspect the exact responses from the server - -### Usage Examples - -```bash -cd examples -python recent_messages_limit_demo.py -``` - -### Key Implementation Pattern - -```python -from agent_memory_client import create_memory_client - -client = await create_memory_client(base_url="http://localhost:8000") - -# Get only the 3 most recent messages -_created, memory = await client.get_or_create_working_memory( - session_id="my-session", - namespace="demo", - context_window_max=3 -) -``` - ---- - -## Getting Started with Examples - -### 1. Prerequisites - -```bash -# Install dependencies -cd /path/to/agent-memory-server -uv sync --all-extras - -# Start memory server (disable auth for local development) -DISABLE_AUTH=true uv run agent-memory api --task-backend=asyncio - -# Set required API keys -export OPENAI_API_KEY="your-openai-key" -``` - -### 2. Run Examples - -```bash -cd examples - -# Start with the travel agent (most comprehensive) -python travel_agent.py --demo - -# Try memory editing workflows -python memory_editing_agent.py --demo - -# Explore simplified memory prompts -python memory_prompt_agent.py - -# Experience learning tracking -python ai_tutor.py --demo - -# LangChain integration (requires langchain, langchain_openai) -python langchain_integration_example.py - -# Recent messages limit feature demo -python recent_messages_limit_demo.py -``` - -### 3. Customize and Extend - -Each example is designed to be: - -- **Self-contained**: Runs independently with minimal setup -- **Configurable**: Supports custom sessions, users, and server URLs -- **Educational**: Well-commented code showing best practices -- **Production-ready**: Robust error handling and logging - -### 4. Implementation Patterns - -Key patterns demonstrated across examples: - -```python -# Memory client setup -client = MemoryAPIClient( - base_url="http://localhost:8000", - default_namespace=namespace, - user_id=user_id -) - -# Tool integration -tools = MemoryAPIClient.get_all_memory_tool_schemas() -response = await openai_client.chat.completions.create( - model="gpt-4o", - messages=messages, - tools=tools -) - -# Tool resolution -for tool_call in response.choices[0].message.tool_calls: - result = await client.resolve_tool_call( - tool_call=tool_call, - session_id=session_id - ) -``` - -## Next Steps - -- **Start with the Interactive Guide**: Best for learning the full system end-to-end in an exploratory environment -- **Start with Travel Agent**: Most comprehensive standalone example showing all features -- **Explore Memory Editing**: Learn advanced memory management patterns -- **Study Code Patterns**: Each example demonstrates different architectural approaches -- **Build Your Own**: Use examples as templates for your specific use case - -All examples include detailed inline documentation and can serve as starting points for building production memory-enhanced AI applications. diff --git a/docs/api-reference-index.md b/docs/api-reference-index.md deleted file mode 100644 index 0cd6e280..00000000 --- a/docs/api-reference-index.md +++ /dev/null @@ -1,78 +0,0 @@ -# API Reference - -Complete reference documentation for all Redis Agent Memory Server interfaces and client SDKs. - -## Server Interfaces - -
- -- 🌐 **REST API** - - --- - - HTTP endpoints for memory operations with complete examples - - [REST API Reference β†’](api.md) - -- πŸ€– **MCP Server** - - --- - - Model Context Protocol tools for AI agents (Claude Desktop, etc.) - - [MCP Reference β†’](mcp.md) - -- πŸ’» **CLI Reference** - - --- - - Command-line interface for server management - - [CLI Reference β†’](cli.md) - -
- -## Client SDKs - -
- -- 🐍 **Python SDK** - - --- - - Async-first client with tool schemas for OpenAI and Anthropic - - [Python SDK β†’](python-sdk.md) - -- πŸ“˜ **TypeScript SDK** - - --- - - Type-safe client for Node.js and browser applications - - [TypeScript SDK β†’](typescript-sdk.md) - -- β˜• **Java SDK** - - --- - - Java client for JVM applications - - [Java SDK β†’](java-sdk.md) - -
- -## Interface Comparison - -| Interface | Best For | Authentication | -|-----------|----------|----------------| -| REST API | Applications, backends, custom integrations | OAuth2/JWT or token | -| MCP Server | Claude Desktop, MCP-compatible AI agents | Environment config | -| CLI | Server administration, development | Local access | -| Python SDK | Python applications with LLM tool integration | Token or OAuth2 | -| TypeScript SDK | Node.js, browser, and TypeScript applications | Token or OAuth2 | -| Java SDK | JVM-based applications | Token or OAuth2 | - -## Interactive API Docs - -When running the server locally, visit `http://localhost:8000/docs` for interactive Swagger documentation where you can try endpoints directly. diff --git a/docs/api/cli.md b/docs/api/cli.md new file mode 100644 index 00000000..1c14ccfc --- /dev/null +++ b/docs/api/cli.md @@ -0,0 +1,437 @@ +# Command Line Interface + +The `agent-memory-server` package provides a command-line interface (CLI) called `agent-memory` for running the REST API and MCP servers, scheduling and processing background tasks, running migrations, and managing authentication tokens. + +## Installation + +The `agent-memory` command is included when you install the server package. + +```bash +pip install agent-memory-server +``` + +Verify the installation by running: + +```bash +agent-memory version +``` + +## Getting help + +All commands and command groups support the `--help` flag. + +| Flag | Description | +|---|---| +| `--help` | Display usage information for the command or command group | + +**Examples** + +```bash +agent-memory --help # Top-level help +agent-memory api --help # Help for a single command +agent-memory token --help # Help for a command group +``` + +## `version` + +Display the installed version of `agent-memory-server`. + +**Syntax** + +```bash +agent-memory version +``` + +--- + +## `api` + +Start the REST API server. + +**Syntax** + +```bash +agent-memory api [OPTIONS] +``` + +**Options** + +| Option | Type | Default | Description | +|---|---|---|---| +| `--port` | integer | `settings.port` (usually `8000`) | Port to run the server on | +| `--host` | string | `0.0.0.0` | Host to bind the server to | +| `--reload` | flag | disabled | Enable auto-reload for development | +| `--task-backend` | `asyncio` \| `docket` | `docket` | Background task backend. `docket` requires a running `agent-memory task-worker`; `asyncio` runs tasks inline in the API process. | +| `--no-worker` *(deprecated)* | flag | β€” | Backwards-compatible alias for `--task-backend=asyncio`. Prefer `--task-backend`. | + +**Examples** + +```bash +# Development mode (no separate worker needed) +agent-memory api --port 8080 --reload --task-backend asyncio + +# Production mode (default Docket backend; requires a separate worker) +agent-memory api --port 8080 +``` + +!!! warning "Limitations of `--task-backend=asyncio`" + + The `asyncio` backend is suitable for development and simple use cases, but has important limitations: + + - **Periodic tasks don't run**: Scheduled maintenance tasks like memory compaction, periodic forgetting, and summary view refresh only execute when a Docket worker is running. These tasks use Docket's `Perpetual` scheduler. + - **No task persistence**: If the server restarts, pending background tasks are lost. + - **No distributed processing**: All tasks run in the API process; you cannot scale workers independently. + + For production deployments, use the default `docket` backend with a separate `agent-memory task-worker` process. + +--- + +## `mcp` + +Start the Model Context Protocol (MCP) server. + +**Syntax** + +```bash +agent-memory mcp [OPTIONS] +``` + +**Options** + +| Option | Type | Default | Description | +|---|---|---|---| +| `--port` | integer | `settings.mcp_port` (usually `9000`) | Port to run the MCP server on | +| `--mode` | `stdio` \| `sse` \| `streamable-http` | `stdio` | MCP transport mode | +| `--task-backend` | `asyncio` \| `docket` | `asyncio` | Background task backend. `docket` requires a running `agent-memory task-worker`. | + +**Examples** + +```bash +# Stdio mode (recommended for Claude Desktop) +agent-memory mcp + +# SSE mode for development (no separate worker needed) +agent-memory mcp --mode sse --port 9001 + +# Streamable HTTP mode for network deployments (e.g. Kubernetes) +agent-memory mcp --mode streamable-http --port 9000 + +# SSE mode for production (requires a separate worker process) +agent-memory mcp --mode sse --port 9001 --task-backend docket +``` + +!!! note "Choosing a mode" + + Stdio mode is designed for tools like Claude Desktop and uses the asyncio backend by default (no worker required). Streamable HTTP mode is suited for deploying the MCP server as a network service where HTTP clients (like Claude Code) connect over the network. Use `--task-backend docket` if you want MCP to enqueue background work into a shared Docket worker. + +--- + +## `task-worker` + +Start a Docket worker to process background tasks from the queue. The worker uses the Docket name configured in settings. + +**Syntax** + +```bash +agent-memory task-worker [OPTIONS] +``` + +**Options** + +| Option | Type | Default | Description | +|---|---|---|---| +| `--concurrency` | integer | `10` | Number of tasks to process concurrently | +| `--redelivery-timeout` | integer | `2 Γ— llm_task_timeout_minutes` (`600` seconds with default config) | Seconds to wait before a task is redelivered to another worker if the current worker fails or times out | + +**Example** + +```bash +agent-memory task-worker --concurrency 5 --redelivery-timeout 600 +``` + +--- + +## `schedule-task` + +Schedule a background task to be processed by a Docket worker. + +**Syntax** + +```bash +agent-memory schedule-task [OPTIONS] +``` + +**Arguments** + +| Argument | Description | +|---|---| +| `TASK_PATH` | Python import path to the task function (e.g. `agent_memory_server.long_term_memory.compact_long_term_memories`) | + +**Options** + +| Option | Description | +|---|---| +| `-a`, `--args TEXT` | Arguments to pass to the task in `key=value` format. Repeatable. Values are auto-converted to bool, integer, or float when possible; otherwise they remain strings. | + +**Example** + +```bash +agent-memory schedule-task "agent_memory_server.long_term_memory.compact_long_term_memories" \ + -a limit=500 \ + -a namespace=my_namespace \ + -a compact_semantic_duplicates=false +``` + +--- + +## `rebuild_index` + +Rebuild the Redis search index. + +**Syntax** + +```bash +agent-memory rebuild_index +``` + +--- + +## `migrate-memories` + +Run the built-in long-term memory migrations. Safe to rerun. Use this after upgrading if you need to backfill fields on existing memory records. + +**Syntax** + +```bash +agent-memory migrate-memories +``` + +--- + +## `migrate-working-memory` + +Migrate legacy `working_memory:*` string keys to Redis JSON. Use this if you are upgrading from an older working-memory format or if you want to remove deprecated legacy `sessions` / `sessions:*` sorted sets from the old session-listing path. + +**Syntax** + +```bash +agent-memory migrate-working-memory [OPTIONS] +``` + +**Options** + +| Option | Description | +|---|---| +| `--dry-run` | Report what would be migrated without making any changes | + +**Examples** + +```bash +# Inspect what would change +agent-memory migrate-working-memory --dry-run + +# Run the migration +agent-memory migrate-working-memory +``` + +--- + +## `token` + +Manage authentication tokens for token-based authentication. This command group provides subcommands for creating, listing, viewing, and removing API tokens. + +**Syntax** + +```bash +agent-memory token [OPTIONS] +``` + +**Subcommands** + +| Subcommand | Description | +|---|---| +| [`add`](#token-add) | Create a new authentication token | +| [`list`](#token-list) | List all authentication tokens | +| [`show`](#token-show) | Show detailed information about a specific token | +| [`remove`](#token-remove) | Remove an authentication token | + +**Security features** + +- All tokens are hashed using bcrypt before storage +- Tokens automatically expire based on Redis TTL if an expiration is set +- The server never stores plaintext tokens +- Partial hash matching is supported for CLI convenience + +### `token add` + +Create a new authentication token. + +**Syntax** + +```bash +agent-memory token add --description [OPTIONS] +``` + +**Required options** + +| Option | Description | +|---|---| +| `-d`, `--description TEXT` | Description for the token (e.g. "API access for service X") | + +**Optional options** + +| Option | Default | Description | +|---|---|---| +| `-e`, `--expires-days INTEGER` | never expires | Number of days until the token expires | +| `--format` `text` \| `json` | `text` | Output format. `json` is recommended for CI and scripting. | +| `--token TEXT` | auto-generated | Use a pre-generated token value instead of letting the CLI generate one. The CLI hashes and stores the provided token; store the plaintext securely in your secrets manager or CI system. | + +**Examples** + +```bash +# Create a token that expires in 30 days +agent-memory token add --description "API access token" --expires-days 30 + +# Create a permanent token (no expiration) +agent-memory token add --description "Service account token" + +# Create a token and return JSON (for CI/scripts) +agent-memory token add --description "CI token" --expires-days 30 --format json + +# Register a pre-generated token (e.g., from a secrets manager) +agent-memory token add --description "Terraform bootstrap" --token "$MY_TOKEN" --format json +``` + +!!! warning "Token shown only once" + + The generated token is displayed only once. Store it securely; it cannot be retrieved again. + +### `token list` + +List all authentication tokens, showing masked token hashes, descriptions, and expiration dates. + +**Syntax** + +```bash +agent-memory token list [OPTIONS] +``` + +**Options** + +| Option | Default | Description | +|---|---|---| +| `--format` `text` \| `json` | `text` | Output format. `json` returns a machine-readable array suitable for CI pipelines. | + +**Text output example** + +``` +Authentication Tokens: +================================================== +Token: abc12345...xyz67890 +Description: API access token +Created: 2025-07-10T18:30:00.000000+00:00 +Expires: 2025-08-09T18:30:00.000000+00:00 +------------------------------ +Token: def09876...uvw54321 +Description: Service account token +Created: 2025-07-10T19:00:00.000000+00:00 +Expires: Never +------------------------------ +``` + +**JSON output example** + +```json +[ + { + "hash": "abc12345def67890xyz", + "description": "API access token", + "created_at": "2025-07-10T18:30:00.000000+00:00", + "expires_at": "2025-08-09T18:30:00.000000+00:00", + "status": "Active" + }, + { + "hash": "def09876uvw54321...", + "description": "Service account token", + "created_at": "2025-07-10T19:00:00.000000+00:00", + "expires_at": null, + "status": "Never Expires" + } +] +``` + +### `token show` + +Show detailed information about a specific token. Supports partial hash matching for convenience. + +**Syntax** + +```bash +agent-memory token show [OPTIONS] +``` + +**Arguments** + +| Argument | Description | +|---|---| +| `TOKEN_HASH` | The token hash (or partial hash) to display. Can be the full hash or just the first few characters; partial hashes must be unique. | + +**Options** + +| Option | Default | Description | +|---|---|---| +| `--format` `text` \| `json` | `text` | Output format. `json` returns a machine-readable object including status. | + +**Examples** + +```bash +# Show token details using full hash +agent-memory token show abc12345def67890xyz + +# Show token details using partial hash (must be unique) +agent-memory token show abc123 +``` + +**JSON output example** + +```json +{ + "hash": "abc12345def67890xyz", + "description": "API access token", + "created_at": "2025-07-10T18:30:00.000000+00:00", + "expires_at": "2025-08-09T18:30:00.000000+00:00", + "status": "Active" +} +``` + +### `token remove` + +Remove an authentication token. By default, asks for confirmation before removal. + +**Syntax** + +```bash +agent-memory token remove [OPTIONS] +``` + +**Arguments** + +| Argument | Description | +|---|---| +| `TOKEN_HASH` | The token hash (or partial hash) to remove. Can be the full hash or just the first few characters. | + +**Options** + +| Option | Description | +|---|---| +| `-f`, `--force` | Remove the token without asking for confirmation | + +**Examples** + +```bash +# Remove token with confirmation prompt +agent-memory token remove abc123 + +# Remove token without confirmation +agent-memory token remove abc123 --force +``` diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 00000000..a7e4af27 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,102 @@ +--- +description: API reference for Agent Memory Server. +--- + +# API Reference + +Every interface for talking to the memory server: HTTP endpoints, the MCP +toolset for AI agents, the CLI for operators, and three client SDKs. +Pick the one that matches your stack β€” they all sit on top of the same +core memory operations. + +## Server Interfaces + +
+ +- :material-web:{ .lg .middle } **[REST API](rest.md)** + + --- + + OpenAPI-described HTTP endpoints for working memory, long-term memory, and prompts. + +- :material-protocol:{ .lg .middle } **[MCP server](mcp.md)** + + --- + + Model Context Protocol tools for AI agent integration (Claude Desktop, etc.). + +- :material-console:{ .lg .middle } **[CLI](cli.md)** + + --- + + Command-line interface for running, indexing, migrating, and scheduling tasks. + +
+ +## Client SDKs + +
+ +- :material-language-python:{ .lg .middle } **[Python SDK](python_sdk.md)** + + --- + + Async-first Python client with tool schemas for OpenAI and Anthropic. + +- :material-language-typescript:{ .lg .middle } **[TypeScript SDK](typescript_sdk.md)** + + --- + + Type-safe client for Node.js and browser applications. + +- :material-coffee:{ .lg .middle } **[Java SDK](java_sdk.md)** + + --- + + JVM client for Java and Kotlin applications. + +
+ +## Source Reference + +
+ +- :material-package:{ .lg .middle } **[Server package](server/index.md)** + + --- + + Auto-generated `agent_memory_server` Python package reference, built from source via [mkdocstrings](https://mkdocstrings.github.io/). + +
+ +## Interface Comparison + +| Interface | Best For | Authentication | +|-----------|----------|----------------| +| REST API | Applications, backends, custom integrations | OAuth2/JWT or token | +| MCP Server | Claude Desktop, MCP-compatible AI agents | Environment config | +| CLI | Server administration, development | Local access | +| Python SDK | Python applications with LLM tool integration | Token or OAuth2 | +| TypeScript SDK | Node.js, browser, and TypeScript applications | Token or OAuth2 | +| Java SDK | JVM-based applications | Token or OAuth2 | + +## Feature Cross-Reference + +| Feature | REST API | MCP Server | CLI | Documentation | +|---------|----------|------------|-----|---------------| +| **Memory Search** (semantic, keyword, hybrid) | βœ… `/v1/long-term-memory/search` | βœ… `search_long_term_memory` | βœ… `agent-memory search` | [REST](rest.md), [MCP](mcp.md), [CLI](cli.md) | +| **Memory Editing** | βœ… `PATCH /v1/long-term-memory/{id}` | βœ… `edit_long_term_memory` | ❌ | [Memory Editing](../user_guide/how_to_guides/memory_editing.md) | +| **Query Optimization** | βœ… `optimize_query` param | βœ… `optimize_query` param | ❌ | [Query Optimization](../user_guide/how_to_guides/query_optimization.md) | +| **Recency Boost** | βœ… Default enabled | βœ… Available | ❌ | [Recency Boost](../concepts/recency_boost.md) | +| **Authentication** | βœ… JWT/Token | βœ… Inherited | βœ… Token management | [Authentication](../user_guide/how_to_guides/authentication.md) | +| **Background Tasks** | βœ… Automatic | βœ… Automatic | βœ… Worker management | [Configuration](../user_guide/how_to_guides/configuration.md) | + +## By Interface Preference + +**REST API users** β†’ [REST API Documentation](rest.md) β†’ [Authentication](../user_guide/how_to_guides/authentication.md) +**MCP/Claude users** β†’ [MCP Server](mcp.md) β†’ [Memory Editing](../user_guide/how_to_guides/memory_editing.md) +**CLI management** β†’ [CLI Reference](cli.md) β†’ [Configuration](../user_guide/how_to_guides/configuration.md) + +!!! tip "Interactive API Docs" + When running the server locally, visit `http://localhost:8000/docs` for + interactive Swagger documentation where you can try endpoints directly. diff --git a/docs/java-sdk.md b/docs/api/java_sdk.md similarity index 100% rename from docs/java-sdk.md rename to docs/api/java_sdk.md diff --git a/docs/mcp.md b/docs/api/mcp.md similarity index 94% rename from docs/mcp.md rename to docs/api/mcp.md index b31b9a6c..7601547c 100644 --- a/docs/mcp.md +++ b/docs/api/mcp.md @@ -88,8 +88,8 @@ For Claude, the easiest way is to use uvx (recommended): Notes: - API keys: Default models use OpenAI. Set `OPENAI_API_KEY`. To use Anthropic instead, set `ANTHROPIC_API_KEY` and also `GENERATION_MODEL` to an Anthropic model (e.g., `claude-3-5-haiku-20241022`). - Make sure your MCP host can find `uvx` (on its PATH or by using an absolute command path). - - macOS: `brew install uv` - - If not on PATH, set `"command"` to an absolute path (e.g., `/opt/homebrew/bin/uvx` on Apple Silicon, `/usr/local/bin/uvx` on Intel macOS). On Linux, `~/.local/bin/uvx` is common. See https://docs.astral.sh/uv/getting-started/ for distro specifics + - macOS: `brew install uv` + - If not on PATH, set `"command"` to an absolute path (e.g., `/opt/homebrew/bin/uvx` on Apple Silicon, `/usr/local/bin/uvx` on Intel macOS). On Linux, `~/.local/bin/uvx` is common. See https://docs.astral.sh/uv/getting-started/ for distro specifics - Set `DISABLE_AUTH=false` in production and configure proper auth per the Authentication guide. If you’re running from a local checkout instead of PyPI, you can use `uv run` with a directory: diff --git a/docs/python-sdk.md b/docs/api/python_sdk.md similarity index 100% rename from docs/python-sdk.md rename to docs/api/python_sdk.md diff --git a/docs/api.md b/docs/api/rest.md similarity index 100% rename from docs/api.md rename to docs/api/rest.md diff --git a/docs/api/server/auth.md b/docs/api/server/auth.md new file mode 100644 index 00000000..aa6126cb --- /dev/null +++ b/docs/api/server/auth.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.auth reference. +--- + +# auth + +::: agent_memory_server.auth diff --git a/docs/api/server/config.md b/docs/api/server/config.md new file mode 100644 index 00000000..1d60c872 --- /dev/null +++ b/docs/api/server/config.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.config reference. +--- + +# config + +::: agent_memory_server.config diff --git a/docs/api/server/extraction.md b/docs/api/server/extraction.md new file mode 100644 index 00000000..f448495d --- /dev/null +++ b/docs/api/server/extraction.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.extraction reference. +--- + +# extraction + +::: agent_memory_server.extraction diff --git a/docs/api/server/filters.md b/docs/api/server/filters.md new file mode 100644 index 00000000..493da0c5 --- /dev/null +++ b/docs/api/server/filters.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.filters reference. +--- + +# filters + +::: agent_memory_server.filters diff --git a/docs/api/server/index.md b/docs/api/server/index.md new file mode 100644 index 00000000..421a7dc9 --- /dev/null +++ b/docs/api/server/index.md @@ -0,0 +1,79 @@ +--- +description: Reference for the agent_memory_server Python package. +--- + +# Server package reference + +Auto-generated reference for the `agent_memory_server` Python package. +Module pages are generated from Google-style docstrings via +[mkdocstrings](https://mkdocstrings.github.io/). + +
+ +- :material-database:{ .lg .middle } **[Models](models.md)** + + --- + + Pydantic data models for memory records, sessions, and search payloads. + +- :material-memory:{ .lg .middle } **[Working memory](working_memory.md)** + + --- + + Session-scoped memory APIs for messages, structured memories, and metadata. + +- :material-database-search:{ .lg .middle } **[Long-term memory](long_term_memory.md)** + + --- + + Persistent memory with semantic search, deduplication, and compaction. + +- :material-strategy:{ .lg .middle } **[Memory strategies](memory_strategies.md)** + + --- + + Pluggable strategies for promoting working memory into long-term storage. + +- :material-vector-line:{ .lg .middle } **[Vector DB](memory_vector_db.md)** + + --- + + Vector database abstraction and factory used by the long-term memory layer. + +- :material-text-search:{ .lg .middle } **[Extraction](extraction.md)** + + --- + + Topic and entity extraction (LLM and BERT-based) over message streams. + +- :material-text-box-outline:{ .lg .middle } **[Summarization](summarization.md)** + + --- + + Conversation summarization when context windows are exceeded. + +- :material-filter:{ .lg .middle } **[Filters](filters.md)** + + --- + + Filter primitives (session, namespace, topics, entities, timestamps). + +- :material-shield-key:{ .lg .middle } **[Auth](auth.md)** + + --- + + OAuth2/JWT verification and JWKS handling. + +- :material-cog:{ .lg .middle } **[Config](config.md)** + + --- + + Settings loaded from environment variables. + +- :material-robot:{ .lg .middle } **[LLM client](llm.md)** + + --- + + LiteLLM-backed chat and embedding client. + +
diff --git a/docs/api/server/llm.md b/docs/api/server/llm.md new file mode 100644 index 00000000..e3ec979b --- /dev/null +++ b/docs/api/server/llm.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.llm reference. +--- + +# llm + +::: agent_memory_server.llm diff --git a/docs/api/server/long_term_memory.md b/docs/api/server/long_term_memory.md new file mode 100644 index 00000000..4400492d --- /dev/null +++ b/docs/api/server/long_term_memory.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.long_term_memory reference. +--- + +# long_term_memory + +::: agent_memory_server.long_term_memory diff --git a/docs/api/server/memory_strategies.md b/docs/api/server/memory_strategies.md new file mode 100644 index 00000000..e2fa77ea --- /dev/null +++ b/docs/api/server/memory_strategies.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.memory_strategies reference. +--- + +# memory_strategies + +::: agent_memory_server.memory_strategies diff --git a/docs/api/server/memory_vector_db.md b/docs/api/server/memory_vector_db.md new file mode 100644 index 00000000..288b1365 --- /dev/null +++ b/docs/api/server/memory_vector_db.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.memory_vector_db reference. +--- + +# memory_vector_db + +::: agent_memory_server.memory_vector_db diff --git a/docs/api/server/models.md b/docs/api/server/models.md new file mode 100644 index 00000000..16119e90 --- /dev/null +++ b/docs/api/server/models.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.models reference. +--- + +# models + +::: agent_memory_server.models diff --git a/docs/api/server/summarization.md b/docs/api/server/summarization.md new file mode 100644 index 00000000..2496e772 --- /dev/null +++ b/docs/api/server/summarization.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.summarization reference. +--- + +# summarization + +::: agent_memory_server.summarization diff --git a/docs/api/server/working_memory.md b/docs/api/server/working_memory.md new file mode 100644 index 00000000..9b436e2e --- /dev/null +++ b/docs/api/server/working_memory.md @@ -0,0 +1,7 @@ +--- +description: agent_memory_server.working_memory reference. +--- + +# working_memory + +::: agent_memory_server.working_memory diff --git a/docs/typescript-sdk.md b/docs/api/typescript_sdk.md similarity index 100% rename from docs/typescript-sdk.md rename to docs/api/typescript_sdk.md diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 00000000..55f78869 Binary files /dev/null and b/docs/assets/favicon.png differ diff --git a/docs/assets/redis-ai-hub/redis-ai-hub-config.js b/docs/assets/redis-ai-hub/redis-ai-hub-config.js new file mode 100644 index 00000000..f2974ada --- /dev/null +++ b/docs/assets/redis-ai-hub/redis-ai-hub-config.js @@ -0,0 +1,4 @@ +// redis-ai-hub: per-library config (loaded before the header script) +window.REDIS_AI_HUB_URL = "/"; +window.REDIS_AI_HUB_LIBRARY = "agent-memory"; +window.REDIS_AI_HUB_CATEGORY = "core"; diff --git a/docs/assets/redis-ai-hub/redis-ai-hub-header.css b/docs/assets/redis-ai-hub/redis-ai-hub-header.css new file mode 100644 index 00000000..43d85785 --- /dev/null +++ b/docs/assets/redis-ai-hub/redis-ai-hub-header.css @@ -0,0 +1,128 @@ +/* Redis AI Hub: shared header styling + * Uses official redis-docs brand palette (from tailwind.config.js) + */ + +#rah-header { + position: sticky; + top: 0; + z-index: 9999; + background: #161F31; + color: #f3f4f6; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Space Grotesk", system-ui, sans-serif; + border-bottom: 1px solid #2D4754; + box-shadow: 0 1px 3px rgba(0,0,0,0.12); +} + +.rah-bar { + display: flex; + align-items: center; + gap: 24px; + padding: 10px 20px; + max-width: 100%; +} + +.rah-brand { + display: flex; + align-items: center; + gap: 8px; + color: #fff !important; + text-decoration: none !important; + font-weight: 700; + font-size: 15px; + white-space: nowrap; +} +.rah-brand:hover { opacity: 0.85; } + +.rah-nav { display: flex; align-items: center; gap: 4px; flex: 1; } + +.rah-dropdown { position: relative; } +.rah-dropdown-btn, +.rah-link { + background: none; + border: none; + color: #B9C2C6; + font-size: 14px; + padding: 6px 12px; + cursor: pointer; + border-radius: 4px; + text-decoration: none !important; + font-weight: 500; +} +.rah-dropdown-btn:hover, +.rah-link:hover { background: rgba(255,255,255,0.06); color: #fff; } +.rah-caret { font-size: 10px; opacity: 0.6; } + +.rah-dropdown-menu { + display: none; + position: absolute; + top: 100%; + left: 0; + margin-top: 4px; + background: #161F31; + border: 1px solid #2D4754; + border-radius: 6px; + min-width: 180px; + padding: 6px; + box-shadow: 0 8px 24px rgba(0,0,0,0.35); +} +.rah-dropdown:hover .rah-dropdown-menu, +.rah-dropdown:focus-within .rah-dropdown-menu { display: block; } + +.rah-item { + display: block; + padding: 8px 12px; + color: #E8EBEC !important; + text-decoration: none !important; + border-radius: 4px; + font-size: 13.5px; +} +.rah-item:hover { background: rgba(255,68,56,0.12); color: #FF4438 !important; } +.rah-item--active { color: #FF4438 !important; font-weight: 600; } + +.rah-actions { display: flex; gap: 10px; align-items: center; } +.rah-search { + background: rgba(255,255,255,0.08); + border: 1px solid #2D4754; + color: #B9C2C6; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + cursor: pointer; + font-family: inherit; +} +.rah-search:hover { background: rgba(255,255,255,0.14); color: #fff; } +.rah-gh { + color: #B9C2C6 !important; + text-decoration: none !important; + font-size: 13px; + padding: 6px 10px; + border-radius: 4px; +} +.rah-gh:hover { color: #fff !important; background: rgba(255,255,255,0.06); } + +.rah-tabs { + display: flex; + gap: 0; + padding: 0 20px; + border-top: 1px solid #2D4754; + background: #091A23; + overflow-x: auto; +} +.rah-tab { + color: #8A99A0 !important; + text-decoration: none !important; + padding: 10px 16px; + font-size: 13px; + border-bottom: 2px solid transparent; + white-space: nowrap; + font-weight: 500; +} +.rah-tab:hover { color: #E8EBEC !important; } +.rah-tab--active { + color: #FF4438 !important; + border-bottom-color: #FF4438; + font-weight: 600; +} + +/* Make sure the host site's own navbar starts below ours */ +body { padding-top: 0; } diff --git a/docs/assets/redis-ai-hub/redis-ai-hub-header.js b/docs/assets/redis-ai-hub/redis-ai-hub-header.js new file mode 100644 index 00000000..b9d16dc2 --- /dev/null +++ b/docs/assets/redis-ai-hub/redis-ai-hub-header.js @@ -0,0 +1,90 @@ +// Redis AI Hub: shared header injector +// Renders a persistent top bar on every per-library docs site. +// In production, this would be injected by the central host (CDN edge or reverse proxy). +// In the prototype, each site bundles this JS and injects on DOMContentLoaded. + +(function () { + const HUB_URL = (window.REDIS_AI_HUB_URL || '/').replace(/\/+$/, '/') || '/'; + const CURRENT = window.REDIS_AI_HUB_LIBRARY || ''; + + const LIBRARIES = { + core: [ + { slug: 'redisvl', name: 'RedisVL', path: 'redisvl/' }, + { slug: 'agent-memory', name: 'Agent Memory', path: 'agent-memory/' }, + { slug: 'agent-kit', name: 'Agent Kit', path: 'agent-kit/' }, + { slug: 'sre-agent', name: 'SRE Agent', path: 'sre-agent/' }, + ], + integration: [ + { slug: 'adk', name: 'Google ADK', path: 'adk/' }, + { slug: 'langchain', name: 'LangChain', path: 'langchain/' }, + { slug: 'langgraph', name: 'LangGraph', path: 'langgraph/' }, + ], + tool: [ + { slug: 'sql', name: 'SQL for Redis', path: 'sql/' }, + { slug: 'optimizer', name: 'Retrieval Optimizer', path: 'optimizer/' }, + ], + content: [ + { slug: 'recipes', name: 'AI Recipes', path: 'recipes/' }, + ], + }; + + function dropdown(label, items) { + const links = items.map(it => { + const isCurrent = it.slug === CURRENT; + return `${it.name}`; + }).join(''); + return ` +
+ +
${links}
+
`; + } + + function siblingTabs() { + let category = null; + for (const cat of Object.keys(LIBRARIES)) { + if (LIBRARIES[cat].some(l => l.slug === CURRENT)) { category = cat; break; } + } + if (!category) return ''; + const tabs = LIBRARIES[category].map(it => { + const isCurrent = it.slug === CURRENT; + return `${it.name}`; + }).join(''); + return `
${tabs}
`; + } + + function inject() { + if (document.getElementById('rah-header')) return; + const header = document.createElement('div'); + header.id = 'rah-header'; + header.innerHTML = ` +
+ + + Redis AI + + +
+ + β˜… GitHub +
+
+ ${siblingTabs()} + `; + document.body.insertBefore(header, document.body.firstChild); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', inject); + } else { + inject(); + } +})(); diff --git a/docs/assets/redis-logo-script-red.svg b/docs/assets/redis-logo-script-red.svg new file mode 100644 index 00000000..b2abedae --- /dev/null +++ b/docs/assets/redis-logo-script-red.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/assets/redis-logo-script.svg b/docs/assets/redis-logo-script.svg new file mode 100644 index 00000000..0f59d4c7 --- /dev/null +++ b/docs/assets/redis-logo-script.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100644 index b3592364..00000000 --- a/docs/cli.md +++ /dev/null @@ -1,322 +0,0 @@ -# Command Line Interface - -The `agent-memory-server` provides a command-line interface (CLI) for managing the server and related tasks. You can access the CLI using the `agent-memory` command (assuming the package is installed in a way that makes the script available in your PATH, e.g., via `pip install ...`). - -## Available Commands - -Here's a list of available commands and their functions: - -### `version` - -Displays the current version of `agent-memory-server`. - -```bash -agent-memory version -``` - -### `api` - -Starts the REST API server. - -```bash -agent-memory api [OPTIONS] -``` - -**Options:** - -- `--port INTEGER`: Port to run the server on. (Default: value from `settings.port`, usually 8000) -- `--host TEXT`: Host to run the server on. (Default: "0.0.0.0") -- `--reload`: Enable auto-reload for development. -- `--task-backend [asyncio|docket]`: Background task backend. `docket` (default) uses Docket-based background workers (requires a running `agent-memory task-worker` for non-blocking tasks). `asyncio` runs tasks inline in the API process and does **not** require a separate worker. -- `--no-worker` (**deprecated**): Backwards-compatible alias for `--task-backend=asyncio`. Maintained for older scripts; prefer `--task-backend`. - -**Examples:** - -```bash -# Development mode (no separate worker needed, asyncio backend) -agent-memory api --port 8080 --reload --task-backend asyncio - -# Production mode (default Docket backend; requires separate worker process) -agent-memory api --port 8080 -``` - -!!! warning "Limitations of `--task-backend=asyncio`" - The `asyncio` backend is suitable for development and simple use cases, but has important limitations: - - - **Periodic tasks don't run**: Scheduled maintenance tasks like memory compaction, periodic forgetting, and summary view refresh only execute when a Docket worker is running. These tasks use Docket's `Perpetual` scheduler. - - **No task persistence**: If the server restarts, pending background tasks are lost. - - **No distributed processing**: All tasks run in the API process; you cannot scale workers independently. - - For production deployments, use the default `docket` backend with a separate `agent-memory task-worker` process. - -### `mcp` - -Starts the Model Context Protocol (MCP) server. - -```bash -agent-memory mcp [OPTIONS] -``` - -**Options:** - -- `--port INTEGER`: Port to run the MCP server on. (Default: value from `settings.mcp_port`, usually 9000) -- `--mode [stdio|sse|streamable-http]`: Run the MCP server in stdio, SSE, or streamable-http mode. (Default: stdio) -- `--task-backend [asyncio|docket]`: Background task backend. `asyncio` (default) runs tasks inline in the MCP process with no separate worker. `docket` sends tasks to a Docket queue, which requires running `agent-memory task-worker`. - -**Examples:** - -```bash -# Stdio mode (recommended for Claude Desktop) - default asyncio backend -agent-memory mcp - -# SSE mode for development (no separate worker needed) -agent-memory mcp --mode sse --port 9001 - -# Streamable HTTP mode for network deployments (e.g. Kubernetes) -agent-memory mcp --mode streamable-http --port 9000 - -# SSE mode for production (requires separate worker process) -agent-memory mcp --mode sse --port 9001 --task-backend docket -``` - -**Note:** Stdio mode is designed for tools like Claude Desktop and, by default, uses the asyncio backend (no worker). Streamable HTTP mode is suited for deploying the MCP server as a network service where HTTP clients (like Claude Code) connect over the network. Use `--task-backend docket` if you want MCP to enqueue background work into a shared Docket worker. - -### `schedule-task` - -Schedules a background task to be processed by a Docket worker. - -```bash -agent-memory schedule-task [OPTIONS] -``` - -**Arguments:** - -- `TASK_PATH`: The Python import path to the task function. For example: `"agent_memory_server.long_term_memory.compact_long_term_memories"` - -**Options:** - -- `--args TEXT` / `-a TEXT`: Arguments to pass to the task in `key=value` format. Can be specified multiple times. Values are automatically converted to boolean, integer, or float if possible, otherwise they remain strings. - -Example: - -```bash -agent-memory schedule-task "agent_memory_server.long_term_memory.compact_long_term_memories" -a limit=500 -a namespace=my_namespace -a compact_semantic_duplicates=false -``` - -### `task-worker` - -Starts a Docket worker to process background tasks from the queue. This worker uses the Docket name configured in settings. - -```bash -agent-memory task-worker [OPTIONS] -``` - -**Options:** - -- `--concurrency INTEGER`: Number of tasks to process concurrently. (Default: 10) -- `--redelivery-timeout INTEGER`: Seconds to wait before a task is redelivered to another worker if the current worker fails or times out. (Default: `2 x llm_task_timeout_minutes` from server settings; with the default config, this is 600 seconds.) - -Example: - -```bash -agent-memory task-worker --concurrency 5 --redelivery-timeout 600 -``` - -### `rebuild_index` - -Rebuilds the search index for Redis Memory Server. - -```bash -agent-memory rebuild_index -``` - -### `migrate-memories` - -Runs the built-in long-term memory migrations. Safe to rerun. - -Use this after upgrading if you need to backfill fields on existing memory -records. - -```bash -uv run agent-memory migrate-memories -``` - -### `migrate-working-memory` - -Migrates legacy `working_memory:*` string keys to Redis JSON. - -Use this if you are upgrading from an older working-memory format or if you -want to remove deprecated legacy `sessions` / `sessions:*` sorted sets from the -old session-listing path. - -Check what needs migration first: - -```bash -uv run agent-memory migrate-working-memory --dry-run -``` - -Run the migration: - -```bash -uv run agent-memory migrate-working-memory -``` - -### `token` Commands - -Manages authentication tokens for token-based authentication. The token command group provides subcommands for creating, listing, viewing, and removing API tokens. - -#### `token add` - -Creates a new authentication token. - -```bash -agent-memory token add --description "DESCRIPTION" [--expires-days DAYS] [--format text|json] [--token TOKEN_VALUE] -``` - -**Options:** - -- `--description TEXT` / `-d TEXT`: **Required**. Description for the token (e.g., "API access for service X") -- `--expires-days INTEGER` / `-e INTEGER`: **Optional**. Number of days until token expires. If not specified, token never expires. -- `--format [text|json]`: **Optional**. Output format. `text` (default) is human-readable; `json` is machine-readable and recommended for CI or scripting. -- `--token TEXT`: **Optional**. Use a pre-generated token value instead of having the CLI generate one. The CLI will hash and store the provided token; make sure you've stored the plaintext securely in your secrets manager or CI system. - -**Examples:** - -```bash -# Create a token that expires in 30 days -agent-memory token add --description "API access token" --expires-days 30 - -# Create a permanent token (no expiration) -agent-memory token add --description "Service account token" - -# Create a token and return JSON (for CI/scripts) -agent-memory token add --description "CI token" --expires-days 30 --format json - -# Register a pre-generated token (e.g., from a secrets manager) -agent-memory token add --description "Terraform bootstrap" --token "$MY_TOKEN" --format json -``` - -**Security Note:** The generated token is displayed only once. Store it securely as it cannot be retrieved again. - -#### `token list` - -Lists all authentication tokens, showing masked token hashes, descriptions, and expiration dates. - -```bash -agent-memory token list [--format text|json] -``` - -When `--format json` is used, the command prints a JSON array of token summaries suitable for scripting and CI pipelines. The default `text` format produces human-readable output like the example below. -**JSON Output Example:** -```json -[ - { - "hash": "abc12345def67890xyz", - "description": "API access token", - "created_at": "2025-07-10T18:30:00.000000+00:00", - "expires_at": "2025-08-09T18:30:00.000000+00:00", - "status": "Active" - }, - { - "hash": "def09876uvw54321...", - "description": "Service account token", - "created_at": "2025-07-10T19:00:00.000000+00:00", - "expires_at": null, - "status": "Never Expires" - } -] -``` - -**Example Output:** -``` -Authentication Tokens: -================================================== -Token: abc12345...xyz67890 -Description: API access token -Created: 2025-07-10T18:30:00.000000+00:00 -Expires: 2025-08-09T18:30:00.000000+00:00 ------------------------------- -Token: def09876...uvw54321 -Description: Service account token -Created: 2025-07-10T19:00:00.000000+00:00 -Expires: Never ------------------------------- -``` - -#### `token show` - -Shows detailed information about a specific token. Supports partial hash matching for convenience. - -```bash -agent-memory token show TOKEN_HASH [--format text|json] -``` - -When `--format json` is used, the command prints a JSON object with token details (including status) suitable for scripting and CI pipelines. The default `text` format produces human-readable output. -**JSON Output Example:** -```json -{ - "hash": "abc12345def67890xyz", - "description": "API access token", - "created_at": "2025-07-10T18:30:00.000000+00:00", - "expires_at": "2025-08-09T18:30:00.000000+00:00", - "status": "Active" -} -``` - -**Arguments:** - -- `TOKEN_HASH`: The token hash (or partial hash) to display. Can be the full hash or just the first few characters. - -**Examples:** - -```bash -# Show token details using full hash -agent-memory token show abc12345def67890xyz - -# Show token details using partial hash (must be unique) -agent-memory token show abc123 -``` - -#### `token remove` - -Removes an authentication token. By default, asks for confirmation before removal. - -```bash -agent-memory token remove TOKEN_HASH [--force] -``` - -**Arguments:** - -- `TOKEN_HASH`: The token hash (or partial hash) to remove. Can be the full hash or just the first few characters. - -**Options:** - -- `--force` / `-f`: Remove the token without asking for confirmation. - -**Examples:** - -```bash -# Remove token with confirmation prompt -agent-memory token remove abc123 - -# Remove token without confirmation -agent-memory token remove abc123 --force -``` - -**Security Features:** - -- All tokens are hashed using bcrypt before storage -- Tokens automatically expire based on Redis TTL if expiration is set -- Server never stores plaintext tokens -- Partial hash matching for CLI convenience - -## Getting Help - -To see help for any command, you can use `--help`: - -```bash -agent-memory --help -agent-memory api --help -agent-memory mcp --help -# etc. -``` diff --git a/docs/contextual-grounding.md b/docs/concepts/contextual_grounding.md similarity index 98% rename from docs/contextual-grounding.md rename to docs/concepts/contextual_grounding.md index c827ee49..7ebc39e0 100644 --- a/docs/contextual-grounding.md +++ b/docs/concepts/contextual_grounding.md @@ -125,7 +125,7 @@ Contextual grounding works with any supported language model, but performance va - **claude-3-5-sonnet**: Excellent at contextual understanding - **claude-3-haiku**: Fast, good for simple grounding -See [LLM Providers](llm-providers.md) for complete model configuration options. +See [LLM Providers](../user_guide/how_to_guides/llm_providers.md) for complete model configuration options. ## Usage Examples diff --git a/docs/concepts/index.md b/docs/concepts/index.md new file mode 100644 index 00000000..4cdf3048 --- /dev/null +++ b/docs/concepts/index.md @@ -0,0 +1,89 @@ +--- +description: Foundational concepts for Agent Memory Server. +--- + +# Concepts + +Memory in this system has **two tiers**. **Working memory** holds the live +conversation for a single session. **Long-term memory** holds anything +worth keeping across conversations β€” facts, preferences, decisions. The +**lifecycle** pages cover how content moves between the two tiers +(extraction, promotion, deduplication, eventual forgetting). Everything +else on this page is a mechanism that supports those two tiers. + +If you only read two pages, read [Working memory](working_memory.md) and +[Long-term memory](long_term_memory.md). Then come back for the rest. + +
+ +- :material-brain:{ .lg .middle } **[Working memory](working_memory.md)** + + --- + + Session-scoped conversation state with automatic summarization and context tracking. + +- :material-database:{ .lg .middle } **[Long-term memory](long_term_memory.md)** + + --- + + Persistent storage with semantic, keyword, and hybrid search across sessions. + +- :material-chart-box:{ .lg .middle } **[Summary views](summary_views.md)** + + --- + + Aggregated views of memory content for dashboards and analytics. + +- :material-refresh:{ .lg .middle } **[Memory lifecycle](memory_lifecycle.md)** + + --- + + How memories are created, promoted, deduplicated, and eventually forgotten. + +- :material-magnify:{ .lg .middle } **[Memory extraction](memory_extraction.md)** + + --- + + How important facts are automatically extracted from conversations. + +- :material-link-variant:{ .lg .middle } **[Contextual grounding](contextual_grounding.md)** + + --- + + How retrieved memories are injected into prompts at the right moment. + +- :material-sort-clock-descending:{ .lg .middle } **[Recency boost](recency_boost.md)** + + --- + + Tunable scoring that biases newer memories without losing semantic relevance. + +
+ +## Related Topics + +| Topic | Description | +|-------|-------------| +| [LangChain Integration](../examples/langchain.md) | Use memory with LangChain agents and chains | +| [Custom Memory Vector Databases](../user_guide/how_to_guides/custom_vector_db.md) | Configure Redis or a custom vector backend | +| [Use cases](../examples/use_cases.md) | What people actually build with this β€” read this if you're still deciding | + +## When to Use Advanced Features + +| Feature | Use When | +|---------|----------| +| [Query Optimization](../user_guide/how_to_guides/query_optimization.md) | Search results aren't matching user intent well | +| [Recency Boost](recency_boost.md) | Recent memories should rank higher than older ones | +| [Advanced Vector Config](../user_guide/how_to_guides/advanced_vector_db.md) | You need to tune performance or use custom distance metrics | +| [Contextual Grounding](contextual_grounding.md) | Extracted memories contain unresolved pronouns like "he" or "it" | +| [Memory Editing](../user_guide/how_to_guides/memory_editing.md) | You need to correct, enrich, or update stored memories after creation | + +## Where to Start + +**Building a chatbot?** Start with [Memory Integration Patterns](../user_guide/how_to_guides/integration_patterns.md) to understand your options. + +**Need to understand the data model?** Read [Working Memory](working_memory.md) and [Long-term Memory](long_term_memory.md). + +**Configuring extraction behavior?** See [Memory Extraction](memory_extraction.md). + +**Looking for server configuration?** See the [How-To Guides](../user_guide/how_to_guides/index.md) for authentication, LLM providers, and deployment. diff --git a/docs/long-term-memory.md b/docs/concepts/long_term_memory.md similarity index 88% rename from docs/long-term-memory.md rename to docs/concepts/long_term_memory.md index fe606c53..8954ec17 100644 --- a/docs/long-term-memory.md +++ b/docs/concepts/long_term_memory.md @@ -21,7 +21,7 @@ Long-term memory provides persistent storage that survives server restarts and s - **Cross-Session**: Accessible from any session - **Persistent**: Survives server restarts and session expiration -- **Multi-Modal Search**: Semantic (vector), keyword (BM25 full-text), and hybrid search β€” configurable embeddings (OpenAI, Bedrock, Ollama, and more via [LiteLLM](llm-providers.md)) +- **Multi-Modal Search**: Semantic (vector), keyword (BM25 full-text), and hybrid search - configurable embeddings (OpenAI, Bedrock, Ollama, and more via [LiteLLM](../user_guide/how_to_guides/llm_providers.md)) - **Deduplication**: Automatic hash-based and semantic deduplication - **Rich Metadata**: Topics, entities, timestamps, memory types - **Compaction**: Automatic cleanup and merging of duplicates @@ -227,8 +227,9 @@ There are two main ways to create long-term memories: The most common approach is to let the system automatically promote memories from working memory to long-term storage. This handles extraction strategies, background processing, and batch optimization. -!!! info "Working Memory Integration" - For automatic memory promotion from conversations, see the [Working Memory documentation](working-memory.md). This covers extraction strategies, background processing, and how to configure the memory server to automatically create long-term memories from conversation content. +!!! note "Working Memory Integration" + + For automatic memory promotion from conversations, see the [Working Memory documentation](working_memory.md). This covers extraction strategies, background processing, and how to configure the memory server to automatically create long-term memories from conversation content. ### 2. Manual Creation via API @@ -300,12 +301,14 @@ EMBEDDING_MODEL=text-embedding-3-small # Embedding model (see LLM Providers for DISTANCE_THRESHOLD=0.8 # Similarity threshold for search ``` -For complete configuration options, see the [Configuration Guide](configuration.md). +For complete configuration options, see the [Configuration Guide](../user_guide/how_to_guides/configuration.md). ## Related Documentation -- [Working Memory](working-memory.md) - Session-scoped memory storage for conversations -- [Memory Integration Patterns](memory-integration-patterns.md) - How to integrate memory with your applications -- [Memory Extraction Strategies](memory-extraction-strategies.md) - Different approaches to memory extraction and storage -- [LLM Providers](llm-providers.md) - Configure OpenAI, Anthropic, AWS Bedrock, Ollama, and more -- [Custom Memory Vector Databases](custom-memory-vector-db.md) - Configuring custom memory vector database implementations +- [Working Memory](working_memory.md) - Session-scoped memory storage for conversations +- [Memory Lifecycle](memory_lifecycle.md) - Creation, promotion, deduplication, and forgetting +- [Memory Editing](../user_guide/how_to_guides/memory_editing.md) - Correct, enrich, or update stored memories after creation +- [Memory Integration Patterns](../user_guide/how_to_guides/integration_patterns.md) - How to integrate memory with your applications +- [Memory Extraction Strategies](memory_extraction.md) - Different approaches to memory extraction and storage +- [LLM Providers](../user_guide/how_to_guides/llm_providers.md) - Configure OpenAI, Anthropic, AWS Bedrock, Ollama, and more +- [Custom Memory Vector Databases](../user_guide/how_to_guides/custom_vector_db.md) - Configuring custom memory vector database implementations diff --git a/docs/memory-extraction-strategies.md b/docs/concepts/memory_extraction.md similarity index 91% rename from docs/memory-extraction-strategies.md rename to docs/concepts/memory_extraction.md index bf27f320..64f4f608 100644 --- a/docs/memory-extraction-strategies.md +++ b/docs/concepts/memory_extraction.md @@ -1,6 +1,6 @@ # Memory Extraction Strategies -This reference documents the configurable extraction strategies that determine how memories are extracted from conversations during [background extraction](memory-integration-patterns.md#pattern-3-background-extraction-automatic). +This reference documents the configurable extraction strategies that determine how memories are extracted from conversations during [background extraction](../user_guide/how_to_guides/integration_patterns.md#pattern-3-background-extraction-automatic). ## Available Strategies @@ -124,6 +124,7 @@ working_memory = WorkingMemory( Allows you to provide a custom extraction prompt for specialized domains. !!! danger "Security Critical" + Custom prompts can introduce security risks including prompt injection and code execution attempts. This strategy includes comprehensive security validation, but understanding the risks is essential for safe usage. ```python @@ -134,9 +135,9 @@ custom_config = MemoryStrategyConfig( Extract technical decisions from: {message} Focus on: - - Technology choices made - - Architecture decisions - - Implementation details + - Technology choices made + - Architecture decisions + - Implementation details Return JSON with memories array containing type, text, topics, entities. Current datetime: {current_datetime} @@ -209,8 +210,9 @@ else: strategy = DiscreteMemoryStrategy() ``` -!!! info "Full Security Documentation" - For comprehensive security guidance, attack examples, and production recommendations, see the [Security Guide](security-custom-prompts.md). +!!! note "Full Security Documentation" + + For comprehensive security guidance, attack examples, and production recommendations, see the [Security Guide](../user_guide/how_to_guides/security.md). ## REST API Usage @@ -230,7 +232,7 @@ curl -X PUT "http://localhost:8000/v1/working-memory/my-session" \ }' ``` -For more comprehensive integration examples, see [Memory Integration Patterns](memory-integration-patterns.md). +For more comprehensive integration examples, see [Memory Integration Patterns](../user_guide/how_to_guides/integration_patterns.md). ## Best Practices @@ -302,14 +304,15 @@ pytest tests/test_prompt_security.py -v ## Related Documentation -- **[Working Memory](working-memory.md)** - Session-scoped, ephemeral memory storage -- **[Long-term Memory](long-term-memory.md)** - Persistent, cross-session memory storage -- **[Security Guide](security-custom-prompts.md)** - Comprehensive security for custom strategies -- **[Memory Lifecycle](memory-lifecycle.md)** - How memories are managed over time -- **[API Reference](api.md)** - REST API for memory management -- **[MCP Server](mcp.md)** - Model Context Protocol integration +- **[Working Memory](working_memory.md)** - Session-scoped, ephemeral memory storage +- **[Long-term Memory](long_term_memory.md)** - Persistent, cross-session memory storage +- **[Security Guide](../user_guide/how_to_guides/security.md)** - Comprehensive security for custom strategies +- **[Memory Lifecycle](memory_lifecycle.md)** - How memories are managed over time +- **[API Reference](../api/rest.md)** - REST API for memory management +- **[MCP Server](../api/mcp.md)** - Model Context Protocol integration --- !!! tip "Getting Started" + Start with the **Discrete Strategy** for most applications. It provides excellent general-purpose memory extraction. Move to specialized strategies (Summary, Preferences, Custom) as your needs become more specific. diff --git a/docs/memory-lifecycle.md b/docs/concepts/memory_lifecycle.md similarity index 50% rename from docs/memory-lifecycle.md rename to docs/concepts/memory_lifecycle.md index 34162d32..f55036d5 100644 --- a/docs/memory-lifecycle.md +++ b/docs/concepts/memory_lifecycle.md @@ -1,6 +1,6 @@ # Memory Lifecycle Management -Redis Agent Memory Server provides sophisticated memory lifecycle management to prevent unlimited growth and maintain optimal performance. This includes automatic background forgetting processes, memory compaction strategies, and server-controlled cleanup operations. +Agent Memory Server provides sophisticated memory lifecycle management to prevent unlimited growth and maintain optimal performance. This includes automatic background forgetting processes, memory compaction strategies, and server-controlled cleanup operations. ## Overview @@ -413,479 +413,23 @@ Automatic lifecycle management (forgetting, compaction, optimization) operates s ## Memory Editing -The Redis Agent Memory Server provides comprehensive memory editing capabilities, allowing you to update, correct, and refine stored memories through both REST API endpoints and MCP tools. This feature enables AI agents and applications to maintain accurate, up-to-date memory records over time. - -### Overview - -Memory editing allows you to modify existing long-term memories without losing their search indexing or metadata. This is essential for: - -- **Correcting mistakes**: Fix inaccurate information in stored memories -- **Updating information**: Reflect changes in user preferences or circumstances -- **Adding details**: Enrich memories with additional context or information -- **Maintaining accuracy**: Keep memory store current and reliable - -**Key Features:** -- **Partial updates**: Modify only the fields you want to change -- **Automatic re-indexing**: Updated memories are re-indexed for search -- **Vector consistency**: Embeddings are regenerated when text changes -- **Metadata preservation**: IDs, timestamps, and other metadata remain stable -- **Atomic operations**: Updates succeed or fail completely - -### Memory Editing Workflow - -#### 1. Find the Memory - -First, locate the memory you want to edit using search: - -```python -# Search for memories to edit -results = await client.search_long_term_memory( - text="user food preferences", - limit=5 -) - -# Find the specific memory -memory_to_edit = results.memories[0] -memory_id = memory_to_edit.id -``` - -#### 2. Prepare Updates - -Specify only the fields you want to change: - -```python -# Update only the text content -updates = { - "text": "User prefers Mediterranean cuisine and is vegetarian" -} - -# Or update multiple fields -updates = { - "text": "User prefers Mediterranean cuisine and is vegetarian", - "topics": ["food", "preferences", "diet", "mediterranean"], - "entities": ["Mediterranean cuisine", "vegetarian"] -} -``` - -#### 3. Apply the Update - -Use the appropriate interface to apply your changes: - -```python -# Update the memory -updated_memory = await client.edit_long_term_memory( - memory_id=memory_id, - updates=updates -) -``` - -### REST API Interface - -#### Endpoint - -**PATCH /v1/long-term-memory/{memory_id}** - -Updates specific fields of an existing memory record. - -#### Request Format - -```http -PATCH /v1/long-term-memory/01HXE2B1234567890ABCDEF -Content-Type: application/json -Authorization: Bearer your_token_here - -{ - "text": "Updated memory text", - "topics": ["new", "topics"], - "entities": ["updated", "entities"], - "memory_type": "semantic", - "event_date": "2024-01-15T14:30:00Z", - "namespace": "updated_namespace", - "user_id": "updated_user" -} -``` - -#### Response Format - -```json -{ - "id": "01HXE2B1234567890ABCDEF", - "text": "Updated memory text", - "memory_type": "semantic", - "topics": ["new", "topics"], - "entities": ["updated", "entities"], - "created_at": "2024-01-10T12:00:00Z", - "persisted_at": "2024-01-10T12:00:00Z", - "updated_at": "2024-01-16T10:30:00Z", - "last_accessed": "2024-01-16T10:30:00Z", - "user_id": "user_123", - "session_id": "session_456", - "namespace": "updated_namespace", - "memory_hash": "new_hash_after_update" -} -``` - -#### cURL Examples - -**Update memory text:** -```bash -curl -X PATCH "http://localhost:8000/v1/long-term-memory/01HXE2B1234567890ABCDEF" \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer your_token" \ - -d '{ - "text": "User prefers dark mode interfaces and uses vim for coding" - }' -``` - -**Update multiple fields:** -```bash -curl -X PATCH "http://localhost:8000/v1/long-term-memory/01HXE2B1234567890ABCDEF" \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer your_token" \ - -d '{ - "text": "User completed Python certification on January 15, 2024", - "memory_type": "episodic", - "event_date": "2024-01-15T14:30:00Z", - "topics": ["education", "certification", "python"], - "entities": ["Python", "certification"] - }' -``` - -### MCP Tool Interface - -#### Tool: edit_long_term_memory - -The MCP server provides an `edit_long_term_memory` tool for AI agents to modify memories through natural conversation. - -#### Tool Schema - -```python -{ - "name": "edit_long_term_memory", - "description": "Update an existing long-term memory with new or corrected information", - "parameters": { - "type": "object", - "properties": { - "memory_id": { - "type": "string", - "description": "The ID of the memory to edit (get this from search results)" - }, - "text": { - "type": "string", - "description": "Updated memory text content" - }, - "topics": { - "type": "array", - "items": {"type": "string"}, - "description": "Updated list of topics" - }, - "entities": { - "type": "array", - "items": {"type": "string"}, - "description": "Updated list of entities" - }, - "memory_type": { - "type": "string", - "enum": ["semantic", "episodic", "message"], - "description": "Type of memory" - }, - "event_date": { - "type": "string", - "description": "Event date for episodic memories (ISO 8601 format)" - }, - "namespace": { - "type": "string", - "description": "Memory namespace" - }, - "user_id": { - "type": "string", - "description": "User ID associated with the memory" - } - }, - "required": ["memory_id"] - } -} -``` - -#### MCP Usage Examples - -**Simple text update:** -```python -await client.call_tool("edit_long_term_memory", { - "memory_id": "01HXE2B1234567890ABCDEF", - "text": "User prefers tea over coffee (updated preference)" -}) -``` - -**Update memory type and event date:** -```python -await client.call_tool("edit_long_term_memory", { - "memory_id": "01HXE2B1234567890ABCDEF", - "memory_type": "episodic", - "event_date": "2024-01-15T14:30:00Z" -}) -``` - -**Comprehensive update:** -```python -await client.call_tool("edit_long_term_memory", { - "memory_id": "01HXE2B1234567890ABCDEF", - "text": "User was promoted to Principal Engineer on January 15, 2024", - "memory_type": "episodic", - "event_date": "2024-01-15T14:30:00Z", - "topics": ["career", "promotion", "engineering", "principal"], - "entities": ["Principal Engineer", "promotion", "January 15, 2024"] -}) -``` - -### Python Client Interface - -#### Method: edit_long_term_memory - -```python -async def edit_long_term_memory( - self, - memory_id: str, - updates: dict[str, Any] -) -> MemoryRecord: - """ - Edit an existing long-term memory record. - - Args: - memory_id: The ID of the memory to edit - updates: Dictionary of fields to update - - Returns: - The updated memory record - - Raises: - HTTPException: If memory not found or update fails - """ -``` - -#### Client Usage Examples - -```python -from agent_memory_client import MemoryAPIClient, MemoryClientConfig - -client = MemoryAPIClient(MemoryClientConfig(base_url="http://localhost:8000")) - -# Simple text correction -updated_memory = await client.edit_long_term_memory( - memory_id="01HXE2B1234567890ABCDEF", - updates={"text": "User actually prefers coffee, not tea"} -) - -# Add more context -updated_memory = await client.edit_long_term_memory( - memory_id="01HXE2B1234567890ABCDEF", - updates={ - "text": "User prefers Italian cuisine, especially pasta and pizza", - "topics": ["food", "preferences", "italian", "cuisine"], - "entities": ["Italian cuisine", "pasta", "pizza"] - } -) - -# Update namespace and user -updated_memory = await client.edit_long_term_memory( - memory_id="01HXE2B1234567890ABCDEF", - updates={ - "namespace": "work_preferences", - "user_id": "user_456" - } -) -``` - -### Editable Fields - -#### Core Content Fields - -- **text**: The main memory content (triggers embedding regeneration) -- **topics**: List of topic tags for categorization -- **entities**: List of named entities mentioned in the memory -- **memory_type**: Type classification (semantic, episodic, message) - -#### Temporal Fields - -- **event_date**: Specific date/time for episodic memories (ISO 8601 format) - -#### Organization Fields - -- **namespace**: Memory namespace for organization -- **user_id**: User associated with the memory - -#### Read-Only Fields - -These fields cannot be edited and are managed automatically: - -- **id**: Unique memory identifier -- **created_at**: Original creation timestamp -- **persisted_at**: When memory was first saved to long-term storage -- **updated_at**: Last modification timestamp (updated automatically) -- **last_accessed**: Last time memory was retrieved (managed by recency system) -- **memory_hash**: Content hash (regenerated when text changes) - -### Update Behavior - -#### Automatic Updates - -When you edit a memory, the system automatically: - -1. **Updates timestamps**: Sets `updated_at` to current time -2. **Regenerates embeddings**: If text content changes, new embeddings are created -3. **Recalculates hash**: Content hash is updated for deduplication -4. **Re-indexes memory**: Search index is updated with new content -5. **Updates access time**: Sets `last_accessed` to current time - -#### Partial Updates - -Only specify fields you want to change - other fields remain unchanged: - -```python -# Only update topics - text, entities, etc. stay the same -updates = {"topics": ["programming", "python", "web-development"]} - -# Only update text - topics, entities, etc. stay the same -updates = {"text": "Updated description of the user's preferences"} -``` - -#### Vector Re-indexing - -When memory text changes, the system automatically: -- Generates new embeddings using the configured embedding model -- Updates the vector index for accurate semantic search -- Maintains search performance and accuracy - -### Error Handling - -#### Common Errors - -**Memory Not Found (404):** -```json -{ - "detail": "Memory not found: 01HXE2B1234567890ABCDEF", - "status_code": 404 -} -``` - -**Invalid Memory ID (400):** -```json -{ - "detail": "Invalid memory ID format", - "status_code": 400 -} -``` - -**Validation Error (422):** -```json -{ - "detail": [ - { - "loc": ["body", "event_date"], - "msg": "invalid datetime format", - "type": "value_error" - } - ], - "status_code": 422 -} -``` - -#### Error Handling in Code - -```python -try: - updated_memory = await client.edit_long_term_memory( - memory_id="01HXE2B1234567890ABCDEF", - updates={"text": "Updated text"} - ) -except HTTPException as e: - if e.status_code == 404: - print("Memory not found") - elif e.status_code == 422: - print("Invalid update data") - else: - print(f"Update failed: {e.detail}") -``` - -### Use Cases and Examples - -#### Correcting User Information - -**Scenario**: User corrects their job title - -```python -# 1. Search for the memory -results = await client.search_long_term_memory( - text="user job title engineer", - limit=1 -) - -# 2. Update with correction -if results.memories: - await client.edit_long_term_memory( - memory_id=results.memories[0].id, - updates={ - "text": "User works as a Senior Software Engineer at TechCorp", - "entities": ["Senior Software Engineer", "TechCorp"] - } - ) -``` - -#### Adding Context to Sparse Memories - -**Scenario**: Enrich a basic memory with additional details - -```python -# Original: "User likes pizza" -# Enhanced with context: -await client.edit_long_term_memory( - memory_id="01HXE2B1234567890ABCDEF", - updates={ - "text": "User likes pizza, especially thin crust with pepperoni and mushrooms from Mario's Pizzeria", - "topics": ["food", "preferences", "pizza", "italian"], - "entities": ["pizza", "thin crust", "pepperoni", "mushrooms", "Mario's Pizzeria"] - } -) -``` - -#### Converting Memory Types - -**Scenario**: Convert a general memory to an episodic memory with event date - -```python -# Change from semantic to episodic with specific date -await client.edit_long_term_memory( - memory_id="01HXE2B1234567890ABCDEF", - updates={ - "text": "User got promoted to Team Lead on March 15, 2024", - "memory_type": "episodic", - "event_date": "2024-03-15T09:00:00Z", - "topics": ["career", "promotion", "team-lead"], - "entities": ["Team Lead", "promotion", "March 15, 2024"] - } -) -``` - -### Best Practices for Memory Editing - -#### Memory Identification - -1. **Use search first**: Always search to find the correct memory ID -2. **Verify before editing**: Check memory content matches your expectations -3. **Handle duplicates**: Consider if multiple memories need the same update - -#### Update Strategy - -1. **Minimal changes**: Only update fields that actually need to change -2. **Preserve context**: Don't remove important information when updating -3. **Consistent formatting**: Maintain consistent data formats across memories -4. **Validate inputs**: Check data formats before making updates - -#### Error Prevention - -1. **Check memory exists**: Handle 404 errors gracefully -2. **Validate data**: Ensure update data matches expected formats -3. **Test updates**: Verify changes work as expected in development -4. **Monitor performance**: Watch for degradation with frequent updates - -This comprehensive memory editing system ensures that your AI agent's memory remains accurate, current, and useful over time, adapting to new information and corrections as they become available. +Long-term memories aren't immutable records β€” they're part of the +lifecycle. After a memory is created it can be **updated**, **corrected**, +or **enriched** through the REST API, the MCP server, and the Python +client. + +Why this matters for the lifecycle: an edit isn't a plain field update. +Changing a memory's `text` regenerates its embedding, recomputes its +content hash (which feeds deduplication), and re-enters the same indexing +pipeline as a newly-created memory. Edits to topics, entities, or +metadata refresh the search filters that other memories are matched +against. In other words, an edited memory passes back through extraction, +embedding, and indexing β€” the same stages a fresh memory walks through. + +That's why editing belongs in the lifecycle picture rather than in a +separate CRUD section: it's a re-entry into the pipeline. + +For the full workflow β€” including the `PATCH /v1/long-term-memory/{id}` +endpoint, the `edit_long_term_memory` MCP tool, the editable field +reference, error handling, and worked use cases β€” see the [**Memory +editing how-to guide**](../user_guide/how_to_guides/memory_editing.md). diff --git a/docs/recency-boost.md b/docs/concepts/recency_boost.md similarity index 100% rename from docs/recency-boost.md rename to docs/concepts/recency_boost.md diff --git a/docs/summary-views.md b/docs/concepts/summary_views.md similarity index 95% rename from docs/summary-views.md rename to docs/concepts/summary_views.md index 632b21e3..96c2e9e2 100644 --- a/docs/summary-views.md +++ b/docs/concepts/summary_views.md @@ -244,6 +244,6 @@ The summarization prompt is automatically truncated to fit within the model's co ## Related Documentation -- [Long-term Memory](long-term-memory.md) - The memory source for summary views -- [Working Memory](working-memory.md) - Session-scoped memory (future summary view source) -- [Configuration](configuration.md) - Server settings including `fast_model` and `summarization_threshold` +- [Long-term Memory](long_term_memory.md) - The memory source for summary views +- [Working Memory](working_memory.md) - Session-scoped memory (future summary view source) +- [Configuration](../user_guide/how_to_guides/configuration.md) - Server settings including `fast_model` and `summarization_threshold` diff --git a/docs/working-memory.md b/docs/concepts/working_memory.md similarity index 85% rename from docs/working-memory.md rename to docs/concepts/working_memory.md index c923a2d2..4a66b272 100644 --- a/docs/working-memory.md +++ b/docs/concepts/working_memory.md @@ -4,10 +4,10 @@ Working memory stores the **current conversation** for a session. It holds messa ## What Working Memory Does -1. **Stores conversation messages** β€” The chat history for a session -2. **Tracks session data** β€” Arbitrary key-value data that lives only in this session -3. **Automatically summarizes** β€” When messages exceed the token limit, older messages are summarized and removed -4. **Promotes memories** β€” Structured memories added here get indexed in long-term storage +1. **Stores conversation messages** - The chat history for a session +2. **Tracks session data** - Arbitrary key-value data that lives only in this session +3. **Automatically summarizes** - When messages exceed the token limit, older messages are summarized and removed +4. **Promotes memories** - Structured memories added here get indexed in long-term storage ## Quick Reference @@ -42,7 +42,7 @@ When your conversation exceeds the model's context window, working memory automa 3. **Removes the summarized messages** to free space 4. **Keeps recent messages** intact -This happens transparentlyβ€”you don't need to trigger it. +This happens transparently - you don't need to trigger it. ### How It Works @@ -130,7 +130,7 @@ working_memory = WorkingMemory( > **⚠️ Always provide `created_at` timestamps** > -> This ensures correct message ordering and proper temporal context when promoting to long-term memory. Omitting `created_at` triggers a deprecation warningβ€”it will become required in a future version. +> This ensures correct message ordering and proper temporal context when promoting to long-term memory. Omitting `created_at` triggers a deprecation warning - it will become required in a future version. ## Session-Specific Data @@ -193,7 +193,7 @@ working_memory = WorkingMemory( ) ``` -See [Memory Extraction Strategies](memory-extraction-strategies.md) for configuration options. +See [Memory Extraction Strategies](memory_extraction.md) for configuration options. ## API Reference @@ -244,11 +244,13 @@ This lets you use TTL to save Redis memory while maintaining conversation contin | `LONG_TERM_MEMORY` | `true` | Enable long-term memory features | | `INDEX_ALL_MESSAGES_IN_LONG_TERM_MEMORY` | `false` | Index messages for reconstruction | -See the [Configuration Guide](configuration.md) for all options. +See the [Configuration Guide](../user_guide/how_to_guides/configuration.md) for all options. ## Related Documentation -- [Long-term Memory](long-term-memory.md) β€” Persistent, cross-session storage -- [Memory Integration Patterns](memory-integration-patterns.md) β€” How to integrate memory -- [Memory Extraction Strategies](memory-extraction-strategies.md) β€” Automatic memory extraction -- [LLM Providers](llm-providers.md) β€” Configure OpenAI, Anthropic, Bedrock, Ollama +- [Long-term Memory](long_term_memory.md) - Persistent, cross-session storage +- [Memory Lifecycle](memory_lifecycle.md) - How memories are created, promoted, and forgotten +- [Memory Editing](../user_guide/how_to_guides/memory_editing.md) - Update or correct stored memories +- [Memory Integration Patterns](../user_guide/how_to_guides/integration_patterns.md) - How to integrate memory +- [Memory Extraction Strategies](memory_extraction.md) - Automatic memory extraction +- [LLM Providers](../user_guide/how_to_guides/llm_providers.md) - Configure OpenAI, Anthropic, Bedrock, Ollama diff --git a/docs/developer-guide-index.md b/docs/developer-guide-index.md deleted file mode 100644 index fed98c06..00000000 --- a/docs/developer-guide-index.md +++ /dev/null @@ -1,60 +0,0 @@ -# Developer Guide - -Learn how to integrate memory into your AI applications. This guide covers integration patterns, memory types, extraction strategies, and memory lifecycle management. - -## Core Concepts - -
- -- πŸ”„ **Memory Integration Patterns** - - --- - - Three patterns for using memory: LLM-driven, code-driven, and background extraction - - [Integration Patterns β†’](memory-integration-patterns.md) - -- πŸ“ **Working Memory** - - --- - - Session-scoped storage for active conversation state - - [Working Memory β†’](working-memory.md) - -- 🧠 **Long-term Memory** - - --- - - Persistent, cross-session storage for knowledge that should be retained - - [Long-term Memory β†’](long-term-memory.md) - -- 🎯 **Memory Extraction Strategies** - - --- - - Configure how memories are extracted: discrete, summary, preferences, or custom - - [Extraction Strategies β†’](memory-extraction-strategies.md) - -
- -## Additional Topics - -| Topic | Description | -|-------|-------------| -| [Summary Views](summary-views.md) | Pre-computed memory summaries for efficient context | -| [Memory Lifecycle](memory-lifecycle.md) | How memories are created, updated, and managed over time | -| [LangChain Integration](langchain-integration.md) | Use memory with LangChain agents and chains | -| [Custom Memory Vector Databases](custom-memory-vector-db.md) | Configure Redis or custom memory vector databases | - -## Where to Start - -**Building a chatbot?** Start with [Memory Integration Patterns](memory-integration-patterns.md) to understand your options. - -**Need to understand the data model?** Read [Working Memory](working-memory.md) and [Long-term Memory](long-term-memory.md). - -**Configuring extraction behavior?** See [Memory Extraction Strategies](memory-extraction-strategies.md). - -**Looking for server configuration?** See the [Operations Guide](operations-guide-index.md) for authentication, LLM providers, and deployment. diff --git a/docs/examples/agent_examples.md b/docs/examples/agent_examples.md new file mode 100644 index 00000000..7c3afd7f --- /dev/null +++ b/docs/examples/agent_examples.md @@ -0,0 +1,143 @@ +# Agent Examples + +Working examples that demonstrate real-world usage patterns of the Agent +Memory Server. Each example focuses on a different aspect of memory +management β€” from basic conversation storage to advanced editing +workflows β€” and runs as a self-contained script (or notebook). + +If you're just trying things out, **start with the +[Interactive Technical Guide](agent_memory_server_interactive_guide.ipynb)**: +it walks through the whole system end-to-end in a notebook. If you'd +rather see one complete agent first, start with the +[**Travel Agent**](travel_agent.md) β€” it uses every memory tool the +server exposes. + +
+ +- :material-notebook:{ .lg .middle } **[Interactive Guide](agent_memory_server_interactive_guide.ipynb)** + + --- + + Twelve-section, cell-by-cell walkthrough of the full memory system. + +- :material-airplane:{ .lg .middle } **[Travel Agent](travel_agent.md)** + + --- + + Most comprehensive example. Auto-discovers and uses every memory tool. + +- :material-message-text:{ .lg .middle } **[Memory Prompt Agent](memory_prompt_agent.md)** + + --- + + Simplified pattern using `memory_prompt()` for context hydration. + +- :material-pencil:{ .lg .middle } **[Memory Editing Agent](memory_editing_agent.md)** + + --- + + Full editing lifecycle: create, search, correct, update, delete. + +- :material-school:{ .lg .middle } **[AI Tutor](ai_tutor.md)** + + --- + + Episodic + semantic memory for learning tracking and weak-concept practice. + +- :material-link-variant:{ .lg .middle } **[LangChain Integration](langchain.md)** + + --- + + Memory-enabled LangChain agents via `get_memory_tools()`. + +- :material-counter:{ .lg .middle } **[Recent Messages Limit Demo](recent_messages_limit_demo.md)** + + --- + + Efficient retrieval of the most recent N messages from working memory. + +
+ +## Getting Started with Examples + +### 1. Prerequisites + +```bash +# Install dependencies +cd /path/to/agent-memory-server +uv sync --all-extras + +# Start memory server (disable auth for local development) +DISABLE_AUTH=true uv run agent-memory api --task-backend=asyncio + +# Set required API keys +export OPENAI_API_KEY="your-openai-key" +``` + +### 2. Run an Example + +```bash +cd examples + +# Most comprehensive standalone agent +python travel_agent.py --demo + +# Memory editing workflows +python memory_editing_agent.py --demo + +# Simplified memory prompts +python memory_prompt_agent.py + +# Learning tracking +python ai_tutor.py --demo + +# LangChain integration +python langchain_integration_example.py + +# Recent messages limit feature +python recent_messages_limit_demo.py +``` + +### 3. Customize and Extend + +Each example is designed to be: + +- **Self-contained**: Runs independently with minimal setup +- **Configurable**: Supports custom sessions, users, and server URLs +- **Educational**: Well-commented code showing best practices +- **Production-ready**: Robust error handling and logging + +### 4. Shared Implementation Patterns + +Most examples follow the same shape: + +```python +# Memory client setup +client = MemoryAPIClient( + base_url="http://localhost:8000", + default_namespace=namespace, + user_id=user_id +) + +# Tool integration +tools = MemoryAPIClient.get_all_memory_tool_schemas() +response = await openai_client.chat.completions.create( + model="gpt-4o", + messages=messages, + tools=tools +) + +# Tool resolution +for tool_call in response.choices[0].message.tool_calls: + result = await client.resolve_tool_call( + tool_call=tool_call, + session_id=session_id + ) +``` + +## Where to Next + +- **Learning the system end-to-end?** β†’ [Interactive Guide](agent_memory_server_interactive_guide.ipynb) +- **Most complete production-style agent?** β†’ [Travel Agent](travel_agent.md) +- **Editing patterns?** β†’ [Memory Editing Agent](memory_editing_agent.md) and the [Memory editing how-to](../user_guide/how_to_guides/memory_editing.md) +- **Building your own?** Each example is a template β€” clone, adapt, ship. diff --git a/docs/examples/agent_memory_server_interactive_guide.ipynb b/docs/examples/agent_memory_server_interactive_guide.ipynb new file mode 120000 index 00000000..3ca2ec28 --- /dev/null +++ b/docs/examples/agent_memory_server_interactive_guide.ipynb @@ -0,0 +1 @@ +../../examples/agent_memory_server_interactive_guide.ipynb \ No newline at end of file diff --git a/docs/examples/ai_tutor.md b/docs/examples/ai_tutor.md new file mode 100644 index 00000000..29f73dd4 --- /dev/null +++ b/docs/examples/ai_tutor.md @@ -0,0 +1,52 @@ +# 🏫 AI Tutor + +**File**: [`examples/ai_tutor.py`](https://github.com/redis/agent-memory-server/blob/main/examples/ai_tutor.py) + +A functional tutoring system that demonstrates episodic memory for learning tracking and semantic memory for concept management. + +## Core Features + +- **Quiz Management**: Runs interactive quizzes and stores results +- **Learning Tracking**: Stores quiz results as episodic memories with timestamps +- **Concept Tracking**: Tracks weak concepts as semantic memories +- **Progress Analysis**: Provides summaries and personalized practice suggestions + +## Memory Patterns Used + +```python +# Episodic: Per-question results with event dates +{ + "text": "User answered 'photosynthesis' question incorrectly", + "memory_type": "episodic", + "event_date": "2024-01-15T10:30:00Z", + "topics": ["quiz", "biology", "photosynthesis"] +} + +# Semantic: Weak concepts for targeted practice +{ + "text": "User struggles with photosynthesis concepts", + "memory_type": "semantic", + "topics": ["weak_concept", "biology", "photosynthesis"] +} +``` + +## Usage Examples + +```bash +cd examples + +# Interactive tutoring session +python ai_tutor.py + +# Demo with sample quiz flow +python ai_tutor.py --demo + +# Custom student session +python ai_tutor.py --user-id student123 --session-id bio_course +``` + +## Key Commands + +- **Practice**: Start a quiz on specific topics +- **Summary**: Get learning progress summary +- **Practice-next**: Get personalized practice recommendations based on weak areas diff --git a/docs/examples/index.md b/docs/examples/index.md new file mode 100644 index 00000000..6d119856 --- /dev/null +++ b/docs/examples/index.md @@ -0,0 +1,40 @@ +--- +description: Examples and integrations for Agent Memory Server. +--- + +# Examples + +Real-world integrations and agent patterns using Agent Memory Server. + +Browse [**Use cases**](use_cases.md) first to see what people actually +build with this. Then jump to [**LangChain**](langchain.md) if you're +wiring memory into an existing chain, or to [**Agent examples**](agent_examples.md) +for end-to-end walkthroughs you can clone and run. + +
+ +- :material-target:{ .lg .middle } **[Use cases](use_cases.md)** + + --- + + Real-world applications across industries: customer support, tutoring, healthcare, e-commerce, and more. + +- :material-link-variant:{ .lg .middle } **[LangChain integration](langchain.md)** + + --- + + Use Agent Memory Server with LangChain for persistent agent memory. + +- :material-robot:{ .lg .middle } **[Agent examples](agent_examples.md)** + + --- + + Complete agents: travel agent, AI tutor, memory editor, and more. + +
+ +!!! tip + + For runnable scripts, see the + [examples directory](https://github.com/redis/agent-memory-server/tree/main/examples) + on GitHub. diff --git a/docs/langchain-integration.md b/docs/examples/langchain.md similarity index 96% rename from docs/langchain-integration.md rename to docs/examples/langchain.md index f94b15f6..d253b203 100644 --- a/docs/langchain-integration.md +++ b/docs/examples/langchain.md @@ -6,7 +6,7 @@ The Python SDK (agent-memory-client) provides a LangChain integration that helps The SDK provides a `get_memory_tools()` function that returns a list of LangChain `StructuredTool` instances. These tools give your LangChain LLMs and agents access to the memory server's capabilities. -For details on available memory operations, see the [Tool Integration](python-sdk.md#tool-integration) section of the Python SDK documentation. +For details on available memory operations, see the [Tool Integration](../api/python_sdk.md#tool-integration) section of the Python SDK documentation. ### Direct LLM Integration @@ -300,6 +300,6 @@ asyncio.run(main()) ## See Also -- [Python SDK Documentation](python-sdk.md) - Complete SDK reference and tool methods -- [Memory Integration Patterns](memory-integration-patterns.md) - Overview of different integration approaches +- [Python SDK Documentation](../api/python_sdk.md) - Complete SDK reference and tool methods +- [Memory Integration Patterns](../user_guide/how_to_guides/integration_patterns.md) - Overview of different integration approaches - [LangChain Integration Example](https://github.com/redis/agent-memory-server/blob/main/examples/langchain_integration_example.py) - Complete working example diff --git a/docs/examples/memory_editing_agent.md b/docs/examples/memory_editing_agent.md new file mode 100644 index 00000000..16761b38 --- /dev/null +++ b/docs/examples/memory_editing_agent.md @@ -0,0 +1,75 @@ +# ✏️ Memory Editing Agent + +**File**: [`examples/memory_editing_agent.py`](https://github.com/redis/agent-memory-server/blob/main/examples/memory_editing_agent.py) + +Demonstrates comprehensive memory editing capabilities through natural conversation patterns. + +## Core Features + +- **Memory Editing Workflow**: Complete lifecycle of creating, searching, editing, and deleting memories +- **All Memory Tools**: Uses all available memory management tools including editing capabilities +- **Realistic Scenarios**: Common patterns like corrections, updates, and information cleanup +- **Interactive Demo**: Both automated demo and interactive modes + +## Memory Operations Demonstrated + +1. **search_memory** β€” Find existing memories using natural language (supports `semantic`, `keyword`, and `hybrid` search modes) +2. **get_long_term_memory** β€” Retrieve specific memories by ID +3. **lazily_create_long_term_memory** β€” Store new information (promoted to long-term storage later) +4. **eagerly_create_long_term_memory** β€” Create long-term memories directly for immediate storage +5. **edit_long_term_memory** β€” Update existing memories +6. **delete_long_term_memories** β€” Remove outdated information +7. **get_or_create_working_memory** β€” Check current working memory session +8. **update_working_memory_data** β€” Store/update session-specific data +9. **get_current_datetime** β€” Get current UTC datetime for grounding relative time expressions + +## Common Editing Scenarios + +```python +# Correction scenario +"Actually, I work at Microsoft, not Google" +# β†’ Search for job memory, edit company name + +# Update scenario +"I got promoted to Senior Engineer" +# β†’ Find job memory, update title and add promotion date + +# Preference change +"I prefer tea over coffee now" +# β†’ Search beverage preferences, update from coffee to tea + +# Information cleanup +"Delete that old job information" +# β†’ Search and remove outdated employment data +``` + +## Usage Examples + +```bash +cd examples + +# Interactive mode (explore memory editing) +python memory_editing_agent.py + +# Automated demo (see complete workflow) +python memory_editing_agent.py --demo + +# Custom configuration +python memory_editing_agent.py --session-id alice_session --user-id alice +``` + +## Demo Conversation Flow + +The automated demo shows a realistic conversation: + +1. **Initial Information**: User shares profile (name, job, preferences) +2. **Corrections**: User corrects information (job company change) +3. **Updates**: User provides updates (promotion, new title) +4. **Multiple Changes**: User updates location and preferences +5. **Information Retrieval**: User asks what agent remembers +6. **Ongoing Updates**: Continued information updates +7. **Memory Management**: Specific memory operations (show/delete) + +## See Also + +- [Memory editing how-to guide](../user_guide/how_to_guides/memory_editing.md) β€” endpoint reference, MCP tool, and editable field details diff --git a/docs/examples/memory_prompt_agent.md b/docs/examples/memory_prompt_agent.md new file mode 100644 index 00000000..6b1d8a44 --- /dev/null +++ b/docs/examples/memory_prompt_agent.md @@ -0,0 +1,47 @@ +# 🧠 Memory Prompt Agent + +**File**: [`examples/memory_prompt_agent.py`](https://github.com/redis/agent-memory-server/blob/main/examples/memory_prompt_agent.py) + +Demonstrates the simplified memory prompt feature for context-aware conversations without manual tool management. + +## Core Concept + +Uses `client.memory_prompt()` to automatically retrieve relevant memories and enrich prompts with contextual information. + +## How It Works + +1. **Store Messages**: All conversation messages stored in working memory +2. **Memory Prompt**: `memory_prompt()` retrieves relevant context automatically +3. **Enriched Context**: Memory context combined with system prompt +4. **LLM Generation**: Enhanced context sent to LLM for personalized responses + +## Usage Examples + +```bash +cd examples +python memory_prompt_agent.py + +# With custom session +python memory_prompt_agent.py --session-id my_session --user-id jane_doe +``` + +## Key Implementation Pattern + +```python +# Automatic memory retrieval and context enrichment +context = await client.memory_prompt( + query=user_message, + session_id=session_id, + long_term_search={ + "text": user_message, + "limit": 5, + "user_id": user_id + } +) + +# Enhanced prompt with memory context +response = await openai_client.chat.completions.create( + model="gpt-4o", + messages=context["messages"] +) +``` diff --git a/docs/examples/recent_messages_limit_demo.md b/docs/examples/recent_messages_limit_demo.md new file mode 100644 index 00000000..9e1682d5 --- /dev/null +++ b/docs/examples/recent_messages_limit_demo.md @@ -0,0 +1,46 @@ +# πŸ“Š Recent Messages Limit Demo + +**File**: [`examples/recent_messages_limit_demo.py`](https://github.com/redis/agent-memory-server/blob/main/examples/recent_messages_limit_demo.py) + +Demonstrates the `recent_messages_limit` parameter for efficiently retrieving only the most recent N messages from working memory. + +## Core Concept + +When working memory grows large, retrieving all messages is expensive. The `recent_messages_limit` parameter lets you fetch only the N most recent messages, useful for context windows and UI displays. + +## Key Features + +- **Efficient Retrieval**: Fetch only the messages you need instead of the full history +- **SDK & HTTP Integration**: Uses `agent_memory_client` to store working memory and raw HTTP requests to retrieve it +- **Multiple Scenarios**: Tests various limits (3, 5, 20, 2) to show how `recent_messages_limit` changes the results +- **Direct API Verification**: Uses the raw HTTP API for retrieval so you can inspect the exact responses from the server + +## Usage Examples + +```bash +cd examples +python recent_messages_limit_demo.py +``` + +## Key Implementation Pattern + +The `recent_messages_limit` parameter is not yet exposed in the high-level Python SDK. Use the REST API directly via `httpx`: + +```python +import httpx + +async with httpx.AsyncClient(base_url="http://localhost:8000") as http: + # Get only the 3 most recent messages + resp = await http.get( + f"/v1/working-memory/{session_id}", + params={"namespace": "demo", "recent_messages_limit": 3}, + ) + resp.raise_for_status() + messages = resp.json()["messages"] +``` + +The equivalent raw request is: + +``` +GET /v1/working-memory/{session_id}?namespace=demo&recent_messages_limit=3 +``` diff --git a/docs/examples/travel_agent.md b/docs/examples/travel_agent.md new file mode 100644 index 00000000..656b259b --- /dev/null +++ b/docs/examples/travel_agent.md @@ -0,0 +1,69 @@ +# 🧳 Travel Agent + +**File**: [`examples/travel_agent.py`](https://github.com/redis/agent-memory-server/blob/main/examples/travel_agent.py) + +A comprehensive travel assistant that demonstrates the most complete integration patterns. + +## Key Features + +- **Automatic Tool Discovery**: Uses `MemoryAPIClient.get_all_memory_tool_schemas()` to automatically discover and integrate all available memory tools +- **Unified Tool Resolution**: Leverages `client.resolve_tool_call()` to handle all memory tool calls uniformly across different LLM providers +- **Working Memory Management**: Session-based conversation state and structured memory storage +- **Long-term Memory**: Persistent memory storage with semantic, keyword, and hybrid search capabilities +- **Optional Web Search**: Cached web search using Tavily API with Redis caching + +## Available Tools + +The travel agent automatically discovers and uses all memory tools: + +1. **search_memory** β€” Search through previous conversations and stored information (supports `semantic`, `keyword`, and `hybrid` search modes) +2. **get_or_create_working_memory** β€” Check current working memory session +3. **lazily_create_long_term_memory** β€” Store important information as structured memories (promoted to long-term storage later) +4. **update_working_memory_data** β€” Store/update session-specific data like trip plans +5. **get_long_term_memory** β€” Retrieve a specific long-term memory by ID +6. **eagerly_create_long_term_memory** β€” Create long-term memories directly for immediate storage +7. **edit_long_term_memory** β€” Update existing long-term memories +8. **delete_long_term_memories** β€” Remove long-term memories +9. **get_current_datetime** β€” Get current UTC datetime for grounding relative time expressions +10. **web_search** (optional) β€” Search the internet for current travel information + +## Usage Examples + +```bash +# Basic interactive usage +cd examples +python travel_agent.py + +# Automated demo showing capabilities +python travel_agent.py --demo + +# With custom configuration +python travel_agent.py --session-id my_trip --user-id john_doe --memory-server-url http://localhost:8001 +``` + +## Environment Setup + +```bash +# Required +export OPENAI_API_KEY="your-openai-key" + +# Optional (for web search) +export TAVILY_API_KEY="your-tavily-key" +export REDIS_URL="redis://localhost:6379" +``` + +## Key Implementation Patterns + +```python +# Tool auto-discovery +memory_tools = MemoryAPIClient.get_all_memory_tool_schemas() + +# Unified tool resolution for any provider +result = await client.resolve_tool_call( + tool_call=provider_tool_call, + session_id=session_id +) + +if result["success"]: + print(result["formatted_response"]) +``` diff --git a/docs/use-cases.md b/docs/examples/use_cases.md similarity index 98% rename from docs/use-cases.md rename to docs/examples/use_cases.md index 80d430e0..e48e098e 100644 --- a/docs/use-cases.md +++ b/docs/examples/use_cases.md @@ -1,6 +1,6 @@ # Use Cases and Examples -Redis Agent Memory Server enables powerful AI applications by providing persistent, searchable memory. Here are real-world use cases and implementation examples across different industries and applications. +Agent Memory Server enables powerful AI applications by providing persistent, searchable memory. Here are real-world use cases and implementation examples across different industries and applications. ## Customer Support @@ -713,4 +713,4 @@ guidance = await health.get_contextual_health_guidance( - **Background processing**: Let automatic promotion handle memory management - **Regular cleanup**: Use forgetting mechanisms for outdated information -These use cases demonstrate the versatility of Redis Agent Memory Server across industries and applications. The key is to design your memory schema and search patterns to match your specific domain needs while leveraging the platform's intelligent features for optimal user experiences. +These use cases demonstrate the versatility of Agent Memory Server across industries and applications. The key is to design your memory schema and search patterns to match your specific domain needs while leveraging the platform's intelligent features for optimal user experiences. diff --git a/docs/for-ais-only/AUTHORING_STANDARD.md b/docs/for-ais-only/AUTHORING_STANDARD.md new file mode 100644 index 00000000..9be80425 --- /dev/null +++ b/docs/for-ais-only/AUTHORING_STANDARD.md @@ -0,0 +1,94 @@ +--- +description: Authoring standard for Redis project documentation. Use this as a system prompt when generating or revising docs. +--- + +# Authoring Standard + +Use this page as a **system prompt** when generating or revising documentation +for a Redis project (`agent-memory-server`, `redis-vl-python`, `sql-redis`, +or similar). It captures the pedagogical, structural, and brand decisions +that the docs are built on. + +--- + +You are writing or revising technical documentation for a Redis project. +Follow this philosophy strictly. + +## Information architecture β€” DiΓ‘taxis-inspired, learning-flow first + +Organize content into four buckets β€” **Concepts** (Explanation), **User Guide** +(Tutorials + How-To), **Examples**, **API Reference** β€” but treat the +framework as a starting point, not a cage. The reader's learning journey +takes priority over quadrant purity: + +- **Cross-link freely between quadrants.** If a concept page benefits from + pointing at the tutorial that demonstrates it, do it. If a how-to needs to + reference an explanation page, link to it. The original DiΓ‘taxis + discourages this; we don't. +- **Open every long page with a porch.** A 2–4 sentence orientation block + that tells the reader (a) what they're about to read, (b) what they need + to know first, and (c) where to go next. Porches are the bridge that the + strict DiΓ‘taxis quadrants refuse to build. +- **Use analogies for hard concepts.** Working memory is the goldfish; + long-term memory is the elephant. Name the analogy, anchor it visually + if possible, and reuse it across pages so it compounds. +- **Every section has an `index.md` landing page** built from a Material + card grid with cross-links to neighboring sections. The landing page is + a router, not a wall of text. + +## Voice and pedagogy + +- Second person, present tense, sentence case headings. +- One purpose per page. If a page is teaching ("how do I think about X"), + don't ambush the reader with reference tables. +- Don't pad with rationale or marketing. If a sentence doesn't help the + reader make a decision or take an action, cut it. +- When introducing a feature, lead with the problem it solves, then the + mental model, then the API. Never the reverse. +- Code examples are runnable, copy-pasteable, and use realistic variable + names. No `foo`/`bar` in non-trivial examples. +- Admonitions (`!!! tip`, `!!! note`, `!!! warning`) for callouts. Never + bare emoji headings. + +## File and structure conventions + +- `snake_case` filenames. Numeric prefixes (`01_quick_start.md`) for ordered + tutorials only β€” never for reference or how-to pages where order is + flexible. +- Heading depth capped at 3. +- `attr_list` syntax: `{ .class }` goes *after* the closing `)` of links and + images; `{: .class }` on the *next line* for paragraphs. Never inline + mid-sentence. +- A `for-ais-only/` section in every repo with `REPOSITORY_MAP.md`, + `BUILD_AND_TEST.md`, `FAILURE_MODES.md`, and this `AUTHORING_STANDARD.md` + for downstream AI-agent ingestion. + +## Brand and layout (don't override) + +- **MkDocs Material** with the shared `redis-brand.css` (Redis palette, + Space Grotesk + Space Mono). +- **Sidebars flush to viewport edges** (`max-width: none` at desktop + breakpoint) β€” the content region is not a centered column. +- **Card grids** on every section landing page. +- Notebooks live in `examples/`, are symlinked into `docs/examples/`, and + render via `mkdocs-jupyter` with explicit cell separators. + +## Zero content loss on reorgs + +When moving or renaming a page, every example, every code block, every link +target from the original must survive. If you're tempted to drop something, +link to it from the new page instead. The diff for a reorg should be +dominated by `R` (rename) operations, not `D` + `A`. + +## Strict build is non-negotiable + +The CI gate is `mkdocs build --strict`. Zero warnings. Zero broken anchors. +Zero missing nav entries. If your edit breaks the build, fix the build +before shipping. Pre-commit mirrors CI. + +## When in doubt, choose the reader + +If DiΓ‘taxis purity, brand consistency, or any other rule above conflicts +with what would actually help a reader learn the material faster, choose +the reader. Document the deviation in the page's porch so the next author +understands why. diff --git a/docs/for-ais-only/BUILD_AND_TEST.md b/docs/for-ais-only/BUILD_AND_TEST.md new file mode 100644 index 00000000..9728d03b --- /dev/null +++ b/docs/for-ais-only/BUILD_AND_TEST.md @@ -0,0 +1,89 @@ +# Build and Test + +## Prerequisites + +- Python 3.12. +- `uv` (https://docs.astral.sh/uv/) β€” `pip install uv`. +- Docker (for `testcontainers` Redis fixtures). +- Optional API keys for tests that hit OpenAI/Anthropic (`make test-api`). + +You MUST `source .venv/bin/activate` before running `uv run` commands. + +## Make targets + +``` +make setup Create .venv, sync deps, install pre-commit hooks +make sync Sync latest dependencies +make test pytest (standard suite) +make test-unit Unit tests only +make test-integration Integration tests (require Redis via testcontainers) +make test-api Full suite including API-key-dependent tests +make test-cov Run tests with coverage +make pre-commit Run the exact formatting/lint hooks used in CI +make verify Full local verification (pre-commit + API tests) +``` + +## Coverage policy + +100% of tests must pass before commit. Run `make verify` locally before pushing. + +## Running a single test + +``` +uv run pytest tests/test_.py::test_ -vv +``` + +## Building the docs + +The docs are MkDocs Material. Notebooks render via `mkdocs-jupyter`; the +Python API reference under `docs/api/server/` is auto-generated by +`mkdocstrings`. + +``` +uv sync --group docs +uv run mkdocs serve # http://127.0.0.1:8000/agent-memory/ +uv run mkdocs build # writes site/ +``` + +The build should complete with zero warnings. Treat any warning as a +breaking change. To enforce this in CI: + +``` +uv run mkdocs build --strict +``` + +## CI gates + +- `make verify` (pre-commit + API tests) on every PR. +- `uv run mkdocs build --strict` on every PR (see `.github/workflows/docs.yml`). + +## Fast iteration loops + +When changing API endpoints: + +``` +uv run pytest tests/test_api.py -x -vv +``` + +When changing memory promotion or extraction: + +``` +uv run pytest tests/test_long_term_memory.py tests/test_extraction.py -x -vv +``` + +When changing MCP tools: + +``` +uv run pytest tests/test_mcp.py -x -vv +``` + +## Running the server locally + +``` +docker-compose up redis # Redis 8 only +DISABLE_AUTH=true uv run agent-memory api # REST on :8000 +DISABLE_AUTH=true uv run agent-memory mcp # MCP (stdio) +uv run agent-memory task-worker # Background worker +``` + +Never set `DISABLE_AUTH=true` outside local development. diff --git a/docs/for-ais-only/FAILURE_MODES.md b/docs/for-ais-only/FAILURE_MODES.md new file mode 100644 index 00000000..8a3ba407 --- /dev/null +++ b/docs/for-ais-only/FAILURE_MODES.md @@ -0,0 +1,67 @@ +# Failure Modes + +Things that look like bugs but are intentional. Read this before "fixing" any +of them. + +## Search uses RedisVL, never raw `redis.ft().search()` + +If you see RedisVL `VectorQuery` / `FilterQuery` builders instead of direct +`redis.ft().search(...)` calls, that is deliberate. The project standardises on +RedisVL because it owns query construction, type coercion, and embedding +field handling. Replacing it with raw FT calls will break filter semantics and +break the project rule. + +## Working memory automatically summarises on overflow + +Long sessions appear to "lose" earlier messages β€” they have actually been +summarised into the working-memory summary field. This is by design: the +context window is bounded by the configured model. Removing the summarisation +step will cause downstream prompt-token explosions. + +## Promotion to long-term memory is asynchronous + +A memory written to working memory is not immediately searchable in +long-term memory. Promotion runs in the background via Docket. Tests that +expect synchronous promotion are wrong; use the explicit promotion call or +wait for the worker. + +## Deduplication is content-hash based + +Two memories with byte-identical content are intentionally collapsed. Tests +that insert "duplicates" and expect two records back are wrong. Vary the +content if you need two records. + +## `DISABLE_AUTH=true` is a development-only escape hatch + +The REST API is locked down by OAuth2/JWT in every other configuration. Tests +and local development use `DISABLE_AUTH=true`; production deployments must +not. Do not "fix" the auth middleware to be optional in production builds. + +## All core operations are async + +The codebase is async-first. Sync wrappers exist only on the client. Adding a +synchronous code path inside `agent_memory_server/*` will break the FastAPI + +Docket event loop assumptions. + +## Inline imports are deliberate where they exist + +Most imports live at the top of the module. The handful of inline imports +exist to avoid circular dependencies, optional-dependency import errors, or +a measurable startup cost. Hoisting them to the top will break one of those. + +## Topic and entity extraction are best-effort + +`extraction.py` may produce empty topic / entity lists for short or +ambiguous content. That is expected. Consumers must not assume a non-empty +result. Do not raise on empty output. + +## Tests use `testcontainers` Redis 8 + +Integration tests start a real Redis 8 container. They require Docker. They +are slow on cold cache. Do not "speed them up" by mocking Redis β€” mocked +tests will not catch RedisVL query regressions. + +## Coverage gate failures are not flakes + +If CI reports coverage below the project bar, do not retry. The failure is +real. Either add a test or delete the unreachable branch. diff --git a/docs/for-ais-only/REPOSITORY_MAP.md b/docs/for-ais-only/REPOSITORY_MAP.md new file mode 100644 index 00000000..112b50ce --- /dev/null +++ b/docs/for-ais-only/REPOSITORY_MAP.md @@ -0,0 +1,118 @@ +# Repository Map + +A module-by-module guide to the Agent Memory Server source tree, written for an +agent that needs to change something and wants to know where to look. + +## Source layout + +``` +agent_memory_server/ + main.py FastAPI application entry point. Builds the app, + wires routers, mounts MCP, registers startup hooks. + api.py REST endpoints (/v1/working-memory, /v1/long-term-memory, + /v1/memory/prompt). Thin layer over working_memory.py + and long_term_memory.py. + mcp.py Model Context Protocol server. Exposes + create_long_term_memories, search_long_term_memory, + memory_prompt, set_working_memory tools. + cli.py `agent-memory` Click CLI: api, mcp, task-worker, + rebuild-index, migrate-memories, schedule-task. + config.py Pydantic Settings. Env vars, OAuth2 config, + model selection, feature flags. + models.py Pydantic data models: WorkingMemory, MemoryRecord, + MemoryRecordResult, MemoryMessage, etc. + auth.py OAuth2/JWT validation with JWKS. Multi-provider + (Auth0, Cognito, Okta, Azure AD). + dependencies.py FastAPI dependency-injection helpers. + working_memory.py Session-scoped memory: get/set/delete, automatic + summarization when context window exceeded. + long_term_memory.py Persistent storage with semantic search via RedisVL. + Promotion from working memory, deduplication. + summarization.py Conversation summarization using configured LLM. + summary_views.py Aggregated views over stored memories. + extraction.py Topic and entity extraction (BERTopic + NER). + filters.py Filter compilation for RedisVL FilterQuery. + memory_strategies.py Pluggable strategies for what gets promoted to + long-term memory and how. + memory_vector_db.py Abstract vector-DB interface. + memory_vector_db_factory.py Concrete backend selection (Redis, Pinecone, + Chroma, Postgres, ...). + working_memory_index.py In-memory index used during working-memory + operations. + prompt_security.py Prompt-injection guards and safe-prompt helpers. + docket_tasks.py Background task definitions (Docket queue). + tasks.py Task wiring helpers. + migrations.py Schema migrations for stored memory records. + healthcheck.py /health endpoint. + logging.py Structlog setup. + llm/ LiteLLM-based client package. + client.py LLMClient with chat() and embed() methods. + types.py ChatCompletionResponse, EmbeddingResponse, LLMBackend. + embeddings.py Embedding-specific helpers. + exceptions.py LLMClientError, ModelValidationError, APIKeyMissingError. + utils/ Cross-cutting helpers. + redis.py Redis connection setup and pooling. + keys.py Redis key naming conventions. + api_keys.py API-key utilities. + redis_query.py RedisVL query construction helpers. + recency.py Recency-boost ranking math. + tag_codec.py Tag encoding/decoding for filterable fields. + datetime.py Timezone-aware datetime helpers. + _aws/ AWS-specific helpers (Bedrock, IAM, Cognito). +``` + +## Test layout + +``` +tests/ + test_api.py REST endpoint coverage. + test_mcp.py MCP tool coverage. + test_working_memory.py Session memory + summarization. + test_long_term_memory.py Vector search, promotion, dedup. + test_extraction.py Topic + entity extraction. + test_summarization.py LLM summarization paths. + test_filters.py Filter compilation. + test_auth.py JWT/JWKS validation. + conftest.py testcontainers Redis fixture, async client fixture. +``` + +## Where features live + +| Feature | Module(s) | +|---|---| +| Store/retrieve a working-memory session | `api.py` β†’ `working_memory.py` β†’ `utils/redis.py` | +| Search long-term memory | `api.py` β†’ `long_term_memory.py` β†’ `filters.py` β†’ `utils/redis_query.py` | +| Promote working β†’ long-term memory | `working_memory.py` β†’ `memory_strategies.py` β†’ `long_term_memory.py` | +| Summarize a conversation | `working_memory.py` β†’ `summarization.py` β†’ `llm/client.py` | +| Extract topics & entities | `extraction.py` β†’ `llm/client.py` | +| Hydrate a prompt with relevant memories | `api.py` (`/v1/memory/prompt`) β†’ `long_term_memory.py` | +| MCP tool surface | `mcp.py` β†’ same business-logic modules as REST | +| Auth on every request | `dependencies.py` β†’ `auth.py` | +| Background indexing & compaction | `docket_tasks.py` β†’ `long_term_memory.py` | +| Choose a vector backend | `memory_vector_db_factory.py` β†’ `memory_vector_db.py` | + +## What to read before changing X + +- **Search behavior.** Read `long_term_memory.py` for the query path, then + `filters.py` for filter semantics, then `utils/redis_query.py` for the actual + RedisVL builders. Project rule: never call `redis.ft().search()` directly β€” + always use RedisVL `VectorQuery` / `FilterQuery`. +- **A new endpoint.** Add the route in `api.py`, the model in `models.py`, the + business logic in the appropriate `*_memory.py` module. Mirror it in `mcp.py` + if it should also be an MCP tool. +- **Authentication.** `auth.py` is the JWKS validator; `dependencies.py` is how + routes opt in. `DISABLE_AUTH=true` is a development-only escape hatch. +- **A new LLM/embedding provider.** Configure via env (LiteLLM resolves it); + no code changes unless you need provider-specific features β€” then extend + `llm/client.py`. +- **A new vector-DB backend.** Implement the `memory_vector_db.py` interface + and register it in `memory_vector_db_factory.py`. + +## What is intentionally not exported + +- `agent_memory_server._aws.*` β€” AWS-specific helpers used by the Bedrock path; + not part of the public contract. +- `agent_memory_server.utils.*` β€” internal helpers; tests may import them but + they are not stable across versions. +- `agent_memory_server.working_memory_index` β€” implementation detail of the + working-memory store. diff --git a/docs/for-ais-only/index.md b/docs/for-ais-only/index.md new file mode 100644 index 00000000..e348c2ac --- /dev/null +++ b/docs/for-ais-only/index.md @@ -0,0 +1,53 @@ +--- +description: Internal AI-agent guide to the Agent Memory Server source tree. +--- + +# For AI Agents Modifying Agent Memory + +This section is the internal counterpart to the user-facing +[AGENTS.md](https://github.com/redis/agent-memory-server/blob/main/AGENTS.md). +It exists for an agent that has been asked to *change* the library: add a +new feature, fix a bug, extend a subsystem. + +Start with the [**Repository map**](REPOSITORY_MAP.md) to find the +subsystem you need. Run [**Build and test**](BUILD_AND_TEST.md) before +and after any change. If something looks broken, check +[**Failure modes**](FAILURE_MODES.md) before assuming it's a bug β€” +several behaviors are intentional and documented there. + +
+ +- :material-map:{ .lg .middle } **[Repository map](REPOSITORY_MAP.md)** + + --- + + Top-down map of every package and module with its responsibility. + +- :material-hammer-wrench:{ .lg .middle } **[Build and test](BUILD_AND_TEST.md)** + + --- + + The exact commands CI runs, plus the local equivalents. + +- :material-alert-circle:{ .lg .middle } **[Failure modes](FAILURE_MODES.md)** + + --- + + Intentional behaviors that look like bugs and where they live. + +- :material-book-edit:{ .lg .middle } **[Authoring standard](AUTHORING_STANDARD.md)** + + --- + + System prompt for generating or revising docs in this repo. + +
+ +## Decision tree + +| Task | Read first | +|---|---| +| Run tests | [Build and test](BUILD_AND_TEST.md) | +| Diagnose "this looks broken" | [Failure modes](FAILURE_MODES.md) before assuming a bug | +| Find a subsystem | [Repository map](REPOSITORY_MAP.md) | +| Write or revise docs | [Authoring standard](AUTHORING_STANDARD.md) | diff --git a/docs/getting-started-index.md b/docs/getting-started-index.md deleted file mode 100644 index 32cdfa41..00000000 --- a/docs/getting-started-index.md +++ /dev/null @@ -1,37 +0,0 @@ -# Getting Started - -Get up and running with Redis Agent Memory Server. Whether you want a quick 5-minute setup or a comprehensive installation guide, start here. - -
- -- πŸš€ **Quick Start** - - --- - - Get a working memory server in 5 minutes with the Python SDK - - [Quick Start Guide β†’](quick-start.md) - -- πŸ“¦ **Installation** - - --- - - Complete installation options: CLI, Docker Compose, and production setup - - [Installation Guide β†’](getting-started.md) - -- πŸ’‘ **Use Cases** - - --- - - Real-world examples across industries and applications - - [Explore Use Cases β†’](use-cases.md) - -
- -## Recommended Path - -**New to memory systems?** Start with the [Quick Start Guide](quick-start.md) to understand the basics and see immediate results. - -**Ready for production?** Jump to the [Installation Guide](getting-started.md) for Docker Compose setup and worker configuration. diff --git a/docs/index.md b/docs/index.md index f46e5266..e617c77f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,47 +1,81 @@ -# Redis Agent Memory Server +--- +description: Agent Memory Server documentation. Session Memory and Long-Term Memory for AI Agents. +--- + +
+ +![Redis](assets/redis-logo-script-red.svg){ .rds-hero__logo } + +# Agent Memory Server -**Give your AI agents persistent memory and context that gets smarter over time.** +Session Memory and Long-Term Memory for AI Agents +{: .rds-hero__tagline } -Transform your AI agents from goldfish 🐠 into elephants 🐘 with Redis-powered memory that automatically learns, organizes, and recalls information across conversations and sessions. +
-- πŸš€ **Quick Start** +- :material-rocket-launch:{ .lg .middle } **[Quick Start](user_guide/01_quick_start.md)** --- - Get up and running in 5 minutes with our step-by-step guide + Get a memory-enabled agent running in 5 minutes. + +- :material-target:{ .lg .middle } **[Use Cases](examples/use_cases.md)** - [Quick Start Guide β†’](quick-start.md) + --- -- 🧠 **Use Cases** + See what you can build: support bots, tutors, personal assistants. + +- :material-language-python:{ .lg .middle } **[Python SDK](api/python_sdk.md)** --- - See real-world examples across industries and applications + Async-first client with OpenAI and Anthropic tool integration. + +
+ +--- + +## Explore the Docs + +
+ +- :material-book-open-variant:{ .lg .middle } **[Concepts](concepts/index.md)** - [Explore Use Cases β†’](use-cases.md) + --- -- 🐍 **Python SDK** + The memory model. Working memory, long-term memory, lifecycle, extraction, summarization. + +- :material-rocket-launch:{ .lg .middle } **[User Guide](user_guide/index.md)** --- - Easy integration with tool abstractions for OpenAI and Anthropic + Tutorials and how-to recipes. Installation, auth, providers, vector DB, integration patterns. - [SDK Documentation β†’](python-sdk.md) +- :material-lightbulb-on:{ .lg .middle } **[Examples](examples/index.md)** + --- + + Runnable agent patterns: travel agent, AI tutor, memory editor, LangChain integration. + +- :material-api:{ .lg .middle } **[API Reference](api/index.md)** + + --- + + REST, MCP, CLI, SDKs, plus the full `agent_memory_server` Python package.
-## What is Redis Agent Memory Server? +## What is Agent Memory Server? -Redis Agent Memory Server is a production-ready memory system for AI agents and applications that: +Agent Memory Server is a production-ready memory system for AI agents and applications that: - **🧠 Remembers everything**: Stores conversation history, user preferences, and important facts across sessions - **πŸ” Finds relevant context**: Uses semantic, keyword, and hybrid search to surface the right information at the right time - **πŸ“ˆ Gets smarter over time**: Automatically extracts, organizes, and deduplicates memories from interactions - **πŸ”Œ Works with any AI model**: REST API and MCP interfaces compatible with OpenAI, Anthropic, and others -- **🌐 Multi-provider support**: Use [100+ LLM providers](llm-providers.md) via LiteLLM (OpenAI, Anthropic, AWS Bedrock, Ollama, Azure, Gemini, and more) +- **🌐 Multi-provider support**: Use [100+ LLM providers](user_guide/how_to_guides/llm_providers.md) via LiteLLM (OpenAI, Anthropic, AWS Bedrock, Ollama, Azure, Gemini, and more) ## Why Use It? @@ -99,47 +133,50 @@ print(f"Found: {results.memories[0].text}") - Advanced filtering by time, topics, entities, users ### πŸ” Intelligent Search + - **Multiple search modes**: Semantic (vector similarity), keyword (full-text), and hybrid (combined) search - **Advanced filters**: Search by user, session, time, topics, entities - **Query optimization**: AI-powered query refinement for better results - **Recency boost**: Time-aware ranking that surfaces relevant recent information ### ✨ Smart Memory Management + - **Automatic extraction**: Pull important facts from conversations - **Contextual grounding**: Resolve pronouns and references ("he" β†’ "John") - **Deduplication**: Prevent duplicate memories with content hashing - **Memory editing**: Update, correct, or enrich existing memories ### πŸš€ Production Ready + - **Multiple interfaces**: REST API, MCP server, Python client - **Authentication**: OAuth2/JWT, token-based, or disabled for development - **Scalable storage**: Redis (default), Pinecone, Chroma, PostgreSQL, and more - **Background processing**: Async tasks for heavy operations - **Multi-tenancy**: User and namespace isolation -## Get Started +## Reader Paths -Ready to give your AI agents perfect memory? +**πŸ‘‹ New to memory systems?** β†’ [Quick Start](user_guide/01_quick_start.md) β†’ [Use Cases](examples/use_cases.md) β†’ [Long-Term Memory](concepts/long_term_memory.md) +**πŸ”§ Ready to integrate?** β†’ [Installation](user_guide/02_installation.md) β†’ [REST API](api/rest.md) β†’ [Configuration](user_guide/how_to_guides/configuration.md) β†’ [Authentication](user_guide/how_to_guides/authentication.md) +**πŸ€– Building an AI agent?** β†’ [MCP Server](api/mcp.md) β†’ [Memory Lifecycle](concepts/memory_lifecycle.md) β†’ [Query Optimization](user_guide/how_to_guides/query_optimization.md) -
+## Get Started -
-**New to memory systems?** +
-Start with our quick tutorial to understand the basics and see immediate results. +[:material-rocket-launch: New to memory systems?](user_guide/01_quick_start.md){ .md-button .md-button--primary } +[:material-api: Ready to integrate?](user_guide/index.md){ .md-button } -[πŸš€ Quick Start Guide](quick-start.md){ .md-button .md-button--primary }
-
-**Ready to integrate?** +## For AI agents -Jump into the Developer Guide for memory patterns and integration strategies. - -[🧠 Developer Guide](memory-integration-patterns.md){ .md-button } -
- -
+If you are an AI agent reading these docs, start with +[`AGENTS.md`](https://github.com/redis/agent-memory-server/blob/main/AGENTS.md) +at the repo root for usage notes, or +[For AI Agents](for-ais-only/index.md) for an internal map of the source +tree. A flat [`llms.txt`](https://ai.redis.io/agent-memory/llms.txt) +index of every doc page is generated at build time. --- @@ -149,7 +186,3 @@ Jump into the Developer Guide for memory patterns and integration strategies. - **🐳 Docker Images**: [Docker Hub](https://hub.docker.com/r/redislabs/agent-memory-server) - **πŸ› Issues**: [Report Issues](https://github.com/redis/agent-memory-server/issues) - **πŸ“– Examples**: [Complete Examples](https://github.com/redis/agent-memory-server/tree/main/examples) - ---- - -**Ready to transform your AI agents?** Start with the [Quick Start Guide](quick-start.md) and build smarter agents in minutes! 🧠✨ diff --git a/docs/javascripts/redis-ai-hub-header.js b/docs/javascripts/redis-ai-hub-header.js new file mode 100644 index 00000000..d4d0671b --- /dev/null +++ b/docs/javascripts/redis-ai-hub-header.js @@ -0,0 +1,87 @@ +// Redis AI Hub: shared header injector +// Renders a persistent top bar on every per-library docs site. +// In production, this would be injected by the central host (CDN edge or reverse proxy). +// In the prototype, each site bundles this JS and injects on DOMContentLoaded. + +(function () { + const HUB_URL = (window.REDIS_AI_HUB_URL || '/').replace(/\/+$/, '/') || '/'; + const CURRENT = window.REDIS_AI_HUB_LIBRARY || ''; + + const LIBRARIES = { + core: [ + { slug: 'redisvl', name: 'RedisVL', path: 'redisvl/' }, + { slug: 'agent-memory', name: 'Agent Memory', path: 'agent-memory/' }, + { slug: 'agent-kit', name: 'Agent Kit', path: 'agent-kit/' }, + { slug: 'sre-agent', name: 'SRE Agent', path: 'sre-agent/' }, + ], + experimental: [ + { slug: 'sql', name: 'SQL for Redis', path: 'sql/' }, + { slug: 'optimizer', name: 'Retrieval Optimizer', path: 'optimizer/' }, + ], + integration: [ + { slug: 'adk', name: 'Google ADK', path: 'adk/' }, + { slug: 'langgraph', name: 'LangGraph', path: 'langgraph/' }, + { slug: 'langchain', name: 'LangChain', path: 'langchain/' }, + { slug: 'recipes', name: 'AI Recipes', path: 'recipes/' }, + ], + }; + + function dropdown(label, items) { + const links = items.map(it => { + const isCurrent = it.slug === CURRENT; + return `${it.name}`; + }).join(''); + return ` +
+ +
${links}
+
`; + } + + function siblingTabs() { + let category = null; + for (const cat of Object.keys(LIBRARIES)) { + if (LIBRARIES[cat].some(l => l.slug === CURRENT)) { category = cat; break; } + } + if (!category) return ''; + const tabs = LIBRARIES[category].map(it => { + const isCurrent = it.slug === CURRENT; + return `${it.name}`; + }).join(''); + return `
${tabs}
`; + } + + function inject() { + if (document.getElementById('rah-header')) return; + const header = document.createElement('div'); + header.id = 'rah-header'; + header.innerHTML = ` +
+ + + Redis AI + + +
+ + β˜… GitHub +
+
+ ${siblingTabs()} + `; + document.body.insertBefore(header, document.body.firstChild); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', inject); + } else { + inject(); + } +})(); diff --git a/docs/operations-guide-index.md b/docs/operations-guide-index.md deleted file mode 100644 index 6473f077..00000000 --- a/docs/operations-guide-index.md +++ /dev/null @@ -1,85 +0,0 @@ -# Operations Guide - -Configure, secure, and deploy your Redis Agent Memory Server in production. This guide covers server configuration, authentication, LLM providers, and infrastructure setup. - -## Server Configuration - -
- -- βš™οΈ **Configuration** - - --- - - Environment variables, YAML config files, and all server settings - - [Configuration Reference β†’](configuration.md) - -- πŸ” **Authentication** - - --- - - OAuth2/JWT, token-based auth, and multi-provider setup - - [Authentication Guide β†’](authentication.md) - -- πŸ›‘οΈ **Security** - - --- - - Security considerations for custom prompts and production deployments - - [Security Guide β†’](security-custom-prompts.md) - -
- -## AI Provider Setup - -
- -- πŸ€– **LLM Providers** - - --- - - Configure OpenAI, Anthropic, AWS Bedrock, Ollama, and 100+ providers via LiteLLM - - [LLM Providers β†’](llm-providers.md) - -- πŸ“ **Embedding Providers** - - --- - - Set up embedding models for semantic search - - [Embedding Providers β†’](embedding-providers.md) - -- πŸ—„οΈ **Memory Vector Databases** - - --- - - Configure Redis or custom memory vector databases - - [Memory Vector Databases β†’](custom-memory-vector-db.md) - -
- -## Quick Reference - -| Topic | Description | -|-------|-------------| -| [Configuration](configuration.md) | All environment variables and YAML settings | -| [Worker timeout tuning](configuration.md#worker-lease-and-task-timeout) | How to size task timeout vs redelivery timeout for Docket workers | -| [Authentication](authentication.md) | OAuth2, token auth, and development mode | -| [Security](security-custom-prompts.md) | Custom prompt security and best practices | -| [LLM Providers](llm-providers.md) | Generation models including AWS Bedrock | -| [Embedding Providers](embedding-providers.md) | Embedding models and dimensions | -| [Memory Vector Databases](custom-memory-vector-db.md) | Storage backend configuration | - -## Where to Start - -**Deploying to production?** Start with [Configuration](configuration.md) to understand all server settings. - -**Setting up authentication?** See [Authentication](authentication.md) for OAuth2 or token-based auth. - -**Using AWS?** The [LLM Providers](llm-providers.md) guide covers AWS Bedrock setup for both generation and embedding models. - -**Customizing storage?** Check [Memory Vector Databases](custom-memory-vector-db.md) for Redis and custom backend options. diff --git a/docs/python-sdk-index.md b/docs/python-sdk-index.md deleted file mode 100644 index a22f54b8..00000000 --- a/docs/python-sdk-index.md +++ /dev/null @@ -1,54 +0,0 @@ -# Python SDK - -The Python SDK provides a simple, async-first interface for integrating memory into your AI applications. It includes client libraries, tool schemas for LLMs, and framework integrations. - -
- -- 🐍 **SDK Documentation** - - --- - - Complete API reference for the Python client library - - [SDK Reference β†’](python-sdk.md) - -- 🦜 **LangChain Integration** - - --- - - Use memory with LangChain agents and chains - - [LangChain Guide β†’](langchain-integration.md) - -- βš™οΈ **Configuration** - - --- - - Environment variables and configuration options - - [Configuration β†’](configuration.md) - -
- -## Installation - -```bash -pip install agent-memory-client -``` - -## Quick Example - -```python -from agent_memory_client import MemoryAPIClient, MemoryClientConfig - -client = MemoryAPIClient(MemoryClientConfig(base_url="http://localhost:8000")) - -# Get memory-enriched context for your LLM -context = await client.memory_prompt( - query="What restaurants should I try?", - session_id="chat_123", - long_term_search={"text": "food preferences", "limit": 5} -) -``` - -See the [SDK Documentation](python-sdk.md) for complete usage examples. diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index cd06070d..b16561f6 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -1,4 +1,4 @@ -/* Custom styles for Redis Agent Memory Server documentation */ +/* Custom styles for Agent Memory Server documentation */ /* Code block improvements */ .highlight pre { @@ -20,6 +20,29 @@ table th { font-weight: 500; } +/* Left sidebar (sections nav) scrolls independently when the nav is taller + * than the viewport. Material's defaults handle this on long pages, but with + * navigation.sections expanded across many sections (User Guide, How-To, + * API Reference, Server package) the nav can exceed viewport height while + * the page itself is short β€” leaving the bottom of the sidebar unreachable. + * Constrain the scrollwrap to viewport-minus-header and force overflow. + * + * Header heights mirror Material defaults: 2.4rem header + 2.4rem tabs on + * desktop, 2.4rem header alone when tabs are absent. We target the larger + * value to be safe; a couple of extra rems of breathing room costs nothing. + */ +@media screen and (min-width: 76.25em) { + .md-sidebar--primary .md-sidebar__scrollwrap { + max-height: calc(100vh - 5.5rem); + overflow-y: auto; + scrollbar-gutter: stable; + } + .md-sidebar--secondary .md-sidebar__scrollwrap { + max-height: calc(100vh - 5.5rem); + overflow-y: auto; + } +} + /* Highlight new features */ .md-content h3:has-text("New in v0.10.0") { color: var(--md-accent-fg-color); @@ -55,3 +78,36 @@ table th { .highlight .language-yaml { border-left: 4px solid var(--md-accent-fg-color); } + +/* mkdocs-jupyter rendering: leave JupyterLab's defaults intact, but draw + * explicit dividers so the reader can tell at a glance: + * 1. where a prose (markdown) cell ends and a code cell begins (and + * vice versa), and + * 2. where a code cell's input ends and its output begins. + */ +.jupyter-wrapper .jp-MarkdownCell + .jp-CodeCell, +.jupyter-wrapper .jp-CodeCell + .jp-MarkdownCell, +.jupyter-wrapper .jp-MarkdownCell + .jp-RawCell, +.jupyter-wrapper .jp-RawCell + .jp-MarkdownCell { + border-top: 1px solid var(--md-default-fg-color--lightest); + margin-top: 1rem; + padding-top: 1rem; +} + +.jupyter-wrapper .jp-CodeCell .jp-Cell-outputWrapper { + border-top: 1px dashed var(--md-default-fg-color--lighter); + margin-top: 0.5rem; + padding-top: 0.5rem; +} + +/* Layout: pin the left sidebar to the viewport's left edge and the right + * TOC to the viewport's right edge by removing Material's centered grid + * cap. Sidebars keep their default 12.1rem widths; the content column + * absorbs all remaining space. Header/tabs use the same grid so they + * also span full width, keeping the layout consistent. + */ +@media screen and (min-width: 76.25em) { + .md-grid { + max-width: none; + } +} diff --git a/docs/stylesheets/redis-ai-hub-header.css b/docs/stylesheets/redis-ai-hub-header.css new file mode 100644 index 00000000..3d23604f --- /dev/null +++ b/docs/stylesheets/redis-ai-hub-header.css @@ -0,0 +1,194 @@ +/* Redis AI Hub: shared header + brand tokens + * Mirrors redis.io typography (Space Grotesk display, Inter body, JetBrains + * Mono code) and brand palette (Redis red #DC382C, Midnight #091A23). + */ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"); + +:root { + --rds-red: #DC382C; + --rds-red-hover: #B82A20; + --rds-red-bright: #FF4438; + --rds-midnight: #091A23; + --rds-ink: #161F31; + --rds-slate: #2D4754; + --rds-mute: #B9C2C6; + --rds-line: #E8EBEC; + --rds-bg: #FFFFFF; + --rds-font-display: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif; + --rds-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif; + --rds-font-mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace; +} + +#rah-header { + position: sticky; + top: 0; + z-index: 9999; + background: var(--rds-bg); + color: var(--rds-midnight); + font-family: var(--rds-font-body); + border-bottom: 1px solid var(--rds-line); +} +html[data-theme="dark"] #rah-header { + background: var(--rds-midnight); + color: var(--rds-line); + border-bottom-color: var(--rds-slate); +} + +.rah-bar { + display: flex; + align-items: center; + gap: 24px; + padding: 12px 24px; + max-width: 100%; +} + +.rah-brand { + display: flex; + align-items: center; + gap: 8px; + color: var(--rds-midnight) !important; + text-decoration: none !important; + font-family: var(--rds-font-display); + font-weight: 600; + font-size: 15px; + letter-spacing: -0.01em; + white-space: nowrap; +} +html[data-theme="dark"] .rah-brand { color: #fff !important; } +.rah-brand:hover { opacity: 0.85; } + +.rah-nav { display: flex; align-items: center; gap: 4px; flex: 1; } + +.rah-dropdown { position: relative; } +.rah-dropdown-btn, +.rah-link { + background: none; + border: none; + color: #4A5C66; + font-family: var(--rds-font-body); + font-size: 14px; + padding: 6px 12px; + cursor: pointer; + border-radius: 4px; + text-decoration: none !important; + font-weight: 500; +} +html[data-theme="dark"] .rah-dropdown-btn, +html[data-theme="dark"] .rah-link { color: var(--rds-mute); } +.rah-dropdown-btn:hover, +.rah-link:hover { background: rgba(9,26,35,0.05); color: var(--rds-midnight); } +html[data-theme="dark"] .rah-dropdown-btn:hover, +html[data-theme="dark"] .rah-link:hover { background: rgba(255,255,255,0.06); color: #fff; } +.rah-caret { font-size: 10px; opacity: 0.6; } + +.rah-dropdown-menu { + display: none; + position: absolute; + top: 100%; + left: 0; + margin-top: 4px; + background: var(--rds-bg); + border: 1px solid var(--rds-line); + border-radius: 8px; + min-width: 200px; + padding: 6px; + box-shadow: 0 12px 28px rgba(9,26,35,0.10); +} +html[data-theme="dark"] .rah-dropdown-menu { + background: var(--rds-ink); + border-color: var(--rds-slate); + box-shadow: 0 12px 28px rgba(0,0,0,0.5); +} +.rah-dropdown:hover .rah-dropdown-menu, +.rah-dropdown:focus-within .rah-dropdown-menu { display: block; } + +.rah-item { + display: block; + padding: 8px 12px; + color: var(--rds-midnight) !important; + text-decoration: none !important; + border-radius: 4px; + font-size: 13.5px; +} +html[data-theme="dark"] .rah-item { color: var(--rds-line) !important; } +.rah-item:hover { background: rgba(220,56,44,0.08); color: var(--rds-red) !important; } +.rah-item--active { color: var(--rds-red) !important; font-weight: 600; } + +.rah-actions { display: flex; gap: 10px; align-items: center; } +.rah-search { + background: rgba(9,26,35,0.04); + border: 1px solid var(--rds-line); + color: #4A5C66; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + cursor: pointer; + font-family: inherit; +} +html[data-theme="dark"] .rah-search { + background: rgba(255,255,255,0.06); + border-color: var(--rds-slate); + color: var(--rds-mute); +} +.rah-search:hover { background: rgba(9,26,35,0.08); color: var(--rds-midnight); } +html[data-theme="dark"] .rah-search:hover { background: rgba(255,255,255,0.12); color: #fff; } +.rah-gh { + color: #4A5C66 !important; + text-decoration: none !important; + font-size: 13px; + padding: 6px 10px; + border-radius: 4px; +} +html[data-theme="dark"] .rah-gh { color: var(--rds-mute) !important; } +.rah-gh:hover { color: var(--rds-midnight) !important; background: rgba(9,26,35,0.05); } +html[data-theme="dark"] .rah-gh:hover { color: #fff !important; background: rgba(255,255,255,0.06); } + +.rah-tabs { + display: flex; + gap: 0; + padding: 0 24px; + border-top: 1px solid var(--rds-line); + background: #FAFBFC; + overflow-x: auto; +} +html[data-theme="dark"] .rah-tabs { + border-top-color: var(--rds-slate); + background: var(--rds-ink); +} +.rah-tab { + color: #6B7A82 !important; + text-decoration: none !important; + padding: 10px 16px; + font-size: 13px; + border-bottom: 2px solid transparent; + white-space: nowrap; + font-weight: 500; +} +html[data-theme="dark"] .rah-tab { color: #8A99A0 !important; } +.rah-tab:hover { color: var(--rds-midnight) !important; } +html[data-theme="dark"] .rah-tab:hover { color: var(--rds-line) !important; } +.rah-tab--active { + color: var(--rds-red) !important; + border-bottom-color: var(--rds-red); + font-weight: 600; +} + +/* Apply redis.io fonts to the host Sphinx theme too */ +body, +.bd-container, +.bd-content, +.bd-sidebar-primary, +.bd-sidebar-secondary { + font-family: var(--rds-font-body); +} +h1, h2, h3, h4, h5, h6, +.bd-page-width h1, .bd-page-width h2, .bd-page-width h3 { + font-family: var(--rds-font-display); + letter-spacing: -0.015em; +} +code, kbd, pre, samp, +.highlight pre { + font-family: var(--rds-font-mono); +} + +body { padding-top: 0; } diff --git a/docs/stylesheets/redis-brand.css b/docs/stylesheets/redis-brand.css new file mode 100644 index 00000000..9e44fde7 --- /dev/null +++ b/docs/stylesheets/redis-brand.css @@ -0,0 +1,79 @@ +/* Redis brand tokens and Material theme overrides for agent-memory-server docs. + * Mirrors the redis-docs tailwind palette (Redis red #FF4438, Redis ink + * #091A23) and self-hosts the Space Grotesk + Space Mono pairing used on + * redis.io. + */ +@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Space+Mono:wght@400;700&display=swap"); + +:root { + /* Mirrors redis-docs tailwind.config.js. */ + --rds-red: #FF4438; /* redis-red-500: primary brand red */ + --rds-red-hover: #D52D1F; /* redis-red-600: hover/pressed */ + --rds-red-bright: #E4291E; /* redis-red-700 */ + --rds-midnight: #091A23; /* redis-ink-900 */ + --rds-ink: #161F31; /* midnight-700 */ + --rds-slate: #2D4754; /* redis-pen-700 */ + --rds-mute: #B9C2C6; /* redis-pen-300 */ + --rds-line: #E8EBEC; /* redis-pen-200 */ + --rds-bg: #FFFFFF; +} + +/* Wire the Redis red into Material's primary/accent slots so the top bar, + * search bar, links, and active nav items pick it up. */ +:root, +[data-md-color-scheme="default"], +[data-md-color-scheme="slate"] { + --md-primary-fg-color: var(--rds-red); + --md-primary-fg-color--light: #FF6B5F; + --md-primary-fg-color--dark: var(--rds-red-hover); + --md-accent-fg-color: var(--rds-red); + --md-accent-fg-color--transparent: rgba(255, 68, 56, 0.1); +} + +/* Bold every top-level entry in the left sidebar. With navigation.sections, + * group labels (Concepts, User Guide, ...) get the section-title treatment, + * but single-page top-level items like Home stay regular weight. This rule + * gives them the same visual weight as the section headers. */ +.md-nav--primary > .md-nav__list > .md-nav__item > .md-nav__link { + font-weight: 700; +} + +/* Landing-page hero: Redis script logo stacked over the wordmark and tagline. + * Mirrors the marketing card used on docs.redisvl.com hand-offs. */ +.rds-hero { + text-align: center; + margin: 1.5rem auto 2.5rem; + padding: 0 1rem; +} + +.rds-hero__logo { + display: block; + margin: 0 auto 0.75rem; + width: clamp(180px, 32vw, 280px); + aspect-ratio: 85 / 27; + height: auto; +} + +.rds-hero h1 { + margin: 0; + font-weight: 700; + font-size: clamp(1.5rem, 3.2vw, 2.125rem); + line-height: 1.15; + color: var(--rds-midnight); + letter-spacing: -0.01em; +} + +[data-md-color-scheme="slate"] .rds-hero h1 { + color: #F2F4F5; +} + +.rds-hero__tagline { + margin: 0.5rem 0 0; + font-size: clamp(1rem, 2vw, 1.25rem); + color: var(--rds-slate); + font-weight: 400; +} + +[data-md-color-scheme="slate"] .rds-hero__tagline { + color: var(--rds-mute); +} diff --git a/docs/quick-start.md b/docs/user_guide/01_quick_start.md similarity index 94% rename from docs/quick-start.md rename to docs/user_guide/01_quick_start.md index d4490c01..01da550c 100644 --- a/docs/quick-start.md +++ b/docs/user_guide/01_quick_start.md @@ -1,6 +1,13 @@ # Quick Start Guide -Get up and running with Redis Agent Memory Server in 5 minutes. This guide shows you how to build memory-enabled AI applications using the Python SDK, with REST API examples as backup. +Get up and running with Agent Memory Server in 5 minutes. This guide shows you how to build memory-enabled AI applications using the Python SDK, with REST API examples as backup. + +!!! info "Need a longer setup walkthrough?" + This guide installs everything inline and assumes you're comfortable + with `pip` and Docker. If you'd rather see the full installation + options first β€” Docker Compose, manual install, native macOS without + Docker, or production deployment β€” start with the + [Getting started guide](02_installation.md) and come back here. ## What You'll Learn @@ -340,12 +347,12 @@ Now that you have the basics working, explore these advanced features: ### πŸ” **Advanced Search** - Try filtering by topics, entities, or time ranges - Experiment with recency boost and query optimization -- See [Working Memory](working-memory.md) and [Long-term Memory](long-term-memory.md) guides for detailed examples +- See [Working Memory](../concepts/working_memory.md) and [Long-term Memory](../concepts/long_term_memory.md) guides for detailed examples ### ✏️ **Memory Editing** - Update existing memories with corrections - Add more context to sparse memories -- See [Memory Lifecycle Guide](memory-lifecycle.md#memory-editing) +- See [Memory Editing Guide](how_to_guides/memory_editing.md) ### πŸ”’ **Production Setup** - Enable authentication (OAuth2/JWT or token-based) @@ -401,10 +408,10 @@ uv run agent-memory task-worker --concurrency 5 & 3. **Start MCP server (if using SSE or streamable HTTP mode):** ```bash -# Production MCP server β€” SSE (uses Docket backend) +# Production MCP server - SSE (uses Docket backend) uv run agent-memory mcp --mode sse --port 9000 --task-backend docket -# Production MCP server β€” streamable HTTP (uses Docket backend) +# Production MCP server - streamable HTTP (uses Docket backend) uv run agent-memory mcp --mode streamable-http --port 9000 --task-backend docket ``` @@ -529,8 +536,8 @@ redis-cli -h localhost -p 6379 ## Get Help - **API Documentation**: Visit `http://localhost:8000/docs` -- **Configuration Guide**: [Configuration](configuration.md) -- **Memory Types**: [Working Memory](working-memory.md) and [Long-term Memory](long-term-memory.md) +- **Configuration Guide**: [Configuration](how_to_guides/configuration.md) +- **Memory Types**: [Working Memory](../concepts/working_memory.md) and [Long-term Memory](../concepts/long_term_memory.md) - **GitHub Issues**: Report problems or ask questions ## What's Next? diff --git a/docs/getting-started.md b/docs/user_guide/02_installation.md similarity index 95% rename from docs/getting-started.md rename to docs/user_guide/02_installation.md index 0dd5f5c9..7c13da80 100644 --- a/docs/getting-started.md +++ b/docs/user_guide/02_installation.md @@ -18,7 +18,7 @@ pip install uv uv sync ``` -3. Set up environment variables (see [Configuration](configuration.md) section) +3. Set up environment variables (see [Configuration](how_to_guides/configuration.md) section) ## Running @@ -82,7 +82,7 @@ When configuring MCP-enabled apps (e.g., Claude Desktop), prefer `uvx` so the ap ``` Notes: -- API keys: Default models use OpenAI. Set `OPENAI_API_KEY`. To use Anthropic instead, set `ANTHROPIC_API_KEY` and also `GENERATION_MODEL` to an Anthropic model (e.g., `claude-3-5-haiku-20241022`). If you have access to GPT-5 models, you can instead set `GENERATION_MODEL` to `gpt-5.2-chat-latest`, `gpt-5.1-chat-latest`, `gpt-5-mini`, or `gpt-5-nano`. See [LLM Providers](llm-providers.md) for all supported providers. +- API keys: Default models use OpenAI. Set `OPENAI_API_KEY`. To use Anthropic instead, set `ANTHROPIC_API_KEY` and also `GENERATION_MODEL` to an Anthropic model (e.g., `claude-3-5-haiku-20241022`). If you have access to GPT-5 models, you can instead set `GENERATION_MODEL` to `gpt-5.2-chat-latest`, `gpt-5.1-chat-latest`, `gpt-5-mini`, or `gpt-5-nano`. See [LLM Providers](how_to_guides/llm_providers.md) for all supported providers. - Make sure your MCP host can find `uvx` (on its PATH or by using an absolute command path). macOS: `brew install uv`. If not on PATH, set `"command"` to an absolute path (e.g., `/opt/homebrew/bin/uvx` on Apple Silicon, `/usr/local/bin/uvx` on Intel macOS). - For production, remove `DISABLE_AUTH` and configure auth. diff --git a/docs/user_guide/03_no_docker_setup.md b/docs/user_guide/03_no_docker_setup.md new file mode 100644 index 00000000..ad58d4aa --- /dev/null +++ b/docs/user_guide/03_no_docker_setup.md @@ -0,0 +1,233 @@ +# Running Agent Memory Server on macOS (No Docker) + +Natively on macOS, including Apple Silicon M-series. No Docker required. + +## Prerequisites + +- macOS (Intel or Apple Silicon) +- Homebrew (https://brew.sh) +- An LLM provider (one of): + - **OpenAI API key** (easiest), or + - **Ollama** (fully local, no API key needed) + +--- + +## Part 1: Redis + +Agent Memory Server uses Redis as its database. Install and start it: + +```bash +brew install redis +brew services start redis +``` + +Verify: +```bash +redis-cli ping +# PONG +``` + +--- + +## Part 2: Agent Memory Server + +### Install + +```bash +brew install python@3.12 +git clone https://github.com/redis/agent-memory-server.git +cd agent-memory-server +pip install uv +make setup +``` + +### Configure + +```bash +cp .env.example .env +``` + +Edit `.env` with **one** of the following configurations: + +**Option A: OpenAI (cloud)** +``` +REDIS_URL=redis://localhost:6379 +OPENAI_API_KEY= +LONG_TERM_MEMORY=true +GENERATION_MODEL=gpt-4o-mini +EMBEDDING_MODEL=text-embedding-3-small +DISABLE_AUTH=true +``` + +**Option B: Ollama (fully local, no API key)** + +First install and start Ollama: +```bash +brew install ollama +ollama serve # Start Ollama server (keep running) +ollama pull llama3.2 # Pull a generation model +ollama pull nomic-embed-text # Pull an embedding model +``` + +Then set `.env`: +``` +REDIS_URL=redis://localhost:6379 +OLLAMA_API_BASE=http://localhost:11434 +GENERATION_MODEL=ollama/llama3.2 +EMBEDDING_MODEL=ollama/nomic-embed-text +REDISVL_VECTOR_DIMENSIONS=768 +LONG_TERM_MEMORY=true +DISABLE_AUTH=true +``` + +> **Note:** When using Ollama, you must set `REDISVL_VECTOR_DIMENSIONS` to match your embedding model (nomic-embed-text = 768, mxbai-embed-large = 1024). + +### Build the search index + +```bash +source .venv/bin/activate +uv run agent-memory rebuild-index +``` + +### Run + +Pick what you need. Each runs in its own terminal. + +**MCP Server** (for AI agent integration, e.g. Orchestrate, Cursor, Claude Desktop): +```bash +source .venv/bin/activate +uv run agent-memory mcp --mode sse --port 9000 +``` + +**REST API** (optional, for HTTP clients): +```bash +source .venv/bin/activate +uv run agent-memory api +``` + +**Background task worker** (optional, for async extraction/compaction): +```bash +source .venv/bin/activate +uv run agent-memory task-worker +``` + +### Verify + +```bash +# MCP server +curl -s http://localhost:9000/sse -H "Accept: text/event-stream" --max-time 3 +# Expected: event: endpoint ... + +# REST API +curl http://localhost:8000/v1/health +# Expected: {"status":"ok"} +``` + +--- + +## Stopping everything + +```bash +brew services stop redis # Stop Redis +# Ctrl+C in each terminal # Stop Agent Memory Server +``` + +## Restarting after reboot + +```bash +brew services start redis +cd agent-memory-server +source .venv/bin/activate +uv run agent-memory mcp --mode sse --port 9000 +``` + +--- + +## Connecting to IBM watsonx Orchestrate (Remote MCP) + +If you need to connect your local MCP server to a cloud service like IBM watsonx Orchestrate, +you need a public URL. Use **ngrok** or **cloudflared** to create a tunnel. + +### Option A: ngrok + +> Requires a free account. Sign up at https://ngrok.com and get your auth token from https://dashboard.ngrok.com/get-started/your-authtoken + +```bash +# Install +brew install ngrok + +# Authenticate (one-time) +ngrok config add-authtoken + +# Start tunnel (in a new terminal, while MCP server is running) +ngrok http 9000 +``` + +Copy the `https://...ngrok-free.dev` URL from the output. + +### Option B: cloudflared + +> No account required for quick tunnels. + +```bash +# Install +brew install cloudflared + +# Start tunnel (in a new terminal, while MCP server is running) +cloudflared tunnel --url http://localhost:9000 +``` + +Copy the `https://...trycloudflare.com` URL from the output. + +### Verify the tunnel + +```bash +curl -s https:///sse \ + -H "Accept: text/event-stream" \ + --max-time 3 +# Expected: event: endpoint ... +``` + +### Add to Orchestrate + +Go to **Agent settings > MCP Servers > Add remote MCP server** and fill in: + +**Server name:** `Redis-Agent-Memory-MCP-Server` +**Description:** `Tools to manage an agent's memory with Redis. Two-tier memory: working/session memory management and long term memory management.` +**MCP server URL:** `https:///sse` +**Transport type:** Server-Sent Events (SSE) + +> ⚠️ The URL **must** end with `/sse`. Without it you'll get a `502 / 404 Not Found` error. + +> ⚠️ Free-tier tunnel URLs change on every restart. Update the URL in Orchestrate each time you restart the tunnel. + +--- + +## Troubleshooting + +**Port 9000/8000 in use:** +```bash +lsof -ti :9000 | xargs kill -9 +``` + +**Redis not running:** +```bash +brew services restart redis +``` + +**Search index missing:** +```bash +uv run agent-memory rebuild-index +``` + +**Python version error:** +Requires Python >=3.12, <3.13. Check with `python3.12 --version` + +**Orchestrate 502/404:** +Make sure the MCP server URL ends with `/sse` + +**ngrok tunnel already exists:** +```bash +pkill -f "ngrok http" +ngrok http 9000 +``` diff --git a/docs/advanced-memory-vector-db.md b/docs/user_guide/how_to_guides/advanced_vector_db.md similarity index 99% rename from docs/advanced-memory-vector-db.md rename to docs/user_guide/how_to_guides/advanced_vector_db.md index 7a49658d..5d677818 100644 --- a/docs/advanced-memory-vector-db.md +++ b/docs/user_guide/how_to_guides/advanced_vector_db.md @@ -1,6 +1,6 @@ # Advanced Memory Vector Database Configuration -This guide covers advanced configuration patterns, custom implementations, and migration strategies for memory vector databases in Redis Agent Memory Server. +This guide covers advanced configuration patterns, custom implementations, and migration strategies for memory vector databases in Agent Memory Server. ## Advanced Factory Patterns diff --git a/docs/authentication.md b/docs/user_guide/how_to_guides/authentication.md similarity index 96% rename from docs/authentication.md rename to docs/user_guide/how_to_guides/authentication.md index 7a02bbac..ee9f4e38 100644 --- a/docs/authentication.md +++ b/docs/user_guide/how_to_guides/authentication.md @@ -1,6 +1,6 @@ # Authentication -The Redis Agent Memory Server supports multiple authentication modes for secure API access. All API endpoints (except `/v1/health`, `/docs`, and `/openapi.json`) require valid authentication unless disabled for development. +The Agent Memory Server supports multiple authentication modes for secure API access. All API endpoints (except `/v1/health`, `/docs`, and `/openapi.json`) require valid authentication unless disabled for development. ## Authentication Modes @@ -128,7 +128,7 @@ You can extract any of these fields in your scripts (for example, `.token` or `. #### Terraform example (register a pre-generated token) -If you generate tokens outside Redis Agent Memory Server (for example via a secrets manager), you can register them using `--token` so the server only ever stores a hash: +If you generate tokens outside Agent Memory Server (for example via a secrets manager), you can register them using `--token` so the server only ever stores a hash: ```hcl variable "agent_memory_token" { diff --git a/docs/aws-bedrock.md b/docs/user_guide/how_to_guides/aws_bedrock.md similarity index 90% rename from docs/aws-bedrock.md rename to docs/user_guide/how_to_guides/aws_bedrock.md index 283d4cfd..5f5e73ad 100644 --- a/docs/aws-bedrock.md +++ b/docs/user_guide/how_to_guides/aws_bedrock.md @@ -1,10 +1,10 @@ # AWS Bedrock Models -The Redis Agent Memory Server supports [Amazon Bedrock](https://aws.amazon.com/bedrock/) for both **embedding models** and **LLM generation models**. This allows you to use AWS-native AI models while keeping your data within the AWS ecosystem. +The Agent Memory Server supports [Amazon Bedrock](https://aws.amazon.com/bedrock/) for both **embedding models** and **LLM generation models**. This allows you to use AWS-native AI models while keeping your data within the AWS ecosystem. -> **See also:** [LLM Providers](llm-providers.md#aws-bedrock) for a broader overview of all supported providers, and [Embedding Providers](embedding-providers.md) for embedding-specific configuration. +> **See also:** [LLM Providers](llm_providers.md#aws-bedrock) for a broader overview of all supported providers, and [Embedding Providers](embedding_providers.md) for embedding-specific configuration. -## Quick Start β€” Run a Full Bedrock-Backed Instance +## Quick Start - Run a Full Bedrock-Backed Instance Follow these steps to get the memory server running entirely on AWS Bedrock in under five minutes. @@ -24,7 +24,7 @@ uv sync --extra aws ```bash # ── AWS credentials ────────────────────────────────────────────── -# (or use an IAM role / AWS CLI profile instead β€” see "AWS Credentials" below) +# (or use an IAM role / AWS CLI profile instead - see "AWS Credentials" below) export AWS_ACCESS_KEY_ID=your-access-key-id export AWS_SECRET_ACCESS_KEY=your-secret-access-key export AWS_REGION_NAME=us-east-1 # Required: used by LiteLLM for Bedrock API calls @@ -80,8 +80,8 @@ All LLM operations in the server go through [LiteLLM](https://docs.litellm.ai/), | Model type | Prefix required? | Example | |------------|------------------|---------| -| **Embedding** | **Yes** β€” must include `bedrock/` | `bedrock/amazon.titan-embed-text-v2:0` | -| **Generation (chat)** | **Optional** β€” not required, but allowed | `anthropic.claude-sonnet-4-5-20250929-v1:0` | +| **Embedding** | **Yes** - must include `bedrock/` | `bedrock/amazon.titan-embed-text-v2:0` | +| **Generation (chat)** | **Optional** - not required, but allowed | `anthropic.claude-sonnet-4-5-20250929-v1:0` | **Why the difference?** LiteLLM can infer the provider for generation models from the Bedrock-style model ID (e.g., `anthropic.claude-*`), so the `bedrock/` prefix is optional for generation. Adding it (e.g., `bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0`) also works. For embedding models, the `bedrock/` prefix is the only way LiteLLM distinguishes a Bedrock embedding call from other providers, so it is **required**. If you omit the prefix on an embedding model, the server will auto-add it and emit a **deprecation warning**, but this fallback will be removed in a future release. @@ -100,21 +100,21 @@ All LLM operations in the server go through [LiteLLM](https://docs.litellm.ai/), | `bedrock/amazon.titan-embed-image-v1` | Amazon | 1024 | Titan multimodal (text + image) embedding * | | `bedrock/cohere.embed-english-v3` | Cohere | 1024 | English-focused embeddings | | `bedrock/cohere.embed-multilingual-v3` | Cohere | 1024 | Multilingual embeddings | -| `bedrock/cohere.embed-v4:0` | Cohere | 1024 | Cohere Embed v4 β€” text + image embedding * | +| `bedrock/cohere.embed-v4:0` | Cohere | 1024 | Cohere Embed v4 - text + image embedding * | > \* Models marked with **\*** are not in `MODEL_CONFIGS` and their dimensions cannot be auto-resolved. You **must** set `REDISVL_VECTOR_DIMENSIONS=1024` explicitly when using them, or you will get vector-size mismatch errors at runtime. ### Generation Models (Anthropic Claude on Bedrock) -The following Anthropic Claude models are available on Bedrock. Models marked **pre-configured** have entries in `MODEL_CONFIGS` (in `config.py`) with validated token limits; the others are fully usable by setting the corresponding environment variable β€” LiteLLM routes the request based on the Bedrock model ID. +The following Anthropic Claude models are available on Bedrock. Models marked **pre-configured** have entries in `MODEL_CONFIGS` (in `config.py`) with validated token limits; the others are fully usable by setting the corresponding environment variable - LiteLLM routes the request based on the Bedrock model ID. | Model ID | Description | Pre-configured | |----------|-------------|:--------------:| -| `anthropic.claude-opus-4-6-v1` | Claude Opus 4.6 β€” latest and most capable | | +| `anthropic.claude-opus-4-6-v1` | Claude Opus 4.6 - latest and most capable | | | `anthropic.claude-sonnet-4-6` | Claude Sonnet 4.6 | | | `anthropic.claude-opus-4-5-20251101-v1:0` | Claude Opus 4.5 | βœ“ | | `anthropic.claude-sonnet-4-5-20250929-v1:0` | Claude Sonnet 4.5 | βœ“ | -| `anthropic.claude-haiku-4-5-20251001-v1:0` | Claude Haiku 4.5 β€” fast & cost-effective | βœ“ | +| `anthropic.claude-haiku-4-5-20251001-v1:0` | Claude Haiku 4.5 - fast & cost-effective | βœ“ | | `anthropic.claude-opus-4-1-20250805-v1:0` | Claude Opus 4.1 | | | `anthropic.claude-sonnet-4-20250514-v1:0` | Claude Sonnet 4 | | | `anthropic.claude-3-5-haiku-20241022-v1:0` | Claude 3.5 Haiku | | @@ -130,14 +130,14 @@ AWS Bedrock support requires additional dependencies. Install the `[aws]` extra: # With pip pip install agent-memory-server[aws] -# With uv (recommended β€” used by this project) +# With uv (recommended - used by this project) uv sync --extra aws ``` This installs: -- **`boto3`** β€” AWS SDK for Python -- **`botocore`** β€” Low-level AWS client library +- **`boto3`** - AWS SDK for Python +- **`botocore`** - Low-level AWS client library > **Without these packages**, any attempt to use Bedrock models will fail at import time. The standard install (`pip install agent-memory-server`) does **not** include them. @@ -207,8 +207,8 @@ export AWS_PROFILE=your-profile The Dockerfile provides two build targets (multi-stage): -- **`standard`** (default) β€” OpenAI / Anthropic support only -- **`aws`** β€” Includes `boto3` and `botocore` for AWS Bedrock support +- **`standard`** (default) - OpenAI / Anthropic support only +- **`aws`** - Includes `boto3` and `botocore` for AWS Bedrock support #### Building the AWS-enabled Image @@ -229,7 +229,7 @@ docker-compose --profile aws up docker-compose --profile aws up api-aws redis ``` -> **Note:** The `aws` profile services (`api-aws`, `mcp-aws`, `task-worker-aws`) are separate from the standard services. Do **not** mix profiles β€” run either `docker-compose up` (standard) or `docker-compose --profile aws up`. +> **Note:** The `aws` profile services (`api-aws`, `mcp-aws`, `task-worker-aws`) are separate from the standard services. Do **not** mix profiles - run either `docker-compose up` (standard) or `docker-compose --profile aws up`. Create a `.env` file with your credentials and model configuration. The Docker Compose AWS services read this file automatically: @@ -333,7 +333,7 @@ REDISVL_VECTOR_DIMENSIONS=1536 ### Example 1: Bedrock Embeddings with OpenAI Generation ```bash -# Embedding model (Bedrock β€” bedrock/ prefix required) +# Embedding model (Bedrock - bedrock/ prefix required) EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v2:0 REDISVL_VECTOR_DIMENSIONS=1024 @@ -360,11 +360,11 @@ AWS_REGION_NAME=us-east-1 AWS_ACCESS_KEY_ID=your-access-key-id AWS_SECRET_ACCESS_KEY=your-secret-access-key -# Embedding model (Bedrock Titan β€” bedrock/ prefix required) +# Embedding model (Bedrock Titan - bedrock/ prefix required) EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v2:0 REDISVL_VECTOR_DIMENSIONS=1024 -# Generation models (Bedrock Claude β€” no prefix needed) +# Generation models (Bedrock Claude - no prefix needed) GENERATION_MODEL=anthropic.claude-sonnet-4-5-20250929-v1:0 FAST_MODEL=anthropic.claude-haiku-4-5-20251001-v1:0 SLOW_MODEL=anthropic.claude-sonnet-4-5-20250929-v1:0 @@ -505,8 +505,8 @@ If you see authentication errors: ## Related Documentation -- [LLM Providers](llm-providers.md) - Comprehensive LLM provider guide (recommended) -- [Embedding Providers](embedding-providers.md) - Embedding model configuration +- [LLM Providers](llm_providers.md) - Comprehensive LLM provider guide (recommended) +- [Embedding Providers](embedding_providers.md) - Embedding model configuration - [Configuration](configuration.md) - Full configuration reference -- [Custom Memory Vector Databases](custom-memory-vector-db.md) - Custom memory vector database setup -- [Getting Started](getting-started.md) - Initial setup guide +- [Custom Memory Vector Databases](custom_vector_db.md) - Custom memory vector database setup +- [Getting Started](../01_quick_start.md) - Initial setup guide diff --git a/docs/configuration.md b/docs/user_guide/how_to_guides/configuration.md similarity index 97% rename from docs/configuration.md rename to docs/user_guide/how_to_guides/configuration.md index 2ccc57d5..2c8c7acd 100644 --- a/docs/configuration.md +++ b/docs/user_guide/how_to_guides/configuration.md @@ -1,6 +1,6 @@ # Configuration -The Redis Agent Memory Server can be configured via environment variables or YAML configuration files. All settings have sensible defaults for development, but you'll want to customize them for production. +The Agent Memory Server can be configured via environment variables or YAML configuration files. All settings have sensible defaults for development, but you'll want to customize them for production. ## Configuration Methods @@ -82,7 +82,7 @@ EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v2:0 REDISVL_VECTOR_DIMENSIONS=1024 # Must match the embedding model dimensions ``` -For detailed AWS Bedrock setup, see [LLM Providers - AWS Bedrock](llm-providers.md#aws-bedrock). +For detailed AWS Bedrock setup, see [LLM Providers - AWS Bedrock](llm_providers.md#aws-bedrock). ### Server Ports ```bash @@ -289,7 +289,7 @@ Pre-configured models: - `anthropic.claude-haiku-4-5-20251001-v1:0` - Claude 4.5 Haiku (Fast) - `anthropic.claude-opus-4-5-20251101-v1:0` - Claude 4.5 Opus (Most capable) -The server uses [LiteLLM](https://docs.litellm.ai/) internally, which supports any Bedrock model. See [LLM Providers](llm-providers.md#aws-bedrock) for setup instructions and adding custom models. +The server uses [LiteLLM](https://docs.litellm.ai/) internally, which supports any Bedrock model. See [LLM Providers](llm_providers.md#aws-bedrock) for setup instructions and adding custom models. ### Embedding Models @@ -302,7 +302,7 @@ The server supports many embedding providers via LiteLLM: - **Cohere**: `cohere/embed-english-v3.0` - **And more...** -See [Embedding Providers](embedding-providers.md) for complete setup instructions, model formats, and dimension configuration. +See [Embedding Providers](embedding_providers.md) for complete setup instructions, model formats, and dimension configuration. ## Configuration Examples diff --git a/docs/custom-memory-vector-db.md b/docs/user_guide/how_to_guides/custom_vector_db.md similarity index 100% rename from docs/custom-memory-vector-db.md rename to docs/user_guide/how_to_guides/custom_vector_db.md diff --git a/docs/development.md b/docs/user_guide/how_to_guides/development.md similarity index 91% rename from docs/development.md rename to docs/user_guide/how_to_guides/development.md index 0dc0e9f5..1d3e227c 100644 --- a/docs/development.md +++ b/docs/user_guide/how_to_guides/development.md @@ -63,8 +63,8 @@ Releases are triggered manually via GitHub Actions workflow dispatch. 3. Go to GitHub Actions β†’ "Release Docker Images" workflow 4. Click "Run workflow" 5. Choose options: - - **Version**: Leave empty to use version from `__init__.py`, or specify a custom version - - **Push latest tag**: Check to also tag as `latest` (recommended for stable releases) + - **Version**: Leave empty to use version from `__init__.py`, or specify a custom version + - **Push latest tag**: Check to also tag as `latest` (recommended for stable releases) 6. Click "Run workflow" This will: diff --git a/docs/embedding-providers.md b/docs/user_guide/how_to_guides/embedding_providers.md similarity index 97% rename from docs/embedding-providers.md rename to docs/user_guide/how_to_guides/embedding_providers.md index 5a4af2ac..c9fbff29 100644 --- a/docs/embedding-providers.md +++ b/docs/user_guide/how_to_guides/embedding_providers.md @@ -1,6 +1,6 @@ # Embedding Providers -The Redis Agent Memory Server uses LiteLLM for embeddings, enabling support for many embedding providers out of the box. +The Agent Memory Server uses LiteLLM for embeddings, enabling support for many embedding providers out of the box. ## Quick Start diff --git a/docs/user_guide/how_to_guides/index.md b/docs/user_guide/how_to_guides/index.md new file mode 100644 index 00000000..70155841 --- /dev/null +++ b/docs/user_guide/how_to_guides/index.md @@ -0,0 +1,127 @@ +--- +description: How-to guides for Agent Memory Server. +--- + +# How-To Guides + +Task-oriented recipes. Each one assumes you already know the basics from +the numbered tutorials and answers a single "how do I..." question. + +## Configure + +
+ +- :material-cog:{ .lg .middle } **[Configuration](configuration.md)** + + --- + + Environment variables and runtime options. + +- :material-shield-key:{ .lg .middle } **[Authentication](authentication.md)** + + --- + + OAuth2/JWT setup with Auth0, Cognito, Okta, Azure AD. + +- :material-shield-lock:{ .lg .middle } **[Custom prompt security](security.md)** + + --- + + Custom prompts, injection protection, hardening. + +
+ +## Connect providers + +
+ +- :material-robot:{ .lg .middle } **[LLM providers](llm_providers.md)** + + --- + + OpenAI, Anthropic, and other LiteLLM-supported chat models. + +- :material-vector-line:{ .lg .middle } **[Embedding providers](embedding_providers.md)** + + --- + + Pick and configure an embedding model for semantic search. + +- :material-aws:{ .lg .middle } **[AWS Bedrock](aws_bedrock.md)** + + --- + + Use Bedrock-hosted Claude, Titan, and Cohere models. + +
+ +## Vector storage + +
+ +- :material-database-search:{ .lg .middle } **[Advanced vector DB](advanced_vector_db.md)** + + --- + + Tune index parameters, choose algorithms, manage migrations. + +- :material-database-edit:{ .lg .middle } **[Custom vector DB](custom_vector_db.md)** + + --- + + Plug in your own vector backend behind the memory layer. + +- :material-tune:{ .lg .middle } **[Query optimization](query_optimization.md)** + + --- + + Lower latency and improve recall on large memory stores. + +- :material-pencil:{ .lg .middle } **[Memory editing](memory_editing.md)** + + --- + + Update, correct, and enrich existing long-term memories via REST, MCP, or the Python client. + +
+ +## Integrate + +
+ +- :material-puzzle:{ .lg .middle } **[Integration patterns](integration_patterns.md)** + + --- + + Recipes for plugging the server into common agent frameworks. + +- :material-toolbox:{ .lg .middle } **[Development](development.md)** + + --- + + Local dev loop, debugging, and contributing back. + +
+ +## Operations Quick Reference + +| Topic | Description | +|-------|-------------| +| [Configuration](configuration.md) | All environment variables and YAML settings | +| [Worker timeout tuning](configuration.md#worker-lease-and-task-timeout) | How to size task timeout vs redelivery timeout for Docket workers | +| [Authentication](authentication.md) | OAuth2, token auth, and development mode | +| [Custom prompt security](security.md) | Custom prompt security and best practices | +| [LLM Providers](llm_providers.md) | Generation models including AWS Bedrock | +| [Embedding Providers](embedding_providers.md) | Embedding models and dimensions | +| [Custom Vector DB](custom_vector_db.md) | Storage backend configuration | +| [Advanced Vector DB](advanced_vector_db.md) | Tune index parameters and algorithms | + +## Where to Start + +**Deploying to production?** Start with [Configuration](configuration.md) to understand all server settings. + +**Setting up authentication?** See [Authentication](authentication.md) for OAuth2 or token-based auth. + +**Using AWS?** The [LLM Providers](llm_providers.md) and [AWS Bedrock](aws_bedrock.md) guides cover Bedrock setup for both generation and embedding models. + +**Customizing storage?** Check [Custom Vector DB](custom_vector_db.md) for Redis and custom backend options. diff --git a/docs/memory-integration-patterns.md b/docs/user_guide/how_to_guides/integration_patterns.md similarity index 99% rename from docs/memory-integration-patterns.md rename to docs/user_guide/how_to_guides/integration_patterns.md index 6e94696b..ec47c589 100644 --- a/docs/memory-integration-patterns.md +++ b/docs/user_guide/how_to_guides/integration_patterns.md @@ -1,6 +1,6 @@ # Memory Integration Patterns -The most common question developers have is: *"How do I actually get memories into and out of my LLM?"* Redis Agent Memory Server provides three distinct patterns for integrating memory with your AI applications, each optimized for different use cases and levels of control. +The most common question developers have is: *"How do I actually get memories into and out of my LLM?"* Agent Memory Server provides three distinct patterns for integrating memory with your AI applications, each optimized for different use cases and levels of control. ## Overview of Using Memory @@ -508,7 +508,7 @@ await client.put_working_memory("car_shopping_session", working_memory) # - "User is shopping for electric vehicles" ``` -For complete details on extraction strategies (discrete, summary, preferences, custom) and security considerations, see [Memory Extraction Strategies](memory-extraction-strategies.md). +For complete details on extraction strategies (discrete, summary, preferences, custom) and security considerations, see [Memory Extraction Strategies](../../concepts/memory_extraction.md). ### Continuous Learning Agent diff --git a/docs/llm-providers.md b/docs/user_guide/how_to_guides/llm_providers.md similarity index 91% rename from docs/llm-providers.md rename to docs/user_guide/how_to_guides/llm_providers.md index f0021c77..633502a0 100644 --- a/docs/llm-providers.md +++ b/docs/user_guide/how_to_guides/llm_providers.md @@ -1,6 +1,6 @@ # LLM Providers -The Redis Agent Memory Server uses [LiteLLM](https://docs.litellm.ai/) as a unified interface for all LLM operations. This enables support for 100+ LLM providers without code changesβ€”just configure environment variables. +The Agent Memory Server uses [LiteLLM](https://docs.litellm.ai/) as a unified interface for all LLM operations. This enables support for 100+ LLM providers without code changes - just configure environment variables. ## Architecture Overview @@ -41,13 +41,13 @@ export OPENAI_API_KEY=sk-... export GENERATION_MODEL=gpt-4o export EMBEDDING_MODEL=text-embedding-3-small -# Anthropic (requires a separate embedding provider β€” Anthropic has no embedding models) +# Anthropic (requires a separate embedding provider - Anthropic has no embedding models) export ANTHROPIC_API_KEY=sk-ant-... export GENERATION_MODEL=claude-3-5-sonnet-20241022 export OPENAI_API_KEY=sk-... # Needed for embeddings export EMBEDDING_MODEL=text-embedding-3-small # Use OpenAI for embeddings -# AWS Bedrock (full stack β€” see "AWS Bedrock" section for details) +# AWS Bedrock (full stack - see "AWS Bedrock" section for details) export AWS_ACCESS_KEY_ID=... export AWS_SECRET_ACCESS_KEY=... export AWS_REGION_NAME=us-east-1 # Required: LiteLLM Bedrock calls @@ -57,7 +57,7 @@ export EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v2:0 # bedrock/ pre export REDISVL_VECTOR_DIMENSIONS=1024 # Must match embedding model ``` -> **Bedrock users:** You must also install the `[aws]` extra (`pip install agent-memory-server[aws]` or `uv sync --extra aws`) to get `boto3` and `botocore`. See [AWS Bedrock](aws-bedrock.md) for a full walkthrough. +> **Bedrock users:** You must also install the `[aws]` extra (`pip install agent-memory-server[aws]` or `uv sync --extra aws`) to get `boto3` and `botocore`. See [AWS Bedrock](aws_bedrock.md) for a full walkthrough. ## Supported Providers @@ -74,7 +74,7 @@ export REDISVL_VECTOR_DIMENSIONS=1024 # Must match e ### Embedding Models -See [Embedding Providers](embedding-providers.md) for complete embedding configuration. +See [Embedding Providers](embedding_providers.md) for complete embedding configuration. **Quick reference:** ```bash @@ -130,7 +130,7 @@ export EMBEDDING_MODEL=text-embedding-3-small AWS Bedrock provides access to foundation models from multiple providers (Anthropic Claude, Amazon Titan, Cohere, etc.) through AWS infrastructure. -> **Full guide:** See [AWS Bedrock Models](aws-bedrock.md) for a complete walkthrough including a Quick Start demo, Docker Compose instructions, IAM policies, and troubleshooting. +> **Full guide:** See [AWS Bedrock Models](aws_bedrock.md) for a complete walkthrough including a Quick Start demo, Docker Compose instructions, IAM policies, and troubleshooting. #### Installation @@ -140,7 +140,7 @@ AWS Bedrock support requires the `[aws]` extra, which installs `boto3` and `boto # With pip pip install agent-memory-server[aws] -# With uv (recommended β€” used by this project) +# With uv (recommended - used by this project) uv sync --extra aws ``` @@ -160,7 +160,7 @@ export AWS_PROFILE=my-profile export AWS_REGION_NAME=us-east-1 # Option 3: IAM role (recommended for production on AWS) -# No explicit credentials needed β€” LiteLLM discovers them from instance metadata +# No explicit credentials needed - LiteLLM discovers them from instance metadata export AWS_REGION_NAME=us-east-1 # Option 4: AWS SSO @@ -184,30 +184,30 @@ export FAST_MODEL=anthropic.claude-haiku-4-5-20251001-v1:0 | Model ID | Description | Pre-configured | |----------|-------------|:--------------:| -| `anthropic.claude-opus-4-6-v1` | Claude Opus 4.6 β€” latest | | +| `anthropic.claude-opus-4-6-v1` | Claude Opus 4.6 - latest | | | `anthropic.claude-sonnet-4-6` | Claude Sonnet 4.6 | | | `anthropic.claude-opus-4-5-20251101-v1:0` | Claude Opus 4.5 | βœ“ | | `anthropic.claude-sonnet-4-5-20250929-v1:0` | Claude Sonnet 4.5 | βœ“ | -| `anthropic.claude-haiku-4-5-20251001-v1:0` | Claude Haiku 4.5 β€” fast & cost-effective | βœ“ | +| `anthropic.claude-haiku-4-5-20251001-v1:0` | Claude Haiku 4.5 - fast & cost-effective | βœ“ | | `anthropic.claude-opus-4-1-20250805-v1:0` | Claude Opus 4.1 | | | `anthropic.claude-sonnet-4-20250514-v1:0` | Claude Sonnet 4 | | | `anthropic.claude-3-5-haiku-20241022-v1:0` | Claude 3.5 Haiku | | | `anthropic.claude-3-haiku-20240307-v1:0` | Claude 3 Haiku | | -Any Bedrock model can be used by setting the environment variable β€” LiteLLM routes based on the model ID convention. +Any Bedrock model can be used by setting the environment variable - LiteLLM routes based on the model ID convention. #### Embedding Models > **Important:** Bedrock embedding models **require** the `bedrock/` prefix. -LiteLLM needs the `bedrock/` prefix to distinguish Bedrock embeddings from other providers. If you omit it, the server auto-adds the prefix and emits a **deprecation warning** β€” this fallback will be removed in a future release. +LiteLLM needs the `bedrock/` prefix to distinguish Bedrock embeddings from other providers. If you omit it, the server auto-adds the prefix and emits a **deprecation warning** - this fallback will be removed in a future release. ```bash -# Correct β€” use bedrock/ prefix +# Correct - use bedrock/ prefix export EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v2:0 export REDISVL_VECTOR_DIMENSIONS=1024 # Must match embedding model dimensions -# Deprecated β€” works but emits a warning +# Deprecated - works but emits a warning export EMBEDDING_MODEL=amazon.titan-embed-text-v2:0 ``` @@ -220,7 +220,7 @@ export EMBEDDING_MODEL=amazon.titan-embed-text-v2:0 | `bedrock/amazon.titan-embed-image-v1` | 1024 | Titan multimodal (text + image) embedding * | | `bedrock/cohere.embed-english-v3` | 1024 | English-focused | | `bedrock/cohere.embed-multilingual-v3` | 1024 | Multilingual | -| `bedrock/cohere.embed-v4:0` | 1024 | Cohere Embed v4 β€” text + image * | +| `bedrock/cohere.embed-v4:0` | 1024 | Cohere Embed v4 - text + image * | > \* Models marked with **\*** are not in `MODEL_CONFIGS`, so their dimensions cannot be auto-resolved. Set `REDISVL_VECTOR_DIMENSIONS=1024` explicitly when using them. @@ -401,7 +401,7 @@ export REDISVL_VECTOR_DIMENSIONS=1024 - Verify IAM permissions include `bedrock:InvokeModel` - Check model is enabled in your AWS region - Ensure both `REGION_NAME` and `AWS_REGION_NAME` are set correctly -- See [AWS Bedrock Troubleshooting](aws-bedrock.md#troubleshooting) for more details +- See [AWS Bedrock Troubleshooting](aws_bedrock.md#troubleshooting) for more details **Bedrock "AWS-related dependencies might be missing"** - Install the `[aws]` extra: `pip install agent-memory-server[aws]` or `uv sync --extra aws` @@ -440,8 +440,8 @@ The following are no longer required: ## See Also -- [AWS Bedrock Models](aws-bedrock.md) - Complete Bedrock guide with Quick Start, IAM policies, and Docker setup -- [Embedding Providers](embedding-providers.md) - Detailed embedding configuration +- [AWS Bedrock Models](aws_bedrock.md) - Complete Bedrock guide with Quick Start, IAM policies, and Docker setup +- [Embedding Providers](embedding_providers.md) - Detailed embedding configuration - [Configuration](configuration.md) - All environment variables -- [Query Optimization](query-optimization.md) - Model selection for query optimization +- [Query Optimization](query_optimization.md) - Model selection for query optimization - [LiteLLM Documentation](https://docs.litellm.ai/) - Full provider list diff --git a/docs/user_guide/how_to_guides/memory_editing.md b/docs/user_guide/how_to_guides/memory_editing.md new file mode 100644 index 00000000..92751437 --- /dev/null +++ b/docs/user_guide/how_to_guides/memory_editing.md @@ -0,0 +1,497 @@ +--- +description: Update, correct, and enrich existing long-term memories. +--- + +# Memory editing + +The Agent Memory Server provides comprehensive memory editing capabilities, allowing you to update, correct, and refine stored memories through both REST API endpoints and MCP tools. This feature enables AI agents and applications to maintain accurate, up-to-date memory records over time. + +## Overview + +Memory editing allows you to modify existing long-term memories without losing their search indexing or metadata. This is essential for: + +- **Correcting mistakes**: Fix inaccurate information in stored memories +- **Updating information**: Reflect changes in user preferences or circumstances +- **Adding details**: Enrich memories with additional context or information +- **Maintaining accuracy**: Keep memory store current and reliable + +**Key Features:** + +- **Partial updates**: Modify only the fields you want to change +- **Automatic re-indexing**: Updated memories are re-indexed for search +- **Vector consistency**: Embeddings are regenerated when text changes +- **Metadata preservation**: IDs, timestamps, and other metadata remain stable +- **Atomic operations**: Updates succeed or fail completely + +## Memory editing workflow + +### 1. Find the memory + +First, locate the memory you want to edit using search: + +```python +# Search for memories to edit +results = await client.search_long_term_memory( + text="user food preferences", + limit=5 +) + +# Find the specific memory +memory_to_edit = results.memories[0] +memory_id = memory_to_edit.id +``` + +### 2. Prepare updates + +Specify only the fields you want to change: + +```python +# Update only the text content +updates = { + "text": "User prefers Mediterranean cuisine and is vegetarian" +} + +# Or update multiple fields +updates = { + "text": "User prefers Mediterranean cuisine and is vegetarian", + "topics": ["food", "preferences", "diet", "mediterranean"], + "entities": ["Mediterranean cuisine", "vegetarian"] +} +``` + +### 3. Apply the update + +Use the appropriate interface to apply your changes: + +```python +# Update the memory +updated_memory = await client.edit_long_term_memory( + memory_id=memory_id, + updates=updates +) +``` + +## REST API interface + +### Endpoint + +**PATCH /v1/long-term-memory/{memory_id}** + +Updates specific fields of an existing memory record. + +### Request format + +```http +PATCH /v1/long-term-memory/01HXE2B1234567890ABCDEF +Content-Type: application/json +Authorization: Bearer your_token_here + +{ + "text": "Updated memory text", + "topics": ["new", "topics"], + "entities": ["updated", "entities"], + "memory_type": "semantic", + "event_date": "2024-01-15T14:30:00Z", + "namespace": "updated_namespace", + "user_id": "updated_user" +} +``` + +### Response format + +```json +{ + "id": "01HXE2B1234567890ABCDEF", + "text": "Updated memory text", + "memory_type": "semantic", + "topics": ["new", "topics"], + "entities": ["updated", "entities"], + "created_at": "2024-01-10T12:00:00Z", + "persisted_at": "2024-01-10T12:00:00Z", + "updated_at": "2024-01-16T10:30:00Z", + "last_accessed": "2024-01-16T10:30:00Z", + "user_id": "user_123", + "session_id": "session_456", + "namespace": "updated_namespace", + "memory_hash": "new_hash_after_update" +} +``` + +### cURL examples + +**Update memory text:** + +```bash +curl -X PATCH "http://localhost:8000/v1/long-term-memory/01HXE2B1234567890ABCDEF" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer your_token" \ + -d '{ + "text": "User prefers dark mode interfaces and uses vim for coding" + }' +``` + +**Update multiple fields:** + +```bash +curl -X PATCH "http://localhost:8000/v1/long-term-memory/01HXE2B1234567890ABCDEF" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer your_token" \ + -d '{ + "text": "User completed Python certification on January 15, 2024", + "memory_type": "episodic", + "event_date": "2024-01-15T14:30:00Z", + "topics": ["education", "certification", "python"], + "entities": ["Python", "certification"] + }' +``` + +## MCP tool interface + +### Tool: edit_long_term_memory + +The MCP server provides an `edit_long_term_memory` tool for AI agents to modify memories through natural conversation. + +### Tool schema + +```python +{ + "name": "edit_long_term_memory", + "description": "Update an existing long-term memory with new or corrected information", + "parameters": { + "type": "object", + "properties": { + "memory_id": { + "type": "string", + "description": "The ID of the memory to edit (get this from search results)" + }, + "text": { + "type": "string", + "description": "Updated memory text content" + }, + "topics": { + "type": "array", + "items": {"type": "string"}, + "description": "Updated list of topics" + }, + "entities": { + "type": "array", + "items": {"type": "string"}, + "description": "Updated list of entities" + }, + "memory_type": { + "type": "string", + "enum": ["semantic", "episodic", "message"], + "description": "Type of memory" + }, + "event_date": { + "type": "string", + "description": "Event date for episodic memories (ISO 8601 format)" + }, + "namespace": { + "type": "string", + "description": "Memory namespace" + }, + "user_id": { + "type": "string", + "description": "User ID associated with the memory" + } + }, + "required": ["memory_id"] + } +} +``` + +### MCP usage examples + +**Simple text update:** + +```python +await client.call_tool("edit_long_term_memory", { + "memory_id": "01HXE2B1234567890ABCDEF", + "text": "User prefers tea over coffee (updated preference)" +}) +``` + +**Update memory type and event date:** + +```python +await client.call_tool("edit_long_term_memory", { + "memory_id": "01HXE2B1234567890ABCDEF", + "memory_type": "episodic", + "event_date": "2024-01-15T14:30:00Z" +}) +``` + +**Comprehensive update:** + +```python +await client.call_tool("edit_long_term_memory", { + "memory_id": "01HXE2B1234567890ABCDEF", + "text": "User was promoted to Principal Engineer on January 15, 2024", + "memory_type": "episodic", + "event_date": "2024-01-15T14:30:00Z", + "topics": ["career", "promotion", "engineering", "principal"], + "entities": ["Principal Engineer", "promotion", "January 15, 2024"] +}) +``` + +## Python client interface + +### Method: edit_long_term_memory + +```python +async def edit_long_term_memory( + self, + memory_id: str, + updates: dict[str, Any] +) -> MemoryRecord: + """ + Edit an existing long-term memory record. + + Args: + memory_id: The ID of the memory to edit + updates: Dictionary of fields to update + + Returns: + The updated memory record + + Raises: + HTTPException: If memory not found or update fails + """ +``` + +### Client usage examples + +```python +from agent_memory_client import MemoryAPIClient, MemoryClientConfig + +client = MemoryAPIClient(MemoryClientConfig(base_url="http://localhost:8000")) + +# Simple text correction +updated_memory = await client.edit_long_term_memory( + memory_id="01HXE2B1234567890ABCDEF", + updates={"text": "User actually prefers coffee, not tea"} +) + +# Add more context +updated_memory = await client.edit_long_term_memory( + memory_id="01HXE2B1234567890ABCDEF", + updates={ + "text": "User prefers Italian cuisine, especially pasta and pizza", + "topics": ["food", "preferences", "italian", "cuisine"], + "entities": ["Italian cuisine", "pasta", "pizza"] + } +) + +# Update namespace and user +updated_memory = await client.edit_long_term_memory( + memory_id="01HXE2B1234567890ABCDEF", + updates={ + "namespace": "work_preferences", + "user_id": "user_456" + } +) +``` + +## Editable fields + +### Core content fields + +- **text**: The main memory content (triggers embedding regeneration) +- **topics**: List of topic tags for categorization +- **entities**: List of named entities mentioned in the memory +- **memory_type**: Type classification (semantic, episodic, message) + +### Temporal fields + +- **event_date**: Specific date/time for episodic memories (ISO 8601 format) + +### Organization fields + +- **namespace**: Memory namespace for organization +- **user_id**: User associated with the memory + +### Read-only fields + +These fields cannot be edited and are managed automatically: + +- **id**: Unique memory identifier +- **created_at**: Original creation timestamp +- **persisted_at**: When memory was first saved to long-term storage +- **updated_at**: Last modification timestamp (updated automatically) +- **last_accessed**: Last time memory was retrieved (managed by recency system) +- **memory_hash**: Content hash (regenerated when text changes) + +## Update behavior + +### Automatic updates + +When you edit a memory, the system automatically: + +1. **Updates timestamps**: Sets `updated_at` to current time +2. **Regenerates embeddings**: If text content changes, new embeddings are created +3. **Recalculates hash**: Content hash is updated for deduplication +4. **Re-indexes memory**: Search index is updated with new content +5. **Updates access time**: Sets `last_accessed` to current time + +### Partial updates + +Only specify fields you want to change - other fields remain unchanged: + +```python +# Only update topics - text, entities, etc. stay the same +updates = {"topics": ["programming", "python", "web-development"]} + +# Only update text - topics, entities, etc. stay the same +updates = {"text": "Updated description of the user's preferences"} +``` + +### Vector re-indexing + +When memory text changes, the system automatically: + +- Generates new embeddings using the configured embedding model +- Updates the vector index for accurate semantic search +- Maintains search performance and accuracy + +## Error handling + +### Common errors + +**Memory Not Found (404):** + +```json +{ + "detail": "Memory not found: 01HXE2B1234567890ABCDEF", + "status_code": 404 +} +``` + +**Invalid Memory ID (400):** + +```json +{ + "detail": "Invalid memory ID format", + "status_code": 400 +} +``` + +**Validation Error (422):** + +```json +{ + "detail": [ + { + "loc": ["body", "event_date"], + "msg": "invalid datetime format", + "type": "value_error" + } + ], + "status_code": 422 +} +``` + +### Error handling in code + +```python +try: + updated_memory = await client.edit_long_term_memory( + memory_id="01HXE2B1234567890ABCDEF", + updates={"text": "Updated text"} + ) +except HTTPException as e: + if e.status_code == 404: + print("Memory not found") + elif e.status_code == 422: + print("Invalid update data") + else: + print(f"Update failed: {e.detail}") +``` + +## Use cases and examples + +### Correcting user information + +**Scenario**: User corrects their job title + +```python +# 1. Search for the memory +results = await client.search_long_term_memory( + text="user job title engineer", + limit=1 +) + +# 2. Update with correction +if results.memories: + await client.edit_long_term_memory( + memory_id=results.memories[0].id, + updates={ + "text": "User works as a Senior Software Engineer at TechCorp", + "entities": ["Senior Software Engineer", "TechCorp"] + } + ) +``` + +### Adding context to sparse memories + +**Scenario**: Enrich a basic memory with additional details + +```python +# Original: "User likes pizza" +# Enhanced with context: +await client.edit_long_term_memory( + memory_id="01HXE2B1234567890ABCDEF", + updates={ + "text": "User likes pizza, especially thin crust with pepperoni and mushrooms from Mario's Pizzeria", + "topics": ["food", "preferences", "pizza", "italian"], + "entities": ["pizza", "thin crust", "pepperoni", "mushrooms", "Mario's Pizzeria"] + } +) +``` + +### Converting memory types + +**Scenario**: Convert a general memory to an episodic memory with event date + +```python +# Change from semantic to episodic with specific date +await client.edit_long_term_memory( + memory_id="01HXE2B1234567890ABCDEF", + updates={ + "text": "User got promoted to Team Lead on March 15, 2024", + "memory_type": "episodic", + "event_date": "2024-03-15T09:00:00Z", + "topics": ["career", "promotion", "team-lead"], + "entities": ["Team Lead", "promotion", "March 15, 2024"] + } +) +``` + +## Best practices for memory editing + +### Memory identification + +1. **Use search first**: Always search to find the correct memory ID +2. **Verify before editing**: Check memory content matches your expectations +3. **Handle duplicates**: Consider if multiple memories need the same update + +### Update strategy + +1. **Minimal changes**: Only update fields that actually need to change +2. **Preserve context**: Don't remove important information when updating +3. **Consistent formatting**: Maintain consistent data formats across memories +4. **Validate inputs**: Check data formats before making updates + +### Error prevention + +1. **Check memory exists**: Handle 404 errors gracefully +2. **Validate data**: Ensure update data matches expected formats +3. **Test updates**: Verify changes work as expected in development +4. **Monitor performance**: Watch for degradation with frequent updates + +This comprehensive memory editing system ensures that your AI agent's memory remains accurate, current, and useful over time, adapting to new information and corrections as they become available. + +## See also + +- [Memory lifecycle](../../concepts/memory_lifecycle.md) β€” how memories are created, promoted, and forgotten +- [Long-term memory](../../concepts/long_term_memory.md) β€” semantic search and persistent storage diff --git a/docs/query-optimization.md b/docs/user_guide/how_to_guides/query_optimization.md similarity index 96% rename from docs/query-optimization.md rename to docs/user_guide/how_to_guides/query_optimization.md index 459dccea..8e592ee8 100644 --- a/docs/query-optimization.md +++ b/docs/user_guide/how_to_guides/query_optimization.md @@ -1,6 +1,6 @@ # Query Optimization -The Redis Agent Memory Server includes intelligent query optimization that uses configurable language models to improve search accuracy and retrieval quality. This feature automatically refines user queries to better match stored memories using specialized AI models. +The Agent Memory Server includes intelligent query optimization that uses configurable language models to improve search accuracy and retrieval quality. This feature automatically refines user queries to better match stored memories using specialized AI models. ## Overview @@ -73,7 +73,7 @@ GENERATION_MODEL=gpt-4o # - Any model supported by LiteLLM (100+ providers) ``` -See [LLM Providers](llm-providers.md) for complete configuration options. +See [LLM Providers](llm_providers.md) for complete configuration options. ## Usage Examples diff --git a/docs/security-custom-prompts.md b/docs/user_guide/how_to_guides/security.md similarity index 93% rename from docs/security-custom-prompts.md rename to docs/user_guide/how_to_guides/security.md index 882bf659..78e058d1 100644 --- a/docs/security-custom-prompts.md +++ b/docs/user_guide/how_to_guides/security.md @@ -3,6 +3,7 @@ This guide covers security considerations when using the CustomMemoryStrategy feature, which allows users to provide custom extraction prompts for specialized memory extraction. !!! danger "Security Critical" + User-provided prompts introduce security risks including prompt injection, template injection, and output manipulation. The system includes comprehensive defenses, but understanding these risks is essential for production deployment. ## Overview @@ -115,7 +116,8 @@ def _validate_memory_output(self, memory: dict[str, Any]) -> bool: The system automatically detects and blocks common attack patterns: -!!! example "Blocked Patterns" +!!! tip "Blocked Patterns" + - **Instruction Override:** `ignore previous instructions`, `forget everything` - **Information Extraction:** `reveal your system prompt`, `show me your instructions` - **Code Execution:** `execute code`, `eval(`, `import`, `subprocess` @@ -224,6 +226,7 @@ logger.warning("Filtered potentially unsafe memory: {memory}") ``` !!! tip "Production Monitoring" + Monitor these security logs in production environments to detect potential attack attempts and adjust security rules as needed. ## Production Recommendations @@ -247,19 +250,19 @@ logger.warning("Filtered potentially unsafe memory: {memory}") If you suspect a security issue: 1. **Immediate Actions:** - - Disable the affected custom prompt - - Review recent memory extractions for anomalies - - Check system logs for security events + - Disable the affected custom prompt + - Review recent memory extractions for anomalies + - Check system logs for security events 2. **Investigation:** - - Identify the source of malicious prompts - - Assess potential data exposure or corruption - - Review user access and authentication logs + - Identify the source of malicious prompts + - Assess potential data exposure or corruption + - Review user access and authentication logs 3. **Remediation:** - - Update security rules if new attack patterns detected - - Notify affected users of any data concerns - - Implement additional security controls as needed + - Update security rules if new attack patterns detected + - Notify affected users of any data concerns + - Implement additional security controls as needed ## API Integration @@ -312,8 +315,8 @@ uv run pytest tests/test_memory_strategies.py tests/test_prompt_security.py ## Related Documentation -- [Working Memory](working-memory.md) - Session-scoped memory storage -- [Long-term Memory](long-term-memory.md) - Persistent memory storage +- [Working Memory](../../concepts/working_memory.md) - Session-scoped memory storage +- [Long-term Memory](../../concepts/long_term_memory.md) - Persistent memory storage - [Authentication](authentication.md) - Securing API access - [Configuration](configuration.md) - System configuration options - [Development Guide](development.md) - Development and testing practices @@ -321,4 +324,5 @@ uv run pytest tests/test_memory_strategies.py tests/test_prompt_security.py --- !!! warning "Security Responsibility" + Security is a shared responsibility. Always validate and review custom prompts before use in production environments. When in doubt, use the built-in memory strategies (discrete, summary, preferences) which have been thoroughly tested and validated. diff --git a/docs/user_guide/index.md b/docs/user_guide/index.md new file mode 100644 index 00000000..79069005 --- /dev/null +++ b/docs/user_guide/index.md @@ -0,0 +1,48 @@ +--- +description: User guide for Agent Memory Server. +--- + +# User Guide + +Start here on your first pass. The numbered tutorials below take you +end-to-end from a clean machine to a memory-enabled application; the +[how-to guides](how_to_guides/index.md) cover specific tasks once you +know the basics. + +## Tutorials + +
+ +- :material-rocket-launch:{ .lg .middle } **[1. Quick start](01_quick_start.md)** + + --- + + Stand up the server, install the Python SDK, and store + retrieve your first memory in five minutes. + +- :material-package-variant:{ .lg .middle } **[2. Installation](02_installation.md)** + + --- + + Full install paths: Docker, pip, source. + +- :material-laptop:{ .lg .middle } **[3. Run without Docker](03_no_docker_setup.md)** + + --- + + Local Redis 8 plus a Python virtualenv only. + +
+ +## Recommended Path + +**New to memory systems?** Start with the [Quick Start Guide](01_quick_start.md) to understand the basics and see immediate results. + +**Ready for production?** Jump to the [Installation Guide](02_installation.md) for Docker Compose setup and worker configuration. + +**No Docker available?** Follow [Run without Docker](03_no_docker_setup.md) to use a local Redis 8 install plus a Python virtualenv. + +## How-to guides + +Once you are past the tutorials, jump to a specific recipe in +[How-To Guides](how_to_guides/index.md): configuration, auth, providers, +vector DB, integration patterns, and more. diff --git a/examples/agent_memory_server_interactive_guide.ipynb b/examples/agent_memory_server_interactive_guide.ipynb index 2672dad5..f2df3e45 100644 --- a/examples/agent_memory_server_interactive_guide.ipynb +++ b/examples/agent_memory_server_interactive_guide.ipynb @@ -6,9 +6,41 @@ "source": [ "# Agent Memory Server - Interactive Technical Guide\n", "\n", - "**Date:** February 5, 2026\n", - "\n", - "This notebook provides a comprehensive, interactive walkthrough of the Redis Agent Memory Server, focusing on **how to integrate memory into your AI applications**.\n", + "This notebook is a comprehensive, interactive walkthrough of the Redis\n", + "Agent Memory Server, focused on **how to integrate memory into your AI\n", + "applications**.\n", + "\n", + "## Overview\n", + "\n", + "The Agent Memory Server gives AI agents two complementary kinds of memory:\n", + "**working memory** (short-term, session-scoped) and **long-term memory**\n", + "(persistent, semantically searchable). This guide builds both up from\n", + "scratch and shows the three integration patterns you can mix and match\n", + "in real applications.\n", + "\n", + "## How to read this notebook\n", + "\n", + "- **First time?** Read top-to-bottom β€” each section builds on the\n", + " previous one, and the later sections combine everything.\n", + "- **Just looking?** The section list below is a scannable table of\n", + " contents β€” jump to whichever pattern matches what you're building.\n", + "- **Running it?** Complete the prerequisites, then execute cells in\n", + " order. State carries between cells.\n", + "\n", + "## Sections\n", + "\n", + "1. **The problem & solution** β€” why stateless LLMs need a memory layer.\n", + "2. **Quick start β€” setup** β€” connect to the server and verify health.\n", + "3. **The three integration patterns** β€” SDK, tool-based, background.\n", + "4. **Pattern 1 β€” code-driven (SDK)** β€” you decide what to remember.\n", + "5. **Pattern 2 β€” LLM-driven (tool-based)** β€” the model decides.\n", + "6. **Pattern 3 β€” background extraction** β€” the server decides.\n", + "7. **Combining patterns** β€” layering all three in one agent.\n", + "8. **Working memory deep dive** β€” sessions, structured data, summaries.\n", + "9. **Long-term memory deep dive** β€” semantic search and filtering.\n", + "10. **Memory types & contextual grounding** β€” episodic, semantic, message.\n", + "11. **Extraction strategy comparison** β€” trade-offs between the patterns.\n", + "12. **Production considerations** β€” auth, scaling, observability.\n", "\n", "---\n", "\n", @@ -35,7 +67,7 @@ "4. **Python dependencies installed**:\n", " ```bash\n", " pip install agent-memory-client httpx openai\n", - " ```" + " ```\n" ] }, { diff --git a/mkdocs.yml b/mkdocs.yml index 8b3377d0..1a40ff7b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,58 +1,66 @@ -site_name: Redis Agent Memory Server -site_description: Give your AI agents persistent memory and context that gets smarter over time -site_url: https://redis.github.io/agent-memory-server +site_name: Agent Memory Server +site_description: Session Memory and Long-Term Memory for AI Agents. +site_url: https://ai.redis.io/agent-memory/ repo_url: https://github.com/redis/agent-memory-server repo_name: redis/agent-memory-server -edit_uri: blob/main/docs +edit_uri: edit/main/docs/ +copyright: Copyright © 2026 Redis Inc. docs_dir: docs + exclude_docs: | - README.md + _build/ + _static/ + _templates/ + conf.py + Makefile + requirements.txt theme: name: material + language: en + logo: assets/redis-logo-script.svg + favicon: assets/favicon.png + font: + text: Space Grotesk + code: Space Mono palette: - # Palette toggle for automatic mode - media: "(prefers-color-scheme)" toggle: icon: material/brightness-auto name: Switch to light mode - - # Palette toggle for light mode - media: "(prefers-color-scheme: light)" scheme: default - primary: red - accent: red + primary: custom + accent: custom toggle: icon: material/brightness-7 name: Switch to dark mode - - # Palette toggle for dark mode - media: "(prefers-color-scheme: dark)" scheme: slate - primary: red - accent: red + primary: custom + accent: custom toggle: icon: material/brightness-4 name: Switch to system preference - features: - - navigation.tabs - - navigation.tabs.sticky + - navigation.instant + - navigation.instant.progress + - navigation.tracking - navigation.sections - - navigation.expand - - navigation.path + - navigation.indexes - navigation.top - navigation.footer - toc.follow - - toc.integrate + - search.suggest - search.highlight - search.share - content.code.copy - - content.code.select + - content.code.annotate + - content.tabs.link - content.action.edit - content.action.view - + - content.tooltips icon: repo: fontawesome/brands/github edit: material/pencil @@ -62,95 +70,173 @@ extra: social: - icon: fontawesome/brands/github link: https://github.com/redis/agent-memory-server - - icon: fontawesome/brands/docker - link: https://hub.docker.com/r/redislabs/agent-memory-server - - version: - provider: mike - default: latest - -nav: - - Home: index.md - - Getting Started: - - getting-started-index.md - - Quick Start: quick-start.md - - Installation: getting-started.md - - Use Cases: use-cases.md - - - Developer Guide: - - developer-guide-index.md - - Memory Integration Patterns: memory-integration-patterns.md - - Working Memory: working-memory.md - - Long-term Memory: long-term-memory.md - - Summary Views: summary-views.md - - Memory Extraction Strategies: memory-extraction-strategies.md - - Memory Lifecycle: memory-lifecycle.md - - LangChain Integration: langchain-integration.md + - icon: fontawesome/brands/python + link: https://pypi.org/project/agent-memory-server/ - - Operations Guide: - - operations-guide-index.md - - Configuration: configuration.md - - Authentication: authentication.md - - Security: security-custom-prompts.md - - LLM Providers: llm-providers.md - - Embedding Providers: embedding-providers.md - - Custom Memory Vector Databases: custom-memory-vector-db.md - - AWS Bedrock: aws-bedrock.md - - - Examples: - - Agent Examples: agent-examples.md - - - Advanced Topics: - - advanced-topics-index.md - - Query Optimization: query-optimization.md - - Recency Boost: recency-boost.md - - Advanced Memory Vector Database Config: advanced-memory-vector-db.md - - Contextual Grounding: contextual-grounding.md - - - API Reference: - - api-reference-index.md - - REST API: api.md - - MCP Server: mcp.md - - CLI Reference: cli.md - - Client SDKs: - - python-sdk-index.md - - Python SDK: python-sdk.md - - TypeScript SDK: typescript-sdk.md - - Java SDK: java-sdk.md - - - Development: - - Development Guide: development.md +extra_css: + - stylesheets/redis-brand.css + - stylesheets/extra.css plugins: - - search: - separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])' - - minify: - minify_html: true - - git-revision-date-localized: - enable_creation_date: true + - search + - autorefs + - section-index + - mkdocstrings: + default_handler: python + handlers: + python: + paths: [.] + options: + docstring_style: google + show_source: true + show_root_heading: true + show_root_full_path: false + show_symbol_type_heading: true + show_symbol_type_toc: true + members_order: source + separate_signature: true + show_signature_annotations: true + signature_crossrefs: true + merge_init_into_class: true + docstring_section_style: table + inherited_members: true + filters: + - "!^_" + - mkdocs-jupyter: + execute: false + include_source: true + theme: light + ignore_h1_titles: false + remove_tag_config: + remove_input_tags: + - hide_input + remove_all_outputs_tags: + - hide_output + - llmstxt: + full_output: llms-full.txt + sections: + Concepts: + - concepts/*.md + User Guide: + - user_guide/*.md + - user_guide/how_to_guides/*.md + Examples: + - examples/*.md + API Reference: + - api/*.md + For AI Agents: + - for-ais-only/*.md markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - tables + - toc: + permalink: true + toc_depth: 3 + - pymdownx.betterem + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.highlight: anchor_linenums: true line_spans: __span pygments_lang_class: true - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.mark + - pymdownx.smartsymbols - pymdownx.snippets - - pymdownx.superfences - - admonition - - pymdownx.details + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format - pymdownx.tabbed: alternate_style: true - - attr_list - - md_in_html - - pymdownx.emoji + slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: lower}} - pymdownx.tasklist: custom_checkbox: true - - toc: - permalink: true + - pymdownx.tilde + +watch: + - agent_memory_server + - AGENTS.md -extra_css: - - stylesheets/extra.css -copyright: | - © 2024 Redis +nav: + - Home: index.md + - Concepts: + - concepts/index.md + - Working memory: concepts/working_memory.md + - Long-term memory: concepts/long_term_memory.md + - Memory lifecycle: concepts/memory_lifecycle.md + - Memory extraction: concepts/memory_extraction.md + - Contextual grounding: concepts/contextual_grounding.md + - Recency boost: concepts/recency_boost.md + - Summary views: concepts/summary_views.md + - User Guide: + - user_guide/index.md + - Quick start: user_guide/01_quick_start.md + - Getting started: user_guide/02_installation.md + - macOS (no Docker): user_guide/03_no_docker_setup.md + - How-To Guides: + - user_guide/how_to_guides/index.md + - Authentication: user_guide/how_to_guides/authentication.md + - Configuration: user_guide/how_to_guides/configuration.md + - LLM providers: user_guide/how_to_guides/llm_providers.md + - Embedding providers: user_guide/how_to_guides/embedding_providers.md + - AWS Bedrock: user_guide/how_to_guides/aws_bedrock.md + - Advanced vector DB: user_guide/how_to_guides/advanced_vector_db.md + - Custom vector DB: user_guide/how_to_guides/custom_vector_db.md + - Query optimization: user_guide/how_to_guides/query_optimization.md + - Memory editing: user_guide/how_to_guides/memory_editing.md + - Integration patterns: user_guide/how_to_guides/integration_patterns.md + - Development: user_guide/how_to_guides/development.md + - Custom prompt security: user_guide/how_to_guides/security.md + - Examples: + - examples/index.md + - Use cases: examples/use_cases.md + - Agent examples: + - examples/agent_examples.md + - Interactive guide: examples/agent_memory_server_interactive_guide.ipynb + - Travel agent: examples/travel_agent.md + - Memory prompt agent: examples/memory_prompt_agent.md + - Memory editing agent: examples/memory_editing_agent.md + - AI tutor: examples/ai_tutor.md + - Recent messages limit demo: examples/recent_messages_limit_demo.md + - LangChain: examples/langchain.md + - API Reference: + - api/index.md + - REST API: api/rest.md + - MCP server: api/mcp.md + - CLI: api/cli.md + - Python SDK: api/python_sdk.md + - TypeScript SDK: api/typescript_sdk.md + - Java SDK: api/java_sdk.md + - Server package: + - api/server/index.md + - Models: api/server/models.md + - Working memory: api/server/working_memory.md + - Long-term memory: api/server/long_term_memory.md + - Memory strategies: api/server/memory_strategies.md + - Vector DB: api/server/memory_vector_db.md + - Extraction: api/server/extraction.md + - Summarization: api/server/summarization.md + - Filters: api/server/filters.md + - Auth: api/server/auth.md + - Config: api/server/config.md + - LLM client: api/server/llm.md + - For AI Agents: + - for-ais-only/index.md + - Repository map: for-ais-only/REPOSITORY_MAP.md + - Build and test: for-ais-only/BUILD_AND_TEST.md + - Failure modes: for-ais-only/FAILURE_MODES.md + - Authoring standard: for-ais-only/AUTHORING_STANDARD.md + - Changelog: https://github.com/redis/agent-memory-server/releases diff --git a/pyproject.toml b/pyproject.toml index 547296e1..cbbd9e48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -156,8 +156,11 @@ dev = [ ] docs = [ "mkdocs-material>=9.5.0", - "mkdocs-minify-plugin>=0.8.0", - "mkdocs-git-revision-date-localized-plugin>=1.2.0", + "mkdocstrings[python]>=0.26.0", + "mkdocs-section-index>=0.3.9", + "mkdocs-llmstxt>=0.2.0", + "mkdocs-autorefs>=1.2.0", + "mkdocs-jupyter>=0.26.3", ] examples = [ "openai>=1.3.7", diff --git a/uv.lock b/uv.lock index 5a236572..86dddb6b 100644 --- a/uv.lock +++ b/uv.lock @@ -99,9 +99,12 @@ dev = [ { name = "types-pyyaml" }, ] docs = [ - { name = "mkdocs-git-revision-date-localized-plugin" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocs-jupyter" }, + { name = "mkdocs-llmstxt" }, { name = "mkdocs-material" }, - { name = "mkdocs-minify-plugin" }, + { name = "mkdocs-section-index" }, + { name = "mkdocstrings", extra = ["python"] }, ] examples = [ { name = "langchain" }, @@ -165,9 +168,12 @@ dev = [ { name = "types-pyyaml", specifier = ">=6.0.12" }, ] docs = [ - { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.2.0" }, + { name = "mkdocs-autorefs", specifier = ">=1.2.0" }, + { name = "mkdocs-jupyter", specifier = ">=0.26.3" }, + { name = "mkdocs-llmstxt", specifier = ">=0.2.0" }, { name = "mkdocs-material", specifier = ">=9.5.0" }, - { name = "mkdocs-minify-plugin", specifier = ">=0.8.0" }, + { name = "mkdocs-section-index", specifier = ">=0.3.9" }, + { name = "mkdocstrings", extras = ["python"], specifier = ">=0.26.0" }, ] examples = [ { name = "langchain", specifier = ">=0.3.0" }, @@ -286,6 +292,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, ] +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, +] + [[package]] name = "asttokens" version = "3.0.1" @@ -372,6 +387,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/2a/fbcbf5a025d3e71ddafad7efd43e34ec4362f4d523c3c471b457148fb211/beartype-0.22.8-py3-none-any.whl", hash = "sha256:b832882d04e41a4097bab9f63e6992bc6de58c414ee84cba9b45b67314f5ab2e", size = 1331895, upload-time = "2025-12-03T05:11:08.373Z" }, ] +[[package]] +name = "beautifulsoup4" +version = "4.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, +] + +[[package]] +name = "bleach" +version = "6.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22", size = 203533, upload-time = "2025-10-27T17:57:39.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6", size = 164437, upload-time = "2025-10-27T17:57:37.538Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, +] + [[package]] name = "boto3" version = "1.42.3" @@ -535,6 +580,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + [[package]] name = "coverage" version = "7.12.0" @@ -604,12 +658,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/f1/00ce3bde3ca542d1acd8f8cfa38e446840945aa6363f9b74746394b14127/cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3", size = 3472985, upload-time = "2026-04-08T01:57:36.714Z" }, ] -[[package]] -name = "csscompressor" -version = "0.9.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/2a/8c3ac3d8bc94e6de8d7ae270bb5bc437b210bb9d6d9e46630c98f4abd20c/csscompressor-0.9.5.tar.gz", hash = "sha256:afa22badbcf3120a4f392e4d22f9fff485c044a1feda4a950ecc5eba9dd31a05", size = 237808, upload-time = "2017-11-26T21:13:08.238Z" } - [[package]] name = "dataclasses-json" version = "0.6.7" @@ -623,6 +671,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686, upload-time = "2024-06-09T16:20:16.715Z" }, ] +[[package]] +name = "debugpy" +version = "1.8.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686, upload-time = "2026-01-29T23:03:42.023Z" }, + { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588, upload-time = "2026-01-29T23:03:43.314Z" }, + { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372, upload-time = "2026-01-29T23:03:45.526Z" }, + { url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3", size = 5372835, upload-time = "2026-01-29T23:03:47.245Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, +] + [[package]] name = "decorator" version = "5.2.1" @@ -632,6 +693,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + [[package]] name = "distlib" version = "0.4.0" @@ -736,6 +806,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/15/a785e992a27620e022d0bc61b6c897ec14cff07c5ab7ff9f27651a21570b/fastapi-0.123.9-py3-none-any.whl", hash = "sha256:f54c69f23db14bd3dbcdfaf3fdce0483ca5f499512380c8e379a70cda30aa920", size = 111776, upload-time = "2025-12-04T22:24:46.042Z" }, ] +[[package]] +name = "fastjsonschema" +version = "2.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, +] + [[package]] name = "fastuuid" version = "0.14.0" @@ -822,30 +901,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] -[[package]] -name = "gitdb" -version = "4.0.12" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "smmap" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, -] - -[[package]] -name = "gitpython" -version = "3.1.45" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gitdb" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, -] - [[package]] name = "greenlet" version = "3.3.0" @@ -855,12 +910,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, + { url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" }, { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, ] +[[package]] +name = "griffelib" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/82/74f4a3310cdabfbb10da554c3a672847f1ed33c6f61dd472681ce7f1fe67/griffelib-2.0.2.tar.gz", hash = "sha256:3cf20b3bc470e83763ffbf236e0076b1211bac1bc67de13daf494640f2de707e", size = 166461, upload-time = "2026-03-27T11:34:51.091Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl", hash = "sha256:925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1", size = 142357, upload-time = "2026-03-27T11:34:46.275Z" }, +] + [[package]] name = "grpcio" version = "1.67.1" @@ -902,14 +967,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, ] -[[package]] -name = "htmlmin2" -version = "0.1.13" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/be/31/a76f4bfa885f93b8167cb4c85cf32b54d1f64384d0b897d45bc6d19b7b45/htmlmin2-0.1.13-py3-none-any.whl", hash = "sha256:75609f2a42e64f7ce57dbff28a39890363bde9e7e5885db633317efbdf8c79a2", size = 34486, upload-time = "2023-03-14T21:28:30.388Z" }, -] - [[package]] name = "httpcore" version = "1.0.9" @@ -1018,6 +1075,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0c/4c/b075da0092003d9a55cf2ecc1cae9384a1ca4f650d51b00fc59875fe76f6/ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4", size = 12130, upload-time = "2023-03-09T15:40:55.021Z" }, ] +[[package]] +name = "ipykernel" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, +] + [[package]] name = "ipython" version = "9.8.0" @@ -1109,12 +1190,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, ] -[[package]] -name = "jsmin" -version = "3.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/73/e01e4c5e11ad0494f4407a3f623ad4d87714909f50b17a06ed121034ff6e/jsmin-3.0.1.tar.gz", hash = "sha256:c0959a121ef94542e807a674142606f7e90214a2b3d1eb17300244bbb5cc2bfc", size = 13925, upload-time = "2022-01-16T20:35:59.13Z" } - [[package]] name = "jsonpatch" version = "1.33" @@ -1175,6 +1250,60 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] +[[package]] +name = "jupyter-client" +version = "8.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020, upload-time = "2026-01-08T13:55:47.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, +] + +[[package]] +name = "jupytext" +version = "1.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/4f13fcba0ed05965a48fca197d89fb8c78c4b61051dc0c9ee9ed92e77a8d/jupytext-1.19.2.tar.gz", hash = "sha256:da6198a42406a09142b6b26ebc46a3ec7077f525222a8f12b1811a0e289a2216", size = 4309931, upload-time = "2026-05-10T17:10:40.345Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/65/b4b86e5fa07543bfbbcdc6c9f7f9f561e66a5f3539992e3009973f2b1314/jupytext-1.19.2-py3-none-any.whl", hash = "sha256:8a31e896c7e9215841783aade24336e945543057e1c2d7f00b22f9e870348688", size = 170653, upload-time = "2026-05-10T17:10:38.418Z" }, +] + [[package]] name = "langchain" version = "1.2.6" @@ -1423,14 +1552,27 @@ wheels = [ [[package]] name = "markdown-it-py" -version = "4.0.0" +version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, +] + +[[package]] +name = "markdownify" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/bc/c8c8eea5335341306b0fa7e1cb33c5e1c8d24ef70ddd684da65f41c49c92/markdownify-1.2.2.tar.gz", hash = "sha256:b274f1b5943180b031b699b199cbaeb1e2ac938b75851849a31fd0c3d6603d09", size = 18816, upload-time = "2025-11-16T19:21:18.565Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ce/f1e3e9d959db134cedf06825fae8d5b294bd368aacdd0831a3975b7c4d55/markdownify-1.2.2-py3-none-any.whl", hash = "sha256:3f02d3cc52714084d6e589f70397b6fc9f2f3a8531481bf35e8cc39f975e186a", size = 15724, upload-time = "2025-11-16T19:21:17.622Z" }, ] [[package]] @@ -1501,6 +1643,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9f/9e/26e1d2d2c6afe15dfba5ca6799eeeea7656dce625c22766e4c57305e9cc2/mcp-1.23.1-py3-none-any.whl", hash = "sha256:3ce897fcc20a41bd50b4c58d3aa88085f11f505dcc0eaed48930012d34c731d8", size = 231433, upload-time = "2025-12-02T18:41:11.195Z" }, ] +[[package]] +name = "mdformat" +version = "0.7.22" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/eb/b5cbf2484411af039a3d4aeb53a5160fae25dd8c84af6a4243bc2f3fedb3/mdformat-0.7.22.tar.gz", hash = "sha256:eef84fa8f233d3162734683c2a8a6222227a229b9206872e6139658d99acb1ea", size = 34610, upload-time = "2025-01-30T18:00:51.418Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/6f/94a7344f6d634fe3563bea8b33bccedee37f2726f7807e9a58440dc91627/mdformat-0.7.22-py3-none-any.whl", hash = "sha256:61122637c9e1d9be1329054f3fa216559f0d1f722b7919b060a8c2a4ae1850e5", size = 34447, upload-time = "2025-01-30T18:00:48.708Z" }, +] + +[[package]] +name = "mdformat-tables" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdformat" }, + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/fc/995ba209096bdebdeb8893d507c7b32b7e07d9a9f2cdc2ec07529947794b/mdformat_tables-1.0.0.tar.gz", hash = "sha256:a57db1ac17c4a125da794ef45539904bb8a9592e80557d525e1f169c96daa2c8", size = 6106, upload-time = "2024-08-23T23:41:33.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/37/d78e37d14323da3f607cd1af7daf262cb87fe614a245c15ad03bb03a2706/mdformat_tables-1.0.0-py3-none-any.whl", hash = "sha256:94cd86126141b2adc3b04c08d1441eb1272b36c39146bab078249a41c7240a9a", size = 5104, upload-time = "2024-08-23T23:41:31.863Z" }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/3d/e0e8d9d1cee04f758120915e2b2a3a07eb41f8cf4654b4734788a522bcd1/mdit_py_plugins-0.6.0.tar.gz", hash = "sha256:2436f14a7295837ac9228a36feeabda867c4abc488c8d019ad5c0bda88eee040", size = 56025, upload-time = "2026-05-07T12:20:42.295Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/d6/48f5b9e44e2e760855d7b489b1317cd7620e82dcb73197961e5cc1391348/mdit_py_plugins-0.6.0-py3-none-any.whl", hash = "sha256:f7e7a25d8b616fee99cb1e330da73451d11a8061baf39bb9663ab9ce0e005b90", size = 66655, upload-time = "2026-05-07T12:20:41.226Z" }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -1519,6 +1698,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, ] +[[package]] +name = "mistune" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/84/620cc3f7e3adf6f5067e10f4dbae71295d8f9e16d5d3f9ef97c40f2f592c/mistune-3.2.1.tar.gz", hash = "sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28", size = 98003, upload-time = "2026-05-03T14:33:22.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/7f/a946aa4f8752b37102b41e64dca18a1976ac705c3a0d1dfe74d820a02552/mistune-3.2.1-py3-none-any.whl", hash = "sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048", size = 53749, upload-time = "2026-05-03T14:33:20.551Z" }, +] + [[package]] name = "mkdocs" version = "1.6.1" @@ -1543,6 +1731,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, ] +[[package]] +name = "mkdocs-autorefs" +version = "1.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/c0/f641843de3f612a6b48253f39244165acff36657a91cc903633d456ae1ac/mkdocs_autorefs-1.4.4.tar.gz", hash = "sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197", size = 56588, upload-time = "2026-02-10T15:23:55.105Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl", hash = "sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089", size = 25530, upload-time = "2026-02-10T15:23:53.817Z" }, +] + [[package]] name = "mkdocs-get-deps" version = "0.2.0" @@ -1558,18 +1760,35 @@ wheels = [ ] [[package]] -name = "mkdocs-git-revision-date-localized-plugin" -version = "1.5.0" +name = "mkdocs-jupyter" +version = "0.26.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "babel" }, - { name = "gitpython" }, + { name = "ipykernel" }, + { name = "jupytext" }, { name = "mkdocs" }, - { name = "tzdata", marker = "sys_platform == 'win32'" }, + { name = "mkdocs-material" }, + { name = "nbconvert" }, + { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0f/c5/1d3c4e6ddae6230b89d09105cb79de711655e3ebd6745f7a92efea0f5160/mkdocs_git_revision_date_localized_plugin-1.5.0.tar.gz", hash = "sha256:17345ccfdf69a1905dc96fb1070dce82d03a1eb6b0d48f958081a7589ce3c248", size = 460697, upload-time = "2025-10-31T16:11:34.44Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/aa/f8d15409a9a3112486994a80d5a975694c7d145c4f8b5b484aeb383420ef/mkdocs_jupyter-0.26.3.tar.gz", hash = "sha256:e1e8bd48a1b96542e84e3028e3066112bac7b94d95ab69f8b91305c84003ca26", size = 1628353, upload-time = "2026-04-17T18:56:31.517Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/51/fe0e3fdb16f6eed65c9459d12bae6a4e1f0bb4e2228cb037e7907b002678/mkdocs_git_revision_date_localized_plugin-1.5.0-py3-none-any.whl", hash = "sha256:933f9e35a8c135b113f21bb57610d82e9b7bcc71dd34fb06a029053c97e99656", size = 26153, upload-time = "2025-10-31T16:11:32.987Z" }, + { url = "https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl", hash = "sha256:cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82", size = 1459740, upload-time = "2026-04-17T18:56:30.031Z" }, +] + +[[package]] +name = "mkdocs-llmstxt" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "markdownify" }, + { name = "mdformat" }, + { name = "mdformat-tables" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7f/f5/4c31cdffa7c09bf48d8c7a50d8342dc100abac98ac4150826bc11afc0c9f/mkdocs_llmstxt-0.5.0.tar.gz", hash = "sha256:b2fa9e6d68df41d7467e948a4745725b6c99434a36b36204857dbd7bb3dfe041", size = 33909, upload-time = "2025-11-20T14:02:24.861Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/2b/82928cc9e8d9269cd79e7ebf015efdc4945e6c646e86ec1d4dba1707f215/mkdocs_llmstxt-0.5.0-py3-none-any.whl", hash = "sha256:753c699913d2d619a9072604b26b6dc9f5fb6d257d9b107857f80c8a0b787533", size = 12040, upload-time = "2025-11-20T14:02:23.483Z" }, ] [[package]] @@ -1604,18 +1823,52 @@ wheels = [ ] [[package]] -name = "mkdocs-minify-plugin" -version = "0.8.0" +name = "mkdocs-section-index" +version = "0.3.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, + { name = "properdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/e2/64d0f3f054ca8efe61e706006ff5f0d49ad99620c62c2e04818573391c33/mkdocs_section_index-0.3.12.tar.gz", hash = "sha256:285635bf86c643b0fc7a343053d7a818049817bff4408f52b80c4367bd5e7268", size = 14946, upload-time = "2026-04-16T19:20:00.953Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/4d/a330cab5e055d45e924cec69da54a3d8ed37643964f8d1fa1a772b496273/mkdocs_section_index-0.3.12-py3-none-any.whl", hash = "sha256:a1100039546beb4ebef63ce6fc91f3195fb9c0c3763105d4d3d7cd31e0a046eb", size = 8932, upload-time = "2026-04-16T19:19:59.741Z" }, +] + +[[package]] +name = "mkdocstrings" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "csscompressor" }, - { name = "htmlmin2" }, - { name = "jsmin" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "pymdown-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/67/fe4b77e7a8ae7628392e28b14122588beaf6078b53eb91c7ed000fd158ac/mkdocs-minify-plugin-0.8.0.tar.gz", hash = "sha256:bc11b78b8120d79e817308e2b11539d790d21445eb63df831e393f76e52e753d", size = 8366, upload-time = "2024-01-29T16:11:32.982Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/5d/f888d4d3eb31359b327bc9b17a212d6ef03fe0b0682fbb3fc2cb849fb12b/mkdocstrings-1.0.4.tar.gz", hash = "sha256:3969a6515b77db65fd097b53c1b7aa4ae840bd71a2ee62a6a3e89503446d7172", size = 100088, upload-time = "2026-04-15T09:16:53.376Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/cd/2e8d0d92421916e2ea4ff97f10a544a9bd5588eb747556701c983581df13/mkdocs_minify_plugin-0.8.0-py3-none-any.whl", hash = "sha256:5fba1a3f7bd9a2142c9954a6559a57e946587b21f133165ece30ea145c66aee6", size = 6723, upload-time = "2024-01-29T16:11:31.851Z" }, + { url = "https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl", hash = "sha256:63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b", size = 35560, upload-time = "2026-04-15T09:16:51.436Z" }, +] + +[package.optional-dependencies] +python = [ + { name = "mkdocstrings-python" }, +] + +[[package]] +name = "mkdocstrings-python" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffelib" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/33/c225eaf898634bdda489a6766fc35d1683c640bffe0e0acd10646b13536d/mkdocstrings_python-2.0.3.tar.gz", hash = "sha256:c518632751cc869439b31c9d3177678ad2bfa5c21b79b863956ad68fc92c13b8", size = 199083, upload-time = "2026-02-20T10:38:36.368Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl", hash = "sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12", size = 104779, upload-time = "2026-02-20T10:38:34.517Z" }, ] [[package]] @@ -1721,6 +1974,70 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] +[[package]] +name = "nbclient" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9", size = 62554, upload-time = "2025-12-23T07:45:46.369Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440", size = 25465, upload-time = "2025-12-23T07:45:44.51Z" }, +] + +[[package]] +name = "nbconvert" +version = "7.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, +] + [[package]] name = "nodeenv" version = "1.9.1" @@ -1839,6 +2156,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, ] +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, +] + [[package]] name = "parso" version = "0.8.5" @@ -1957,6 +2283,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, ] +[[package]] +name = "properdocs" +version = "1.6.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/29/f27a4e1eddf72ed3db6e47818fbafe6debbf09fd7051f9c1a007239b46ef/properdocs-1.6.7.tar.gz", hash = "sha256:adc7b16e562890af0e098a7e5b02e3a81c20894a87d6a28d345c9300de73c26e", size = 276141, upload-time = "2026-03-20T20:07:48.167Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/4d/fc923f5c85318ee8cc903566dc4e0ebe41b2dfc1d2ecf5546db232397ed6/properdocs-1.6.7-py3-none-any.whl", hash = "sha256:6fa0cfa2e01bf338f684892c8a506cf70ea88ae7f3479c933b6fa20168101cbd", size = 225406, upload-time = "2026-03-20T20:07:46.875Z" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +] + [[package]] name = "ptyprocess" version = "0.7.0" @@ -2321,6 +2686,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, ] +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, +] + [[package]] name = "redis" version = "6.4.0" @@ -2538,15 +2924,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] -[[package]] -name = "smmap" -version = "5.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, -] - [[package]] name = "sniffio" version = "1.3.1" @@ -2565,6 +2942,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] +[[package]] +name = "soupsieve" +version = "2.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, +] + [[package]] name = "sqlalchemy" version = "2.0.44" @@ -2692,6 +3078,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/10/b8523105c590c5b8349f2587e2fdfe51a69544bd5a76295fc20f2374f470/tiktoken-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffc5288f34a8bc02e1ea7047b8d041104791d2ddbf42d1e5fa07822cbffe16bd", size = 878694, upload-time = "2025-10-06T20:21:59.876Z" }, ] +[[package]] +name = "tinycss2" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload-time = "2024-10-24T14:58:29.895Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload-time = "2024-10-24T14:58:28.029Z" }, +] + [[package]] name = "tokenizers" version = "0.22.1" @@ -2717,6 +3115,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/46/e33a8c93907b631a99377ef4c5f817ab453d0b34f93529421f42ff559671/tokenizers-0.22.1-cp39-abi3-win_amd64.whl", hash = "sha256:65fd6e3fb11ca1e78a6a93602490f134d1fdeb13bcef99389d5102ea318ed138", size = 2674684, upload-time = "2025-09-19T09:49:24.953Z" }, ] +[[package]] +name = "tornado" +version = "6.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" }, + { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" }, + { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" }, + { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" }, + { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" }, + { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" }, +] + [[package]] name = "tqdm" version = "4.67.1" @@ -2941,6 +3356,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, ] +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, +] + [[package]] name = "wrapt" version = "2.0.1"