package agent import ( "context" "fmt" "time" "chorus.services/bzzz/internal/common/runtime" "chorus.services/bzzz/logging" ) // Runner manages the execution of the autonomous agent type Runner struct { services *runtime.RuntimeServices logger logging.Logger taskTracker runtime.SimpleTaskTracker announcer *runtime.CapabilityAnnouncer statusReporter *runtime.StatusReporter running bool } // NewRunner creates a new agent runner func NewRunner(services *runtime.RuntimeServices, logger logging.Logger) *Runner { return &Runner{ services: services, logger: logger, running: false, } } // Start begins the agent execution func (r *Runner) Start(ctx context.Context) error { if r.running { return fmt.Errorf("agent runner is already running") } r.logger.Info("🤖 Starting autonomous agent runner") // Initialize task tracker r.taskTracker = runtime.NewTaskTracker( r.services.Config.Agent.MaxTasks, r.services.Node.ID().ShortString(), r.services.PubSub, ) // Connect decision publisher to task tracker if available if r.services.DecisionPublisher != nil { r.taskTracker.SetDecisionPublisher(r.services.DecisionPublisher) r.logger.Info("📤 Task completion decisions will be published to DHT") } // Initialize capability announcer r.announcer = runtime.NewCapabilityAnnouncer( r.services.PubSub, r.services.Node.ID().ShortString(), ) // Initialize status reporter r.statusReporter = runtime.NewStatusReporter(r.services.Node) // Start background services r.startBackgroundServices() r.running = true r.logger.Info("✅ Autonomous agent runner started successfully") return nil } // Stop gracefully stops the agent execution func (r *Runner) Stop(ctx context.Context) error { if !r.running { return nil } r.logger.Info("🛑 Stopping autonomous agent runner") r.running = false // Any cleanup specific to agent execution would go here r.logger.Info("✅ Autonomous agent runner stopped") return nil } // startBackgroundServices starts all background services for the agent func (r *Runner) startBackgroundServices() { // Start availability announcements if r.taskTracker != nil { // TODO: Implement availability announcements // r.taskTracker.AnnounceAvailability() r.logger.Info("📡 Task tracker initialized") } // Announce capabilities and role if r.announcer != nil { r.announcer.AnnounceCapabilitiesOnChange(r.services) r.announcer.AnnounceRoleOnStartup(r.services) r.logger.Info("📢 Capability and role announcements completed") } // Start status reporting if r.statusReporter != nil { r.statusReporter.Start() r.logger.Info("📊 Status reporting started") } r.logger.Info("🔍 Listening for peers on local network...") r.logger.Info("📡 Ready for task coordination and meta-discussion") r.logger.Info("🎯 HMMM collaborative reasoning enabled") } // GetTaskTracker returns the task tracker for external use func (r *Runner) GetTaskTracker() runtime.SimpleTaskTracker { return r.taskTracker } // IsRunning returns whether the agent runner is currently running func (r *Runner) IsRunning() bool { return r.running } // GetServices returns the runtime services func (r *Runner) GetServices() *runtime.RuntimeServices { return r.services } // HandleTask would handle incoming tasks - placeholder for future implementation func (r *Runner) HandleTask(taskID string, taskData interface{}) error { if !r.running { return fmt.Errorf("agent runner is not running") } // Add task to tracker r.taskTracker.AddTask(taskID) r.logger.Info("📋 Started task: %s", taskID) // Placeholder for actual task processing go func() { // Simulate task processing time.Sleep(5 * time.Second) // Complete task r.taskTracker.CompleteTaskWithDecision( taskID, true, "Task completed successfully", []string{}, // No files modified in this example ) r.logger.Info("✅ Completed task: %s", taskID) }() return nil } // GetStatus returns the current agent status func (r *Runner) GetStatus() map[string]interface{} { status := map[string]interface{}{ "running": r.running, "type": "agent", "timestamp": time.Now().Unix(), } if r.taskTracker != nil { status["active_tasks"] = len(r.taskTracker.GetActiveTasks()) status["max_tasks"] = r.taskTracker.GetMaxTasks() // TODO: Implement availability and status methods status["available"] = len(r.taskTracker.GetActiveTasks()) < r.taskTracker.GetMaxTasks() status["task_status"] = "active" } if r.services != nil && r.services.Node != nil { status["node_id"] = r.services.Node.ID().ShortString() status["connected_peers"] = r.services.Node.ConnectedPeers() } if r.services != nil && r.services.Config != nil { status["agent_id"] = r.services.Config.Agent.ID status["role"] = r.services.Config.Agent.Role status["specialization"] = r.services.Config.Agent.Specialization status["capabilities"] = r.services.Config.Agent.Capabilities } return status }