From f71e0767a4151e4cdb529b19b08e69590f5ed39d Mon Sep 17 00:00:00 2001 From: null Date: Sun, 24 May 2026 19:49:46 -0500 Subject: [PATCH] Add a required editable Agent prompt, prefilled from the Forgejo issue title, URL, body, and expected working notes. --- .../components/git/AssignIssueAgentDialog.tsx | 124 ++++++++++++------ 1 file changed, 84 insertions(+), 40 deletions(-) diff --git a/frontend/src/components/git/AssignIssueAgentDialog.tsx b/frontend/src/components/git/AssignIssueAgentDialog.tsx index f28966d..7720bbf 100644 --- a/frontend/src/components/git/AssignIssueAgentDialog.tsx +++ b/frontend/src/components/git/AssignIssueAgentDialog.tsx @@ -1,6 +1,8 @@ "use client"; +import Link from "next/link"; import { useEffect, useState } from "react"; +import { ExternalLink } from "lucide-react"; import { useListAgentsApiV1AgentsGet, @@ -30,6 +32,31 @@ type AssignIssueAgentDialogProps = { onSuccess: (result: AssignIssueAgentResponse) => void; }; +function buildDefaultAgentPrompt(issue: ForgejoIssue, repositoryName: string) { + const issueBody = (issue.body ?? issue.body_preview ?? "").trim(); + const lines = [ + `Work on ${repositoryName}#${issue.forgejo_issue_number}: ${issue.title}`, + "", + "Use this Forgejo issue as the source of truth.", + `Issue URL: ${issue.html_url}`, + ]; + + if (issueBody) { + lines.push("", "Issue details:", issueBody); + } + + lines.push( + "", + "Expected approach:", + "- Read the relevant Pipeline code before editing.", + "- Keep the work scoped to this issue.", + "- Run targeted validation and report what passed.", + "- Post progress, blockers, and handoff notes back to the Pipeline task.", + ); + + return lines.join("\n"); +} + export function AssignIssueAgentDialog({ issue, repositoryName, @@ -46,6 +73,7 @@ export function AssignIssueAgentDialog({ const [error, setError] = useState(null); const [linkedBoards, setLinkedBoards] = useState([]); const [boardsLoading, setBoardsLoading] = useState(false); + const [linkedBoardsLoaded, setLinkedBoardsLoaded] = useState(false); // Fetch only boards linked to this issue's repository — prevents picking a // board that the backend will reject with "not linked to any board". @@ -53,6 +81,7 @@ export function AssignIssueAgentDialog({ if (!open || !issue) return; let cancelled = false; setBoardsLoading(true); + setLinkedBoardsLoaded(false); setLinkedBoards([]); setBoardId(""); getLinkedBoardsForRepository(issue.repository_id) @@ -65,7 +94,10 @@ export function AssignIssueAgentDialog({ if (!cancelled) setLinkedBoards([]); }) .finally(() => { - if (!cancelled) setBoardsLoading(false); + if (!cancelled) { + setBoardsLoading(false); + setLinkedBoardsLoaded(true); + } }); return () => { cancelled = true; }; }, [open, issue]); @@ -91,29 +123,37 @@ export function AssignIssueAgentDialog({ setInstructions(""); setStartImmediately(true); setError(null); + setLinkedBoardsLoaded(false); } }, [open]); + useEffect(() => { + if (!open || !issue) return; + setInstructions(buildDefaultAgentPrompt(issue, repositoryName)); + }, [open, issue, repositoryName]); + useEffect(() => { setAgentId(""); }, [boardId]); if (!issue) return null; - const noLinkedBoards = !boardsLoading && linkedBoards.length === 0; + const noLinkedBoards = + linkedBoardsLoaded && !boardsLoading && linkedBoards.length === 0; + const prompt = instructions.trim(); const handleSubmit = async () => { - if (!boardId) return; + if (!boardId || !agentId || !prompt) return; setIsSubmitting(true); setError(null); try { const result = await assignIssueToAgent(issue.id, { board_id: boardId, - assigned_agent_id: agentId || undefined, + assigned_agent_id: agentId, priority, start_immediately: startImmediately, - status: startImmediately && agentId ? "in_progress" : "inbox", - instructions: instructions.trim() || undefined, + status: startImmediately ? "in_progress" : "inbox", + instructions: prompt, }); onSuccess(result); onOpenChange(false); @@ -183,12 +223,17 @@ export function AssignIssueAgentDialog({

Before you can assign an agent, link{" "} {repositoryName}{" "} - to a board in{" "} - - Board Settings → Git Repositories - - . + to the board that should own this task. Open the target board and + use its Git Project repositories panel, or manage tracked + repositories first.

+ + Manage Git repositories + + ) : ( <> @@ -221,10 +266,7 @@ export function AssignIssueAgentDialog({
+ {boardId && !agentsQuery.isLoading && agents.length === 0 ? ( +

+ No agents are available on this board yet. +

+ ) : null}
@@ -263,33 +310,34 @@ export function AssignIssueAgentDialog({