Metadata-Version: 2.4
Name: langchain-memorae
Version: 0.1.1
Summary: MeMorae memory and retrieval adapters for LangChain and LangGraph
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: httpx<1,>=0.25
Requires-Dist: langchain-core<2,>=0.3
Requires-Dist: langchain-classic<2,>=1
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Provides-Extra: examples
Requires-Dist: langchain-openai>=0.2; extra == "examples"
Requires-Dist: langgraph>=0.2; extra == "examples"
Requires-Dist: flask>=3; extra == "examples"

# langchain-memorae

MeMorae memory and retrieval adapters for LangChain, LangGraph, and local chatbots.

## What it does

`langchain-memorae` connects Python applications to an existing MeMorae backend with a project API key. It can save user and optionally assistant messages as sources, then retrieve relevant long-term memory context for a conversation. MeMorae controls extraction, approval, and retrieval; the package does not bypass those rules.

[GitHub](https://github.com/KeshavKandoi/MEMORA) · [PyPI](https://pypi.org/project/langchain-memorae/)

## Install

```bash
python -m pip install langchain-memorae
```

The MeMorae backend must already be running and reachable from your application. LangChain core and the classic memory interface are installed as package dependencies. The examples have optional dependencies: `python -m pip install 'langchain-memorae[examples]'`.

## Development install

From the repository root, install an editable copy:

```bash
python -m pip install -e integrations/langchain-memorae
```

## Configure

Set these variables in the server environment where your chatbot runs:

| Variable | Purpose |
| --- | --- |
| `MEMORAE_API_KEY` | MeMorae project API key |
| `MEMORAE_BASE_URL` | Backend URL, such as `http://localhost:8000` |
| `MEMORAE_SUBJECT_ID` | Stable identifier for the end user |
| `MEMORAE_NAMESPACE` | Optional memory space; defaults to `default` |

Create a project API key in the MeMorae dashboard's project API key settings. Copy it when it is created or revealed, and store it in a server-side secret manager or an untracked `.env` file.

## Quickstart

```python
import os
from langchain_memorae import MeMoraeMemory

memory = MeMoraeMemory(
    api_key=os.environ["MEMORAE_API_KEY"],
    base_url=os.getenv("MEMORAE_BASE_URL", "http://localhost:8000"),
    subject_id=os.environ["MEMORAE_SUBJECT_ID"],
    namespace=os.getenv("MEMORAE_NAMESPACE", "default"),
)

context = memory.load_memory_variables({"input": "What food do I like?"})
print(context["history"])
memory.save_context({"input": "I love pizza"}, {"output": "Got it."})
```

`history` is a compact string containing the memories returned for the input query. Messages are submitted for asynchronous MeMorae processing. Supported facts become retrievable after extraction and indexing complete.

## LangChain memory

Call `load_memory_variables` before generating the response, then `save_context` with the turn. Set `save_assistant=True` if assistant messages should also be submitted as sources; by default, only the user message is saved.

```python
from langchain_memorae import MeMoraeMemory

memory = MeMoraeMemory(
    api_key=api_key,
    base_url=base_url,
    subject_id=subject_id,
    namespace=namespace,
    save_assistant=True,
)

context = memory.load_memory_variables({"input": question})["history"]
answer = chatbot.generate(question, context=context)
memory.save_context({"input": question}, {"output": answer})
```

## Retriever

Use `MeMoraeRetriever` anywhere a LangChain retriever is accepted. `invoke` returns LangChain `Document` objects; each document includes `memory_id`, type, and available `source_ids` metadata.

```python
from langchain_memorae import MeMoraeRetriever

retriever = MeMoraeRetriever(
    api_key=api_key,
    base_url=base_url,
    subject_id=subject_id,
    namespace=namespace,
)
docs = retriever.invoke("What sports do I enjoy?")
```

## LangGraph

Use a recall node before the answer node. Pass the recalled context into the prompt, then use a save node after the answer to record the user turn. The complete runnable example is in [`examples/langgraph_chatbot.py`](examples/langgraph_chatbot.py).

```python
def recall(state):
    return {"history": memory.load_memory_variables({"input": state["input"]})["history"]}

def save(state):
    memory.save_context({"input": state["input"]}, {"output": state["output"]})
    return {}
```

## Local chatbot integration

For Flask, Ollama, or another local Python chatbot, load memories for the incoming message, add the returned string to your prompt or context, generate the answer, and save the user message and (optionally) assistant answer. See [`examples/local_chatbot_flask.py`](examples/local_chatbot_flask.py). The ChatOpenAI example is in [`examples/basic_chatbot.py`](examples/basic_chatbot.py).

## Indexing and troubleshooting

Ingestion is asynchronous. Newly submitted messages can take a few seconds to appear in retrieval. For local Docker deployments, make sure the worker and Beat services are running; the retrieval indexes also need to be available.

| Symptom | What to check |
| --- | --- |
| `history` is empty | Wait for processing and indexing. For local Docker, check worker, Beat, OpenSearch, and Qdrant. |
| HTTP `503` | MeMorae search or an indexing service may be unavailable. Check backend and index service health. |
| HTTP `401` or `403` | Confirm the project API key is valid, active, and belongs to the intended project. |
| `pip` cannot install globally on macOS | Create and activate a Python virtual environment, then install inside it. |

## Security and scope

Keep `MEMORAE_API_KEY` on the server. Never expose it in browser JavaScript, commit `.env`, or print the key in logs. Use one stable `subject_id` per end user so their memories remain scoped to that user. Use `namespace` to separate memory spaces for the same subject, and pass the same subject and namespace when saving and retrieving.

`clear()` does not delete remote MeMorae memories. Manage remote memory lifecycle through the MeMorae dashboard and its review controls.
