fix: pass SESSION_NAME to all agent-session.sh function calls
Library functions need explicit session name argument — they no longer have closure over $SESSION_NAME from the parent script. - agent_kill_session: add $SESSION_NAME to all 11 call sites - agent_inject_into_session: add $SESSION_NAME to all call sites in phase-handler.sh and gardener-agent.sh - agent_kill_session: guard against missing arg (defensive)
This commit is contained in:
parent
350acccd8b
commit
d83098f382
4 changed files with 26 additions and 25 deletions
|
|
@ -100,7 +100,7 @@ CLAIMED=false
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -f "$LOCKFILE" "$STATUSFILE"
|
rm -f "$LOCKFILE" "$STATUSFILE"
|
||||||
# Kill any live session so Claude doesn't run without an orchestrator attached
|
# Kill any live session so Claude doesn't run without an orchestrator attached
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
# If we claimed the issue but never created a PR, unclaim it
|
# If we claimed the issue but never created a PR, unclaim it
|
||||||
if [ "$CLAIMED" = true ] && [ -z "${PR_NUMBER:-}" ]; then
|
if [ "$CLAIMED" = true ] && [ -z "${PR_NUMBER:-}" ]; then
|
||||||
log "cleanup: unclaiming issue (no PR created)"
|
log "cleanup: unclaiming issue (no PR created)"
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ do_merge() {
|
||||||
notify_ctx \
|
notify_ctx \
|
||||||
"✅ PR #${pr} merged! Issue #${ISSUE} done." \
|
"✅ PR #${pr} merged! Issue #${ISSUE} done." \
|
||||||
"✅ PR <a href='${CODEBERG_WEB}/pulls/${pr}'>#${pr}</a> merged! <a href='${CODEBERG_WEB}/issues/${ISSUE}'>Issue #${ISSUE}</a> done."
|
"✅ PR <a href='${CODEBERG_WEB}/pulls/${pr}'>#${pr}</a> merged! <a href='${CODEBERG_WEB}/issues/${ISSUE}'>Issue #${ISSUE}</a> done."
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
cleanup_worktree
|
cleanup_worktree
|
||||||
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
||||||
exit 0
|
exit 0
|
||||||
|
|
@ -166,7 +166,7 @@ do_merge() {
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
"${API}/issues/${ISSUE}" -d '{"state":"closed"}' >/dev/null 2>&1 || true
|
"${API}/issues/${ISSUE}" -d '{"state":"closed"}' >/dev/null 2>&1 || true
|
||||||
cleanup_labels
|
cleanup_labels
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
cleanup_worktree
|
cleanup_worktree
|
||||||
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
||||||
exit 0
|
exit 0
|
||||||
|
|
@ -240,13 +240,13 @@ _on_phase_change() {
|
||||||
log "PR already exists: #${PR_NUMBER}"
|
log "PR already exists: #${PR_NUMBER}"
|
||||||
else
|
else
|
||||||
log "ERROR: PR creation got 409 but no existing PR found"
|
log "ERROR: PR creation got 409 but no existing PR found"
|
||||||
agent_inject_into_session "ERROR: Could not create PR (HTTP 409, no existing PR found). Check the Codeberg API. Retry by writing PHASE:awaiting_ci again after verifying the branch was pushed."
|
agent_inject_into_session "$SESSION_NAME" "ERROR: Could not create PR (HTTP 409, no existing PR found). Check the Codeberg API. Retry by writing PHASE:awaiting_ci again after verifying the branch was pushed."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log "ERROR: PR creation failed (HTTP ${PR_HTTP_CODE})"
|
log "ERROR: PR creation failed (HTTP ${PR_HTTP_CODE})"
|
||||||
notify "failed to create PR (HTTP ${PR_HTTP_CODE})"
|
notify "failed to create PR (HTTP ${PR_HTTP_CODE})"
|
||||||
agent_inject_into_session "ERROR: Could not create PR (HTTP ${PR_HTTP_CODE}). Check branch was pushed: git push origin ${BRANCH}. Then write PHASE:awaiting_ci again."
|
agent_inject_into_session "$SESSION_NAME" "ERROR: Could not create PR (HTTP ${PR_HTTP_CODE}). Check branch was pushed: git push origin ${BRANCH}. Then write PHASE:awaiting_ci again."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
@ -254,7 +254,7 @@ _on_phase_change() {
|
||||||
# No CI configured? Treat as success immediately
|
# No CI configured? Treat as success immediately
|
||||||
if [ "${WOODPECKER_REPO_ID:-2}" = "0" ]; then
|
if [ "${WOODPECKER_REPO_ID:-2}" = "0" ]; then
|
||||||
log "no CI configured — treating as passed"
|
log "no CI configured — treating as passed"
|
||||||
agent_inject_into_session "CI passed on PR #${PR_NUMBER} (no CI configured for this project).
|
agent_inject_into_session "$SESSION_NAME" "CI passed on PR #${PR_NUMBER} (no CI configured for this project).
|
||||||
Write PHASE:awaiting_review to the phase file, then stop and wait for review feedback."
|
Write PHASE:awaiting_review to the phase file, then stop and wait for review feedback."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -290,14 +290,14 @@ Write PHASE:awaiting_review to the phase file, then stop and wait for review fee
|
||||||
if ! $CI_DONE; then
|
if ! $CI_DONE; then
|
||||||
log "TIMEOUT: CI didn't complete in ${CI_POLL_TIMEOUT}s"
|
log "TIMEOUT: CI didn't complete in ${CI_POLL_TIMEOUT}s"
|
||||||
notify "CI timeout on PR #${PR_NUMBER}"
|
notify "CI timeout on PR #${PR_NUMBER}"
|
||||||
agent_inject_into_session "CI TIMEOUT: CI did not complete within 30 minutes for PR #${PR_NUMBER} (SHA: ${CI_CURRENT_SHA:0:7}). This may be an infrastructure issue. Write PHASE:needs_human if you cannot proceed."
|
agent_inject_into_session "$SESSION_NAME" "CI TIMEOUT: CI did not complete within 30 minutes for PR #${PR_NUMBER} (SHA: ${CI_CURRENT_SHA:0:7}). This may be an infrastructure issue. Write PHASE:needs_human if you cannot proceed."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "CI: ${CI_STATE}"
|
log "CI: ${CI_STATE}"
|
||||||
|
|
||||||
if [ "$CI_STATE" = "success" ]; then
|
if [ "$CI_STATE" = "success" ]; then
|
||||||
agent_inject_into_session "CI passed on PR #${PR_NUMBER}.
|
agent_inject_into_session "$SESSION_NAME" "CI passed on PR #${PR_NUMBER}.
|
||||||
Write PHASE:awaiting_review to the phase file, then stop and wait for review feedback:
|
Write PHASE:awaiting_review to the phase file, then stop and wait for review feedback:
|
||||||
echo \"PHASE:awaiting_review\" > \"${PHASE_FILE}\""
|
echo \"PHASE:awaiting_review\" > \"${PHASE_FILE}\""
|
||||||
else
|
else
|
||||||
|
|
@ -366,7 +366,7 @@ Write PHASE:awaiting_review to the phase file, then stop and wait for review fee
|
||||||
"CI failed on PR #${PR_NUMBER}: step=${FAILED_STEP:-unknown} (attempt ${CI_FIX_COUNT}/${MAX_CI_FIXES})" \
|
"CI failed on PR #${PR_NUMBER}: step=${FAILED_STEP:-unknown} (attempt ${CI_FIX_COUNT}/${MAX_CI_FIXES})" \
|
||||||
"CI failed on PR <a href='${PR_URL:-${CODEBERG_WEB}/pulls/${PR_NUMBER}}'>#${PR_NUMBER}</a> | <a href='${_ci_pipeline_url}'>Pipeline #${PIPELINE_NUM:-?}</a><br>Step: <code>${FAILED_STEP:-unknown}</code> (exit ${FAILED_EXIT:-?})<br>Attempt ${CI_FIX_COUNT}/${MAX_CI_FIXES}<br><pre>${_ci_snippet:-no logs}</pre>"
|
"CI failed on PR <a href='${PR_URL:-${CODEBERG_WEB}/pulls/${PR_NUMBER}}'>#${PR_NUMBER}</a> | <a href='${_ci_pipeline_url}'>Pipeline #${PIPELINE_NUM:-?}</a><br>Step: <code>${FAILED_STEP:-unknown}</code> (exit ${FAILED_EXIT:-?})<br>Attempt ${CI_FIX_COUNT}/${MAX_CI_FIXES}<br><pre>${_ci_snippet:-no logs}</pre>"
|
||||||
|
|
||||||
agent_inject_into_session "CI failed on PR #${PR_NUMBER} (attempt ${CI_FIX_COUNT}/${MAX_CI_FIXES}).
|
agent_inject_into_session "$SESSION_NAME" "CI failed on PR #${PR_NUMBER} (attempt ${CI_FIX_COUNT}/${MAX_CI_FIXES}).
|
||||||
|
|
||||||
Failed step: ${FAILED_STEP:-unknown} (exit code ${FAILED_EXIT:-?}, pipeline #${PIPELINE_NUM:-?})
|
Failed step: ${FAILED_STEP:-unknown} (exit code ${FAILED_EXIT:-?}, pipeline #${PIPELINE_NUM:-?})
|
||||||
|
|
||||||
|
|
@ -401,7 +401,7 @@ Instructions:
|
||||||
PR_NUMBER="$FOUND_PR"
|
PR_NUMBER="$FOUND_PR"
|
||||||
log "found PR #${PR_NUMBER}"
|
log "found PR #${PR_NUMBER}"
|
||||||
else
|
else
|
||||||
agent_inject_into_session "ERROR: Cannot find open PR for branch ${BRANCH}. Did you push? Verify with git status and git push origin ${BRANCH}, then write PHASE:awaiting_ci."
|
agent_inject_into_session "$SESSION_NAME" "ERROR: Cannot find open PR for branch ${BRANCH}. Did you push? Verify with git status and git push origin ${BRANCH}, then write PHASE:awaiting_ci."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
@ -473,7 +473,7 @@ Instructions:
|
||||||
|
|
||||||
if [ "$VERDICT" = "APPROVE" ]; then
|
if [ "$VERDICT" = "APPROVE" ]; then
|
||||||
REVIEW_FOUND=true
|
REVIEW_FOUND=true
|
||||||
agent_inject_into_session "Approved! PR #${PR_NUMBER} has been approved by the reviewer.
|
agent_inject_into_session "$SESSION_NAME" "Approved! PR #${PR_NUMBER} has been approved by the reviewer.
|
||||||
Write PHASE:done to the phase file — the orchestrator will handle the merge:
|
Write PHASE:done to the phase file — the orchestrator will handle the merge:
|
||||||
echo \"PHASE:done\" > \"${PHASE_FILE}\""
|
echo \"PHASE:done\" > \"${PHASE_FILE}\""
|
||||||
break
|
break
|
||||||
|
|
@ -485,7 +485,7 @@ Write PHASE:done to the phase file — the orchestrator will handle the merge:
|
||||||
notify "PR #${PR_NUMBER}: hit ${MAX_REVIEW_ROUNDS} review rounds, needs human attention"
|
notify "PR #${PR_NUMBER}: hit ${MAX_REVIEW_ROUNDS} review rounds, needs human attention"
|
||||||
fi
|
fi
|
||||||
REVIEW_FOUND=true
|
REVIEW_FOUND=true
|
||||||
agent_inject_into_session "Review feedback (round ${REVIEW_ROUND}) on PR #${PR_NUMBER}:
|
agent_inject_into_session "$SESSION_NAME" "Review feedback (round ${REVIEW_ROUND}) on PR #${PR_NUMBER}:
|
||||||
|
|
||||||
${REVIEW_TEXT}
|
${REVIEW_TEXT}
|
||||||
|
|
||||||
|
|
@ -520,7 +520,7 @@ Instructions:
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
"${API}/issues/${ISSUE}" -d '{"state":"closed"}' >/dev/null 2>&1 || true
|
"${API}/issues/${ISSUE}" -d '{"state":"closed"}' >/dev/null 2>&1 || true
|
||||||
cleanup_labels
|
cleanup_labels
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
cleanup_worktree
|
cleanup_worktree
|
||||||
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
||||||
exit 0
|
exit 0
|
||||||
|
|
@ -528,7 +528,7 @@ Instructions:
|
||||||
log "PR #${PR_NUMBER} was closed WITHOUT merge — NOT closing issue"
|
log "PR #${PR_NUMBER} was closed WITHOUT merge — NOT closing issue"
|
||||||
notify "⚠️ PR #${PR_NUMBER} closed without merge. Issue #${ISSUE} remains open."
|
notify "⚠️ PR #${PR_NUMBER} closed without merge. Issue #${ISSUE} remains open."
|
||||||
cleanup_labels
|
cleanup_labels
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
cleanup_worktree
|
cleanup_worktree
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -540,7 +540,7 @@ Instructions:
|
||||||
if ! $REVIEW_FOUND && [ "$REVIEW_POLL_ELAPSED" -ge "$REVIEW_POLL_TIMEOUT" ]; then
|
if ! $REVIEW_FOUND && [ "$REVIEW_POLL_ELAPSED" -ge "$REVIEW_POLL_TIMEOUT" ]; then
|
||||||
log "TIMEOUT: no review after 3h"
|
log "TIMEOUT: no review after 3h"
|
||||||
notify "no review received for PR #${PR_NUMBER} after 3h"
|
notify "no review received for PR #${PR_NUMBER} after 3h"
|
||||||
agent_inject_into_session "TIMEOUT: No review received after 3 hours for PR #${PR_NUMBER}. Write PHASE:needs_human to escalate to a human reviewer."
|
agent_inject_into_session "$SESSION_NAME" "TIMEOUT: No review received after 3 hours for PR #${PR_NUMBER}. Write PHASE:needs_human to escalate to a human reviewer."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── PHASE: needs_human ──────────────────────────────────────────────────────
|
# ── PHASE: needs_human ──────────────────────────────────────────────────────
|
||||||
|
|
@ -563,7 +563,7 @@ Instructions:
|
||||||
if [ -z "${PR_NUMBER:-}" ]; then
|
if [ -z "${PR_NUMBER:-}" ]; then
|
||||||
log "ERROR: PHASE:done but no PR_NUMBER — cannot merge"
|
log "ERROR: PHASE:done but no PR_NUMBER — cannot merge"
|
||||||
notify "PHASE:done but no PR known — needs human attention"
|
notify "PHASE:done but no PR known — needs human attention"
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
cleanup_labels
|
cleanup_labels
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
@ -576,7 +576,7 @@ Instructions:
|
||||||
|
|
||||||
# If we reach here, merge failed (do_merge returned 1)
|
# If we reach here, merge failed (do_merge returned 1)
|
||||||
log "merge failed — injecting error into session"
|
log "merge failed — injecting error into session"
|
||||||
agent_inject_into_session "Merge failed for PR #${PR_NUMBER}. The orchestrator could not merge automatically. This may be due to merge conflicts or CI. Investigate the PR state and write PHASE:needs_human if human intervention is required."
|
agent_inject_into_session "$SESSION_NAME" "Merge failed for PR #${PR_NUMBER}. The orchestrator could not merge automatically. This may be due to merge conflicts or CI. Investigate the PR state and write PHASE:needs_human if human intervention is required."
|
||||||
|
|
||||||
# ── PHASE: failed ───────────────────────────────────────────────────────────
|
# ── PHASE: failed ───────────────────────────────────────────────────────────
|
||||||
elif [ "$phase" = "PHASE:failed" ]; then
|
elif [ "$phase" = "PHASE:failed" ]; then
|
||||||
|
|
@ -663,7 +663,7 @@ $(printf '%s' "$REFUSAL_JSON" | head -c 2000)
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLAIMED=false # Don't unclaim again in cleanup()
|
CLAIMED=false # Don't unclaim again in cleanup()
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
cleanup_worktree
|
cleanup_worktree
|
||||||
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
rm -f "$PHASE_FILE" "$IMPL_SUMMARY_FILE" "$THREAD_FILE"
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -686,7 +686,7 @@ $(printf '%s' "$REFUSAL_JSON" | head -c 2000)
|
||||||
-d '{"labels":["backlog"]}' >/dev/null 2>&1 || true
|
-d '{"labels":["backlog"]}' >/dev/null 2>&1 || true
|
||||||
|
|
||||||
CLAIMED=false # Don't unclaim again in cleanup()
|
CLAIMED=false # Don't unclaim again in cleanup()
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
if [ -n "${PR_NUMBER:-}" ]; then
|
if [ -n "${PR_NUMBER:-}" ]; then
|
||||||
log "keeping worktree (PR #${PR_NUMBER} still open)"
|
log "keeping worktree (PR #${PR_NUMBER} still open)"
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -277,7 +277,7 @@ On unrecoverable error:
|
||||||
printf 'PHASE:failed\nReason: %s\n' 'describe error' > '${PHASE_FILE}'"
|
printf 'PHASE:failed\nReason: %s\n' 'describe error' > '${PHASE_FILE}'"
|
||||||
|
|
||||||
# ── Reset phase + result files ────────────────────────────────────────────
|
# ── Reset phase + result files ────────────────────────────────────────────
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
rm -f "$PHASE_FILE" "$RESULT_FILE"
|
rm -f "$PHASE_FILE" "$RESULT_FILE"
|
||||||
touch "$RESULT_FILE"
|
touch "$RESULT_FILE"
|
||||||
|
|
||||||
|
|
@ -288,7 +288,7 @@ if ! create_agent_session "$SESSION_NAME" "$PROJECT_REPO_ROOT"; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
agent_inject_into_session "$PROMPT"
|
agent_inject_into_session "$SESSION_NAME" "$PROMPT"
|
||||||
log "Prompt sent to tmux session"
|
log "Prompt sent to tmux session"
|
||||||
matrix_send "gardener" "🌱 Gardener session started for ${CODEBERG_REPO}" 2>/dev/null || true
|
matrix_send "gardener" "🌱 Gardener session started for ${CODEBERG_REPO}" 2>/dev/null || true
|
||||||
|
|
||||||
|
|
@ -332,7 +332,7 @@ Re-run your analysis from scratch:
|
||||||
rm -f "$RESULT_FILE"
|
rm -f "$RESULT_FILE"
|
||||||
touch "$RESULT_FILE"
|
touch "$RESULT_FILE"
|
||||||
if create_agent_session "$SESSION_NAME" "$PROJECT_REPO_ROOT" 2>/dev/null; then
|
if create_agent_session "$SESSION_NAME" "$PROJECT_REPO_ROOT" 2>/dev/null; then
|
||||||
agent_inject_into_session "$RECOVERY_MSG"
|
agent_inject_into_session "$SESSION_NAME" "$RECOVERY_MSG"
|
||||||
log "Recovery session started"
|
log "Recovery session started"
|
||||||
IDLE_ELAPSED=0
|
IDLE_ELAPSED=0
|
||||||
else
|
else
|
||||||
|
|
@ -353,7 +353,7 @@ Re-run your analysis from scratch:
|
||||||
if [ "$IDLE_ELAPSED" -ge "$MAX_RUNTIME" ]; then
|
if [ "$IDLE_ELAPSED" -ge "$MAX_RUNTIME" ]; then
|
||||||
log "TIMEOUT: gardener session idle for ${MAX_RUNTIME}s — killing"
|
log "TIMEOUT: gardener session idle for ${MAX_RUNTIME}s — killing"
|
||||||
matrix_send "gardener" "⚠️ Gardener session timed out after ${MAX_RUNTIME}s" 2>/dev/null || true
|
matrix_send "gardener" "⚠️ Gardener session timed out after ${MAX_RUNTIME}s" 2>/dev/null || true
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
continue
|
continue
|
||||||
|
|
@ -365,7 +365,7 @@ Re-run your analysis from scratch:
|
||||||
log "phase: ${CURRENT_PHASE}"
|
log "phase: ${CURRENT_PHASE}"
|
||||||
|
|
||||||
if [ "$CURRENT_PHASE" = "PHASE:done" ] || [ "$CURRENT_PHASE" = "PHASE:failed" ]; then
|
if [ "$CURRENT_PHASE" = "PHASE:done" ] || [ "$CURRENT_PHASE" = "PHASE:failed" ]; then
|
||||||
agent_kill_session
|
agent_kill_session "$SESSION_NAME"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -60,5 +60,6 @@ inject_formula() {
|
||||||
|
|
||||||
# Kill a tmux session gracefully (no-op if not found).
|
# Kill a tmux session gracefully (no-op if not found).
|
||||||
agent_kill_session() {
|
agent_kill_session() {
|
||||||
tmux kill-session -t "$1" 2>/dev/null || true
|
local session="${1:-}"
|
||||||
|
[ -n "$session" ] && tmux kill-session -t "$session" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue