conversation

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MessageToAPI

func MessageToAPI(m Message) api.Message

func MessagesToAPI

func MessagesToAPI(messages []Message) []api.Message

Types

type Conversation

type Conversation struct {
	ID             uint `gorm:"primaryKey"`
	ShortName      sql.NullString
	Title          string
	Agent          sql.NullString
	Workspace      sql.NullString
	SelectedRootID *uint     `gorm:"index"`
	SelectedRoot   *Message  `gorm:"foreignKey:SelectedRootID"`
	RootMessages   []Message `gorm:"-:all"`
	LastMessageAt  time.Time
}

type ConversationList

type ConversationList struct {
	Total   int
	Items   []ConversationListItem
	HasMore bool
}

type ConversationListItem

type ConversationListItem struct {
	ID            uint
	ShortName     string
	Title         string
	Workspace     string
	LastMessageAt time.Time
}

type Message

type Message struct {
	ID        uint `gorm:"primaryKey"`
	CreatedAt time.Time
	Metadata  api.MessageMeta

	ConversationID  *uint         `gorm:"index"`
	Conversation    *Conversation `gorm:"foreignKey:ConversationID"`
	ParentID        *uint         `gorm:"index"`
	Parent          *Message      `gorm:"foreignKey:ParentID"`
	Replies         []Message     `gorm:"foreignKey:ParentID"`
	SelectedReplyID *uint         `gorm:"index"`
	SelectedReply   *Message      `gorm:"foreignKey:SelectedReplyID"`

	Role             api.MessageRole
	Content          string
	ReasoningContent string
	Parts            []api.ContentPart `gorm:"serializer:json-compat"`
	ToolCalls        []api.ToolCall    `gorm:"serializer:json-compat"` // a json array of tool calls (from the model)
	ToolResults      []api.ToolResult  `gorm:"serializer:json-compat"` // a json array of tool results
}

func MessageFromAPI

func MessageFromAPI(m api.Message) Message

func MessagesFromAPI

func MessagesFromAPI(messages []api.Message) []Message

func (*Message) AfterFind

func (m *Message) AfterFind(tx *gorm.DB) error

AfterFind is a GORM hook that runs after loading a Message from the database. For legacy rows that lack Parts, it builds Parts from the Content/ReasoningContent fields.

func (*Message) BeforeSave

func (m *Message) BeforeSave(tx *gorm.DB) error

BeforeSave is a GORM hook that clears the legacy Content and ReasoningContent fields before writing, so only Parts is persisted.

func (*Message) SetTextContent

func (m *Message) SetTextContent(content string)

SetTextContent updates the first text-type part, or appends one if none exists.

func (*Message) TextContent

func (m *Message) TextContent() string

TextContent returns the message's text content, extracted from text-type parts. AfterFind guarantees Parts is always populated.

func (*Message) ThinkingContent

func (m *Message) ThinkingContent() string

ThinkingContent returns the message's thinking/reasoning content, extracted from thinking-type parts. AfterFind guarantees Parts is always populated.

type Repo

type Repo interface {
	LoadConversationList(limit int) (ConversationList, error)
	SearchConversations(query string, limit int) (ConversationList, error)

	FindConversationByShortName(shortName string) (*Conversation, error)
	FindLatestConversationByWorkspace(workspace string) (*Conversation, error)
	ConversationShortNameCompletions(search string) []string
	GetConversationByID(id uint) (*Conversation, error)
	GetRootMessages(conversationID uint) ([]Message, error)

	CreateConversation(title string) (*Conversation, error)
	UpdateConversation(*Conversation) error
	DeleteConversation(id uint) error

	GetMessageByID(messageID uint) (*Message, error)

	SaveMessage(message Message) (*Message, error)
	UpdateMessage(message *Message) error
	CloneBranch(toClone Message) (*Message, uint, error)
	Reply(to *Message, messages ...Message) ([]Message, error)

	// BranchMessage creates a new message at the same position as msg (same
	// parent and conversation) with the given content, without copying any
	// descendants, and sets it as the selected path. Returns the new message.
	BranchMessage(msg Message, content string) (*Message, error)

	// BranchRootMessage creates a new root message in oldRoot's conversation
	// with the given content. The old root's selected reply is re-parented to
	// the new root and the conversation's selected root is updated. This
	// avoids mutating a shared root in-place when the system prompt changes.
	// Returns the new root message.
	BranchRootMessage(oldRoot *Message, content string) (*Message, error)

	PathToRoot(message *Message) ([]Message, error)
	PathToLeaf(message *Message) ([]Message, error)

	// GetSelectedThread returns the "selected thread" of the conversation:
	// a chain of messages starting from SelectedRoot, following each
	// message's SelectedReply until the leaf is reached.
	GetSelectedThread(*Conversation) ([]Message, error)

	// SetSelected marks message as the selected choice at its position in the
	// tree. If the message has no parent, it becomes the conversation's
	// SelectedRoot; otherwise it becomes its parent's SelectedReply.
	SetSelected(message *Message) error

	// DeleteMessage deletes the given message. If withDescendants is false,
	// its children are re-parented to the deleted message's parent (or made
	// root messages), preserving the selected path where possible. If
	// withDescendants is true, the message and all its descendants are
	// deleted, and the parent's selected reply is updated to a sibling if
	// one exists.
	DeleteMessage(msg Message, withDescendants bool) error

	// CycleSelectedRoot advances (forward=true) or retreats (forward=false)
	// the conversation's SelectedRoot among the available root messages.
	// Returns nil without error when there is only one root message.
	CycleSelectedRoot(conv *Conversation, forward bool) (*Message, error)

	// CycleSelectedReply advances or retreats the message's SelectedReply
	// among its available replies.
	// Returns nil without error when there is only one reply.
	CycleSelectedReply(message *Message, forward bool) (*Message, error)

	// StartConversation creates a new conversation with the given messages.
	StartConversation(messages ...Message) (*Conversation, []Message, error)

	CloneConversation(toClone Conversation) (*Conversation, uint, error)
}

Repo exposes message and conversation management operations.

func NewRepo

func NewRepo(db *gorm.DB) (Repo, error)

type TemplateData added in v0.7.0

type TemplateData struct {
	Date      string // current date in YYYY-MM-DD format
	Workspace string // effective workspace path (sandbox-aware)
}

TemplateData carries the variables available in system prompt templates.

Jump to

Keyboard shortcuts

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