LlamaIndex’s Memory composes blocks. Anona plugs in as one of them, supplying
long-term memory alongside the short-term buffer rather than replacing it. No
vector store to operate, no LLM key to supply.
Setup
Pass memory to any LlamaIndex agent (FunctionAgent, ReActAgent, …).
Memory calls this block’s context into its own template and prepends it to
the system message on every model call, so relevant memories are visible
before the agent’s first response of a turn, including before each
follow-up model call inside a tool-calling round, not just the first one.
LlamaIndex re-asks for the same query several times over the course of one
turn; this block keeps a short-lived cache so those repeats reuse the first
answer instead of calling Anona again each time.
How and when a turn is stored
Unlike Anona’s LangChain or CrewAI adapters, this block does not store a turn
the moment it finishes. LlamaIndex’s Memory keeps its own short-term FIFO of
recent messages (token_limit / chat_history_token_ratio, 30,000 tokens /
70% by default) and only pushes the oldest messages out to each memory
block, Anona’s included, once that buffer fills up. That is the same
contract LlamaIndex’s own built-in blocks (VectorMemoryBlock,
FactExtractionMemoryBlock) are written against: a memory block is long-term
storage for what falls out of the short-term window, not a mirror of every
turn.
In practice:
- A short conversation may never cross the default ~21,000-token threshold,
in which case nothing reaches Anona at all. The whole conversation still
lives in LlamaIndex’s own short-term buffer for the life of the session.
- When the buffer does flush, whole turns move together. A tool-calling
round (the question, the tool call, the tool result, the final answer),
arrives as one batch, never split across separate writes.
- The most recent turn is never flushed by itself, at any
token_limit.
Memory’s eviction always keeps at least one complete turn resident, so
the newest turn only leaves the buffer once another turn pushes it out.
Memory has no flush-now or close method. Concretely: the last turn of
a conversation is never stored by this block at all, no matter how low
you set token_limit. There is always one more turn that never arrives
to evict it.
Lowering token_limit and/or chat_history_token_ratio on
Memory.from_defaults(...) makes every earlier turn reach Anona sooner.
It does not change the point above. The last turn is still excluded either
way.
Guaranteeing the last turn is captured
If losing the final exchange of a conversation is a problem for your use
case (it usually is, since closing questions and final decisions are often the
most worth remembering), don’t rely on eviction for it. Call the bridge
directly at whatever point your application considers a turn or a session
finished:
This is the same MemoryBridge the block itself uses. bridge.remember(...)
is already public API, so this needs no new code, just a call at your own
turn or session boundary. It fires immediately rather than waiting on buffer
pressure, so it’s a reasonable choice even for turns that aren’t the last
one, if you’d rather not depend on token_limit timing at all.
Use a durable database URI
Memory.from_defaults() defaults to an in-memory SQLite database when
async_database_uri is left unset. That default does not survive across
separate agent runs: reusing the same memory object for a second
agent.run(...) call (the normal one-run-per-turn pattern) starts the
short-term buffer over from empty, so it never accumulates enough history
across turns for this block to receive anything. Point async_database_uri
at a real file or database for any multi-turn session.
Scoping
A memory written under one user_id is only ever returned to a query carrying
the same user_id, so a single space can serve every end user of your app.
Memory.from_defaults(session_id=...) is LlamaIndex’s own key for its
short-term buffer, and it never reaches Anona. Memory.aget()/Memory.aput()
call this block with only messages, never session_id, so Anona-side
isolation comes exclusively from the user_id / agent_id / session_id
fixed on the MemoryBridge at construction time. Two different LlamaIndex
sessions sharing one MemoryBridge share the same Anona memories, so scope
each end user’s Memory to its own MemoryBridge (or at least its own
user_id), not just its own session_id.
Failure behaviour
If Anona is unreachable the block yields no memories and the agent continues.
Failures are logged, never raised.