PR complete a task
Change-Id: Icb3f24db0ccd2914a528370d96b8c21168b24e98
diff --git a/server/agent/manager.go b/server/agent/manager.go
index ab2ce72..016f5ac 100644
--- a/server/agent/manager.go
+++ b/server/agent/manager.go
@@ -149,6 +149,32 @@
return m.isRunning[agentName]
}
+// CompleteTaskForAgent finds the agent performing a task and resets its state
+func (m *Manager) CompleteTaskForAgent(taskID string) error {
+ // Get the task to find the assignee
+ task, err := m.taskManager.GetTask(taskID)
+ if err != nil {
+ return fmt.Errorf("failed to get task %s: %w", taskID, err)
+ }
+
+ // Find the agent assigned to this task
+ agent, exists := m.agents[task.Assignee]
+ if !exists {
+ return fmt.Errorf("agent %s not found for task %s", task.Assignee, taskID)
+ }
+
+ // Reset the agent's current task and running state
+ agent.CurrentTask = nil
+ agent.IsRunning = false
+ m.isRunning[agent.Name] = false
+
+ m.logger.Info("Completed task for agent",
+ slog.String("task_id", taskID),
+ slog.String("agent", agent.Name))
+
+ return nil
+}
+
// Close shuts down the agent manager
func (m *Manager) Close() error {
// Stop all running agents
diff --git a/server/app/proposal.go b/server/app/proposal.go
index 8feaded..7858d2b 100644
--- a/server/app/proposal.go
+++ b/server/app/proposal.go
@@ -28,6 +28,14 @@
return fmt.Errorf("failed to process webhook: %w", err)
}
+ // Complete the task for the agent that was performing it
+ if err := a.manager.CompleteTaskForAgent(taskID); err != nil {
+ a.logger.Warn("Failed to complete task for agent",
+ slog.String("task_id", taskID),
+ slog.String("error", err.Error()))
+ // Don't fail the webhook if agent completion fails
+ }
+
a.logger.Info("Proposal approved via webhook",
slog.String("task_id", taskID),
slog.String("repository", fmt.Sprintf("%s/%s", a.config.GitHub.Owner, a.config.GitHub.Repo)),
diff --git a/server/git/webhook.go b/server/git/webhook.go
index df12492..285ea28 100644
--- a/server/git/webhook.go
+++ b/server/git/webhook.go
@@ -281,14 +281,14 @@
webhook.PullRequest.Head != nil
}
-// ExtractTaskID extracts task ID from branch name like "solution/{task-id}" or "subtasks/{task-id}"
+// ExtractTaskID extracts task ID from branch name like "solution/[task-id]-title" or "subtasks/[task-id]-title"
func ExtractTaskID(branchName string) (string, error) {
- // Match patterns like "solution/task-123", "subtasks/task-456", etc.
- re := regexp.MustCompile(`^(?:solution|subtasks)/(.+)$`)
+ // Match patterns like "solution/[task-123]-title", "subtasks/[task-456]-description", etc.
+ re := regexp.MustCompile(`^(?:solution|subtasks)/\[([^\]]+)\]-.+$`)
matches := re.FindStringSubmatch(branchName)
if len(matches) != 2 {
- return "", fmt.Errorf("branch name '%s' does not match expected pattern (solution/{task-id} or subtasks/{task-id})", branchName)
+ return "", fmt.Errorf("branch name '%s' does not match expected pattern (solution/[task-id]-title or subtasks/[task-id]-title)", branchName)
}
return matches[1], nil
diff --git a/server/tm/git_tm/git_task_manager.go b/server/tm/git_tm/git_task_manager.go
index a49a866..f7d7a07 100644
--- a/server/tm/git_tm/git_task_manager.go
+++ b/server/tm/git_tm/git_task_manager.go
@@ -1103,7 +1103,7 @@
cleanTitle = cleanTitle[:40]
}
- return fmt.Sprintf("%s/%s-%s", prefix, task.ID, cleanTitle)
+ return fmt.Sprintf("%s/[%s]-%s", prefix, task.ID, cleanTitle)
}
// buildSolutionPRDescription creates PR description from template