statestore

package
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2026 License: Apache-2.0 Imports: 12 Imported by: 5

Documentation

Overview

Package statestore provides conversation state persistence and management.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidID = errors.New("invalid conversation ID")

ErrInvalidID is returned when an invalid conversation ID is provided.

View Source
var ErrInvalidState = errors.New("invalid conversation state")

ErrInvalidState is returned when a conversation state is invalid.

View Source
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).

func (*LLMSummarizer) Summarize added in v1.3.1

func (s *LLMSummarizer) Summarize(ctx context.Context, messages []types.Message) (string, error)

Summarize compresses the given messages into a concise summary.

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

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

func (s *MemoryStore) LoadSummaries(ctx context.Context, id string) ([]Summary, error)

LoadSummaries returns all summaries for the given conversation.

func (*MemoryStore) MessageCount added in v1.3.1

func (s *MemoryStore) MessageCount(ctx context.Context, id string) (int, error)

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

func (s *MemoryStore) SaveSummary(ctx context.Context, id string, summary Summary) error

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

func (s *RedisStore) AppendMessages(ctx context.Context, id string, messages []types.Message) error

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

func (s *RedisStore) LoadSummaries(ctx context.Context, id string) ([]Summary, error)

LoadSummaries returns all summaries for the conversation.

func (*RedisStore) MessageCount added in v1.3.1

func (s *RedisStore) MessageCount(ctx context.Context, id string) (int, error)

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

func (s *RedisStore) SaveSummary(ctx context.Context, id string, summary Summary) error

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL