Use CortexDB as a memory store for LlamaIndex agents and query engines.
LlamaIndex Integration
LlamaIndex defines BaseMemory and BaseRetriever contracts. CortexDB plugs into both via the v1 SDK.
Install
pip install cortexdbai llama-index llama-index-llms-openai
Memory
import os
from datetime import datetime, timezone
from uuid import uuid4
from typing import List
from llama_index.core.memory import BaseMemory
from llama_index.core.llms import ChatMessage, MessageRole
from cortexdb.v1 import V1Client
client = V1Client(
api_url="https://api-v1.cortexdb.ai",
actor="user:alice",
bearer=os.environ["CORTEX_TOKEN"],
)
SCOPE = "org:acme/user:alice"
class CortexMemory(BaseMemory):
def get(self, input: str | None = None) -> List[ChatMessage]:
pack = client.recall(
scope=SCOPE, view="holistic", query=input or "",
include=["beliefs", "facts", "episodes"],
budgets={"max_tokens": 3000},
)
ctx = pack["context_block"]
if not ctx:
return []
return [ChatMessage(role=MessageRole.SYSTEM, content=f"<recall>{ctx}</recall>")]
def get_all(self) -> List[ChatMessage]:
return self.get(None)
def put(self, message: ChatMessage) -> None:
client.experience(
scope=SCOPE, text=str(message.content),
role=("assistant" if message.role == MessageRole.ASSISTANT else "user"),
observed_at=datetime.now(timezone.utc).isoformat(),
idempotency_key=f"li-{uuid4()}",
)
def set(self, messages: List[ChatMessage]) -> None:
for m in messages:
self.put(m)
def reset(self) -> None:
pass
from llama_index.core.agent import ReActAgent
from llama_index.llms.openai import OpenAI
agent = ReActAgent.from_tools(tools, llm=OpenAI(model="gpt-4o"), memory=CortexMemory())
agent.chat("Our API rate limit is 1000 req/s per tenant.")
agent.chat("What is our API rate limit?") # recalls from CortexDB
Retriever
from llama_index.core.retrievers import BaseRetriever
from llama_index.core.schema import NodeWithScore, TextNode
class CortexRetriever(BaseRetriever):
def __init__(self, scope: str, k: int = 8):
super().__init__()
self._scope = scope
self._k = k
def _retrieve(self, query) -> List[NodeWithScore]:
pack = client.recall(scope=self._scope, query=str(query), include=["facts", "episodes"])
nodes = []
for fact in pack["layers"].get("facts", []):
nodes.append(NodeWithScore(
node=TextNode(
text=f"{fact['subject']['name']} {fact['predicate']} {fact['object']['value']}",
metadata={"layer": "fact", "id": fact["fact_id"]},
),
score=fact["confidence"],
))
return nodes[: self._k]