open-swe/agent/tools/request_pr_review.py
Adam Moussa b9c348ebba
feat(reviewer): explicit-request verdicts + shell verdict guard
Mention-triggered reviews that explicitly ask for a verdict now submit a
real APPROVE/REQUEST_CHANGES through publish_review; auto-reviews stay
advisory (COMMENT). Authorization is enforced in code: publish_review
honors a verdict only when the dispatching webhook set verdict_requested,
which only the explicit-mention path does.

- request_pr_review gains instructions (forwarded verbatim into an escaped
  requester_instructions data block) and request_verdict
- self-review guard downgrades verdicts on Open SWE-authored PRs; stale
  APPROVEs are best-effort dismissed when later findings land
- new PullRequestVerdictGuardMiddleware blocks gh pr review
  --approve/-a/--request-changes/-r, gh api, and curl verdict fallbacks on
  both the coding-agent and reviewer graphs
- shared escape helper moved to agent/utils/prompt_data.py
2026-07-20 15:06:53 -04:00

74 lines
2.6 KiB
Python

from typing import Any
from langgraph.config import get_config
from agent.utils.slack import GitHubPrRef, parse_github_pr_url
async def trigger_pr_review_from_ref(
pr_ref: GitHubPrRef,
*,
source: str,
github_login: str = "",
github_user_id: int | None = None,
slack_channel_id: str = "",
slack_thread_ts: str = "",
instructions: str = "",
request_verdict: bool = False,
) -> dict[str, Any]:
from agent.webhooks.github import trigger_pr_review_from_ref as _trigger_pr_review_from_ref
return await _trigger_pr_review_from_ref(
pr_ref,
source=source,
github_login=github_login,
github_user_id=github_user_id,
slack_channel_id=slack_channel_id,
slack_thread_ts=slack_thread_ts,
instructions=instructions,
request_verdict=request_verdict,
)
async def request_pr_review(
pr_url: str,
instructions: str = "",
request_verdict: bool = False,
) -> dict[str, Any]:
"""Start the reviewer agent for a GitHub pull request URL.
Args:
pr_url: The pull request URL, e.g.
``https://github.com/OWNER/REPO/pull/NUMBER``.
instructions: The requesting user's review instructions, passed
VERBATIM (do not paraphrase, summarize, or add your own). They may
set review focus, a merge bar, or verdict criteria for the
reviewer.
request_verdict: Set True ONLY when the user explicitly asked for a
review verdict (approve / request changes) in their own words.
Never infer it from tone or context. When True, the reviewer run
is authorized to submit a real GitHub APPROVE or REQUEST_CHANGES;
otherwise it publishes an advisory comment review. Never attempt
to approve or request changes yourself via ``gh pr review`` or the
GitHub API — that path is blocked.
"""
pr_ref = parse_github_pr_url(pr_url)
if not pr_ref:
return {
"success": False,
"error": "Expected a GitHub PR URL like https://github.com/OWNER/REPO/pull/NUMBER",
}
configurable = get_config().get("configurable", {})
source = configurable.get("source") or "agent"
slack_thread = configurable.get("slack_thread") or {}
return await trigger_pr_review_from_ref(
pr_ref,
source=source,
github_login=configurable.get("github_login", ""),
github_user_id=configurable.get("github_user_id"),
slack_channel_id=slack_thread.get("channel_id", ""),
slack_thread_ts=slack_thread.get("thread_ts", ""),
instructions=instructions,
request_verdict=request_verdict,
)