> ## Documentation Index
> Fetch the complete documentation index at: https://metacognition-fdc534de-master.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from LangChain chat memory

> Move from LangChain chat buffers to Tex-backed recall.

If you came from the [LangChain recipe](/recipes/langchain), this page gives the longer comparison.

LangChain memory classes live inside your process. They keep buffers, summaries, or graphs near the chain. Tex stores memory outside the process and returns the relevant slice when you call **`recall`**.

## Mapping

| LangChain                              | Tex equivalent                                                                                        |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `ConversationBufferMemory`             | `recall(q=user_msg, session_id=sid, top_k=20)` returns the relevant 20 turns instead of the last N.   |
| `ConversationBufferWindowMemory(k=10)` | `recall(q=user_msg, session_id=sid, top_k=10)` uses the same `k`, but ranks by relevance.             |
| `ConversationSummaryMemory`            | Tex stores extracted observations automatically. Read them from `recall`'s `hits.observations`.       |
| `ConversationKGMemory`                 | Tex builds an entity graph in the background. Query via `hits.entities` (linked across observations). |

## Migration

<Tabs>
  <Tab title="ConversationChain - before">
    ```python theme={null}
    from langchain.chains import ConversationChain
    from langchain.memory import ConversationBufferWindowMemory
    from langchain_openai import ChatOpenAI

    memory = ConversationBufferWindowMemory(k=10, return_messages=True)
    chain = ConversationChain(
        llm=ChatOpenAI(model="gpt-4o"),
        memory=memory,
    )

    answer = chain.invoke({"input": user_msg})["response"]
    ```
  </Tab>

  <Tab title="Tex retrieval - after">
    ```python theme={null}
    from langchain.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    from tex import Tex

    tex = Tex(api_key=..., base_url=...)

    def chat(user_msg: str, sid: str) -> str:
        hits = tex.recall(q=user_msg, session_id=sid, top_k=10)
        memory = "\n".join(f"- {h.text}" for h in hits.hits.turns)

        prompt = ChatPromptTemplate.from_messages([
            ("system", "Relevant memory:\n{memory}"),
            ("user", "{input}"),
        ])
        chain = prompt | ChatOpenAI(model="gpt-4o")

        answer = chain.invoke({"memory": memory, "input": user_msg}).content

        tex.conversations.remember(session_id=sid, turns=[
            {"role":"user","text": user_msg, "timestamp": now_iso()},
            {"role":"assistant","text": answer, "timestamp": now_iso()},
        ])
        return answer
    ```
  </Tab>
</Tabs>

## Trade-offs

LangChain memory has no network hop. Tex adds a network call: writes are usually around 150ms, and reads can take a few seconds.

In return, memory survives deploys, prompts stay bounded, sessions can share memory, and each recall has a confidence score.

For a small hobby bot, a buffer may be enough. For a customer-facing app, Tex is usually the cleaner path.

## Drop-in adapter (optional)

If your codebase has dozens of LangChain chains and you'd rather not rewrite them all, wrap Tex in a `BaseChatMemory` subclass:

```python tex_chat_memory.py theme={null}
from typing import Any
from langchain.memory.chat_memory import BaseChatMemory
from langchain.schema import BaseMessage, HumanMessage, AIMessage
from tex import Tex

class TexChatMemory(BaseChatMemory):
    def __init__(self, tex: Tex, session_id: str, top_k: int = 10, **kw):
        super().__init__(**kw)
        self._tex = tex
        self._session_id = session_id
        self._top_k = top_k

    @property
    def memory_variables(self) -> list[str]:
        return ["history"]

    def load_memory_variables(self, inputs: dict[str, Any]) -> dict[str, Any]:
        q = inputs.get("input", "")
        hits = self._tex.recall(q=q, session_id=self._session_id, top_k=self._top_k)
        history = "\n".join(f"- {h.text}" for h in hits.hits.turns)
        return {"history": history}

    def save_context(self, inputs: dict[str, Any], outputs: dict[str, Any]) -> None:
        self._tex.conversations.remember(
            session_id=self._session_id,
            turns=[
                {"role":"user","text": inputs["input"], "timestamp": now_iso()},
                {"role":"assistant","text": outputs["response"], "timestamp": now_iso()},
            ],
        )

    def clear(self) -> None:
        # No-op. Tex memory persists by design.
        pass
```

Use it like any other LangChain memory:

```python theme={null}
chain = ConversationChain(
    llm=ChatOpenAI(),
    memory=TexChatMemory(tex=tex, session_id="chat-1"),
)
```
