Skip to main content

Overview

The message types in ff-ai extend the Vercel AI SDK’s ModelMessage with additional metadata for persistence and identification.

ConversationMessage

The ConversationMessage namespace provides types and utilities for working with conversation messages.

Type Definition

Message Structure

A ConversationMessage includes:
ConversationMessage.Id
required
UUID v7 identifier for the message. Generated automatically using the uuid package.
Date
required
Timestamp when the message was created. Used for ordering messages chronologically.
'user' | 'assistant' | 'tool' | 'system'
required
The role of the message sender (inherited from AI SDK)
string | ContentPart[]
required
The message content. Can be a simple string or an array of content parts (text, images, tool calls, etc.)

Creating Messages

Messages are typically created automatically when using createTurnHandler. The turn handler’s saveUserMessage and onStep methods handle message creation internally. If you need to manually create a message (e.g., for custom storage implementations), construct it with the required fields:
Most users should rely on createTurnHandler to manage message creation automatically rather than creating messages manually.

Converting Messages

convertToUIMessage

Convert a ConversationMessage to the AI SDK’s UIMessage format for rendering in user interfaces:
Signature:
Behavior:
  • Extracts text parts from the message content
  • Maps tool role to assistant (UI convention)
  • Preserves message ID for React keys
  • Returns an array of UIMessagePart objects

Message Roles

Messages can have different roles based on their source:
Messages sent by the end user. These are the primary input to the AI model.
Messages generated by the AI model. Can include text responses or tool calls.
Results from tool executions. These provide context back to the model.
System instructions that guide the model’s behavior. Not stored in conversation history by default.

Content Types

Messages can contain different types of content:

Text Content

Simple string content:

Structured Content

Array of content parts for complex messages:

Tool Calls

Assistant messages requesting tool execution:

Working with Messages

Complete Example

Multi-part Messages

Tool Result Messages

Message IDs

Message IDs use UUID v7, which provides:
  • Time-ordered: IDs are sortable by creation time
  • Unique: Globally unique across distributed systems
  • Performance: Efficient for database indexing
The first part of the UUID encodes the timestamp, making it naturally ordered.

Type Safety

The ConversationMessage.Id type is branded using Valibot:
This prevents accidental mixing of message IDs with other string types:

Best Practices

Don’t manually construct ConversationMessage objects. Use fromModelMessage to ensure IDs and timestamps are properly generated:
When displaying messages in a UI, always convert them first:
Store complete messages including metadata. Don’t discard id and createdAt as they’re needed for message ordering and deduplication.
Always check if content is a string or array:

Next Steps

Turn Handler

Automatically manage message creation and persistence

Conversation Store

Store and retrieve conversation messages

Examples

See complete examples with messages