Skip to content

Memory: short-term and long-term

An agent remembers at three different time scales, and Locus keeps them as three separate surfaces so you can choose a backend for each. Oracle Database 26ai can back all of them, in the same database as the business data the agent acts on.

Layer What it holds Lifetime Locus surface Oracle Database 26ai
Working memory The messages of the current run: prompt, tool calls, observations One run Agent(conversation_manager=…): SlidingWindowManager, SummarizingManager, ContextCompactor In-process, nothing to persist
Short-term memory (the thread) The full state of one conversation: messages, tool results, iteration, so a thread can resume in another process or after a crash The thread Agent(checkpointer=…) and thread_id= on every call oracle_checkpointer() for durable threads; OracleCheckpointSaver keeps every version for history and resume-from-any-point
Long-term memory Facts that outlive any thread: preferences, standing rules, what was learned handling earlier cases Until you delete it Agent(memory_manager=…): LLMMemoryManager(store=…) or OracleAgentMemoryManager OracleStore as the store; OracleAgentMemoryManager over Oracle's oracleagentmemory client
Knowledge (RAG) Documents the agent retrieves rather than remembers Your corpus RAGRetriever(...).as_tool() OracleVectorStore, OracleInDBChunker, OracleInDBEmbeddings, OracleADBLoader

Working memory

Working memory is the context window. It is not stored anywhere; the question is what to drop when a long run no longer fits. A ConversationManager decides: SlidingWindowManager keeps the last n messages, SummarizingManager folds older turns into a summary, and ContextCompactor archives tool output and replaces it with a reference. See the agent loop for where it runs.

from locus.agent import Agent
from locus.memory.conversation import SlidingWindowManager

agent = Agent(model="oci:openai.gpt-5.5", conversation_manager=SlidingWindowManager(window_size=20))

Short-term memory: the thread

A checkpointer saves the agent's state under a thread_id and loads it back on the next call, from any process. That is what makes a conversation survive a restart, a deploy, or a hand-off to the next shift.

import os

from locus.agent import Agent
from locus.memory.backends import oracle_checkpointer

cp = oracle_checkpointer(
    dsn=os.environ["ORACLE_DSN"],
    user=os.environ["ORACLE_USER"],
    password=os.environ["ORACLE_PASSWORD"],
    wallet_location=os.environ["ORACLE_WALLET"],
    wallet_password=os.environ.get("ORACLE_WALLET_PASSWORD", ""),
    table_name="support_threads",
)
agent = Agent(model="oci:openai.gpt-5.5", checkpointer=cp)
agent.run_sync("My name is Alice.", thread_id="case-100")
agent.run_sync("What is my name?", thread_id="case-100")  # another process, same thread

oracle_checkpointer() keeps the latest state of each thread. OracleCheckpointSaver keeps every version, so you can list a thread's history and resume from any earlier checkpoint. Ten backends ship in total; Checkpointers compares them.

Long-term memory

Long-term memory is what the agent keeps across threads: Alice's preferences should be known in her next case, not only in this one. A MemoryManager runs two hooks around every run: before the first model call it retrieves relevant memories into the system prompt; after the run it extracts durable facts and persists them.

import os

from locus.agent import Agent
from locus.memory import LLMMemoryManager
from locus.memory.store_backends import OracleStore

store = OracleStore(
    dsn=os.environ["ORACLE_DSN"],
    user=os.environ["ORACLE_USER"],
    password=os.environ["ORACLE_PASSWORD"],
    wallet_location=os.environ["ORACLE_WALLET"],
    wallet_password=os.environ.get("ORACLE_WALLET_PASSWORD", ""),
)
agent = Agent(model="oci:openai.gpt-5.5", memory_manager=LLMMemoryManager(store=store))

agent.run_sync("I'm Alice. I always want quotes in EUR, never in USD.", thread_id="case-100")
agent.run_sync("Which currency do I want my quotes in?", thread_id="case-200")  # new thread: EUR

Two managers ship. LLMMemoryManager works over any BaseStore, with Oracle Database 26ai through OracleStore, and lets you scope memories per user or tenant; out of the box it extracts with a small heuristic (standing rules such as "always … never …", who the user is, project context, links), and you pass extract_fn to let a model decide what is worth keeping. OracleAgentMemoryManager wraps Oracle's own agent-memory client (oracleagentmemory): extraction, context-card summaries and retrieval scoped by user, agent and thread, all inside the database. Long-term memory manager covers both.

Knowledge is not memory

What the agent should look up belongs in retrieval, not in memory: policy pages, runbooks, past resolutions. RAG covers embedders, vector stores and retriever.as_tool(); on Oracle Database 26ai the whole pipeline can run inside the database.

Why one database

Threads, memories and vectors can each live in a different system; on Oracle Database 26ai they live in one, next to the tables the agent reads and writes through its tools. That means one set of credentials, one backup and retention policy, one place to audit what the agent knew when it acted, and no copy of customer data in a separate memory service. Oracle Database 26ai lists every primitive; notebooks 37 to 44 run each one.