Overview
TheConversationStore is the core abstraction in ff-ai for managing conversation persistence. It provides a provider-agnostic interface that can be implemented with any storage backend.
Interface
TheConversationStore is defined as an Effect Context.Tag with two methods:
Methods
getMessages
Retrieve messages from a conversation thread.object
required
Parameters for retrieving messages
Effect<ConversationMessage[], StoreError>
An Effect that resolves to an array of messages, ordered chronologically (oldest first)
windowSize parameter controls conversation context:
- Counts only user messages (not assistant or tool messages)
- Returns all messages from the Nth most recent user message onward
- Default is 10 user messages
- Set to
0to retrieve no messages - The implementation handles cases where fewer messages exist than the window size
saveMessages
Persist messages to a conversation thread.object
required
Parameters for saving messages
Effect<void, StoreError>
An Effect that resolves when messages are saved successfully
Thread Identifier
Both methods accept aThreadIdentifier which consists of:
- Organize conversations by resource (user, project, workspace)
- Have multiple conversation threads per resource
- Easily query all conversations for a resource
Error Handling
Both methods return an Effect that may fail withStoreError:
Implementing a Custom Provider
You can implement a custom storage provider by creating a Layer that provides theConversationStore service:
Built-in Providers
Drizzle Provider
PostgreSQL-backed storage using Drizzle ORM
Best Practices
Choose appropriate window sizes
Choose appropriate window sizes
Larger window sizes provide more context but increase token costs and latency. Start with the default of 10 user messages and adjust based on your use case.
Handle errors gracefully
Handle errors gracefully
Always handle
StoreError in your application logic. Consider fallbacks like returning empty arrays or cached data.Use consistent identifiers
Use consistent identifiers
Establish a naming convention for
resourceId and threadId early. For example: user-{uuid} and thread-{uuid}.Consider pagination
Consider pagination
For very long conversations, the window size mechanism provides automatic pagination based on user messages.
Next Steps
Messages
Learn about message types and utilities
Turn Handler
Use the high-level turn handler API
Drizzle Provider
Set up PostgreSQL storage
Examples
See complete implementations