Memory & Persistence

When you use LLMs directly they all have a different approach to memory and chat persistence.

Here we standardize on a simple approach

  • By default a session always retains its history/context
  • To disable that behaviour, set a new session to incognito mode
  • Memory is stored at an app + user id level

Let's go over a few examples

Authenticated User

Open a session with a user_id and tell the agent your shoe size. A week later, in a new session, it still knows.

val agents = VisionAgents(apiKey = "your_api_key")
agents.setUser(User(id = "user-123")) { yourBackend.agentToken() }
val support = agents.agent("support")
// Remembers for the user setUser named.
val options = SessionOptions(memory = SessionOptions.Memory())

val monday = support.chat(options)
ask(monday, "I wear a size 10 shoe.")
monday.close()

val friday = support.chat(options)
println(ask(friday, "What size should I order in these running shoes?"))
// Size 10, going by what you told me before.

suspend fun ask(session: AgentSession, text: String): String = coroutineScope {
    val answer = async(start = CoroutineStart.UNDISPATCHED) {
        session.events()
            .takeWhile { it.type != "responded" }
            .filter { it.type == "response_delta" }
            .fold("") { soFar, event -> soFar + event.text }
    }
    session.responses.create(text)
    answer.await()
}

What the agent learns is saved as the conversation goes, and recalled when a session opens. Every memory is kept under your app and the user_id, so one person's memories never reach another. In a browser, as on a phone, pass memory: {}: it remembers for the user setUser named, since a user's device can't name anyone else. A backend names whichever of its users it means, or the one it acts for when it names none.

Incognito

An incognito session saves nothing. Tell it your shoe size and the next session has no idea, and the conversation itself is not stored anywhere.

agents.setUser(User(id = "user-456")) { yourBackend.agentToken() }
// Remembers for user-456, the user setUser named.
val options = SessionOptions(memory = SessionOptions.Memory())

val secret = support.chat(options.copy(incognito = true))
ask(secret, "I wear a size 10 shoe.")
secret.close()

val later = support.chat(options)
println(ask(later, "What size should I order in these running shoes?"))
// I don't know your shoe size yet. What size do you wear?

support.sessions.get(secret.id) // throws: not found

An incognito session has no transcript, so it can't be listed, searched, forked or rewound. It still recalls what earlier sessions learned about the person; it just adds nothing.

Forgetting

Ending a session keeps what it learned. To forget one session, delete its memories. To forget a person, truncate their memories: everything learned about them, in every session and by every agent, is deleted.

import { Client } from "@stream-io/calypso";

const api = new Client();

await api.agent("support").sessions.deleteMemories(sessionId);
await api.memories.truncate("user-123");