From 32f795e1ef1dd976576a85b484e797e82fd7cdf9 Mon Sep 17 00:00:00 2001 From: Jiayuan Date: Sun, 29 Mar 2026 17:01:19 +0800 Subject: [PATCH] feat(agent): trigger agent on member comment (on_comment trigger) When a member comments on an issue assigned to an agent, automatically enqueue a new task if the agent has on_comment trigger enabled (or no triggers configured). Combined with session persistence, the agent resumes its prior conversation context and sees the new feedback. - Add HasActiveTaskForIssue query to prevent duplicate task enqueue - Refactor shouldEnqueueAgentTask into reusable isAgentTriggerEnabled - Add shouldEnqueueOnComment with active-task and status guards - Call trigger logic from CreateComment handler --- server/internal/handler/comment.go | 8 ++++++++ server/internal/handler/issue.go | 28 +++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/internal/handler/comment.go b/server/internal/handler/comment.go index be6adb9f..0e00c472 100644 --- a/server/internal/handler/comment.go +++ b/server/internal/handler/comment.go @@ -125,6 +125,14 @@ func (h *Handler) CreateComment(w http.ResponseWriter, r *http.Request) { "issue_status": issue.Status, }) + // If the issue is assigned to an agent with on_comment trigger, enqueue a new task. + // The agent will resume its prior session and see this comment. + if h.shouldEnqueueOnComment(r.Context(), issue) { + if _, err := h.TaskService.EnqueueTaskForIssue(r.Context(), issue); err != nil { + slog.Warn("enqueue agent task on comment failed", "issue_id", issueID, "error", err) + } + } + writeJSON(w, http.StatusCreated, resp) } diff --git a/server/internal/handler/issue.go b/server/internal/handler/issue.go index 08369f5d..f6f1f736 100644 --- a/server/internal/handler/issue.go +++ b/server/internal/handler/issue.go @@ -375,6 +375,32 @@ func (h *Handler) shouldEnqueueAgentTask(ctx context.Context, issue db.Issue) bo if issue.Status != "todo" { return false } + return h.isAgentTriggerEnabled(ctx, issue, "on_assign") +} + +// shouldEnqueueOnComment returns true if a member comment on this issue should +// trigger the assigned agent. Conditions: issue is assigned to an agent, the +// agent has on_comment trigger enabled, and no task is already active. +func (h *Handler) shouldEnqueueOnComment(ctx context.Context, issue db.Issue) bool { + // Don't trigger on terminal statuses. + if issue.Status == "done" || issue.Status == "cancelled" { + return false + } + if !h.isAgentTriggerEnabled(ctx, issue, "on_comment") { + return false + } + // Don't enqueue if there's already an active task for this issue. + hasActive, err := h.Queries.HasActiveTaskForIssue(ctx, issue.ID) + if err != nil || hasActive { + return false + } + return true +} + +// isAgentTriggerEnabled checks if an issue is assigned to an agent with a +// specific trigger type enabled. Returns true if the agent has no triggers +// configured (default-enabled behavior). +func (h *Handler) isAgentTriggerEnabled(ctx context.Context, issue db.Issue, triggerType string) bool { if !issue.AssigneeType.Valid || issue.AssigneeType.String != "agent" || !issue.AssigneeID.Valid { return false } @@ -392,7 +418,7 @@ func (h *Handler) shouldEnqueueAgentTask(ctx context.Context, issue db.Issue) bo return false } for _, trigger := range triggers { - if trigger.Type == "on_assign" && trigger.Enabled { + if trigger.Type == triggerType && trigger.Enabled { return true } }