feat(companion): add engine orchestrator tying all sub-engines together
This commit is contained in:
123
internal/companion/engine.go
Normal file
123
internal/companion/engine.go
Normal file
@@ -0,0 +1,123 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user