feat: support multiple agents running concurrently on the same issue

- Relax ClaimAgentTask SQL constraint from per-issue to per-(issue, agent)
  serialization, allowing different agents to run in parallel on the same issue
- Update GetActiveTaskForIssue API to return all active tasks (array) instead of
  just the first one
- Refactor AgentLiveCard to render one card per active task, routing WebSocket
  messages by task_id for independent timelines
- Fix shouldEnqueueOnComment to use per-agent dedup so a mentioned agent's
  pending task doesn't block the assigned agent's on_comment trigger

Closes MUL-160
This commit is contained in:
Jiang Bohan 2026-04-07 18:19:57 +08:00
parent 638033c9ff
commit b94108768e
8 changed files with 139 additions and 86 deletions

View file

@ -77,10 +77,10 @@ SELECT * FROM agent_task_queue
WHERE id = $1;
-- name: ClaimAgentTask :one
-- Claims the next queued task for an agent, enforcing per-issue serialization:
-- a task is only claimable when no other task for the same issue is already
-- dispatched or running. This guarantees serial execution within an issue
-- while allowing parallel execution across different issues.
-- Claims the next queued task for an agent, enforcing per-(issue, agent) serialization:
-- a task is only claimable when no other task for the same issue AND same agent is
-- already dispatched or running. This allows different agents to work on the same
-- issue in parallel while preventing a single agent from running duplicate tasks.
UPDATE agent_task_queue
SET status = 'dispatched', dispatched_at = now()
WHERE id = (
@ -89,6 +89,7 @@ WHERE id = (
AND NOT EXISTS (
SELECT 1 FROM agent_task_queue active
WHERE active.issue_id = atq.issue_id
AND active.agent_id = atq.agent_id
AND active.status IN ('dispatched', 'running')
)
ORDER BY atq.priority DESC, atq.created_at ASC