readysite / website / internal / assist / undo.go
2.4 KB
undo.go
package assist

import (
	"log"

	"github.com/readysite/readysite/website/models"
)

// UndoMutation reverts a mutation to its before state.
func UndoMutation(m *models.Mutation) error {
	log.Printf("[ASSIST] UndoMutation: id=%s type=%s action=%s", m.ID, m.EntityType, m.Action)

	handler, ok := GetEntityHandler(m.EntityType)
	if !ok {
		return nil // Unknown entity type, skip
	}

	switch m.Action {
	case ActionCreate:
		// Delete the created entity
		return handler.Delete(m.EntityID)
	case ActionUpdate:
		// Restore previous state
		if m.BeforeState == "" {
			return nil
		}
		return handler.Restore(m.EntityID, m.BeforeState)
	}

	return nil
}

// RedoMutation re-applies a mutation using its after state.
func RedoMutation(m *models.Mutation) error {
	log.Printf("[ASSIST] RedoMutation: id=%s type=%s action=%s", m.ID, m.EntityType, m.Action)

	if m.AfterState == "" {
		return nil
	}

	handler, ok := GetEntityHandler(m.EntityType)
	if !ok {
		return nil // Unknown entity type, skip
	}

	switch m.Action {
	case ActionCreate:
		// Re-create the entity
		return handler.Insert(m.AfterState)
	case ActionUpdate:
		// Re-apply the update
		return handler.Restore(m.EntityID, m.AfterState)
	}

	return nil
}

// UndoConversation undoes the last AI action in a conversation.
func UndoConversation(conv *models.Conversation) error {
	if conv == nil {
		return nil
	}

	messages, _ := conv.Messages()
	for i := len(messages) - 1; i >= 0; i-- {
		if messages[i].Role == RoleAssistant {
			mutations, _ := messages[i].Mutations()
			for j := len(mutations) - 1; j >= 0; j-- {
				m := mutations[j]
				if CanUndo(m) {
					if err := UndoMutation(m); err == nil {
						m.Undone = true
						models.Mutations.Update(m)
						log.Printf("[ASSIST] UndoConversation: undid mutation=%s", m.ID)
					}
				}
			}
			break
		}
	}
	return nil
}

// RedoConversation redoes undone actions in a conversation.
func RedoConversation(conv *models.Conversation) error {
	if conv == nil {
		return nil
	}

	messages, _ := conv.Messages()
	for i := len(messages) - 1; i >= 0; i-- {
		if messages[i].Role == RoleAssistant {
			mutations, _ := messages[i].Mutations()
			for _, m := range mutations {
				if CanRedo(m) {
					if err := RedoMutation(m); err == nil {
						m.Undone = false
						models.Mutations.Update(m)
						log.Printf("[ASSIST] RedoConversation: redid mutation=%s", m.ID)
					}
				}
			}
			break
		}
	}
	return nil
}
← Back