zepto-claw · Episode 2

My AI agent had amnesia. Here's the 20 lines that fixed it.

It forgot my name the moment it answered. The fix is one small file.

Building your own claw — a series where we build a tiny AI agent one small piece at a time.

▶ Watch the build on YouTube

Last time we built an AI agent in 12 lines. It worked. It talked back. And it had one embarrassing problem.

I told it my name. One message later, I asked what my name was. It had no idea.

That's not a bug. The model is stateless. Every call starts from a blank slate. It doesn't forget — it never knew. So if you want it to remember, you have to keep the conversation yourself.

The code

This is the whole memory. It lives in one new file, db.ts. Node ships SQLite built in now, so there's nothing to install:

import { DatabaseSync } from "node:sqlite";

const db = new DatabaseSync("zeptoclaw.db");
db.exec("CREATE TABLE IF NOT EXISTS messages (role TEXT, content TEXT)");

const insert = db.prepare("INSERT INTO messages (role, content) VALUES (?, ?)");
const selectAll = db.prepare("SELECT role, content FROM messages ORDER BY rowid");

export function addMessage(role: string, content: string) {
  insert.run(role, content);
}
export function getMessages() {
  return selectAll.all() as { role: string; content: string }[];
}

Then three lines wire it into ask() — replay the past, then ask the new question, then save both sides of the turn:

const history = getMessages()
  .map((m) => `${m.role}: ${m.content}`)
  .join("\n");
const fullPrompt = history ? `${history}\nuser: ${prompt}` : prompt;
// ...after we get the reply:
addMessage("user", prompt);
addMessage("assistant", reply);

How it works

Every turn, we read the whole chat back out of SQLite, glue it in front of the new question, and send the lot. The model sees the past as if it remembered. After it answers, we save both lines so next turn has them too.

The database is just one file on disk, zeptoclaw.db. Quit the program, run it again, ask "what's my name?" — it still says Senna. The file is the memory.

Try it yourself

  1. Add db.ts with the code above.
  2. In ask(), load the history and prepend it to the prompt.
  3. After each reply, call addMessage() for both the question and the answer.

Run it twice. Tell it your name, quit, restart, ask. It remembers.

One honest caveat: this replays the full history every turn. Fine for a tutorial claw, not for ten thousand messages. Trimming the window is its own piece — small first.

Watch the full build: the zepto-claw E02 Short, and subscribe on YouTube for E03. Catching up? Start with E01.