Update with log/slog logging
Change-Id: Ie86d7082bb50576fdfbd898c44bd2905e389c399
diff --git a/server/agent/manager.go b/server/agent/manager.go
index 45b0965..88bfe21 100644
--- a/server/agent/manager.go
+++ b/server/agent/manager.go
@@ -3,7 +3,7 @@
import (
"context"
"fmt"
- "log"
+ "log/slog"
"os"
"os/exec"
"path/filepath"
@@ -30,16 +30,21 @@
subtaskService *subtasks.SubtaskService
isRunning map[string]bool
stopChannels map[string]chan struct{}
+ logger *slog.Logger
}
// NewManager creates a new agent manager
-func NewManager(cfg *config.Config, taskManager tm.TaskManager) (*Manager, error) {
+func NewManager(cfg *config.Config, taskManager tm.TaskManager, logger *slog.Logger) (*Manager, error) {
+ if logger == nil {
+ logger = slog.Default()
+ }
// Create auto-assigner
autoAssigner := assignment.NewAutoAssigner(cfg.Agents)
// Create GitHub PR provider
githubConfig := git.GitHubConfig{
- Token: cfg.GitHub.Token,
+ Token: cfg.GitHub.Token,
+ Logger: logger,
}
prProvider := git.NewGitHubPullRequestProvider(cfg.GitHub.Owner, cfg.GitHub.Repo, githubConfig)
@@ -57,6 +62,7 @@
cloneManager: cloneManager,
isRunning: make(map[string]bool),
stopChannels: make(map[string]chan struct{}),
+ logger: logger,
}
// Initialize agents
@@ -111,6 +117,7 @@
m.config.GitHub.Owner,
m.config.GitHub.Repo,
m.cloneManager,
+ m.logger,
)
return nil
@@ -177,7 +184,10 @@
go m.runAgentLoop(agent, loopInterval, stopChan)
- log.Printf("Started agent %s (%s) with %s model", agentName, agent.Role, agent.Model)
+ m.logger.Info("Started agent",
+ slog.String("name", agentName),
+ slog.String("role", agent.Role),
+ slog.String("model", agent.Model))
return nil
}
@@ -191,7 +201,7 @@
delete(m.stopChannels, agentName)
m.isRunning[agentName] = false
- log.Printf("Stopped agent %s", agentName)
+ m.logger.Info("Stopped agent", slog.String("name", agentName))
return nil
}
@@ -203,11 +213,13 @@
for {
select {
case <-stopChan:
- log.Printf("Agent %s stopping", agent.Name)
+ m.logger.Info("Agent stopping", slog.String("name", agent.Name))
return
case <-ticker.C:
if err := m.processAgentTasks(agent); err != nil {
- log.Printf("Error processing tasks for agent %s: %v", agent.Name, err)
+ m.logger.Error("Error processing tasks for agent",
+ slog.String("agent", agent.Name),
+ slog.String("error", err.Error()))
}
}
}
@@ -225,16 +237,22 @@
return fmt.Errorf("failed to get tasks for agent %s: %w", agent.Name, err)
}
- log.Printf("Processing %d tasks for agent %s", len(tasks), agent.Name)
+ m.logger.Info("Processing tasks for agent",
+ slog.Int("task_count", len(tasks)),
+ slog.String("agent", agent.Name))
for _, task := range tasks {
if task.Status == tm.StatusToDo || task.Status == tm.StatusPending {
if err := m.processTask(agent, task); err != nil {
- log.Printf("Error processing task %s: %v", task.ID, err)
+ m.logger.Error("Error processing task",
+ slog.String("task_id", task.ID),
+ slog.String("error", err.Error()))
// Mark task as failed
task.Status = tm.StatusFailed
if err := m.taskManager.UpdateTask(task); err != nil {
- log.Printf("Error updating failed task %s: %v", task.ID, err)
+ m.logger.Error("Error updating failed task",
+ slog.String("task_id", task.ID),
+ slog.String("error", err.Error()))
}
agent.Stats.TasksFailed++
} else {
@@ -256,7 +274,10 @@
ctx := context.Background()
startTime := time.Now()
- log.Printf("Agent %s processing task %s: %s", agent.Name, task.ID, task.Title)
+ m.logger.Info("Agent processing task",
+ slog.String("agent", agent.Name),
+ slog.String("task_id", task.ID),
+ slog.String("title", task.Title))
// Mark task as in progress
task.Status = tm.StatusInProgress
@@ -267,9 +288,11 @@
// Check if this task should generate subtasks (with LLM decision)
if m.shouldGenerateSubtasks(task) {
- log.Printf("LLM determined task %s should generate subtasks", task.ID)
+ m.logger.Info("LLM determined task should generate subtasks", slog.String("task_id", task.ID))
if err := m.generateSubtasksForTask(ctx, task); err != nil {
- log.Printf("Warning: Failed to generate subtasks for task %s: %v", task.ID, err)
+ m.logger.Warn("Failed to generate subtasks for task",
+ slog.String("task_id", task.ID),
+ slog.String("error", err.Error()))
// Continue with normal processing if subtask generation fails
} else {
// Task has been converted to subtask management, mark as completed
@@ -283,7 +306,9 @@
return fmt.Errorf("failed to update task with subtasks: %w", err)
}
- log.Printf("Task %s converted to subtasks by agent %s using LLM analysis", task.ID, agent.Name)
+ m.logger.Info("Task converted to subtasks by agent using LLM analysis",
+ slog.String("task_id", task.ID),
+ slog.String("agent", agent.Name))
return nil
}
}
@@ -326,7 +351,11 @@
agent.Stats.AvgTime = (agent.Stats.AvgTime + duration.Milliseconds()) / 2
}
- log.Printf("Task %s completed by agent %s in %v. PR: %s", task.ID, agent.Name, duration, prURL)
+ m.logger.Info("Task completed by agent",
+ slog.String("task_id", task.ID),
+ slog.String("agent", agent.Name),
+ slog.Duration("duration", duration),
+ slog.String("pr_url", prURL))
return nil
}
@@ -415,11 +444,15 @@
return fmt.Errorf("failed to get agent clone: %w", err)
}
- log.Printf("Agent %s working in clone: %s", agent.Name, clonePath)
+ m.logger.Info("Agent working in clone",
+ slog.String("agent", agent.Name),
+ slog.String("clone_path", clonePath))
// Refresh the clone with latest changes
if err := m.cloneManager.RefreshAgentClone(agent.Name); err != nil {
- log.Printf("Warning: Failed to refresh clone for agent %s: %v", agent.Name, err)
+ m.logger.Warn("Failed to refresh clone for agent",
+ slog.String("agent", agent.Name),
+ slog.String("error", err.Error()))
}
// All Git operations use the agent's clone directory
@@ -490,7 +523,9 @@
return fmt.Errorf("failed to push branch: %w", err)
}
- log.Printf("Agent %s successfully pushed branch %s", agent.Name, branchName)
+ m.logger.Info("Agent successfully pushed branch",
+ slog.String("agent", agent.Name),
+ slog.String("branch", branchName))
return nil
}
@@ -583,7 +618,10 @@
}
explanation := m.autoAssigner.GetRecommendationExplanation(task, agentName)
- log.Printf("Auto-assigned task %s to %s: %s", taskID, agentName, explanation)
+ m.logger.Info("Auto-assigned task to agent",
+ slog.String("task_id", taskID),
+ slog.String("agent", agentName),
+ slog.String("explanation", explanation))
return nil
}
@@ -631,7 +669,9 @@
ctx := context.Background()
decision, err := m.subtaskService.ShouldGenerateSubtasks(ctx, task)
if err != nil {
- log.Printf("Warning: Failed to get LLM subtask decision for task %s: %v", task.ID, err)
+ m.logger.Warn("Failed to get LLM subtask decision for task",
+ slog.String("task_id", task.ID),
+ slog.String("error", err.Error()))
// Fallback to simple heuristics
return task.Priority == tm.PriorityHigh || len(task.Description) > 200
}
@@ -639,11 +679,14 @@
// Update task to mark as evaluated
task.SubtasksEvaluated = true
if err := m.taskManager.UpdateTask(task); err != nil {
- log.Printf("Warning: Failed to update task evaluation status: %v", err)
+ m.logger.Warn("Failed to update task evaluation status", slog.String("error", err.Error()))
}
- log.Printf("LLM subtask decision for task %s: needs_subtasks=%v, complexity=%d, reasoning=%s",
- task.ID, decision.NeedsSubtasks, decision.ComplexityScore, decision.Reasoning)
+ m.logger.Info("LLM subtask decision for task",
+ slog.String("task_id", task.ID),
+ slog.Bool("needs_subtasks", decision.NeedsSubtasks),
+ slog.Int("complexity_score", decision.ComplexityScore),
+ slog.String("reasoning", decision.Reasoning))
return decision.NeedsSubtasks
}
@@ -670,13 +713,20 @@
task.SubtasksPRURL = prURL
task.SubtasksGenerated = true
- log.Printf("Generated subtask PR for task %s: %s", task.ID, prURL)
- log.Printf("Proposed %d subtasks and %d new agents for task %s", len(analysis.Subtasks), len(analysis.AgentCreations), task.ID)
+ m.logger.Info("Generated subtask PR for task",
+ slog.String("task_id", task.ID),
+ slog.String("pr_url", prURL))
+ m.logger.Info("Proposed subtasks and new agents for task",
+ slog.String("task_id", task.ID),
+ slog.Int("subtask_count", len(analysis.Subtasks)),
+ slog.Int("new_agent_count", len(analysis.AgentCreations)))
// Log proposed new agents if any
if len(analysis.AgentCreations) > 0 {
for _, agent := range analysis.AgentCreations {
- log.Printf("Proposed new agent: %s with skills: %v", agent.Role, agent.Skills)
+ m.logger.Info("Proposed new agent",
+ slog.String("role", agent.Role),
+ slog.Any("skills", agent.Skills))
}
}
@@ -700,19 +750,21 @@
// Close all LLM providers
for _, agent := range m.agents {
if err := agent.Provider.Close(); err != nil {
- log.Printf("Error closing provider for agent %s: %v", agent.Name, err)
+ m.logger.Error("Error closing provider for agent",
+ slog.String("agent", agent.Name),
+ slog.String("error", err.Error()))
}
}
// Cleanup all agent Git clones
if err := m.cloneManager.CleanupAllClones(); err != nil {
- log.Printf("Error cleaning up agent clones: %v", err)
+ m.logger.Error("Error cleaning up agent clones", slog.String("error", err.Error()))
}
// Cleanup subtask service
if m.subtaskService != nil {
if err := m.subtaskService.Close(); err != nil {
- log.Printf("Error closing subtask service: %v", err)
+ m.logger.Error("Error closing subtask service", slog.String("error", err.Error()))
}
}