Conversations & follow-ups
Every turn belongs to a conversation. Finn keeps the context of a
conversation server-side, so follow-up questions understand what came before —
you just need to thread the conversationId.
Start a conversation, then follow up
Section titled “Start a conversation, then follow up”// First question — no conversationId, so Finn starts a new conversation.const first = finn.sendMessage('How many active members do I have?');for await (const c of first) process.stdout.write(c.text);const { conversationId } = await first.completed;
// Follow-up — pass the id back, and Finn keeps the context.const second = finn.sendMessage('How many joined in the last 90 days?', { conversationId,});for await (const c of second) process.stdout.write(c.text);await second.completed;Because the second call carries the conversationId, “in the last 90 days” is
understood against the same members the first question was about.
Send options
Section titled “Send options”sendMessage(text, options) accepts a
SendMessageOptions:
| Option | Type | Description |
|---|---|---|
conversationId | string | Continue an existing conversation. Omit to start a new one (or continue the client’s current one). |
systemPrompt | string | Per-conversation system-prompt override — honored only when creating a new conversation. See System prompts. |
Persisting conversations
Section titled “Persisting conversations”The conversationId is just a string — store it wherever you keep user state
(a session, a database row, a cache) and reuse it later, even across process
restarts or reconnects:
const turn = finn.sendMessage(userQuestion, { conversationId: saved ?? undefined });const { conversationId } = await turn.completed;await db.users.update(userId, { finnConversationId: conversationId });