conversationstore

package
v0.1.66 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package conversationstore provides persistence for the OpenAI-compatible Conversations lifecycle endpoints.

Index

Constants

View Source
const (
	// DefaultMemoryStoreTTL bounds in-memory conversation retention by age.
	// It mirrors the OpenAI Conversations retention window (~30 days).
	DefaultMemoryStoreTTL = 30 * 24 * time.Hour
	// DefaultMemoryStoreMaxEntries bounds in-memory conversation retention by count.
	DefaultMemoryStoreMaxEntries = 10000
	// DefaultMemoryStoreMaxBytes bounds in-memory conversation retention by
	// total serialized size. Conversations grow per turn without bound, so
	// entry counts alone do not bound memory.
	DefaultMemoryStoreMaxBytes = 64 << 20
	// DefaultMemoryStoreCleanupInterval limits full expired-entry sweeps.
	DefaultMemoryStoreCleanupInterval = time.Minute
)
View Source
const (
	// DefaultPersistentStoreTTL bounds stored conversation retention in
	// persistent backends, matching the in-memory default; expired rows are
	// swept hourly.
	DefaultPersistentStoreTTL = 30 * 24 * time.Hour

	// CleanupInterval is how often persistent stores sweep expired conversations.
	CleanupInterval = 1 * time.Hour
)

Variables

View Source
var (
	// ErrNotFound indicates a requested conversation was not found.
	ErrNotFound = errors.New("conversation not found")
	// ErrItemNotFound indicates a requested item was not present in an existing
	// conversation.
	ErrItemNotFound = errors.New("conversation item not found")
	// ErrDuplicateItem indicates an append would introduce an item id already
	// present in the conversation.
	ErrDuplicateItem = errors.New("conversation item id already exists")
	// ErrMetadataLimitExceeded indicates a patch would make the final metadata
	// object exceed the OpenAI Conversations limit.
	ErrMetadataLimitExceeded = errors.New("conversation metadata limit exceeded")
)

Functions

This section is empty.

Types

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

MemoryStore keeps conversation snapshots in process memory. Data survives across requests but not process restarts.

func NewMemoryStore

func NewMemoryStore(options ...MemoryStoreOption) *MemoryStore

NewMemoryStore creates an empty in-memory conversation store. Retention is bounded by default; options can adjust or disable the bounds.

func (*MemoryStore) AppendItems

func (s *MemoryStore) AppendItems(_ context.Context, id string, items []json.RawMessage) error

AppendItems atomically appends items to an existing conversation snapshot.

func (*MemoryStore) Close

func (s *MemoryStore) Close() error

Close releases resources (no-op for memory store).

func (*MemoryStore) Create

func (s *MemoryStore) Create(_ context.Context, conversation *StoredConversation) error

Create stores a new conversation snapshot.

func (*MemoryStore) Delete

func (s *MemoryStore) Delete(_ context.Context, id string) error

Delete removes one conversation snapshot by id.

func (*MemoryStore) DeleteItem added in v0.1.58

func (s *MemoryStore) DeleteItem(_ context.Context, id, targetItemID string) (*StoredConversation, error)

DeleteItem removes one item while holding the append lock.

func (*MemoryStore) Get

Get retrieves one conversation snapshot by id.

func (*MemoryStore) MergeMetadata added in v0.1.58

func (s *MemoryStore) MergeMetadata(_ context.Context, id string, metadata map[string]string) (*StoredConversation, error)

MergeMetadata overlays metadata while holding the same lock that protects item appends, so a metadata update cannot restore a stale item slice.

type MemoryStoreOption

type MemoryStoreOption func(*MemoryStore)

MemoryStoreOption configures bounded in-memory conversation retention.

func WithMaxBytes

func WithMaxBytes(maxBytes int64) MemoryStoreOption

WithMaxBytes caps the total serialized size of stored conversations with FIFO eviction. Non-positive values disable the cap.

func WithMaxEntries

func WithMaxEntries(maxEntries int) MemoryStoreOption

WithMaxEntries caps stored conversations with FIFO eviction. Non-positive values disable the cap.

func WithTTL

func WithTTL(ttl time.Duration) MemoryStoreOption

WithTTL expires stored conversations after ttl. Non-positive values disable TTL.

type MongoDBStore

type MongoDBStore struct {
	// contains filtered or unexported fields
}

MongoDBStore persists conversation snapshots in MongoDB.

func NewMongoDBStore

func NewMongoDBStore(database *mongo.Database) (*MongoDBStore, error)

NewMongoDBStore creates collection indexes if needed and starts the hourly expired-snapshot sweep.

func (*MongoDBStore) AppendItems

func (s *MongoDBStore) AppendItems(ctx context.Context, id string, items []json.RawMessage) error

AppendItems atomically appends items to an existing, unexpired conversation. Items are stored as JSON strings, so an optimistic compare-and-swap keeps id uniqueness and the append in the same atomic operation.

func (*MongoDBStore) Close

func (s *MongoDBStore) Close() error

Close stops the cleanup loop; client lifecycle is managed by the storage layer.

func (*MongoDBStore) Create

func (s *MongoDBStore) Create(ctx context.Context, conversation *StoredConversation) error

Create stores a new conversation snapshot. An existing snapshot with the same id is only replaced when it has already expired.

func (*MongoDBStore) Delete

func (s *MongoDBStore) Delete(ctx context.Context, id string) error

Delete removes one unexpired conversation snapshot by id.

func (*MongoDBStore) DeleteExpired

func (s *MongoDBStore) DeleteExpired(ctx context.Context) error

DeleteExpired removes all expired conversation snapshots.

func (*MongoDBStore) DeleteItem added in v0.1.58

func (s *MongoDBStore) DeleteItem(ctx context.Context, id, targetItemID string) (*StoredConversation, error)

DeleteItem uses an optimistic compare-and-swap because MongoDB stores each raw item as a JSON string to preserve its exact shape.

func (*MongoDBStore) Get

Get retrieves one conversation snapshot by id.

func (*MongoDBStore) MergeMetadata added in v0.1.58

func (s *MongoDBStore) MergeMetadata(ctx context.Context, id string, metadata map[string]string) (*StoredConversation, error)

MergeMetadata uses an optimistic compare-and-swap on the serialized snapshot. Items live in a separate field, so they are never rewritten.

type Result

type Result struct {
	Store Store
}

Result holds the initialized conversation store.

func New

func New(ctx context.Context, shared storage.Storage) (*Result, error)

New creates a conversation store on the shared storage connection.

func (*Result) Close

func (r *Result) Close() error

Close releases resources held by the conversation store.

type SQLStore added in v0.1.60

type SQLStore struct {
	// contains filtered or unexported fields
}

SQLStore persists conversation snapshots in a SQL database.

func NewSQLStore added in v0.1.60

func NewSQLStore(ctx context.Context, db sqlx.DB) (*SQLStore, error)

NewSQLStore creates the conversation_snapshots table if needed and starts the hourly expired-snapshot sweep.

func (*SQLStore) AppendItems added in v0.1.60

func (s *SQLStore) AppendItems(ctx context.Context, id string, items []json.RawMessage) error

AppendItems atomically appends items to an existing, unexpired conversation, so two concurrently completing turns cannot overwrite each other's exchange.

func (*SQLStore) Close added in v0.1.60

func (s *SQLStore) Close() error

Close stops the cleanup loop; connection lifecycle is managed by the storage layer.

func (*SQLStore) Create added in v0.1.60

func (s *SQLStore) Create(ctx context.Context, conversation *StoredConversation) error

Create stores a new conversation snapshot. An existing snapshot with the same id is only replaced when it has already expired.

func (*SQLStore) Delete added in v0.1.60

func (s *SQLStore) Delete(ctx context.Context, id string) error

Delete removes one unexpired conversation snapshot by id.

func (*SQLStore) DeleteExpired added in v0.1.60

func (s *SQLStore) DeleteExpired(ctx context.Context) error

DeleteExpired removes all expired conversation snapshots.

func (*SQLStore) DeleteItem added in v0.1.60

func (s *SQLStore) DeleteItem(ctx context.Context, id, targetItemID string) (*StoredConversation, error)

DeleteItem atomically removes the first item with the requested id.

func (*SQLStore) Get added in v0.1.60

func (s *SQLStore) Get(ctx context.Context, id string) (*StoredConversation, error)

Get retrieves one conversation snapshot by id.

func (*SQLStore) MergeMetadata added in v0.1.60

func (s *SQLStore) MergeMetadata(ctx context.Context, id string, metadata map[string]string) (*StoredConversation, error)

MergeMetadata atomically overlays metadata in the snapshot JSON while leaving the independently stored item array untouched.

type Store

type Store interface {
	Create(ctx context.Context, conversation *StoredConversation) error
	Get(ctx context.Context, id string) (*StoredConversation, error)
	// MergeMetadata atomically overlays metadata without rewriting items that a
	// concurrently completing Responses turn may be appending.
	MergeMetadata(ctx context.Context, id string, metadata map[string]string) (*StoredConversation, error)
	// AppendItems atomically appends items to an existing conversation, so two
	// concurrently completing turns cannot overwrite each other's exchange the
	// way a Get-then-Update would.
	AppendItems(ctx context.Context, id string, items []json.RawMessage) error
	// DeleteItem atomically removes one item and returns the updated snapshot.
	DeleteItem(ctx context.Context, id, itemID string) (*StoredConversation, error)
	Delete(ctx context.Context, id string) error
	Close() error
}

Store defines persistence operations for the Conversations lifecycle API.

type StoredConversation

type StoredConversation struct {
	Conversation *core.Conversation `json:"conversation"`
	Items        []json.RawMessage  `json:"items,omitempty"`
	UserPath     string             `json:"user_path,omitempty"`
	RequestID    string             `json:"request_id,omitempty"`
	StoredAt     time.Time          `json:"stored_at"`
	ExpiresAt    time.Time          `json:"expires_at"`
}

StoredConversation keeps the public conversation snapshot separate from gateway-only metadata (initial items, owning user path, request id).

Jump to

Keyboard shortcuts

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