Metadata-Version: 2.3
Name: langchain-memoryrouter
Version: 0.1.0
Summary: MemoryRouter integration for LangChain and LangGraph
Author: MemoryRouter
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: httpx>=0.25
Requires-Dist: langchain-core>=0.3.0
Requires-Dist: langgraph>=0.2.0
Requires-Dist: pytest>=8 ; extra == 'test'
Requires-Dist: pytest-asyncio>=0.23 ; extra == 'test'
Requires-Dist: respx>=0.21 ; extra == 'test'
Requires-Dist: ruff>=0.8 ; extra == 'test'
Requires-Dist: mypy>=1.10 ; extra == 'test'
Requires-Python: >=3.9
Project-URL: Documentation, https://memoryrouter.ai/docs
Project-URL: Homepage, https://memoryrouter.ai
Project-URL: Repository, https://github.com/johnrood/MemoryRouter
Provides-Extra: test
Description-Content-Type: text/markdown

# langchain-memoryrouter

MemoryRouter memory for LangChain and LangGraph.

MemoryRouter gives every user in your AI product a private memory vault. This package lets LangChain developers use that memory layer through tools, graph nodes, or a LangChain `BaseStore`.

## Install

```bash
pip install langchain-memoryrouter
```

Get a Memory Key at [memoryrouter.ai](https://memoryrouter.ai). In multi-user products, map each app user to their own Memory Key.

## Storage hygiene

Every write path sanitizes messages before ingest. MemoryRouter stores conversation text only:

- Keeps `HumanMessage` text as `user`
- Keeps `AIMessage` text as `assistant`
- Drops `ToolMessage` entirely
- Drops AI tool calls and function-call args
- Drops AI messages that are only tool calls with no text

This is enforced in tools, nodes, and store writes. It is not a config option.

## Pattern 1: tools

Works with LangChain `bind_tools()` and LangGraph `create_react_agent()`.

```python
from langchain_memoryrouter import create_memory_tools

tools = create_memory_tools(memory_key="mk_user_123")
model_with_tools = model.bind_tools(list(tools))
```

The package exposes two primitives only:

- `memoryrouter_retain` stores sanitized conversation text with `/v1/memory/ingest`
- `memoryrouter_recall` searches memory with `/v1/memory/search`

No `reflect` tool. MemoryRouter is retain and recall.

## Pattern 2: LangGraph nodes

Use nodes when you want memory to run automatically in the graph.

```python
from langchain_memoryrouter import create_recall_node, create_retain_node

recall_node = create_recall_node(memory_key_config_key="memory_key")
retain_node = create_retain_node(memory_key_config_key="memory_key")

result = graph.invoke(
    {"messages": messages},
    config={"configurable": {"memory_key": "mk_user_123", "thread_id": "chat_abc"}},
)
```

`create_recall_node` calls `/v1/memory/prepare` and returns a ready-to-inject memory context block. `create_retain_node` sanitizes and calls `/v1/memory/ingest`.

## Pattern 3: BaseStore

Use `MemoryRouterStore` as a semantic long-term store for LangGraph.

```python
from langchain_memoryrouter import MemoryRouterStore

store = MemoryRouterStore(memory_key="mk_user_123")
graph = builder.compile(store=store)
```

MemoryRouter is semantic memory, not a literal KV database. `mset` retains text into the user's vault. `mget` searches by key and returns the best matching memory content.

## API targeted

Base URL: `https://api.memoryrouter.ai`

Auth: `Authorization: Bearer mk_xxx`

Retain:

```http
POST /v1/memory/ingest
{
  "messages": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}],
  "session_id": "optional",
  "model": "optional",
  "embeddings": "optional"
}
```

Recall:

```http
POST /v1/memory/search
{"query": "what does the user prefer", "limit": 10}
```

Graph recall context:

```http
POST /v1/memory/prepare
{
  "messages": [{"role": "user", "content": "..."}],
  "session_id": "optional",
  "density": "default",
  "context_limit": 10
}
```
