Files
DivaCode/internal/companion/engine.go

124 lines
2.8 KiB
Go

package companion
import (
"context"
"sync"
"time"
"git.db123.ir/db123/divacode/internal/config"
"git.db123.ir/db123/divacode/internal/storage"
"git.db123.ir/db123/divacode/pkg/personality"
"git.db123.ir/db123/divacode/pkg/types"
)
type PromptInput struct {
UserMessage string
RecentMessages []types.Message
Memories []string
}
type Engine struct {
mu sync.Mutex
cfg *config.Config
db *storage.DB
personality *PersonalityEngine
relationship *RelationshipEngine
reflection *ReflectionEngine
promptBuilder *PromptBuilder
mood *MoodEngine
lastContact time.Time
pendingAutoMsg string
}
func NewEngine(cfg *config.Config, db *storage.DB) *Engine {
return &Engine{
cfg: cfg,
db: db,
personality: NewPersonalityEngine(db),
relationship: NewRelationshipEngine(db),
reflection: NewReflectionEngine(db),
promptBuilder: NewPromptBuilder(cfg),
mood: NewMoodEngine(),
lastContact: time.Now(),
}
}
func (e *Engine) BuildPrompt(ctx context.Context, input *PromptInput) (string, error) {
e.mu.Lock()
defer e.mu.Unlock()
traits := e.personality.Current()
rel := e.relationship.Current()
mood := e.mood.Current()
observations := e.reflection.RecentObservations(5)
prompt := e.promptBuilder.Build(&BuildInput{
SystemPrompt: e.cfg.SystemPrompt,
Traits: traits,
Relationship: rel,
Mood: mood,
Observations: observations,
UserMessage: input.UserMessage,
Memories: input.Memories,
Messages: input.RecentMessages,
})
e.lastContact = time.Now()
return prompt, nil
}
func (e *Engine) WriteDiary(ctx context.Context) error {
e.mu.Lock()
defer e.mu.Unlock()
return e.reflection.GenerateDiary(ctx, e.lastContact)
}
func (e *Engine) Mood() types.Mood {
e.mu.Lock()
defer e.mu.Unlock()
return e.mood.Current()
}
func (e *Engine) Trust() float64 {
e.mu.Lock()
defer e.mu.Unlock()
return e.relationship.Trust()
}
func (e *Engine) LastContactDuration() time.Duration {
e.mu.Lock()
defer e.mu.Unlock()
return time.Since(e.lastContact)
}
func (e *Engine) QueueAutonomousMessage(msg string) {
e.mu.Lock()
defer e.mu.Unlock()
e.pendingAutoMsg = msg
}
func (e *Engine) PopAutonomousMessage() string {
e.mu.Lock()
defer e.mu.Unlock()
msg := e.pendingAutoMsg
e.pendingAutoMsg = ""
return msg
}
func (e *Engine) Personality() *PersonalityEngine { return e.personality }
func (e *Engine) Relationship() *RelationshipEngine { return e.relationship }
func (e *Engine) Reflection() *ReflectionEngine { return e.reflection }
type BuildInput struct {
SystemPrompt string
Traits []personality.TraitValue
Relationship *personality.RelationshipMetrics
Mood types.Mood
Observations []personality.Observation
UserMessage string
Memories []string
Messages []types.Message
}