Documentation
¶
Overview ¶
Package statestore provides conversation state persistence and management.
Index ¶
- Variables
- type ConversationState
- type InMemoryIndex
- type IndexResult
- type LLMSummarizer
- type ListOptions
- type MemoryStore
- func (s *MemoryStore) AppendMessages(ctx context.Context, id string, messages []types.Message) error
- func (s *MemoryStore) Delete(ctx context.Context, id string) error
- func (s *MemoryStore) Fork(ctx context.Context, sourceID, newID string) error
- func (s *MemoryStore) List(ctx context.Context, opts ListOptions) ([]string, error)
- func (s *MemoryStore) Load(ctx context.Context, id string) (*ConversationState, error)
- func (s *MemoryStore) LoadRecentMessages(ctx context.Context, id string, n int) ([]types.Message, error)
- func (s *MemoryStore) LoadSummaries(ctx context.Context, id string) ([]Summary, error)
- func (s *MemoryStore) MessageCount(ctx context.Context, id string) (int, error)
- func (s *MemoryStore) Save(ctx context.Context, state *ConversationState) error
- func (s *MemoryStore) SaveSummary(ctx context.Context, id string, summary Summary) error
- type MessageAppender
- type MessageIndex
- type MessageReader
- type RedisOption
- type RedisStore
- func (s *RedisStore) AppendMessages(ctx context.Context, id string, messages []types.Message) error
- func (s *RedisStore) Delete(ctx context.Context, id string) error
- func (s *RedisStore) Fork(ctx context.Context, sourceID, newID string) error
- func (s *RedisStore) List(ctx context.Context, opts ListOptions) ([]string, error)
- func (s *RedisStore) Load(ctx context.Context, id string) (*ConversationState, error)
- func (s *RedisStore) LoadRecentMessages(ctx context.Context, id string, n int) ([]types.Message, error)
- func (s *RedisStore) LoadSummaries(ctx context.Context, id string) ([]Summary, error)
- func (s *RedisStore) MessageCount(ctx context.Context, id string) (int, error)
- func (s *RedisStore) Save(ctx context.Context, state *ConversationState) error
- func (s *RedisStore) SaveSummary(ctx context.Context, id string, summary Summary) error
- type Store
- type Summarizer
- type Summary
- type SummaryAccessor
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidID = errors.New("invalid conversation ID")
ErrInvalidID is returned when an invalid conversation ID is provided.
var ErrInvalidState = errors.New("invalid conversation state")
ErrInvalidState is returned when a conversation state is invalid.
var ErrNotFound = errors.New("conversation not found")
ErrNotFound is returned when a conversation doesn't exist in the store.
Functions ¶
This section is empty.
Types ¶
type ConversationState ¶
type ConversationState struct {
ID string // Unique conversation identifier
UserID string // User who owns this conversation
Messages []types.Message // Message history (using unified types.Message)
SystemPrompt string // System prompt for this conversation
Summaries []Summary // Compressed summaries of old turns
TokenCount int // Total tokens in messages
LastAccessedAt time.Time // Last time conversation was accessed
Metadata map[string]interface{} // Arbitrary metadata (e.g., extracted context)
}
ConversationState represents stored conversation state in the state store. This is the primary data structure for persisting and loading conversation history.
type InMemoryIndex ¶ added in v1.3.1
type InMemoryIndex struct {
// contains filtered or unexported fields
}
InMemoryIndex provides an in-memory implementation of MessageIndex using brute-force cosine similarity search. Suitable for development, testing, and conversations with up to ~10K messages.
func NewInMemoryIndex ¶ added in v1.3.1
func NewInMemoryIndex(provider providers.EmbeddingProvider) *InMemoryIndex
NewInMemoryIndex creates a new in-memory message index.
func (*InMemoryIndex) Delete ¶ added in v1.3.1
func (idx *InMemoryIndex) Delete(_ context.Context, conversationID string) error
Delete removes all indexed messages for a conversation.
func (*InMemoryIndex) Index ¶ added in v1.3.1
func (idx *InMemoryIndex) Index( ctx context.Context, conversationID string, turnIndex int, message types.Message, ) error
Index adds a message to the search index by computing its embedding.
func (*InMemoryIndex) Search ¶ added in v1.3.1
func (idx *InMemoryIndex) Search(ctx context.Context, conversationID, query string, k int) ([]IndexResult, error)
Search finds the top-k messages most relevant to the query string.
type IndexResult ¶ added in v1.3.1
type IndexResult struct {
// TurnIndex is the position of the message in the conversation history.
TurnIndex int
// Message is the full message content.
Message types.Message
// Score is the relevance score (higher is more relevant, typically 0.0-1.0).
Score float64
}
IndexResult represents a single search result from the message index.
type LLMSummarizer ¶ added in v1.3.1
type LLMSummarizer struct {
// contains filtered or unexported fields
}
LLMSummarizer uses an LLM provider to compress messages into summaries.
func NewLLMSummarizer ¶ added in v1.3.1
func NewLLMSummarizer(provider providers.Provider) *LLMSummarizer
NewLLMSummarizer creates a new LLM-based summarizer. A cheaper/faster model is recommended (e.g., GPT-3.5, Claude Haiku).
type ListOptions ¶
type ListOptions struct {
// UserID filters conversations by the user who owns them.
// If empty, all conversations are returned (subject to pagination).
UserID string
// Limit is the maximum number of conversation IDs to return.
// If 0, a default limit (e.g., 100) should be applied.
Limit int
// Offset is the number of conversations to skip (for pagination).
Offset int
// SortBy specifies the field to sort by (e.g., "created_at", "updated_at").
// If empty, implementation-specific default sorting is used.
SortBy string
// SortOrder specifies sort direction: "asc" or "desc".
// If empty, defaults to "desc" (newest first).
SortOrder string
}
ListOptions provides filtering and pagination options for listing conversations.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore provides an in-memory implementation of the Store interface. It is thread-safe and suitable for development, testing, and single-instance deployments. For distributed systems, use RedisStore or a database-backed implementation.
func NewMemoryStore ¶
func NewMemoryStore() *MemoryStore
NewMemoryStore creates a new in-memory state store.
func (*MemoryStore) AppendMessages ¶ added in v1.3.1
func (s *MemoryStore) AppendMessages(ctx context.Context, id string, messages []types.Message) error
AppendMessages appends messages to the conversation's message history.
func (*MemoryStore) Delete ¶
func (s *MemoryStore) Delete(ctx context.Context, id string) error
Delete removes a conversation state by ID.
func (*MemoryStore) Fork ¶ added in v1.1.6
func (s *MemoryStore) Fork(ctx context.Context, sourceID, newID string) error
Fork creates a copy of an existing conversation state with a new ID.
func (*MemoryStore) List ¶
func (s *MemoryStore) List(ctx context.Context, opts ListOptions) ([]string, error)
List returns conversation IDs matching the given criteria.
func (*MemoryStore) Load ¶
func (s *MemoryStore) Load(ctx context.Context, id string) (*ConversationState, error)
Load retrieves a conversation state by ID. Returns a deep copy to prevent external mutations.
func (*MemoryStore) LoadRecentMessages ¶ added in v1.3.1
func (s *MemoryStore) LoadRecentMessages(ctx context.Context, id string, n int) ([]types.Message, error)
LoadRecentMessages returns the last n messages for the given conversation.
func (*MemoryStore) LoadSummaries ¶ added in v1.3.1
LoadSummaries returns all summaries for the given conversation.
func (*MemoryStore) MessageCount ¶ added in v1.3.1
MessageCount returns the total number of messages in the conversation.
func (*MemoryStore) Save ¶
func (s *MemoryStore) Save(ctx context.Context, state *ConversationState) error
Save persists a conversation state. If it already exists, it will be updated.
func (*MemoryStore) SaveSummary ¶ added in v1.3.1
SaveSummary appends a summary to the conversation's summary list.
type MessageAppender ¶ added in v1.3.1
type MessageAppender interface {
// AppendMessages appends messages to the conversation's message history.
// Creates the conversation if it doesn't exist.
AppendMessages(ctx context.Context, id string, messages []types.Message) error
}
MessageAppender allows appending messages without a full load+replace+save cycle. This is an optional interface — stores that implement it enable incremental saves. Pipeline stages type-assert for this interface and fall back to Store.Save when unavailable.
type MessageIndex ¶ added in v1.3.1
type MessageIndex interface {
// Index adds a message to the search index for the given conversation.
// turnIndex is the position of the message in the conversation history.
Index(ctx context.Context, conversationID string, turnIndex int, message types.Message) error
// Search finds the top-k messages most relevant to the query string.
// Results are ordered by descending relevance score.
Search(ctx context.Context, conversationID string, query string, k int) ([]IndexResult, error)
// Delete removes all indexed messages for a conversation.
Delete(ctx context.Context, conversationID string) error
}
MessageIndex provides semantic search over conversation messages. Implementations can use embedding-based vector search or other similarity methods to find messages relevant to a given query.
type MessageReader ¶ added in v1.3.1
type MessageReader interface {
// LoadRecentMessages returns the last n messages for the given conversation.
// Returns ErrNotFound if the conversation doesn't exist.
LoadRecentMessages(ctx context.Context, id string, n int) ([]types.Message, error)
// MessageCount returns the total number of messages in the conversation.
// Returns ErrNotFound if the conversation doesn't exist.
MessageCount(ctx context.Context, id string) (int, error)
}
MessageReader allows loading a subset of messages without full state deserialization. This is an optional interface — stores that implement it enable efficient partial reads. Pipeline stages type-assert for this interface and fall back to Store.Load when unavailable.
type RedisOption ¶
type RedisOption func(*RedisStore)
RedisOption configures a RedisStore.
func WithPrefix ¶
func WithPrefix(prefix string) RedisOption
WithPrefix sets the key prefix for Redis keys. Default is "promptkit".
func WithTTL ¶
func WithTTL(ttl time.Duration) RedisOption
WithTTL sets the time-to-live for conversation states. After this duration, conversations will be automatically deleted. Default is 24 hours. Set to 0 for no expiration.
type RedisStore ¶
type RedisStore struct {
// contains filtered or unexported fields
}
RedisStore provides a Redis-backed implementation of the Store interface. It uses JSON serialization for state storage and supports automatic TTL-based cleanup. This implementation is suitable for distributed systems and production deployments.
func NewRedisStore ¶
func NewRedisStore(client *redis.Client, opts ...RedisOption) *RedisStore
NewRedisStore creates a new Redis-backed state store.
Example:
store := NewRedisStore(
redis.NewClient(&redis.Options{Addr: "localhost:6379"}),
WithTTL(24 * time.Hour),
WithPrefix("myapp"),
)
func (*RedisStore) AppendMessages ¶ added in v1.3.1
AppendMessages appends messages to the conversation's message list using RPUSH.
func (*RedisStore) Delete ¶
func (s *RedisStore) Delete(ctx context.Context, id string) error
Delete removes a conversation state from Redis.
func (*RedisStore) Fork ¶ added in v1.1.6
func (s *RedisStore) Fork(ctx context.Context, sourceID, newID string) error
Fork creates a copy of an existing conversation state with a new ID.
func (*RedisStore) List ¶
func (s *RedisStore) List(ctx context.Context, opts ListOptions) ([]string, error)
List returns conversation IDs matching the given criteria.
func (*RedisStore) Load ¶
func (s *RedisStore) Load(ctx context.Context, id string) (*ConversationState, error)
Load retrieves a conversation state by ID from Redis.
func (*RedisStore) LoadRecentMessages ¶ added in v1.3.1
func (s *RedisStore) LoadRecentMessages(ctx context.Context, id string, n int) ([]types.Message, error)
LoadRecentMessages returns the last n messages using LRANGE on the messages list. Falls back to loading from the monolithic key if the list doesn't exist.
func (*RedisStore) LoadSummaries ¶ added in v1.3.1
LoadSummaries returns all summaries for the conversation.
func (*RedisStore) MessageCount ¶ added in v1.3.1
MessageCount returns the total number of messages. Falls back to loading from the monolithic key if the list doesn't exist.
func (*RedisStore) Save ¶
func (s *RedisStore) Save(ctx context.Context, state *ConversationState) error
Save persists a conversation state to Redis with TTL.
func (*RedisStore) SaveSummary ¶ added in v1.3.1
SaveSummary appends a summary to the conversation's summary list.
type Store ¶
type Store interface {
// Load retrieves conversation state by ID
Load(ctx context.Context, id string) (*ConversationState, error)
// Save persists conversation state
Save(ctx context.Context, state *ConversationState) error
// Fork creates a copy of an existing conversation state with a new ID
// The original conversation is left unchanged. Returns ErrNotFound if sourceID doesn't exist.
Fork(ctx context.Context, sourceID, newID string) error
}
Store defines the interface for persistent conversation state storage.
type Summarizer ¶ added in v1.3.1
type Summarizer interface {
// Summarize compresses the given messages into a concise summary.
Summarize(ctx context.Context, messages []types.Message) (string, error)
}
Summarizer compresses a batch of messages into a summary string. Implementations may use LLM providers, extractive methods, or other compression strategies.
type Summary ¶
type Summary struct {
StartTurn int // First turn included in this summary
EndTurn int // Last turn included in this summary
Content string // Summarized content
TokenCount int // Token count of the summary
CreatedAt time.Time // When this summary was created
}
Summary represents a compressed version of conversation turns. Used to maintain context while reducing token count for older conversations.
type SummaryAccessor ¶ added in v1.3.1
type SummaryAccessor interface {
// LoadSummaries returns all summaries for the given conversation.
// Returns nil (not an error) if no summaries exist.
LoadSummaries(ctx context.Context, id string) ([]Summary, error)
// SaveSummary appends a summary to the conversation's summary list.
SaveSummary(ctx context.Context, id string, summary Summary) error
}
SummaryAccessor allows reading and writing summaries independently of the full state. This is an optional interface for stores that support efficient summary operations.