Crux
CookbookBasics

Chat with memory

Compose recent messages, working state, episodes, and proposed facts for a practical chat agent.

This recipe shows the default memory shape for a useful assistant. It keeps a short recent window, tracks typed task state, records notable events, and proposes long-term facts instead of silently changing the user's profile.

import { prompt } from '@crux/core'
import { generate } from '@crux/ai'
import { memory, recentMessages, workingState, episodes, facts } from '@crux/core/memory'
import { z } from 'zod'

const assistantMemory = memory({
  id: 'chat-assistant',
  store,
  namespace: ({ input }) => `user:${input.userId}:thread:${input.threadId}`,
  blocks: [
    recentMessages({ id: 'recent', maxMessages: 12 }),
    workingState({
      id: 'state',
      schema: z.object({
        goal: z.string().optional(),
        openQuestions: z.array(z.string()).default([]),
      }),
    }),
    episodes({ id: 'episodes', embed: dense }),
    facts({
      id: 'facts',
      embed: dense,
      extract: async (turn) => extractProfileFacts(turn),
      write: { mode: 'propose' },
    }),
  ],
})

const chatInput = z.object({
  userId: z.string(),
  threadId: z.string(),
  message: z.string(),
})

const chatPrompt = prompt({
  id: 'chat',
  use: [assistantMemory],
  input: chatInput,
  system: 'Answer clearly. Use memory only when it is relevant.',
  prompt: ({ input }) => input.message,
})

export async function reply(input: z.infer<typeof chatInput>) {
  const result = await generate(chatPrompt, { model, input })
  return result.text
}

After generate() finishes, Crux captures the user and assistant messages and flushes the memory blocks. If the model extracts a candidate fact, it becomes a proposal:

const pending = await assistantMemory.proposals.list({
  namespace: 'user:u1:thread:t1',
})

await assistantMemory.proposals.approve(pending[0].id)

For product UX, surface proposals in a settings panel or admin review queue. Use write: { mode: 'auto' } only for memories sourced from explicit user actions or trusted product events.

On this page

No Headings