# Octopoda: Persistent Memory for AI Agents

**Your agents remember everything. Crash-safe. Sub-millisecond. Framework-agnostic.**

[![PyPI](https://img.shields.io/pypi/v/octopoda)](https://pypi.org/project/octopoda/)
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)

## Install

```bash
pip install octopoda
```

## Quick Start (3 lines)

```python
from octopoda import AgentRuntime

agent = AgentRuntime("my_agent")
agent.remember("user_pref", "Alice is vegetarian and lives in London")
results = agent.recall_similar("what food does the user like?")
```

That's it. Memory persists across crashes, restarts, and deployments.

## Why Octopoda?

Every AI agent framework has the same problem: agents forget everything when they restart. Octopoda fixes that with a single `pip install`.

**vs Mem0:** Octopoda runs 100% locally (no cloud dependency), includes a knowledge graph, temporal versioning, conflict detection, and shared memory pools. Mem0 doesn't offer these.

**vs raw vector DBs (Pinecone, ChromaDB):** Octopoda is purpose-built for agent memory. You get key-value recall, semantic search, entity extraction, audit trails, and crash recovery out of the box. With a vector DB, you build all of that yourself.

**vs framework built-in memory (LangChain, CrewAI):** Those are basic chat history buffers. Octopoda gives you structured long-term memory with versioning, search, and cross-agent sharing.

## What You Get

| Feature | Description |
|---------|-------------|
| **Semantic Search** | Find memories by meaning, not just exact keys (bge-small-en-v1.5, 384-dim) |
| **Fact Extraction** | LLM decomposes text into tagged facts for 60%+ better search accuracy |
| **Knowledge Graph** | Auto-extracted entity relationships in SQLite (no Neo4j needed) |
| **Temporal Versioning** | Track how facts change over time with full history |
| **Crash Recovery** | Automatic snapshots, sub-millisecond restore |
| **Shared Memory** | Agents share knowledge across processes |
| **Audit Trail** | Every memory operation logged with context |
| **Cloud API** | Multi-tenant REST API with auth, rate limiting, Swagger docs |
| **MCP Server** | 13 tools for Claude, Cursor, VS Code, ChatGPT |
| **100% Offline** | Everything runs locally. Zero cloud dependencies. |

## Semantic Search

```bash
pip install octopoda[ai]  # Adds local embeddings (33MB model, runs on CPU)
```

```python
agent = AgentRuntime("my_agent")

# Store memories — auto-embeds for semantic search
agent.remember("bio", "Alice is a vegetarian living in London")
agent.remember("work", "Alice is a senior engineer at Google")

# Search by meaning
results = agent.recall_similar("where does the user work?")
# Returns: "Alice is a senior engineer at Google"

# Temporal history — see how memories change over time
history = agent.recall_history("bio")

# Knowledge graph — auto-extracted entities and relationships
related = agent.related("Alice")
```

## Boost Search Quality with Fact Extraction

Out of the box, semantic search scores ~0.65 (industry baseline). Add any LLM and Octopoda decomposes memories into individual facts, pushing accuracy to **0.87+**.

### Use Your Own API Key (Recommended)

```bash
# OpenAI
export OCTOPODA_LLM_PROVIDER=openai
export OCTOPODA_OPENAI_API_KEY=sk-...

# Or Anthropic
export OCTOPODA_LLM_PROVIDER=anthropic
export OCTOPODA_ANTHROPIC_API_KEY=sk-ant-...

# Or ANY OpenAI-compatible API (Groq, Together, Mistral, local)
export OCTOPODA_LLM_PROVIDER=openai
export OCTOPODA_OPENAI_API_KEY=gsk_...
export OCTOPODA_OPENAI_BASE_URL=https://api.groq.com/openai/v1
```

### Use Local Ollama (Free)

```bash
# Install Ollama (https://ollama.com), then:
ollama pull llama3.2
export OCTOPODA_LLM_PROVIDER=ollama
```

### What Fact Extraction Does

```python
agent.remember("meeting", "Alice said Q2 revenue hit $4.2M and we need to hire 3 engineers by March")

# Without fact extraction: stored as one blob, hard to search
# With fact extraction: decomposed into individual facts:
#   - "Q2 revenue reached $4.2M (financial, quarterly results)"
#   - "Need to hire 3 engineers by March (hiring, staffing, deadline)"
#   - "Alice reported on Q2 results (person, meeting)"
#
# Now searching "hiring plans" returns the specific fact, not the whole paragraph.
```

No config needed beyond setting the provider. If no LLM is configured, memories are stored and embedded as-is (still works, just lower search accuracy).

## Cloud API

Run the REST API for multi-tenant production use:

```bash
octopoda --api-port 8000
```

```bash
# Store a memory
curl -X POST http://localhost:8000/v1/agents/my_agent/remember \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key": "task_result", "value": "Pipeline completed successfully"}'

# Semantic search
curl -X POST http://localhost:8000/v1/agents/my_agent/similar \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "did the pipeline finish?"}'
```

Full Swagger docs at `/docs`. Multi-tenant auth, rate limiting, per-tenant LLM settings via `PUT /v1/settings`.

## MCP Server (Claude, Cursor, VS Code)

Give any MCP-compatible AI persistent memory with zero code:

```bash
pip install octopoda
```

Add to your Claude Desktop config (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "octopoda": {
      "command": "octopoda-mcp"
    }
  }
}
```

13 memory tools: `octopoda_remember`, `octopoda_recall`, `octopoda_recall_similar`, `octopoda_recall_history`, `octopoda_related`, `octopoda_search`, `octopoda_snapshot`, `octopoda_restore`, `octopoda_share`, `octopoda_read_shared`, `octopoda_list_agents`, `octopoda_agent_stats`, `octopoda_log_decision`.

## Framework Integrations

```python
# LangChain
from synrix_runtime.integrations.langchain_memory import SynrixMemory
memory = SynrixMemory(agent_id="my_chain")

# CrewAI
from synrix_runtime.integrations.crewai_memory import SynrixCrewMemory
crew_memory = SynrixCrewMemory(crew_id="research_crew")

# AutoGen
from synrix_runtime.integrations.autogen_memory import SynrixAutoGenMemory
memory = SynrixAutoGenMemory(group_id="dev_team")

# OpenAI Agents SDK
from synrix_runtime.integrations.openai_agents import SynrixOpenAIMemory
memory = SynrixOpenAIMemory()
```

## Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| `OCTOPODA_LLM_PROVIDER` | `none` | LLM for fact extraction: `openai`, `anthropic`, `ollama`, `none` |
| `OCTOPODA_OPENAI_API_KEY` | | OpenAI API key |
| `OCTOPODA_OPENAI_MODEL` | `gpt-4o-mini` | OpenAI model |
| `OCTOPODA_OPENAI_BASE_URL` | `https://api.openai.com/v1` | Any OpenAI-compatible endpoint |
| `OCTOPODA_ANTHROPIC_API_KEY` | | Anthropic API key |
| `OCTOPODA_ANTHROPIC_MODEL` | `claude-haiku-4-5-20251001` | Anthropic model |
| `OCTOPODA_OLLAMA_URL` | `http://localhost:11434` | Ollama server URL |
| `OCTOPODA_OLLAMA_MODEL` | `llama3.2` | Ollama model |
| `OCTOPODA_EMBEDDING_MODEL` | `BAAI/bge-small-en-v1.5` | Embedding model (33MB) |
| `SYNRIX_DATA_DIR` | `~/.synrix/data` | Data directory |
| `SYNRIX_API_PORT` | `8741` | Cloud API port |

## Architecture

```
octopoda (public API — from octopoda import AgentRuntime)
  synrix_runtime (runtime layer)
    api/          — AgentRuntime, Cloud API (FastAPI), MCP Server
    core/         — Daemon, heartbeat, recovery, garbage collection
    monitoring/   — Metrics, anomaly detection, audit, performance
    integrations/ — LangChain, CrewAI, AutoGen, OpenAI
    dashboard/    — Flask dashboard with SSE real-time streaming
  synrix (SDK layer)
    sqlite_client — SQLite + vector search + knowledge graph
    embeddings    — Local embeddings (sentence-transformers)
    extractor     — NER + relationship extraction (spaCy)
    fact_extractor — Multi-provider LLM fact decomposition
```

## License

MIT (fully open source)

---

**Octopoda** — Persistent memory for AI agents. Install, import, ship.
