mirror of
https://github.com/Dvorinka/Trackeep.git
synced 2026-06-03 20:12:58 +00:00
182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/trackeep/backend/models"
|
|
)
|
|
|
|
// UserContext represents the contextual data available to the AI
|
|
type UserContext struct {
|
|
Bookmarks []models.Bookmark
|
|
Tasks []models.Task
|
|
Files []models.File
|
|
Notes []models.Note
|
|
}
|
|
|
|
// buildUserContext gathers user data based on session configuration
|
|
func buildUserContext(userID uint, session models.ChatSession) (*UserContext, error) {
|
|
context := &UserContext{}
|
|
|
|
// Get bookmarks
|
|
if session.IncludeBookmarks {
|
|
var bookmarks []models.Bookmark
|
|
models.DB.Where("user_id = ?", userID).Limit(20).Order("updated_at desc").Find(&bookmarks)
|
|
context.Bookmarks = bookmarks
|
|
}
|
|
|
|
// Get tasks
|
|
if session.IncludeTasks {
|
|
var tasks []models.Task
|
|
models.DB.Where("user_id = ?", userID).Limit(20).Order("updated_at desc").Find(&tasks)
|
|
context.Tasks = tasks
|
|
}
|
|
|
|
// Get files
|
|
if session.IncludeFiles {
|
|
var files []models.File
|
|
models.DB.Where("user_id = ?", userID).Limit(20).Order("updated_at desc").Find(&files)
|
|
context.Files = files
|
|
}
|
|
|
|
// Get notes
|
|
if session.IncludeNotes {
|
|
var notes []models.Note
|
|
models.DB.Where("user_id = ?", userID).Limit(20).Order("updated_at desc").Find(¬es)
|
|
context.Notes = notes
|
|
}
|
|
|
|
return context, nil
|
|
}
|
|
|
|
// buildSystemPrompt creates a system prompt with user context
|
|
func buildSystemPrompt(context *UserContext) string {
|
|
prompt := `You are a helpful AI assistant for Trackeep, a personal productivity and knowledge management platform.
|
|
You have access to the user's personal data including bookmarks, tasks, files, and notes.
|
|
Your role is to help them organize, find information, and manage their digital life effectively.
|
|
|
|
Key capabilities:
|
|
- Help find specific bookmarks, tasks, or notes
|
|
- Suggest organization strategies
|
|
- Answer questions about their saved content
|
|
- Help with task planning and prioritization
|
|
- Assist with learning progress tracking
|
|
|
|
Be helpful, concise, and actionable. If you reference specific items, mention their titles or key details.
|
|
|
|
--- USER DATA ---`
|
|
|
|
// Add bookmarks context
|
|
if len(context.Bookmarks) > 0 {
|
|
prompt += "\n\nBOOKMARKS:\n"
|
|
for i, bookmark := range context.Bookmarks {
|
|
if i >= 10 { // Limit to prevent token overflow
|
|
prompt += "... and " + strconv.Itoa(len(context.Bookmarks)-10) + " more bookmarks\n"
|
|
break
|
|
}
|
|
prompt += fmt.Sprintf("- %s: %s", bookmark.Title, bookmark.URL)
|
|
if bookmark.Description != "" {
|
|
prompt += " (" + bookmark.Description + ")"
|
|
}
|
|
if bookmark.IsFavorite {
|
|
prompt += " ⭐"
|
|
}
|
|
prompt += "\n"
|
|
}
|
|
}
|
|
|
|
// Add tasks context
|
|
if len(context.Tasks) > 0 {
|
|
prompt += "\n\nTASKS:\n"
|
|
for i, task := range context.Tasks {
|
|
if i >= 10 {
|
|
prompt += "... and " + strconv.Itoa(len(context.Tasks)-10) + " more tasks\n"
|
|
break
|
|
}
|
|
status := string(task.Status)
|
|
priority := string(task.Priority)
|
|
prompt += fmt.Sprintf("- [%s] %s (Priority: %s)", status, task.Title, priority)
|
|
if task.DueDate != nil {
|
|
prompt += " Due: " + task.DueDate.Format("Jan 2")
|
|
}
|
|
prompt += "\n"
|
|
}
|
|
}
|
|
|
|
// Add files context
|
|
if len(context.Files) > 0 {
|
|
prompt += "\n\nFILES:\n"
|
|
for i, file := range context.Files {
|
|
if i >= 10 {
|
|
prompt += "... and " + strconv.Itoa(len(context.Files)-10) + " more files\n"
|
|
break
|
|
}
|
|
prompt += fmt.Sprintf("- %s (%s, %s)", file.OriginalName, file.FileType, formatFileSize(file.FileSize))
|
|
if file.Description != "" {
|
|
prompt += " - " + file.Description
|
|
}
|
|
prompt += "\n"
|
|
}
|
|
}
|
|
|
|
// Add notes context
|
|
if len(context.Notes) > 0 {
|
|
prompt += "\n\nNOTES:\n"
|
|
for i, note := range context.Notes {
|
|
if i >= 10 {
|
|
prompt += "... and " + strconv.Itoa(len(context.Notes)-10) + " more notes\n"
|
|
break
|
|
}
|
|
prompt += fmt.Sprintf("- %s", note.Title)
|
|
if note.Description != "" {
|
|
prompt += " - " + note.Description
|
|
}
|
|
if note.IsPinned {
|
|
prompt += " 📌"
|
|
}
|
|
prompt += "\n"
|
|
}
|
|
}
|
|
|
|
prompt += "\n--- END USER DATA ---\n\nNow respond to the user's message based on this context."
|
|
return prompt
|
|
}
|
|
|
|
// getContextItemIDs extracts IDs from context for tracking
|
|
func getContextItemIDs(context *UserContext) []string {
|
|
var ids []string
|
|
|
|
for _, bookmark := range context.Bookmarks {
|
|
ids = append(ids, "bookmark:"+strconv.Itoa(int(bookmark.ID)))
|
|
}
|
|
|
|
for _, task := range context.Tasks {
|
|
ids = append(ids, "task:"+strconv.Itoa(int(task.ID)))
|
|
}
|
|
|
|
for _, file := range context.Files {
|
|
ids = append(ids, "file:"+strconv.Itoa(int(file.ID)))
|
|
}
|
|
|
|
for _, note := range context.Notes {
|
|
ids = append(ids, "note:"+strconv.Itoa(int(note.ID)))
|
|
}
|
|
|
|
return ids
|
|
}
|
|
|
|
// formatFileSize formats file size in human readable format
|
|
func formatFileSize(bytes int64) string {
|
|
const unit = 1024
|
|
if bytes < unit {
|
|
return fmt.Sprintf("%d B", bytes)
|
|
}
|
|
div, exp := int64(unit), 0
|
|
for n := bytes / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
|
}
|