A multi-turn chat app built with the AI SDK's useChat hook and Trigger.dev's chat.task. Conversations run as durable Trigger.dev tasks with realtime streaming, automatic message accumulation, and persistence across page refreshes.
The conversation itself — your application data.
| Column | Description |
|---|---|
id |
Unique chat ID (generated on the client) |
title |
Display title for the sidebar |
messages |
Full UIMessage[] history (JSON) |
A Chat lives forever (until the user deletes it). It is independent of any particular Trigger.dev run.
The transport's connection state for a chat — what the frontend needs to reconnect to the same Trigger.dev run after a page refresh.
| Column | Description |
|---|---|
id |
Same as the chat ID (1:1 relationship) |
runId |
The Trigger.dev run handling this conversation |
publicAccessToken |
Scoped token for reading the run's stream and sending input stream messages |
lastEventId |
Stream position — used to resume without replaying old events |
A Chat can outlive many ChatSessions. When the run ends (turn timeout, max turns reached, crash), the ChatSession is gone but the Chat and its messages remain. The next message from the user starts a fresh run and creates a new ChatSession for the same Chat.
Think of it as: Chat = the conversation, ChatSession = the live connection to the run handling it.
Persistence is handled server-side in the Trigger.dev task via three hooks:
onChatStart— Creates the Chat and ChatSession records when a new conversation starts (turn 0).onTurnStart— Saves messages and updates the session before streaming begins, so a mid-stream page refresh still shows the user's message.onTurnComplete— Saves the assistant's response and thelastEventIdfor stream resumption.
This reference assumes you already have the local webapp running per the repo's CONTRIBUTING.md (Docker services, pnpm run db:migrate, pnpm run db:seed, webapp on :3030).
Unlike hello-world, the ai-chat project is not in the webapp seed. You'll need to create it manually:
-
Open http://localhost:3030, log in, switch to the
Referencesorg, and create a new project calledai-chat. -
Grab the project ref (
proj_...) from the URL and a Dev secret key from the project's API keys page. -
Set up this app's env and database:
cd references/ai-chat cp .env.example .env # Fill in TRIGGER_PROJECT_REF, TRIGGER_SECRET_KEY, # NEXT_PUBLIC_TRIGGER_PROJECT_DASHBOARD_PATH, and at least one # of OPENAI_API_KEY / ANTHROPIC_API_KEY. npx prisma migrate deploy
The
DATABASE_URLin.env.examplepoints at the local Postgres started bypnpm run dockerand uses a separateai_chatdatabase.
Three terminals from the repo root:
# 1. Webapp (if not already running)
pnpm run dev --filter webapp
# 2. Trigger CLI dev (registers the chat tasks with the local webapp)
cd references/ai-chat && pnpm exec trigger dev
# 3. Next.js dev server for the chat UI
cd references/ai-chat && pnpm run devOpen http://localhost:3000 to use the chat app.