A customer texts in March about a quote. They email in April with a question about financing. In May they’re back on WhatsApp: “ok, ready to go ahead with the one we talked about.”
A good salesperson remembers “the one we talked about.” An AI agent can only remember what fits in its prompt, and a months-long thread across three channels doesn’t fit.
The obvious fixes both fail. Send the whole history and prompts get slow, expensive and eventually too long. Send only the last few messages and the agent forgets the quote, the objection and the name of the person’s partner.
Myna does neither. Every turn, the agent sees two things:
- The recent conversation, word for word.
- A summary of everything older than that.
Count, then characters
“Recent” can’t just mean “the last N messages.” A thread of short texts and a thread of long emails take up wildly different amounts of room. Email and webchat run out of space long before a text thread with the same number of messages does.
So the recent window is decided in two steps: take the newest messages up to a fixed count, then trim from the oldest end until they fit a character budget. The newest message is always kept, however long it is.
One definition of “recent”
Here’s a subtle failure mode. If the prompt and the summarizer each decide for themselves what counts as recent, they’ll eventually disagree. Then a message either appears twice (summarized and shown word for word) or falls into the gap between them and disappears.
Myna uses one shared definition for both. Every message is either shown word for word or covered by the summary. None appears in both, and none slips through. We have a test that fails if those two ever drift apart.
Roll it up, don’t redo it
The summary is rolling. When messages leave the recent window, they’re folded into the existing summary in a small update. The full history is never re-summarized.
That keeps the cost of each update flat. It depends only on the few messages that just aged out, plus a short summary, no matter whether the conversation is ten messages long or ten thousand. Once a thread is longer than the window, nearly every turn pushes one exchange out, so nearly every turn makes one small, cheap update.
Contacts with a long history from before this feature catch up gradually, a batch at a time across their next few turns, instead of stalling one reply with a giant summarizing job.
Consolidate, don’t drop the oldest facts
The summary has a fixed maximum length, and the rule for staying under it matters more than the length itself: fit by consolidating, never by dropping the oldest facts.
The summarizer is told to keep names, dates, prices, commitments, objections and open questions; to merge duplicates; to skip retelling every message; and never to invent anything. Mentioning the channel is reserved for when it matters, like “they asked about this on email.”
Myna enforces the rule in code too. A summary that comes back too long is rejected, not quietly cut short, because cutting the end off is exactly how you lose the oldest facts. Even the fallback, used when summarizing fails, only ever appends. It never deletes what the summary already says.
The summary is soft memory
Summaries are lossy. That’s fine, as long as nothing important depends on them alone.
So Myna never trusts the summary with the hard facts. Qualification answers, upcoming appointments, open tickets and contact details are read fresh from the database on every turn, and shown to the agent as their own structured context. The summary carries the softer material: who was mentioned, what was quoted, what the customer pushed back on, what was promised, what’s still open.
And it knows its place. The agent is told that the summary is background, not the live thread, and that when it conflicts with a recent message, the latest message, or a tool result, the newer, direct source wins.
The summary helps in a couple of quieter ways too. It helps the agent’s memory search work out what a vague follow-up like “what about the other one?” refers to. And an agent with history behind it doesn’t open with a first-time greeting.
One memory across every channel
There’s one summary per contact, covering every channel. A detail from last week’s WhatsApp chat reaches today’s SMS follow-up. Switch the contact to a different agent or campaign and the memory comes with them. (Yes, there’s a test for the WhatsApp-to-SMS case specifically.)
Pay only for turns that need it
Summarizing happens inline, but only for turns that will actually get a reply. If a turn is blocked before the agent runs, because the customer opted out or a teammate has taken over the conversation, the summary isn’t touched. Building each turn’s context just reads the stored summary, and only the separate update step does any real work.
The work itself goes to a small, fast model. Summarizing is a narrow job, and it doesn’t need the same model that plans and writes replies.
A checkpoint instead of locks
Two messages can arrive at almost the same moment, and two turns can try to update the same summary. Without care, one update could overwrite the other and silently skip a stretch of history.
Each summary stores a checkpoint: the newest message it includes. An update only saves if the checkpoint is still what it expected. If another turn got there first, the update rolls back and tries again from the new state. A crash or a concurrent turn can’t skip history.
When things go wrong, the reply still goes out
- The summarizer fails or rambles: that batch falls back to a plain append, as much as fits without deleting anything.
- Nothing fits: the messages wait and are folded in on a later turn. Nothing is lost.
- Anything else breaks: it’s logged, and the turn carries on with the summary it already had.
Summarizing never stops a customer from getting a reply.
The takeaway
Long-conversation memory isn’t about cramming more into a prompt. It’s about deciding, precisely, what the agent sees word for word, what it sees as a summary, and what it never takes from the summary at all.
Recent messages verbatim. Older ones rolled into a summary that consolidates instead of forgetting. Hard facts straight from the database. That’s how an agent picks up “the one we talked about” two months and three channels later.