CookbookRAG
Episodic recall
Recall relevant past chat events with the episodes memory block.
Use episodes() when the agent needs to answer questions about what happened before. It is append-only, scoped by namespace, and can use dense vector search when the backing store supports it.
import { prompt } from "@use-crux/core";
import { generate } from "@use-crux/ai";
import { memory, episodes } from "@use-crux/core/memory";
import { z } from "zod";
const chatEpisodes = episodes({
id: "episodes",
embed: dense,
});
const chatMemory = memory({
id: "chat",
store,
namespace: ({ input }) => `user:${input.userId}:thread:${input.threadId}`,
blocks: [chatEpisodes],
});
const assistantInput = z.object({
userId: z.string(),
threadId: z.string(),
message: z.string(),
});
const assistant = prompt({
id: "assistant",
use: [chatMemory],
input: assistantInput,
system: "Use relevant prior episodes when answering.",
prompt: ({ input }) => input.message,
});
export async function handleMessage(input: z.infer<typeof assistantInput>) {
return generate(assistant, { model, input });
}You can also record non-chat events directly:
await chatEpisodes.record(
{
content: "User accepted the pricing recommendation",
metadata: { source: "ui", event: "accepted_recommendation" },
},
{
store,
namespace: "user:u1:thread:t1",
memoryId: "chat",
},
);Direct calls should pass the same memoryId and namespace as the composed memory() instance so reads and writes share keys.