context.go
package assist
import (
"sort"
"github.com/readysite/readysite/website/models"
)
// MaxNotesInContext is the maximum number of notes to include in AI context.
const MaxNotesInContext = 10
// noteScore represents a note with its relevance score.
type noteScore struct {
note *models.Note
score int
}
// SelectRelevantNotes returns the most relevant notes for the AI context.
// Notes are scored by category match with current context and recency.
func SelectRelevantNotes(ctx *ConversationContext, maxNotes int) []*models.Note {
if maxNotes <= 0 {
maxNotes = MaxNotesInContext
}
// Get all active notes
notes, err := models.Notes.Search("WHERE Active = true ORDER BY UpdatedAt DESC")
if err != nil || len(notes) == 0 {
return nil
}
// If we have fewer notes than the limit, return all
if len(notes) <= maxNotes {
return notes
}
// Score each note based on relevance
scored := make([]noteScore, len(notes))
for i, note := range notes {
scored[i] = noteScore{
note: note,
score: scoreNote(note, ctx),
}
}
// Sort by score descending
sort.Slice(scored, func(i, j int) bool {
return scored[i].score > scored[j].score
})
// Return top notes
result := make([]*models.Note, maxNotes)
for i := 0; i < maxNotes; i++ {
result[i] = scored[i].note
}
return result
}
// scoreNote calculates a relevance score for a note.
// Higher scores indicate more relevant notes.
func scoreNote(note *models.Note, ctx *ConversationContext) int {
score := 0
// Base score for being active
score += 10
// Preference notes are always relevant
if note.Type == models.NoteTypePreference {
score += 20
}
// Convention notes are generally relevant
if note.Type == models.NoteTypeConvention {
score += 15
}
// Learned patterns add some value
if note.Type == models.NoteTypeLearned {
score += 10
}
// Category-based scoring
if ctx != nil {
// If working on a page, content and style notes are more relevant
if ctx.CurrentPageID != "" {
if note.Category == models.NoteCategoryContent {
score += 15
}
if note.Category == models.NoteCategoryStyle {
score += 15
}
}
// If working on a collection, structure notes are more relevant
if ctx.CurrentCollectionID != "" {
if note.Category == models.NoteCategoryStructure {
score += 15
}
}
}
// User-created notes are slightly more important than AI-learned ones
if note.Source == models.NoteSourceUser {
score += 5
}
return score
}
// GetActiveNotes returns all active notes.
func GetActiveNotes() []*models.Note {
notes, _ := models.Notes.Search("WHERE Active = true ORDER BY UpdatedAt DESC")
return notes
}
// GetNotesByType returns active notes of a specific type.
func GetNotesByType(noteType string) []*models.Note {
notes, _ := models.Notes.Search("WHERE Active = true AND Type = ? ORDER BY UpdatedAt DESC", noteType)
return notes
}
// GetNotesByCategory returns active notes of a specific category.
func GetNotesByCategory(category string) []*models.Note {
notes, _ := models.Notes.Search("WHERE Active = true AND Category = ? ORDER BY UpdatedAt DESC", category)
return notes
}