One personal AI, every channel
Here's the scene this cookbook is about. Your personal agent runs on OpenClaw. On Monday you message it on WhatsApp: "the dentist moved to Thursday". On Wednesday you ask it on Telegram: "what's my week look like?" It knows about the dentist. Not because the two chats share a transcript (they don't), but because both channels write to and read from the same Korely memory.
That's the whole trick: the channel is ephemeral, the memory is not. One memory store, one entity graph, one set of facts. Every surface your agent lives on sees the same brain.
Everything in this recipe runs over the Korely REST API or SDK.
Install korely-memory, set your kor_live_ key once, and every
channel your agent runs in writes and reads from the same memory. No per-channel
configuration. There is no plugin to install.
Setup: two steps
You need a Korely account and an API key. Get started in the quickstart. Then install the SDK once, wherever your agent runs:
$ pip install korely-memory
$ export KORELY_API_KEY=kor_live_... From that moment, every channel your agent bridges, WhatsApp, Telegram, Discord, Slack, Signal, iMessage and the rest, talks to the agent, and the agent reads and writes the same shared memory. The memory is attached to the agent, not to the chat surface. Add a new channel next month and it inherits everything the agent already knows.
What flows where
The Monday-to-Wednesday scene, as actual tool calls:
Monday · WhatsApp
"Dentist moved to Thursday"
- One message, one channel
- Chat history stays on WhatsApp
Korely
add()
- Memory stored in Korely
- Fact extracted into the graph
Wednesday · Telegram
"What's my week look like?"
- Different channel
- No shared transcript
Korely
get_context()
- Active typed facts, assembled
- Contradictions resolved
Answer
It knows about the dentist
- Context from Monday, surfaced Wednesday
The Wednesday read is a get_context() call: Korely assembles
the active typed facts for the entity into one ready-to-prompt block, with
contradictions already resolved. Reads are retrieval, not generation. No
generative model composes output on the read path; your agent's own model
does the reasoning on what comes back. Fact assembly is a deterministic
lookup, typically under 50 ms, so the memory lookup never becomes the
slow part of a chat reply.
Interactions to try
The recipes are prompt-level: you say things to your agent, the agent decides which SDK or REST calls to make. Three to start with, in any channel:
1. Teach it something
"Remember that Marta prefers morning meetings."
The agent calls add() and gets a confirmation back:
from korely_memory import Korely
korely = Korely() # reads KORELY_API_KEY from env
korely.add(
"Marta prefers morning meetings",
agent_id="personal-assistant",
user_id="me",
)
On the Korely side, the write path does the heavy lifting: the memory is
embedded, entities are extracted on our own infrastructure, and a typed
fact, (Marta, prefers, morning meetings), lands in the graph
with bi-temporal validity. It is queryable from every channel until it is
contradicted or you forget it.
2. Ask it back, anywhere
"What do you know about Marta?"
The agent calls get_facts() filtered to the entity
Marta and gets back a flat list of her active typed facts. For a
broader "what's my week look like?" recall, the agent reaches for
get_context() instead, the moat read path, which assembles the
relevant active facts into a ready-to-prompt block. Here we want the precise
per-entity facts:
facts = korely.get_facts(entity="Marta")
# flat list of typed fact triples, active only by default.
# Attribute access (dataclasses), and the verb is normalized:
# "prefers" is stored as predicate "likes", raw verb kept in predicate_raw.
# facts[0].subject -> "Marta"
# facts[0].predicate -> "likes"
# facts[0].predicate_raw -> "prefers"
# facts[0].object -> "morning meetings"
# facts[0].valid_from -> "2026-06-08"
# facts[0].invalid_at -> None (None = still active)
# Superseded facts (invalid_at set) are hidden by default.
# For facts grouped by family, use get_profile() instead. Facts are bi-temporal: if you later say Marta switched to afternoons, the old fact is superseded, not deleted, and the agent only sees the current one. Same answer on Telegram, Discord, or Signal, because it's the same memory. And because the read is a deterministic lookup with no AI call in the path, it costs nothing and returns in milliseconds.
3. Hand work to your future self
"Save this article draft for me to review."
The agent calls add() with the article draft as content.
Then you open the Korely app on your laptop and the memory is just
there, a note you can read, edit, or delete. The memory store is
shared between you and your agent: the agent writes from WhatsApp, you
polish in the editor, the agent sees your edits on the next read. Korely
is the only memory layer where your agent's memory is also something
you can open and work on yourself.
Privacy and the off switch
The agent accesses memory scoped to
your account only via a kor_live_ key.
There's no shared corpus, no cross-account leakage by construction.
Two controls matter day to day:
- Revoke anytime. Delete or rotate your API key and every channel loses memory access at the same instant, because they all authenticate with the same key.
- Forget propagates everywhere. The Memory Panel in the app shows every fact Korely holds about you, and lets you edit or forget each one, a built-in forget flow you control. A fact you forget stops reaching every channel instantly, because there is only one memory to forget it from.
Everything is stored EU-hosted, on our own infrastructure (Postgres + pgvector), and your memory is always accessible via the app or the REST API.
Recall is agent-driven, by design
Every memory access is an explicit SDK or REST call. The agent decides when to read or write, and in practice modern models reach for memory reliably on explicit asks ("remember…", "what do you know about…"). Korely never silently captures your messages or injects memory into a reply on its own. Each call is explicit in your agent's code, so you always know what was read and what was written.
Where to go next
- OpenClaw integration guide: the full setup for routing channel messages through your agent.
- Temporal facts: how contradiction detection keeps "current" answers current when your life changes.
- Human in the loop: the Memory Panel and why we think the end user should always be able to see and edit what their agent remembers.
- SDK reference: all methods,
parameters, and response shapes for
korely-memory.
Built something on this? We want to see it. Email [email protected]. Cross-channel personal agents are exactly the use case we built Korely for, and real setups shape the product.