Documentation
¶
Overview ¶
Package thread defines a Store interface and Thread entity for managing persistent, multi-conduit thread state.
A Thread holds a stable UUID, a *state.Buffer, timestamps, and a Metadata map for conduit-specific key-value pairs (e.g., external system identifiers). Metadata is always initialized as a non-nil empty map when a Thread is created via a Store, so conduits can write immediately without a nil check. The GetMetadata and SetMetadata methods provide thread-safe access to Metadata under a separate read-write lock, independent of the per-thread Lock/Unlock used for turn appending.
Store is the persistence abstraction with six methods:
- Create: generate a new Thread with a random UUID
- Get: retrieve a Thread by ID
- GetBy: retrieve the first Thread that matches a metadata key-value pair (linear scan; O(n) time, returns the thread and true on success, nil and false if no thread matches)
- Save: persist a Thread and update its UpdatedAt timestamp
- Delete: remove a Thread by ID
- List: return all stored Threads
Two Store implementations are provided:
- MemoryStore: in-memory map, ephemeral
- JSONStore: persists threads as individual .json files
Serialization enforces that delta artifacts (streaming fragments such as TextDelta, ReasoningDelta, and ToolCallDelta) are never persisted. Attempting to serialize a Thread that contains delta artifacts returns an error.
The thread/ package depends only on artifact/ and state/, keeping the dependency graph clean and cycle-free.
Package thread (serialize.go) provides JSON marshaling and unmarshaling for Thread turns and artifacts. Only non-delta artifact types can be persisted; attempts to serialize a delta artifact (TextDelta, ReasoningDelta, ToolCallDelta) return an error.
Index ¶
- type JSONStore
- type MemoryStore
- func (s *MemoryStore) Create() (*Thread, error)
- func (s *MemoryStore) Delete(id string) bool
- func (s *MemoryStore) Get(id string) (*Thread, bool)
- func (s *MemoryStore) GetBy(key, value string) (*Thread, bool)
- func (s *MemoryStore) List() ([]*Thread, error)
- func (s *MemoryStore) Save(thread *Thread) error
- type Store
- type Thread
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type JSONStore ¶
type JSONStore struct {
// contains filtered or unexported fields
}
JSONStore persists threads as individual JSON files in a directory.
func NewJSONStore ¶
NewJSONStore creates a new JSONStore backed by the given directory. The directory is created if it does not exist. Existing threads are loaded from disk into the in-memory cache.
Malformed or unreadable .json files are silently skipped during the initial directory scan. This prevents a single corrupted file from aborting startup, but means data loss for that specific thread is not reported.
func (*JSONStore) Get ¶
Get retrieves a thread by ID. If not in cache, it attempts to load from disk.
func (*JSONStore) GetBy ¶
GetBy retrieves a thread by a metadata key-value pair. It performs a linear scan over all cached threads and returns the first match.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore is an in-memory Store implementation.
func NewMemoryStore ¶
func NewMemoryStore() *MemoryStore
NewMemoryStore creates a new empty in-memory store.
func (*MemoryStore) Create ¶
func (s *MemoryStore) Create() (*Thread, error)
Create generates a new Thread with a random ID and stores it.
func (*MemoryStore) Delete ¶
func (s *MemoryStore) Delete(id string) bool
Delete removes a thread from the store.
func (*MemoryStore) Get ¶
func (s *MemoryStore) Get(id string) (*Thread, bool)
Get retrieves a thread by ID.
func (*MemoryStore) GetBy ¶
func (s *MemoryStore) GetBy(key, value string) (*Thread, bool)
GetBy retrieves a thread by a metadata key-value pair. It performs a linear scan over all threads and returns the first match.
func (*MemoryStore) List ¶
func (s *MemoryStore) List() ([]*Thread, error)
List returns all threads in the store.
func (*MemoryStore) Save ¶
func (s *MemoryStore) Save(thread *Thread) error
Save updates the thread's UpdatedAt and stores it.
type Store ¶
type Store interface {
// Create generates a new Thread with a random UUID and stores it.
Create() (*Thread, error)
// Get retrieves a Thread by ID. The second return value is false
// if the thread does not exist.
Get(id string) (*Thread, bool)
// GetBy retrieves a Thread by a metadata key-value pair.
// The second return value is false if no thread matches.
GetBy(key, value string) (*Thread, bool)
// Save persists the given Thread, updating its UpdatedAt timestamp.
Save(thread *Thread) error
// Delete removes a Thread by ID and returns true if it existed.
Delete(id string) bool
// List returns all stored Threads.
List() ([]*Thread, error)
}
Store abstracts persistence for Thread instances. Implementations must be safe for concurrent use.
type Thread ¶
type Thread struct {
// ID is the unique identifier for this thread (random UUID).
ID string
// State holds the mutable thread turn history.
// It is not safe for concurrent use; callers must hold the lock.
State *state.Buffer
// CreatedAt is set when the thread is first created.
CreatedAt time.Time
// UpdatedAt is advanced on every successful Save.
UpdatedAt time.Time
// Metadata holds arbitrary key-value pairs for conduit-specific
// thread mapping (e.g., external system identifiers).
Metadata map[string]string
// contains filtered or unexported fields
}
Thread represents a persistent thread with identity, state, and per-thread locking.
func (*Thread) GetMetadata ¶
GetMetadata retrieves a metadata value by key.
func (*Thread) Lock ¶
Lock attempts to acquire the thread lock in a non-blocking manner. Returns true if the lock was acquired, or false if the thread is already busy (another conduit holds the lock).
func (*Thread) MarshalJSON ¶
MarshalJSON serializes the thread to JSON.
func (*Thread) SetMetadata ¶
SetMetadata sets a metadata key-value pair.
func (*Thread) UnmarshalJSON ¶
UnmarshalJSON deserializes a thread from JSON.