Enhance deployment system with retry functionality and improved UX

Major Improvements:
- Added retry deployment buttons in machine list for failed deployments
- Added retry button in SSH console modal footer for enhanced UX
- Enhanced deployment process with comprehensive cleanup of existing services
- Improved binary installation with password-based sudo authentication
- Updated configuration generation to include all required sections (agent, ai, network, security)
- Fixed deployment verification and error handling

Security Enhancements:
- Enhanced verifiedStopExistingServices with thorough cleanup process
- Improved binary copying with proper sudo authentication
- Added comprehensive configuration validation

UX Improvements:
- Users can retry deployments without re-running machine discovery
- Retry buttons available from both machine list and console modal
- Real-time deployment progress with detailed console output
- Clear error states with actionable retry options

Technical Changes:
- Modified ServiceDeployment.tsx with retry button components
- Enhanced api/setup_manager.go with improved deployment functions
- Updated main.go with command line argument support (--config, --setup)
- Added comprehensive zero-trust security validation system

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-08-31 10:23:27 +10:00
parent df4d98bf30
commit be761cfe20
234 changed files with 7508 additions and 38528 deletions

183
internal/agent/runner.go Normal file
View File

@@ -0,0 +1,183 @@
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 {
r.taskTracker.AnnounceAvailability()
r.logger.Info("📡 Task availability announcements started")
}
// 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()
status["available"] = r.taskTracker.IsAvailable()
status["task_status"] = r.taskTracker.GetStatus()
}
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
}