Memory for agents. It forgets the way people do.
Before every model call, your agent hands over what is new and gets back the request to submit. Old episodes fade with time, their facts stay, and recall brings them back when the conversation turns to them.
const request = await memory.chat.decorate(memoryId, newMessages, { model, tools });
const reply = await openai.chat.completions.create(request);
memory.chat.report(memoryId, reply);An example conversation, oldest message first. Older lines are drawn fainter, by one over the square root of their age, except an early line giving the launch date, which stays bright because the conversation keeps coming back to it.
Watch a conversation get decorated.
Turn 41 of a long conversation. The agent sends one new message; the request that comes back has the history in proportion, two facts recalled from weeks ago, and an ask for the facts of what is leaving.
Ember marks what we add. Your messages come back as you sent them. The model’s reply to this request carries the note, and turns 12–15 leave the view on the next call.
Three steps around the call you already make.
Decorate
Send what is new since the last call. Get back the full request: your instructions, the facts block, the history still in view, recall, and the note ask when history is leaving.
Submit it yourself
Send the request to OpenAI with your own key, from your own process. Chat Completions or Responses, any model, your tools. It never passes through us.
Report
Hand over the reply. It returns at once; facts are scored, what left the view is indexed and recall for the next message is prepared in the background.
About ten lines. Your loop stays yours.
Wrap the model call, add the note tool to your tools, and answer note calls with NOTE_RESULT. When we cannot be reached, the SDK builds the request from a local tail of recent turns and the call goes ahead.
import OpenAI from 'openai';
import { Threadless } from '@threadlessai/sdk';
const openai = new OpenAI();
const memory = new Threadless(); // reads THREADLESS_API_KEY
const tools = [...yourTools, memory.chat.noteTool];
const request = await memory.chat.decorate(memoryId, newMessages, { model: 'gpt-5', tools });
const reply = await openai.chat.completions.create(
request as unknown as OpenAI.ChatCompletionCreateParamsNonStreaming,
);
memory.chat.report(memoryId, reply);from openai import OpenAI
from threadlessai import Threadless
openai = OpenAI()
memory = Threadless() # reads THREADLESS_API_KEY
tools = [*your_tools, memory.chat.note_tool]
request = memory.chat.decorate(memory_id, new_messages, {"model": "gpt-5", "tools": tools})
reply = openai.chat.completions.create(**request)
memory.chat.report(memory_id, reply)Forgetting by time and use. Facts kept. Recall on cue.
Truncation loses the start, summaries drift, and searching everything makes nothing stand out. People forget well instead; so does this.
Episodes
The conversation is cut into episodes, one per concept, never splitting a tool call from its output.
Forgetting by time
Each episode's activation fades with the square root of real time and rises every time it matters again. The least active leave the view first.
Facts kept
Before an episode leaves, your model writes its facts and milestones with the note tool. They stay in view after the turns are gone.
Recall
When the conversation touches something old, the facts and passages about it come back, dated, before the model is called.
After a day of silence the next turn sleeps first: the view fades before the reply, so the agent comes back with the gap accounted for. The mechanism in full
Benchmark results are coming.
We are running the public long-memory benchmarks against the hosted service. We will publish the scores with the method and the runs behind them. Until then we publish no numbers.
Long-term memory in chat assistantspending
Very long conversations across sessionspending
Results will appear in the changelog when they are in.
Two meters. Pricing is being finalised.
You pay OpenAI for your model calls directly. We meter the memory: the turns it serves and the history it holds.
User turns
A decorate call that carries a new user message. Calls inside a tool loop are free.
Stored memory
What each memory holds, measured daily and averaged over the month.
Start free
A free allowance of turns and memories, no card. Enterprise terms on request.
See what each meter covers