readysite / website / internal / assist / assist.go
2.3 KB
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
}
← Back