store

package
v2.5.1 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrConversationNotFound is returned when a conversation lookup finds no matching row.
	ErrConversationNotFound = errors.New("conversation not found")

	// ErrConversationConflict is returned when creating a conversation violates
	// the unique index on (RootPostID, BotID).
	ErrConversationConflict = errors.New("conversation already exists for this thread and bot")
)

Functions

This section is empty.

Types

type Conversation

type Conversation struct {
	ID           string  `json:"id"            db:"id"`
	UserID       string  `json:"user_id"       db:"userid"`
	BotID        string  `json:"bot_id"        db:"botid"`
	ChannelID    *string `json:"channel_id"    db:"channelid"`
	RootPostID   *string `json:"root_post_id"  db:"rootpostid"`
	Title        string  `json:"title"         db:"title"`
	SystemPrompt string  `json:"system_prompt" db:"systemprompt"`
	Operation    string  `json:"operation"     db:"operation"`
	CreatedAt    int64   `json:"created_at"    db:"createdat"`
	UpdatedAt    int64   `json:"updated_at"    db:"updatedat"`
	DeleteAt     int64   `json:"delete_at"     db:"deleteat"`
}

Conversation represents a first-class conversation entity stored in LLM_Conversations.

type ConversationSummary

type ConversationSummary struct {
	ID         string  `json:"id"           db:"id"`
	UserID     string  `json:"user_id"      db:"userid"`
	BotID      string  `json:"bot_id"       db:"botid"`
	ChannelID  *string `json:"channel_id"   db:"channelid"`
	RootPostID *string `json:"root_post_id" db:"rootpostid"`
	Title      string  `json:"title"        db:"title"`
	TurnCount  int     `json:"turn_count"   db:"turncount"`
	UpdatedAt  int64   `json:"updated_at"   db:"updatedat"`
}

ConversationSummary is a lightweight view of a conversation with its turn count, used for listing conversations in the RHS threads panel.

type Store

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

Store provides database operations for the AI plugin.

func New

func New(db *sqlx.DB) *Store

New creates a new Store from an existing sqlx.DB connection. Reuses the same connection that mmapi.NewDBClient provides.

func (*Store) CleanupDeletedConversations

func (s *Store) CleanupDeletedConversations() error

CleanupDeletedConversations permanently deletes all soft-deleted conversations and their associated turns within a single transaction.

func (*Store) CountActiveAgents

func (s *Store) CountActiveAgents() (int, error)

CountActiveAgents returns the number of non-deleted agents.

func (*Store) CreateAgent

func (s *Store) CreateAgent(cfg *llm.BotConfig) error

CreateAgent inserts a new user agent into the database. It generates the ID and sets CreateAt/UpdateAt timestamps automatically.

func (*Store) CreateConversation

func (s *Store) CreateConversation(conv *Conversation) error

CreateConversation inserts a new conversation row. The caller must set ID, UserID, BotID, CreatedAt, and UpdatedAt before calling.

func (*Store) CreateTurn

func (s *Store) CreateTurn(turn *Turn) error

CreateTurn inserts a new turn row. The caller must set ID, ConversationID, Role, Content, Sequence, and CreatedAt before calling.

func (*Store) CreateTurnAutoSequence

func (s *Store) CreateTurnAutoSequence(turn *Turn) error

CreateTurnAutoSequence inserts a new turn, atomically computing the next Sequence value via a subquery. On success the assigned sequence is written back into turn.Sequence.

Under PostgreSQL READ COMMITTED, two concurrent inserts for the same conversation can read the same MAX(Sequence) before either commits. The UNIQUE index on (ConversationID, Sequence) catches this, and the method retries (up to 3 times) so the second writer succeeds.

func (*Store) DB

func (s *Store) DB() *sqlx.DB

DB returns the underlying sqlx.DB for use in migration drivers.

func (*Store) DeleteAgent

func (s *Store) DeleteAgent(id string) error

DeleteAgent performs a soft delete by setting DeleteAt to the current timestamp.

func (*Store) DeleteResponseTurns

func (s *Store) DeleteResponseTurns(conversationID, postID string) error

DeleteResponseTurns removes the post's anchor turn and any assistant or tool_result turns between it and the originating user turn. Callers must build any completion request before calling this.

func (*Store) GetAgent

func (s *Store) GetAgent(id string) (*llm.BotConfig, error)

GetAgent retrieves a single active (non-deleted) agent by ID. Returns nil, nil if the agent does not exist or is soft-deleted.

func (*Store) GetConfig

func (s *Store) GetConfig() (*config.Config, error)

GetConfig retrieves the currently active configuration from the database. Returns nil, nil if no active config exists (e.g., fresh install before migration).

func (*Store) GetConversation

func (s *Store) GetConversation(id string) (*Conversation, error)

GetConversation retrieves a non-deleted conversation by ID. Returns ErrConversationNotFound if the conversation does not exist or is soft-deleted.

func (*Store) GetConversationByThreadBotUser

func (s *Store) GetConversationByThreadBotUser(rootPostID, botID, userID string) (*Conversation, error)

GetConversationByThreadBotUser looks up a non-deleted conversation by (RootPostID, BotID, UserID). Returns ErrConversationNotFound when no conversation exists for the given tuple.

func (*Store) GetConversationSummariesForUser

func (s *Store) GetConversationSummariesForUser(userID string, limit, offset int) ([]ConversationSummary, error)

GetConversationSummariesForUser returns conversations for a user ordered by UpdatedAt DESC, including a turn count per conversation. Only non-deleted conversations are returned.

func (*Store) GetMaxSequenceForConversation

func (s *Store) GetMaxSequenceForConversation(conversationID string) (int, error)

GetMaxSequenceForConversation returns the maximum sequence number for turns in the given conversation, or 0 if no turns exist.

func (*Store) GetSystemValue

func (s *Store) GetSystemValue(key string) (string, error)

GetSystemValue retrieves a value from the Agents_System key-value table. Returns empty string if the key does not exist.

func (*Store) GetTurnByPostID

func (s *Store) GetTurnByPostID(postID string) (*Turn, error)

GetTurnByPostID retrieves a turn by its PostID. Returns nil, nil if no turn with the given PostID exists.

func (*Store) GetTurnsForConversation

func (s *Store) GetTurnsForConversation(conversationID string) ([]Turn, error)

GetTurnsForConversation retrieves all turns for a conversation ordered by Sequence ascending. Returns an empty slice (not nil) if no turns exist.

func (*Store) IsConfigMigrated

func (s *Store) IsConfigMigrated() (bool, error)

IsConfigMigrated checks whether any active configuration exists in the database. Returns true if config has been migrated from config.json to the database.

func (*Store) ListAgents

func (s *Store) ListAgents() ([]*llm.BotConfig, error)

ListAgents returns all active (non-deleted) agents, ordered by creation time descending.

func (*Store) ListAgentsByCreator

func (s *Store) ListAgentsByCreator(creatorID string) ([]*llm.BotConfig, error)

ListAgentsByCreator returns all active agents created by the specified user.

func (*Store) RunMigrations

func (s *Store) RunMigrations() error

RunMigrations runs all pending Morph schema migrations. The caller must hold a cluster mutex before calling this method. Morph also uses a PostgreSQL advisory lock internally for additional HA safety.

func (*Store) SaveConfig

func (s *Store) SaveConfig(cfg config.Config) error

SaveConfig persists a new configuration to the database with history. The previous active config is deactivated and a new active row is inserted. All prior configs are preserved with Active = false.

func (*Store) SetSystemValue

func (s *Store) SetSystemValue(key, value string) error

SetSystemValue upserts a value in the Agents_System key-value table.

func (*Store) SoftDeleteConversation

func (s *Store) SoftDeleteConversation(id string, deleteAt int64) error

SoftDeleteConversation sets the DeleteAt timestamp on a conversation. Turns are not deleted until CleanupDeletedConversations runs.

func (*Store) UpdateAgent

func (s *Store) UpdateAgent(cfg *llm.BotConfig) error

UpdateAgent updates an existing agent's mutable fields. It sets UpdateAt automatically. The caller must supply the full agent struct (read-modify-write pattern). Does NOT update ID, CreatorID, BotUserID, CreateAt, or DeleteAt.

func (*Store) UpdateConversationRootPostID

func (s *Store) UpdateConversationRootPostID(id string, rootPostID string) error

UpdateConversationRootPostID sets the RootPostID and updates the UpdatedAt timestamp. This is used when the post ID is only known after creation (e.g., thread analysis DM posts).

func (*Store) UpdateConversationTitle

func (s *Store) UpdateConversationTitle(id, title string) error

UpdateConversationTitle updates the title and UpdatedAt timestamp of a conversation.

func (*Store) UpdateTurnContent

func (s *Store) UpdateTurnContent(id string, content json.RawMessage) error

UpdateTurnContent replaces the Content JSONB column for a specific turn.

func (*Store) UpdateTurnPostID

func (s *Store) UpdateTurnPostID(id string, postID *string) error

UpdateTurnPostID sets or clears the PostID column for a turn. The webapp's anchor lookup expects at most one assistant turn per post_id.

func (*Store) UpdateTurnTokens

func (s *Store) UpdateTurnTokens(id string, tokensIn, tokensOut int64) error

UpdateTurnTokens updates the TokensIn and TokensOut fields on a turn.

type Turn

type Turn struct {
	ID             string          `json:"id"              db:"id"`
	ConversationID string          `json:"conversation_id" db:"conversationid"`
	PostID         *string         `json:"post_id"         db:"postid"`
	Role           string          `json:"role"            db:"role"`
	Content        json.RawMessage `json:"content"         db:"content"`
	TokensIn       int64           `json:"tokens_in"       db:"tokensin"`
	TokensOut      int64           `json:"tokens_out"      db:"tokensout"`
	Sequence       int             `json:"sequence"        db:"sequence"`
	CreatedAt      int64           `json:"created_at"      db:"createdat"`
}

Turn represents a single turn in a conversation stored in LLM_Turns.

Jump to

Keyboard shortcuts

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