Skip to content

Memory & conversations

A single run() is stateless — each call starts fresh. Real assistants need to remember the thread. ask(prompt, id) loads that conversation’s transcript from a ConversationStore, runs the loop with it as history, and saves the updated transcript back. The next ask with the same id continues where it left off.

const agent = createClient({ baseUrl, style: "openai", model }) // in-memory store by default
await agent.ask("Book me a flight to Berlin.", { toolkit: tk, id: "user-42" })
await agent.ask("Actually, make it Munich.", { toolkit: tk, id: "user-42" }) // same thread — remembered
await agent.ask("What is 21 + 21?", { toolkit: tk }) // no id → one-shot

No id ⇒ a stateless one-shot, identical to run. That’s the whole memory model: an id is a thread.

Pluggable store — persist across processes

Section titled “Pluggable store — persist across processes”

The default store keeps transcripts in memory for the client’s lifetime. To survive restarts or share a thread across processes, implement two methods — get(id) → messages and save(id, messages) — over a file, database, or Redis, and pass it to the client.

import { createClient, type ConversationStore } from "toolnexus"
const redisStore: ConversationStore = {
async get(id) {
const raw = await redis.get(`conv:${id}`)
return raw ? JSON.parse(raw) : undefined
},
async save(id, messages) {
await redis.set(`conv:${id}`, JSON.stringify(messages))
},
}
const agent = createClient({ baseUrl, style: "openai", model, store: redisStore })

The same id works on the streaming paths. Pass on_text to ask to stream assistant deltas while ask still returns the final result, or use stream(prompt, { toolkit, id }) to iterate events (text / tool_call / tool_result / usage / done). With an id, the thread is loaded before streaming and saved on the terminal done event.

The lower-level run(prompt, { toolkit, history }) takes an explicit history array, and a stateful client.conversation({ toolkit }) wrapper retains history across send calls — both there when you want to manage the transcript yourself instead of by id.

Memory is also how durable suspension resumes