storage

package
v0.155.0 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrJobNotFound = errors.New("scheduled job not found")

ErrJobNotFound is returned by ScheduledJobStorage when a job ID is not found.

Functions

This section is empty.

Types

type ConversationMetadata

type ConversationMetadata = domain.ConversationMetadata

ConversationMetadata contains metadata about a conversation

type ConversationStorage

type ConversationStorage interface {
	// SaveConversation saves a conversation with a unique ID
	SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

	// LoadConversation loads a conversation by its ID
	LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

	// ListConversations returns a list of conversation summaries
	ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

	// DeleteConversation removes a conversation by its ID
	DeleteConversation(ctx context.Context, conversationID string) error

	// UpdateConversationMetadata updates metadata for a conversation
	UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

	// ListConversationsNeedingTitles returns conversations that need title generation
	ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

	// Close closes the storage connection
	Close() error

	// Health checks if the storage is healthy and reachable
	Health(ctx context.Context) error
}

ConversationStorage defines the interface for persistent conversation storage

type ConversationSummary

type ConversationSummary = domain.ConversationSummary

ConversationSummary contains summary information about a conversation

type D1Config added in v0.123.0

type D1Config struct {
	AccountID  string `json:"account_id" yaml:"account_id"`
	DatabaseID string `json:"database_id" yaml:"database_id"`
	APIToken   string `json:"api_token" yaml:"api_token"`
	BaseURL    string `json:"base_url,omitempty" yaml:"base_url,omitempty"`
}

D1Config contains Cloudflare D1-specific configuration. D1 is SQLite exposed over an HTTP query API, so the driver writes the same schema as SQLite but over the network instead of a local file handle.

type D1Storage added in v0.123.0

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

D1Storage implements ConversationStorage and SessionGroupStorage on top of Cloudflare D1. D1 is SQLite exposed over an HTTP query API, so this driver issues the exact same SQL as SQLiteStorage but ships it over the network via POST /accounts/{account}/d1/database/{database}/query instead of a local file handle. Timestamps are stored as UTC RFC3339 strings so ORDER BY sorts chronologically regardless of the runner's timezone and external readers get unambiguous ISO-8601 values.

func NewD1Storage added in v0.123.0

func NewD1Storage(config D1Config) (*D1Storage, error)

NewD1Storage creates a new Cloudflare D1 storage instance and ensures the schema exists (idempotent CREATE ... IF NOT EXISTS, byte-for-byte identical to the SQLite migrations).

func (*D1Storage) AppendHistory added in v0.148.0

func (s *D1Storage) AppendHistory(ctx context.Context, command string) error

AppendHistory appends a command to the shell history.

func (*D1Storage) Close added in v0.123.0

func (s *D1Storage) Close() error

Close releases resources. D1 holds no persistent connection, so this is a no-op.

func (*D1Storage) DeleteConversation added in v0.123.0

func (s *D1Storage) DeleteConversation(ctx context.Context, conversationID string) error

DeleteConversation removes a conversation by its ID.

func (*D1Storage) DeleteJob added in v0.148.0

func (s *D1Storage) DeleteJob(ctx context.Context, id string) error

DeleteJob removes a job by ID.

func (*D1Storage) DeletePlan added in v0.148.0

func (s *D1Storage) DeletePlan(ctx context.Context, id string) error

DeletePlan removes a plan by ID.

func (*D1Storage) GetSessionGroup added in v0.123.0

func (s *D1Storage) GetSessionGroup(ctx context.Context, groupKey string) (SessionGroupEntry, bool, error)

GetSessionGroup returns the entry for groupKey or (_, false, nil) if missing.

func (*D1Storage) Health added in v0.123.0

func (s *D1Storage) Health(ctx context.Context) error

Health checks that the D1 database is reachable and answering queries.

func (*D1Storage) ListConversations added in v0.123.0

func (s *D1Storage) ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

ListConversations returns a list of conversation summaries (lean: no models/tags/title fields).

func (*D1Storage) ListConversationsNeedingTitles added in v0.123.0

func (s *D1Storage) ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

ListConversationsNeedingTitles returns conversations that need title generation. It carries Model/Tags/TitleGenerated/TitleInvalidated/TitleGenerationTime (the title-generation batch path needs them) and therefore uses a dedicated mapper rather than the lean ListConversations one.

func (*D1Storage) ListJobs added in v0.148.0

func (s *D1Storage) ListJobs(ctx context.Context) ([]*domain.ScheduledJob, error)

ListJobs returns all jobs sorted by CreatedAt ascending.

func (*D1Storage) ListPlans added in v0.148.0

func (s *D1Storage) ListPlans(ctx context.Context) ([]*PlanRecord, error)

ListPlans returns all plans sorted by CreatedAt descending.

func (*D1Storage) ListSessionGroups added in v0.123.0

func (s *D1Storage) ListSessionGroups(ctx context.Context) (map[string]SessionGroupEntry, error)

ListSessionGroups returns all session-group entries.

func (*D1Storage) LoadConversation added in v0.123.0

func (s *D1Storage) LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

LoadConversation loads a conversation by its ID using the simplified schema.

func (*D1Storage) LoadHistory added in v0.148.0

func (s *D1Storage) LoadHistory(ctx context.Context, limit int) ([]string, error)

LoadHistory returns the most recent commands up to limit in chronological order; limit <= 0 returns everything.

func (*D1Storage) LoadJob added in v0.148.0

func (s *D1Storage) LoadJob(ctx context.Context, id string) (*domain.ScheduledJob, error)

LoadJob returns a job by ID.

func (*D1Storage) LoadPlan added in v0.148.0

func (s *D1Storage) LoadPlan(ctx context.Context, id string) (*PlanRecord, error)

LoadPlan returns a plan by ID.

func (*D1Storage) PutSessionGroup added in v0.123.0

func (s *D1Storage) PutSessionGroup(ctx context.Context, groupKey string, entry SessionGroupEntry) error

PutSessionGroup creates or replaces the entry for groupKey via UPSERT.

func (*D1Storage) SaveConversation added in v0.123.0

func (s *D1Storage) SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

SaveConversation saves a conversation with its entries using the simplified schema.

func (*D1Storage) SaveJob added in v0.148.0

func (s *D1Storage) SaveJob(ctx context.Context, job *domain.ScheduledJob) error

SaveJob creates or updates a scheduled job via UPSERT.

func (*D1Storage) SavePlan added in v0.148.0

func (s *D1Storage) SavePlan(ctx context.Context, plan *PlanRecord) error

SavePlan creates a plan record via UPSERT.

func (*D1Storage) UpdateConversationMetadata added in v0.123.0

func (s *D1Storage) UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

UpdateConversationMetadata updates metadata for a conversation.

type EntryLine added in v0.100.1

type EntryLine struct {
	Type  string                   `json:"type"`
	Index int                      `json:"index"`
	Entry domain.ConversationEntry `json:"entry"`
}

EntryLine represents an entry line in v2 format

type JsonlStorage added in v0.92.6

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

JsonlStorage implements ConversationStorage using JSONL files

func NewJsonlStorage added in v0.92.6

func NewJsonlStorage(config JsonlStorageConfig) (*JsonlStorage, error)

NewJsonlStorage creates a new JSONL storage instance

func (*JsonlStorage) AppendHistory added in v0.148.0

func (s *JsonlStorage) AppendHistory(_ context.Context, command string) error

AppendHistory appends a command to the shell history file.

func (*JsonlStorage) Close added in v0.92.6

func (s *JsonlStorage) Close() error

Close closes the storage (no-op for JSONL)

func (*JsonlStorage) DeleteConversation added in v0.92.6

func (s *JsonlStorage) DeleteConversation(ctx context.Context, conversationID string) error

DeleteConversation removes a conversation file

func (*JsonlStorage) DeleteJob added in v0.148.0

func (s *JsonlStorage) DeleteJob(_ context.Context, id string) error

DeleteJob removes a job by ID. Returns ErrJobNotFound if it did not exist.

func (*JsonlStorage) DeletePlan added in v0.148.0

func (s *JsonlStorage) DeletePlan(_ context.Context, id string) error

DeletePlan removes a plan by ID.

func (*JsonlStorage) GetSessionGroup added in v0.106.2

func (s *JsonlStorage) GetSessionGroup(_ context.Context, groupKey string) (SessionGroupEntry, bool, error)

GetSessionGroup returns the entry for groupKey, or (_, false, nil) if missing.

func (*JsonlStorage) Health added in v0.92.6

func (s *JsonlStorage) Health(ctx context.Context) error

Health checks if the storage is accessible

func (*JsonlStorage) ListConversations added in v0.92.6

func (s *JsonlStorage) ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

ListConversations returns a list of conversation summaries

func (*JsonlStorage) ListConversationsNeedingTitles added in v0.92.6

func (s *JsonlStorage) ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

ListConversationsNeedingTitles returns conversations that need title generation

func (*JsonlStorage) ListJobs added in v0.148.0

func (s *JsonlStorage) ListJobs(_ context.Context) ([]*domain.ScheduledJob, error)

ListJobs returns all jobs sorted by CreatedAt ascending.

func (*JsonlStorage) ListPlans added in v0.148.0

func (s *JsonlStorage) ListPlans(_ context.Context) ([]*PlanRecord, error)

ListPlans returns all plans sorted by CreatedAt descending.

func (*JsonlStorage) ListSessionGroups added in v0.106.2

func (s *JsonlStorage) ListSessionGroups(_ context.Context) (map[string]SessionGroupEntry, error)

ListSessionGroups returns all entries from the on-disk index.

func (*JsonlStorage) LoadConversation added in v0.92.6

func (s *JsonlStorage) LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

LoadConversation loads a conversation from a JSONL file Supports both v1 format (2-line: metadata + entries array) and v2 format (entry lines + trailing metadata, append-only)

func (*JsonlStorage) LoadHistory added in v0.148.0

func (s *JsonlStorage) LoadHistory(_ context.Context, limit int) ([]string, error)

LoadHistory returns the most recent commands up to limit.

func (*JsonlStorage) LoadJob added in v0.148.0

func (s *JsonlStorage) LoadJob(_ context.Context, id string) (*domain.ScheduledJob, error)

LoadJob reads a single job by ID. Returns ErrJobNotFound if the file does not exist.

func (*JsonlStorage) LoadPlan added in v0.148.0

func (s *JsonlStorage) LoadPlan(_ context.Context, id string) (*PlanRecord, error)

LoadPlan returns a plan by ID. For JSONL, the ID is the filename stem.

func (*JsonlStorage) PutSessionGroup added in v0.106.2

func (s *JsonlStorage) PutSessionGroup(_ context.Context, groupKey string, entry SessionGroupEntry) error

PutSessionGroup creates or replaces the entry for groupKey using an atomic temp-file + rename so concurrent agent subprocesses don't see a partially written file.

func (*JsonlStorage) SaveConversation added in v0.92.6

func (s *JsonlStorage) SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

SaveConversation saves a conversation to a JSONL file

func (*JsonlStorage) SaveJob added in v0.148.0

func (s *JsonlStorage) SaveJob(_ context.Context, job *domain.ScheduledJob) error

SaveJob writes the job to disk atomically as YAML.

func (*JsonlStorage) SavePlan added in v0.148.0

func (s *JsonlStorage) SavePlan(_ context.Context, plan *PlanRecord) error

SavePlan writes the plan as a markdown file named after the plan ID.

func (*JsonlStorage) UpdateConversationMetadata added in v0.92.6

func (s *JsonlStorage) UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

UpdateConversationMetadata updates only the metadata of a conversation For both v1 and v2 formats, this requires a full rewrite of the file (v2 format is used for the output regardless of input format)

type JsonlStorageConfig added in v0.92.6

type JsonlStorageConfig struct {
	Path string `json:"path" yaml:"path"`
	// PlansPath is the directory plan markdown files are stored in. When
	// empty, plans land next to the conversations directory (dir(Path)/plans).
	PlansPath string `json:"plans_path,omitempty" yaml:"plans_path,omitempty"`
}

JsonlStorageConfig contains JSONL-specific configuration

type MemoryStorage added in v0.46.0

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

MemoryStorage implements ConversationStorage using in-memory storage This allows conversation history features to work without persistent storage

func NewMemoryStorage added in v0.46.0

func NewMemoryStorage() *MemoryStorage

NewMemoryStorage creates a new in-memory storage instance

func (*MemoryStorage) AppendHistory added in v0.148.0

func (m *MemoryStorage) AppendHistory(ctx context.Context, command string) error

AppendHistory appends a command to the shell history.

func (*MemoryStorage) Close added in v0.46.0

func (m *MemoryStorage) Close() error

Close closes the storage connection (no-op for memory storage)

func (*MemoryStorage) DeleteConversation added in v0.46.0

func (m *MemoryStorage) DeleteConversation(ctx context.Context, conversationID string) error

DeleteConversation removes a conversation by its ID

func (*MemoryStorage) DeleteJob added in v0.148.0

func (m *MemoryStorage) DeleteJob(ctx context.Context, id string) error

DeleteJob removes a job by ID.

func (*MemoryStorage) DeletePlan added in v0.148.0

func (m *MemoryStorage) DeletePlan(ctx context.Context, id string) error

DeletePlan removes a plan by ID.

func (*MemoryStorage) GetSessionGroup added in v0.106.2

func (m *MemoryStorage) GetSessionGroup(_ context.Context, groupKey string) (SessionGroupEntry, bool, error)

GetSessionGroup returns the entry for groupKey or (_, false, nil) if missing.

func (*MemoryStorage) Health added in v0.46.0

func (m *MemoryStorage) Health(ctx context.Context) error

Health checks if the storage is healthy and reachable

func (*MemoryStorage) ListConversations added in v0.46.0

func (m *MemoryStorage) ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

ListConversations returns a list of conversation summaries

func (*MemoryStorage) ListConversationsNeedingTitles added in v0.46.0

func (m *MemoryStorage) ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

ListConversationsNeedingTitles returns conversations that need title generation

func (*MemoryStorage) ListJobs added in v0.148.0

func (m *MemoryStorage) ListJobs(ctx context.Context) ([]*domain.ScheduledJob, error)

ListJobs returns copies of all jobs sorted by CreatedAt ascending.

func (*MemoryStorage) ListPlans added in v0.148.0

func (m *MemoryStorage) ListPlans(ctx context.Context) ([]*PlanRecord, error)

ListPlans returns copies of all plans sorted by CreatedAt descending.

func (*MemoryStorage) ListSessionGroups added in v0.106.2

func (m *MemoryStorage) ListSessionGroups(_ context.Context) (map[string]SessionGroupEntry, error)

ListSessionGroups returns a copy of all session-group entries.

func (*MemoryStorage) LoadConversation added in v0.46.0

func (m *MemoryStorage) LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

LoadConversation loads a conversation by its ID

func (*MemoryStorage) LoadHistory added in v0.148.0

func (m *MemoryStorage) LoadHistory(ctx context.Context, limit int) ([]string, error)

LoadHistory returns the most recent commands up to limit.

func (*MemoryStorage) LoadJob added in v0.148.0

func (m *MemoryStorage) LoadJob(ctx context.Context, id string) (*domain.ScheduledJob, error)

LoadJob returns a copy of a job by ID, so callers can't mutate stored state.

func (*MemoryStorage) LoadPlan added in v0.148.0

func (m *MemoryStorage) LoadPlan(ctx context.Context, id string) (*PlanRecord, error)

LoadPlan returns a copy of a plan by ID.

func (*MemoryStorage) PutSessionGroup added in v0.106.2

func (m *MemoryStorage) PutSessionGroup(_ context.Context, groupKey string, entry SessionGroupEntry) error

PutSessionGroup creates or replaces the entry for groupKey.

func (*MemoryStorage) SaveConversation added in v0.46.0

func (m *MemoryStorage) SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

SaveConversation saves a conversation with a unique ID

func (*MemoryStorage) SaveJob added in v0.148.0

func (m *MemoryStorage) SaveJob(ctx context.Context, job *domain.ScheduledJob) error

SaveJob creates or updates a scheduled job.

func (*MemoryStorage) SavePlan added in v0.148.0

func (m *MemoryStorage) SavePlan(ctx context.Context, plan *PlanRecord) error

SavePlan creates a plan record.

func (*MemoryStorage) UpdateConversationMetadata added in v0.46.0

func (m *MemoryStorage) UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

UpdateConversationMetadata updates metadata for a conversation

type MetadataLine added in v0.100.1

type MetadataLine struct {
	Version  int                  `json:"v"`
	Type     string               `json:"type"`
	Metadata ConversationMetadata `json:"metadata"`
}

MetadataLine represents the first line in v2 format

type PlanRecord added in v0.148.0

type PlanRecord struct {
	ID        string    `json:"id" yaml:"id"`
	Title     string    `json:"title" yaml:"title"`
	Body      string    `json:"body" yaml:"body"`
	CreatedAt time.Time `json:"created_at" yaml:"created_at"`
}

PlanRecord is a stored plan-mode plan. The ID is the filename stem "<UTC stamp>-<slug>" (e.g. "2026-07-17-153000-add-auth"), identical across backends, and Body is the raw plan markdown without the title H1.

type PlanStorage added in v0.148.0

type PlanStorage interface {
	// SavePlan creates or replaces a plan record. The ID must be set by the caller.
	SavePlan(ctx context.Context, plan *PlanRecord) error

	// LoadPlan returns a plan by ID. Returns an error when the plan does not exist.
	LoadPlan(ctx context.Context, id string) (*PlanRecord, error)

	// ListPlans returns all plans sorted by CreatedAt descending.
	ListPlans(ctx context.Context) ([]*PlanRecord, error)

	// DeletePlan removes a plan by ID. Returns an error when the plan does not exist.
	DeletePlan(ctx context.Context, id string) error
}

PlanStorage defines the interface for persisting plan-mode plans.

type PostgresConfig

type PostgresConfig struct {
	Host     string `json:"host" yaml:"host"`
	Port     int    `json:"port" yaml:"port"`
	Database string `json:"database" yaml:"database"`
	Username string `json:"username" yaml:"username"`
	Password string `json:"password" yaml:"password"`
	SSLMode  string `json:"ssl_mode" yaml:"ssl_mode"`
}

PostgresConfig contains Postgres-specific configuration

type PostgresStorage

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

PostgresStorage implements ConversationStorage on top of the shared sqlStore core. It speaks the same single-table schema as SQLite/D1 (see #839); only the placeholder style differs, which sqlStore.rebind normalizes.

func NewPostgresStorage

func NewPostgresStorage(config PostgresConfig) (*PostgresStorage, error)

NewPostgresStorage creates a new PostgreSQL storage instance

func (PostgresStorage) AppendHistory added in v0.148.0

func (s PostgresStorage) AppendHistory(ctx context.Context, command string) error

AppendHistory appends a command to the shell history log.

func (PostgresStorage) Close

func (s PostgresStorage) Close() error

Close closes the database connection.

func (PostgresStorage) DB added in v0.93.0

func (s PostgresStorage) DB() *sql.DB

DB returns the underlying database connection.

func (PostgresStorage) DeleteConversation

func (s PostgresStorage) DeleteConversation(ctx context.Context, conversationID string) error

DeleteConversation removes a conversation by its ID.

func (PostgresStorage) DeleteJob added in v0.148.0

func (s PostgresStorage) DeleteJob(ctx context.Context, id string) error

DeleteJob removes a job by ID. Returns ErrJobNotFound when the job does not exist.

func (PostgresStorage) DeletePlan added in v0.148.0

func (s PostgresStorage) DeletePlan(ctx context.Context, id string) error

DeletePlan removes a plan by ID.

func (PostgresStorage) GetSessionGroup added in v0.106.2

func (s PostgresStorage) GetSessionGroup(ctx context.Context, groupKey string) (SessionGroupEntry, bool, error)

GetSessionGroup returns the entry for groupKey or (_, false, nil) if missing.

func (PostgresStorage) Health

func (s PostgresStorage) Health(ctx context.Context) error

Health checks if the database is reachable and functional.

func (PostgresStorage) ListConversations

func (s PostgresStorage) ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

ListConversations returns a list of conversation summaries.

func (PostgresStorage) ListConversationsNeedingTitles added in v0.46.0

func (s PostgresStorage) ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

ListConversationsNeedingTitles returns conversations that need title generation.

func (PostgresStorage) ListJobs added in v0.148.0

func (s PostgresStorage) ListJobs(ctx context.Context) ([]*domain.ScheduledJob, error)

ListJobs returns all jobs sorted by CreatedAt ascending.

func (PostgresStorage) ListPlans added in v0.148.0

func (s PostgresStorage) ListPlans(ctx context.Context) ([]*PlanRecord, error)

ListPlans returns all plans sorted by CreatedAt descending.

func (PostgresStorage) ListSessionGroups added in v0.106.2

func (s PostgresStorage) ListSessionGroups(ctx context.Context) (map[string]SessionGroupEntry, error)

ListSessionGroups returns all session-group entries.

func (PostgresStorage) LoadConversation

func (s PostgresStorage) LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

LoadConversation loads a conversation by its ID.

func (PostgresStorage) LoadHistory added in v0.148.0

func (s PostgresStorage) LoadHistory(ctx context.Context, limit int) ([]string, error)

LoadHistory returns the most recent commands up to limit in chronological order; limit <= 0 returns everything.

func (PostgresStorage) LoadJob added in v0.148.0

func (s PostgresStorage) LoadJob(ctx context.Context, id string) (*domain.ScheduledJob, error)

LoadJob returns a job by ID. Returns ErrJobNotFound when the job does not exist.

func (PostgresStorage) LoadPlan added in v0.148.0

func (s PostgresStorage) LoadPlan(ctx context.Context, id string) (*PlanRecord, error)

LoadPlan returns a plan by ID.

func (PostgresStorage) PutSessionGroup added in v0.106.2

func (s PostgresStorage) PutSessionGroup(ctx context.Context, groupKey string, entry SessionGroupEntry) error

PutSessionGroup creates or replaces the entry for groupKey via UPSERT.

func (PostgresStorage) SaveConversation

func (s PostgresStorage) SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

SaveConversation saves a conversation with its entries using the single-table schema (messages are stored as an embedded JSON blob).

func (PostgresStorage) SaveJob added in v0.148.0

func (s PostgresStorage) SaveJob(ctx context.Context, job *domain.ScheduledJob) error

SaveJob creates or updates a scheduled job via UPSERT.

func (PostgresStorage) SavePlan added in v0.148.0

func (s PostgresStorage) SavePlan(ctx context.Context, plan *PlanRecord) error

SavePlan creates a plan record via UPSERT.

func (PostgresStorage) UpdateConversationMetadata

func (s PostgresStorage) UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

UpdateConversationMetadata updates metadata for a conversation.

type RedisConfig

type RedisConfig struct {
	Host     string `json:"host" yaml:"host"`
	Port     int    `json:"port" yaml:"port"`
	Database int    `json:"database" yaml:"database"`
	Password string `json:"password,omitempty" yaml:"password,omitempty"`
	Username string `json:"username,omitempty" yaml:"username,omitempty"`
	TTL      int    `json:"ttl,omitempty" yaml:"ttl,omitempty"` // TTL in seconds, 0 means no expiration
}

RedisConfig contains Redis-specific configuration

type RedisStorage

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

RedisStorage implements ConversationStorage using Redis

func NewRedisStorage

func NewRedisStorage(config RedisConfig) (*RedisStorage, error)

NewRedisStorage creates a new Redis storage instance

func (*RedisStorage) AppendHistory added in v0.148.0

func (s *RedisStorage) AppendHistory(ctx context.Context, command string) error

AppendHistory appends a command to the shell history list.

func (*RedisStorage) Close

func (s *RedisStorage) Close() error

Close closes the Redis connection

func (*RedisStorage) DeleteConversation

func (s *RedisStorage) DeleteConversation(ctx context.Context, conversationID string) error

DeleteConversation removes a conversation by its ID

func (*RedisStorage) DeleteJob added in v0.148.0

func (s *RedisStorage) DeleteJob(ctx context.Context, id string) error

DeleteJob removes a job by ID.

func (*RedisStorage) DeletePlan added in v0.148.0

func (s *RedisStorage) DeletePlan(ctx context.Context, id string) error

DeletePlan removes a plan by ID.

func (*RedisStorage) GetSessionGroup added in v0.106.2

func (s *RedisStorage) GetSessionGroup(ctx context.Context, groupKey string) (SessionGroupEntry, bool, error)

GetSessionGroup returns the entry for groupKey or (_, false, nil) if missing.

func (*RedisStorage) Health

func (s *RedisStorage) Health(ctx context.Context) error

Health checks if Redis is reachable and functional

func (*RedisStorage) ListConversations

func (s *RedisStorage) ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

ListConversations returns a list of conversation summaries

func (*RedisStorage) ListConversationsNeedingTitles added in v0.46.0

func (s *RedisStorage) ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

ListConversationsNeedingTitles returns conversations that need title generation

func (*RedisStorage) ListJobs added in v0.148.0

func (s *RedisStorage) ListJobs(ctx context.Context) ([]*domain.ScheduledJob, error)

ListJobs returns all jobs sorted by CreatedAt ascending.

func (*RedisStorage) ListPlans added in v0.148.0

func (s *RedisStorage) ListPlans(ctx context.Context) ([]*PlanRecord, error)

ListPlans returns all plans sorted by CreatedAt descending.

func (*RedisStorage) ListSessionGroups added in v0.106.2

func (s *RedisStorage) ListSessionGroups(ctx context.Context) (map[string]SessionGroupEntry, error)

ListSessionGroups returns all entries from the session-groups hash.

func (*RedisStorage) LoadConversation

func (s *RedisStorage) LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

LoadConversation loads a conversation by its ID

func (*RedisStorage) LoadHistory added in v0.148.0

func (s *RedisStorage) LoadHistory(ctx context.Context, limit int) ([]string, error)

LoadHistory returns the most recent commands up to limit.

func (*RedisStorage) LoadJob added in v0.148.0

func (s *RedisStorage) LoadJob(ctx context.Context, id string) (*domain.ScheduledJob, error)

LoadJob returns a job by ID.

func (*RedisStorage) LoadPlan added in v0.148.0

func (s *RedisStorage) LoadPlan(ctx context.Context, id string) (*PlanRecord, error)

LoadPlan returns a plan by ID.

func (*RedisStorage) PutSessionGroup added in v0.106.2

func (s *RedisStorage) PutSessionGroup(ctx context.Context, groupKey string, entry SessionGroupEntry) error

PutSessionGroup creates or replaces the entry for groupKey via an atomic HSET. If a TTL is configured for this Redis backend, the TTL is refreshed on the parent hash so the index doesn't outlive the conversation data.

func (*RedisStorage) SaveConversation

func (s *RedisStorage) SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

SaveConversation saves a conversation with its entries

func (*RedisStorage) SaveJob added in v0.148.0

func (s *RedisStorage) SaveJob(ctx context.Context, job *domain.ScheduledJob) error

SaveJob creates or updates a scheduled job. The configured conversation TTL deliberately does not apply - a scheduled job must not silently expire.

func (*RedisStorage) SavePlan added in v0.148.0

func (s *RedisStorage) SavePlan(ctx context.Context, plan *PlanRecord) error

SavePlan creates a plan record. The configured conversation TTL deliberately does not apply - plans are an audit trail and must not silently expire.

func (*RedisStorage) UpdateConversationMetadata

func (s *RedisStorage) UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

UpdateConversationMetadata updates metadata for a conversation

type SQLiteConfig

type SQLiteConfig struct {
	Path string `json:"path" yaml:"path"`
}

SQLiteConfig contains SQLite-specific configuration

type SQLiteStorage

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

SQLiteStorage implements ConversationStorage on top of the shared sqlStore core, backed by a local pure-Go SQLite file.

func NewSQLiteStorage

func NewSQLiteStorage(config SQLiteConfig) (*SQLiteStorage, error)

NewSQLiteStorage creates a new SQLite storage instance.

func (SQLiteStorage) AppendHistory added in v0.148.0

func (s SQLiteStorage) AppendHistory(ctx context.Context, command string) error

AppendHistory appends a command to the shell history log.

func (SQLiteStorage) Close

func (s SQLiteStorage) Close() error

Close closes the database connection.

func (SQLiteStorage) DB added in v0.93.0

func (s SQLiteStorage) DB() *sql.DB

DB returns the underlying database connection.

func (SQLiteStorage) DeleteConversation

func (s SQLiteStorage) DeleteConversation(ctx context.Context, conversationID string) error

DeleteConversation removes a conversation by its ID.

func (SQLiteStorage) DeleteJob added in v0.148.0

func (s SQLiteStorage) DeleteJob(ctx context.Context, id string) error

DeleteJob removes a job by ID. Returns ErrJobNotFound when the job does not exist.

func (SQLiteStorage) DeletePlan added in v0.148.0

func (s SQLiteStorage) DeletePlan(ctx context.Context, id string) error

DeletePlan removes a plan by ID.

func (SQLiteStorage) GetSessionGroup added in v0.106.2

func (s SQLiteStorage) GetSessionGroup(ctx context.Context, groupKey string) (SessionGroupEntry, bool, error)

GetSessionGroup returns the entry for groupKey or (_, false, nil) if missing.

func (SQLiteStorage) Health

func (s SQLiteStorage) Health(ctx context.Context) error

Health checks if the database is reachable and functional.

func (SQLiteStorage) ListConversations

func (s SQLiteStorage) ListConversations(ctx context.Context, limit, offset int) ([]ConversationSummary, error)

ListConversations returns a list of conversation summaries.

func (SQLiteStorage) ListConversationsNeedingTitles added in v0.46.0

func (s SQLiteStorage) ListConversationsNeedingTitles(ctx context.Context, limit int) ([]ConversationSummary, error)

ListConversationsNeedingTitles returns conversations that need title generation.

func (SQLiteStorage) ListJobs added in v0.148.0

func (s SQLiteStorage) ListJobs(ctx context.Context) ([]*domain.ScheduledJob, error)

ListJobs returns all jobs sorted by CreatedAt ascending.

func (SQLiteStorage) ListPlans added in v0.148.0

func (s SQLiteStorage) ListPlans(ctx context.Context) ([]*PlanRecord, error)

ListPlans returns all plans sorted by CreatedAt descending.

func (SQLiteStorage) ListSessionGroups added in v0.106.2

func (s SQLiteStorage) ListSessionGroups(ctx context.Context) (map[string]SessionGroupEntry, error)

ListSessionGroups returns all session-group entries.

func (SQLiteStorage) LoadConversation

func (s SQLiteStorage) LoadConversation(ctx context.Context, conversationID string) ([]domain.ConversationEntry, ConversationMetadata, error)

LoadConversation loads a conversation by its ID.

func (SQLiteStorage) LoadHistory added in v0.148.0

func (s SQLiteStorage) LoadHistory(ctx context.Context, limit int) ([]string, error)

LoadHistory returns the most recent commands up to limit in chronological order; limit <= 0 returns everything.

func (SQLiteStorage) LoadJob added in v0.148.0

func (s SQLiteStorage) LoadJob(ctx context.Context, id string) (*domain.ScheduledJob, error)

LoadJob returns a job by ID. Returns ErrJobNotFound when the job does not exist.

func (SQLiteStorage) LoadPlan added in v0.148.0

func (s SQLiteStorage) LoadPlan(ctx context.Context, id string) (*PlanRecord, error)

LoadPlan returns a plan by ID.

func (SQLiteStorage) PutSessionGroup added in v0.106.2

func (s SQLiteStorage) PutSessionGroup(ctx context.Context, groupKey string, entry SessionGroupEntry) error

PutSessionGroup creates or replaces the entry for groupKey via UPSERT.

func (SQLiteStorage) SaveConversation

func (s SQLiteStorage) SaveConversation(ctx context.Context, conversationID string, entries []domain.ConversationEntry, metadata ConversationMetadata) error

SaveConversation saves a conversation with its entries using the single-table schema (messages are stored as an embedded JSON blob).

func (SQLiteStorage) SaveJob added in v0.148.0

func (s SQLiteStorage) SaveJob(ctx context.Context, job *domain.ScheduledJob) error

SaveJob creates or updates a scheduled job via UPSERT.

func (SQLiteStorage) SavePlan added in v0.148.0

func (s SQLiteStorage) SavePlan(ctx context.Context, plan *PlanRecord) error

SavePlan creates a plan record via UPSERT.

func (SQLiteStorage) UpdateConversationMetadata

func (s SQLiteStorage) UpdateConversationMetadata(ctx context.Context, conversationID string, metadata ConversationMetadata) error

UpdateConversationMetadata updates metadata for a conversation.

type ScheduledJobStorage added in v0.148.0

type ScheduledJobStorage interface {
	// SaveJob creates or updates a scheduled job.
	SaveJob(ctx context.Context, job *domain.ScheduledJob) error

	// LoadJob returns a job by ID. Returns ErrJobNotFound when the job does not exist.
	LoadJob(ctx context.Context, id string) (*domain.ScheduledJob, error)

	// ListJobs returns all jobs sorted by CreatedAt ascending.
	ListJobs(ctx context.Context) ([]*domain.ScheduledJob, error)

	// DeleteJob removes a job by ID. Returns ErrJobNotFound when the job does not exist.
	DeleteJob(ctx context.Context, id string) error
}

ScheduledJobStorage defines the interface for persisting scheduled jobs. Implementations must be safe for concurrent access. Change notification is the consumer's job: the scheduler polls ListJobs and diffs (see internal/services/scheduler).

type SessionGroupEntry added in v0.106.2

type SessionGroupEntry struct {
	CurrentSessionID string    `json:"current_session_id"`
	History          []string  `json:"history,omitempty"`
	LastRollover     time.Time `json:"last_rollover,omitempty"`
	UpdatedAt        time.Time `json:"updated_at"`
}

SessionGroupEntry tracks the active session for a given group key plus a rollover history so old conversations can still be looked up via `infer conversations list`.

type SessionGroupStorage added in v0.106.2

type SessionGroupStorage interface {
	// GetSessionGroup returns the entry for groupKey. The bool is false when
	// no entry exists; the error is non-nil only on storage failure.
	GetSessionGroup(ctx context.Context, groupKey string) (SessionGroupEntry, bool, error)

	// PutSessionGroup creates or replaces the entry for groupKey atomically.
	PutSessionGroup(ctx context.Context, groupKey string, entry SessionGroupEntry) error

	// ListSessionGroups returns all entries keyed by their group key. Used by
	// administrative tooling and tests.
	ListSessionGroups(ctx context.Context) (map[string]SessionGroupEntry, error)
}

SessionGroupStorage defines the interface for persisting the session-group index that maps a stable channel/sender key (e.g. "channel-telegram-12345") to the current conversation session UUID for that key.

func NewMemorySessionGroupStorage added in v0.106.2

func NewMemorySessionGroupStorage() SessionGroupStorage

NewMemorySessionGroupStorage returns an in-memory SessionGroupStorage. Used as a fallback when conversation storage is disabled but the rollover manager still needs somewhere to keep group state for the lifetime of the process.

type ShellHistoryStorage added in v0.148.0

type ShellHistoryStorage interface {
	// AppendHistory appends a command to the history log.
	AppendHistory(ctx context.Context, command string) error

	// LoadHistory returns the most recent commands up to limit.
	LoadHistory(ctx context.Context, limit int) ([]string, error)
}

ShellHistoryStorage defines the interface for persisting shell command history.

type StorageConfig

type StorageConfig struct {
	// Type specifies the storage backend type (see config.StorageType* constants)
	Type config.StorageType `json:"type" yaml:"type"`

	// SQLite specific configuration
	SQLite SQLiteConfig `json:"sqlite,omitempty" yaml:"sqlite,omitempty"`

	// Postgres specific configuration
	Postgres PostgresConfig `json:"postgres,omitempty" yaml:"postgres,omitempty"`

	// Redis specific configuration
	Redis RedisConfig `json:"redis,omitempty" yaml:"redis,omitempty"`

	// JSONL specific configuration
	Jsonl JsonlStorageConfig `json:"jsonl,omitempty" yaml:"jsonl,omitempty"`

	// D1 specific configuration
	D1 D1Config `json:"d1,omitempty" yaml:"d1,omitempty"`
}

StorageConfig contains configuration for storage backends

func NewStorageFromConfig added in v0.46.0

func NewStorageFromConfig(cfg *config.Config) StorageConfig

NewStorageFromConfig creates a storage configuration from app config

type Stores added in v0.148.0

type Stores struct {
	Conversations ConversationStorage
	SessionGroups SessionGroupStorage
	ScheduledJobs ScheduledJobStorage
	Plans         PlanStorage
	ShellHistory  ShellHistoryStorage
}

Stores is the aggregate returned by NewStorage, holding all storage backends.

func NewStorage

func NewStorage(config StorageConfig) (*Stores, error)

NewStorage creates a new storage instance based on the provided configuration

type TrailingMetaLine added in v0.100.1

type TrailingMetaLine struct {
	Type     string               `json:"type"`
	Metadata ConversationMetadata `json:"metadata"`
}

TrailingMetaLine represents a metadata line without version (used after entries)

type V2EntryLine added in v0.100.1

type V2EntryLine struct {
	Version int                      `json:"v,omitempty"`
	Type    string                   `json:"type"`
	Index   int                      `json:"index"`
	Entry   domain.ConversationEntry `json:"entry"`
}

V2EntryLine represents an entry line in v2 format (first entry has version)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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