feat(agent-queue): agent authors PR title + description (.aq_pr.md)

In PR mode the agent is asked to write .aq_pr.md (line 1 = PR title, then a markdown
description) based on the task + the diff it produced. The factory reads it for
`gh pr create` (via --body-file) and removes it before committing (never part of the
PR). Falls back to a derived title if absent. selftest asserts the authored title is
used and .aq_pr.md is not committed.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
saravanakumardb1 2026-05-31 05:48:37 -07:00
parent d0e800247c
commit e634d4915f
2 changed files with 33 additions and 10 deletions

View File

@ -685,18 +685,27 @@ _fleet_pr_prepare() {
# <base>, and echo the PR URL. Returns 1 with no output if there is nothing to # <base>, and echo the PR URL. Returns 1 with no output if there is nothing to
# commit or any git/gh step fails (caller leaves pr_url empty). # commit or any git/gh step fails (caller leaves pr_url empty).
_fleet_pr_open() { _fleet_pr_open() {
local dir=$1 base=${2:-main} jid=$3 title=$4 logf=$5 local dir=$1 base=${2:-main} jid=$3 fallback_title=$4 logf=$5
local br="aq/job/$jid" local br="aq/job/$jid" prmeta="$dir/.aq_pr.md" title="" body=""
# The agent writes .aq_pr.md (line 1 = PR title, then the description) from the
# task + the diff it produced. Read it, then REMOVE it so it is never committed.
if [[ -f "$prmeta" ]]; then
title=$(head -1 "$prmeta" | sed 's/^#* *//' | cut -c1-72)
body=$(tail -n +2 "$prmeta" | sed '/./,$!d') # body = rest, drop leading blanks
rm -f "$prmeta"
fi
[[ -n "$title" ]] || title="$fallback_title"
[[ -n "$body" ]] || body="Automated by agent-queue fleet (job $jid)."
git -C "$dir" add -A >>"$logf" 2>&1 git -C "$dir" add -A >>"$logf" 2>&1
if git -C "$dir" diff --cached --quiet 2>/dev/null; then if git -C "$dir" diff --cached --quiet 2>/dev/null; then
echo "PR: no changes to commit — skipping PR" >>"$logf"; return 1 echo "PR: no changes to commit — skipping PR" >>"$logf"; return 1
fi fi
git -C "$dir" commit --quiet -m "$title" >>"$logf" 2>&1 || { echo "PR: commit failed" >>"$logf"; return 1; } git -C "$dir" commit --quiet -m "$title" >>"$logf" 2>&1 || { echo "PR: commit failed" >>"$logf"; return 1; }
git -C "$dir" push --quiet -u origin "$br" >>"$logf" 2>&1 || { echo "PR: push failed" >>"$logf"; return 1; } git -C "$dir" push --quiet -u origin "$br" >>"$logf" 2>&1 || { echo "PR: push failed" >>"$logf"; return 1; }
local url local url rc bf; bf=$(mktemp); printf '%s\n' "$body" > "$bf"
url=$( cd "$dir" && "$GH_BIN" pr create --base "$base" --head "$br" \ url=$( cd "$dir" && "$GH_BIN" pr create --base "$base" --head "$br" --title "$title" --body-file "$bf" 2>>"$logf" )
--title "$title" --body "Automated by agent-queue fleet (job $jid)." 2>>"$logf" ) \ rc=$?; rm -f "$bf"
|| { echo "PR: gh pr create failed" >>"$logf"; return 1; } [[ $rc -eq 0 && -n "$url" ]] || { echo "PR: gh pr create failed" >>"$logf"; return 1; }
printf '%s' "$url" | tr -d '\n' printf '%s' "$url" | tr -d '\n'
} }
@ -798,6 +807,17 @@ run_worker() {
if [[ -n "$_prep" && -d "$_prep" ]]; then if [[ -n "$_prep" && -d "$_prep" ]]; then
cwd="$_prep"; pr_dir="$_prep" cwd="$_prep"; pr_dir="$_prep"
echo "PR mode: agent cwd=$cwd on branch aq/job/$pr_jid (base $pr_base, repo $pr_repo)" >> "$logf" echo "PR mode: agent cwd=$cwd on branch aq/job/$pr_jid (base $pr_base, repo $pr_repo)" >> "$logf"
# Ask the agent to author the PR title + description from the task and the
# diff it produces. It writes .aq_pr.md (line 1 = title, rest = description);
# the factory reads it for `gh pr create` and removes it before committing.
{
printf '\n\n---\n'
printf 'When you have finished the task above, write a file named `.aq_pr.md` in the '
printf 'current working directory describing your change for a GitHub pull request:\n'
printf ' - the FIRST line is a concise PR title (<= 72 chars, no prefixes/quotes)\n'
printf ' - then a blank line, then a short markdown description of WHAT you changed and WHY\n'
printf 'Base it on the actual diff you produced. This file is read to open the PR and is NOT committed.\n'
} >> "$bodyf"
else else
echo "PR mode: prepare failed for $pr_repo — running in $cwd, no PR" >> "$logf" echo "PR mode: prepare failed for $pr_repo — running in $cwd, no PR" >> "$logf"
fi fi

View File

@ -871,7 +871,7 @@ prseed="$tmp/pr-seed"; git clone -q "$prbare" "$prseed" 2>/dev/null
&& echo seed > README.md && git add -A && git commit -qm seed \ && echo seed > README.md && git add -A && git commit -qm seed \
&& git branch -M main && git push -q origin main ) >/dev/null 2>&1 && git branch -M main && git push -q origin main ) >/dev/null 2>&1
prengine="$tmp/pr-engine" prengine="$tmp/pr-engine"
printf '#!/usr/bin/env bash\necho "pr change" > PR_CHANGE.md\necho done\nexit 0\n' > "$prengine"; chmod +x "$prengine" printf '#!/usr/bin/env bash\necho "pr change" > PR_CHANGE.md\nprintf "Add smoke marker file\\n\\nWhy: smoke-test PR mode.\\n" > .aq_pr.md\necho done\nexit 0\n' > "$prengine"; chmod +x "$prengine"
ghstub="$tmp/gh-stub" ghstub="$tmp/gh-stub"
printf '#!/usr/bin/env bash\necho "$@" >> "%s"\necho "https://github.com/test/repo/pull/7"\nexit 0\n' "$tmp/gh-calls.log" > "$ghstub"; chmod +x "$ghstub" printf '#!/usr/bin/env bash\necho "$@" >> "%s"\necho "https://github.com/test/repo/pull/7"\nexit 0\n' "$tmp/gh-calls.log" > "$ghstub"; chmod +x "$ghstub"
export AGENT_QUEUE_ROOT="$tmp/queue-fl-pr"; export AQ_FLEET_CWD="$work" export AGENT_QUEUE_ROOT="$tmp/queue-fl-pr"; export AQ_FLEET_CWD="$work"
@ -882,13 +882,16 @@ export AQ_FSTUB_CALLS="$tmp/fl-pr-calls.log" AQ_FSTUB_CLAIM_FLAG="$tmp/fl-pr-cla
AQ_FLEET=1 AQ_FLEET_PR=1 AQ_FLEET_AUTOSHIP=1 AGENT_QUEUE_VERIFY=true AGENT_QUEUE_POLL=1 \ AQ_FLEET=1 AQ_FLEET_PR=1 AQ_FLEET_AUTOSHIP=1 AGENT_QUEUE_VERIFY=true AGENT_QUEUE_POLL=1 \
AQ_FLEET_REPOS_DIR="$tmp/pr-repos" GH_BIN="$ghstub" DEVIN_BIN="$prengine" "$AQ" run --once >/dev/null 2>&1 AQ_FLEET_REPOS_DIR="$tmp/pr-repos" GH_BIN="$ghstub" DEVIN_BIN="$prengine" "$AQ" run --once >/dev/null 2>&1
if git -C "$prbare" rev-parse --verify aq/job/fjob_pr >/dev/null 2>&1 \ if git -C "$prbare" rev-parse --verify aq/job/fjob_pr >/dev/null 2>&1 \
&& grep -q 'pr create' "$tmp/gh-calls.log" 2>/dev/null \ && grep -q -- '--title Add smoke marker file' "$tmp/gh-calls.log" 2>/dev/null \
&& git -C "$prbare" ls-tree -r aq/job/fjob_pr --name-only 2>/dev/null | grep -qx 'PR_CHANGE.md' \
&& ! git -C "$prbare" ls-tree -r aq/job/fjob_pr --name-only 2>/dev/null | grep -qx '.aq_pr.md' \
&& grep -q '/fleet/jobs/fjob_pr/lease/release :: .*"prUrl":"https://github.com/test/repo/pull/7"' "$AQ_FSTUB_CALLS"; then && grep -q '/fleet/jobs/fjob_pr/lease/release :: .*"prUrl":"https://github.com/test/repo/pull/7"' "$AQ_FSTUB_CALLS"; then
pass "fleet PR mode: agent branch pushed + PR opened + prUrl reported on release" pass "fleet PR mode: agent-authored PR title used + .aq_pr.md not committed + prUrl reported"
else else
echo "gh-calls: $(cat "$tmp/gh-calls.log" 2>/dev/null)" >&2 echo "gh-calls: $(cat "$tmp/gh-calls.log" 2>/dev/null)" >&2
echo "tree: $(git -C "$prbare" ls-tree -r aq/job/fjob_pr --name-only 2>/dev/null | tr '\n' ' ')" >&2
grep release "$AQ_FSTUB_CALLS" >&2 2>/dev/null grep release "$AQ_FSTUB_CALLS" >&2 2>/dev/null
fail "PR mode did not push branch / open PR / report prUrl" fail "PR mode did not push branch / use authored title / report prUrl"
fi fi
unset AQ_FSTUB_REPO AQ_FSTUB_BASE unset AQ_FSTUB_REPO AQ_FSTUB_BASE