blob: f03327a013a9d388a558e246df460152a8b47cc6 [file] [log] [blame]
package server
import (
"fmt"
"log/slog"
"os"
"time"
"github.com/iomodo/staff/agent"
"github.com/iomodo/staff/config"
"github.com/iomodo/staff/git"
"github.com/iomodo/staff/tm/git_tm"
"github.com/joho/godotenv"
)
// Server type defines application global state
type Server struct {
logger *slog.Logger
manager *agent.Manager
config *config.Config
}
// NewServer creates new Server
func NewServer(logger *slog.Logger, configPath string) (*Server, error) {
_ = godotenv.Load()
// Load configuration
cfg, err := config.LoadConfigWithEnvOverrides(configPath)
if err != nil {
return nil, fmt.Errorf("failed to load config: %w", err)
}
s := &Server{
logger: logger,
config: cfg,
}
pwd, _ := os.Getwd()
s.logger.Info("Current working directory", slog.String("path", pwd))
return s, nil
}
// Start method starts the server with configured agents
func (s *Server) Start() error {
s.logger.Info("Server is starting...")
// Create task manager using config
workingDir := "."
gitInterface := git.DefaultGit(workingDir)
tasksDir := s.config.Tasks.StoragePath
taskManager := git_tm.NewGitTaskManagerWithLogger(gitInterface, tasksDir, s.logger)
// Create agent manager with config
var err error
s.manager, err = agent.NewManager(s.config, taskManager, s.logger)
if err != nil {
return fmt.Errorf("failed to create agent manager: %w", err)
}
// Start all configured agents with a default loop interval
defaultInterval := 1 * time.Second
for _, agentConfig := range s.config.Agents {
s.logger.Info("Starting agent",
slog.String("name", agentConfig.Name),
slog.String("role", agentConfig.Role),
slog.String("model", agentConfig.Model))
if err := s.manager.StartAgent(agentConfig.Name, defaultInterval); err != nil {
s.logger.Error("Failed to start agent",
slog.String("agent", agentConfig.Name),
slog.String("error", err.Error()))
continue
}
}
s.logger.Info("Server started successfully", slog.Int("agents", len(s.config.Agents)))
return nil
}
// Shutdown method shuts server down
func (s *Server) Shutdown() {
s.logger.Info("Stopping Server...")
if s.manager != nil {
if err := s.manager.Close(); err != nil {
s.logger.Error("Error closing manager", slog.String("error", err.Error()))
}
}
s.logger.Info("All agents stopped")
s.logger.Info("Server stopped")
}
// GetManager returns the agent manager instance
func (s *Server) GetManager() *agent.Manager {
return s.manager
}
// GetConfig returns the server configuration
func (s *Server) GetConfig() *config.Config {
return s.config
}