assist.go
// Package assist provides AI conversation types and helpers.
package assist
import (
"encoding/json"
"github.com/readysite/readysite/website/models"
)
// Message roles
const (
RoleUser = "user"
RoleAssistant = "assistant"
RoleSystem = "system"
)
// Mutation actions
const (
ActionCreate = "create"
ActionUpdate = "update"
ActionDelete = "delete"
)
// ToolCall represents an AI tool invocation.
// Note: models.ToolCallItem is a view-model projection of this type for templates.
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Arguments string `json:"arguments"`
Result string `json:"result"`
Error string `json:"error,omitempty"`
}
// ConversationContext holds contextual information for AI conversations.
type ConversationContext struct {
CurrentPageID string `json:"currentPageId,omitempty"`
CurrentCollectionID string `json:"currentCollectionId,omitempty"`
SelectedElements []string `json:"selectedElements,omitempty"`
LastAction string `json:"lastAction,omitempty"`
Model string `json:"model,omitempty"` // Per-conversation model override
}
// GetToolCalls parses tool calls from a message.
func GetToolCalls(m *models.Message) ([]ToolCall, error) {
var calls []ToolCall
if m.ToolCalls == "" {
return calls, nil
}
err := json.Unmarshal([]byte(m.ToolCalls), &calls)
return calls, err
}
// SetToolCalls sets tool calls on a message.
func SetToolCalls(m *models.Message, calls []ToolCall) error {
data, err := json.Marshal(calls)
if err != nil {
return err
}
m.ToolCalls = string(data)
return nil
}
// GetContext parses context from a conversation.
func GetContext(c *models.Conversation) (*ConversationContext, error) {
var ctx ConversationContext
if c.Context == "" {
return &ctx, nil
}
err := json.Unmarshal([]byte(c.Context), &ctx)
return &ctx, err
}
// SetContext sets context on a conversation.
func SetContext(c *models.Conversation, ctx *ConversationContext) error {
data, err := json.Marshal(ctx)
if err != nil {
return err
}
c.Context = string(data)
return nil
}
// CanUndo returns true if a mutation can be undone.
func CanUndo(m *models.Mutation) bool {
return !m.Undone && m.Action != ActionDelete
}
// CanRedo returns true if a mutation can be redone.
func CanRedo(m *models.Mutation) bool {
return m.Undone
}