diff --git a/agent/utils/github_comments.py b/agent/utils/github_comments.py
index 16723895..ce57d710 100644
--- a/agent/utils/github_comments.py
+++ b/agent/utils/github_comments.py
@@ -25,7 +25,6 @@ __all__ = [
"fetch_pr_comments_since_last_tag",
"format_github_comment_body_for_prompt",
"get_thread_id_from_branch",
- "parse_github_review_command",
"post_github_comment",
"react_to_github_comment",
"sanitize_github_comment_body",
@@ -33,8 +32,6 @@ __all__ = [
]
OPEN_SWE_TAGS = ("@openswe", "@open-swe", "@openswe-dev")
-_OPEN_SWE_MENTION_RE = re.compile(r"(?i)@(?:openswe-dev|open-swe|openswe)\b")
-_REVIEW_COMMAND_RE = re.compile(r"(?i)\Areview(?:\s+(https?://\S+))?\s*\Z")
UNTRUSTED_GITHUB_COMMENT_OPEN_TAG = ""
UNTRUSTED_GITHUB_COMMENT_CLOSE_TAG = ""
_SANITIZED_UNTRUSTED_GITHUB_COMMENT_OPEN_TAG = "[blocked-untrusted-comment-tag-open]"
@@ -76,23 +73,6 @@ def get_thread_id_from_branch(branch_name: str) -> str | None:
return match.group(0) if match else None
-def parse_github_review_command(body: str) -> tuple[bool, str | None]:
- """Detect ``@open-swe review [URL]`` in a GitHub comment body.
-
- Returns ``(is_review_command, optional_pr_url)``. When ``is_review_command``
- is True and the URL is None, the command applies to the PR being commented
- on. The URL — if present — is returned as-is so the caller can validate it
- with ``parse_github_pr_url``.
- """
- if not body:
- return False, None
- stripped = _OPEN_SWE_MENTION_RE.sub("", body).strip()
- match = _REVIEW_COMMAND_RE.match(stripped)
- if not match:
- return False, None
- return True, match.group(1) or None
-
-
def sanitize_github_comment_body(body: str) -> str:
"""Strip reserved trust wrapper tags from raw GitHub comment bodies."""
sanitized = body.replace(
diff --git a/agent/utils/slack.py b/agent/utils/slack.py
index 3db5de8c..b1d2d109 100644
--- a/agent/utils/slack.py
+++ b/agent/utils/slack.py
@@ -23,10 +23,6 @@ logger = logging.getLogger(__name__)
SLACK_API_BASE_URL = "https://slack.com/api"
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN", "")
-GITHUB_PR_URL_RE = re.compile(r"https?://(?:www\.)?github\.com/[^\s<>|]+/[^\s<>|]+/pull/\d+")
-URL_RE = re.compile(r"https?://[^\s<>|]+")
-
-
DEFAULT_ASSISTANT_STATUS = "is thinking…"
# Curated rotating loading strings shown by Slack while the indicator is active.
@@ -174,36 +170,6 @@ def parse_github_pr_url(url: str) -> GitHubPrRef | None:
)
-def parse_slack_review_command(text: str) -> GitHubPrRef | None:
- stripped = text.strip()
- command_match = re.fullmatch(r"(?is)review\s+(.+)", stripped)
- if not command_match:
- return None
-
- rest = command_match.group(1).strip()
- url_match = GITHUB_PR_URL_RE.search(rest)
- if not url_match:
- return None
-
- trailing_text = rest[url_match.end() :].strip()
- if trailing_text and trailing_text != ">" and not trailing_text.startswith("|"):
- return None
-
- return parse_github_pr_url(url_match.group(0))
-
-
-def looks_like_slack_pr_review_command(text: str) -> bool:
- stripped = text.strip()
- if not re.match(r"(?is)^review\b", stripped):
- return False
- for match in URL_RE.finditer(stripped):
- parsed = urlparse(match.group(0).strip("<>"))
- host = (parsed.hostname or "").lower()
- if parsed.scheme in {"http", "https"} and host in {"github.com", "www.github.com"}:
- return True
- return False
-
-
def select_slack_context_messages(
messages: list[dict[str, Any]],
current_message_ts: str,
diff --git a/agent/webapp.py b/agent/webapp.py
index 174a36e8..85de78d5 100644
--- a/agent/webapp.py
+++ b/agent/webapp.py
@@ -55,7 +55,6 @@ from .utils.auth import (
persist_encrypted_github_token,
resolve_github_token_from_email,
)
-from .utils.authorship import OPEN_SWE_BOT_NAME
from .utils.comments import get_recent_comments
from .utils.github_app import (
get_github_app_installation_token,
@@ -70,7 +69,6 @@ from .utils.github_comments import (
fetch_pr_comments_since_last_tag,
format_github_comment_body_for_prompt,
get_thread_id_from_branch,
- parse_github_review_command,
react_to_github_comment,
sanitize_github_comment_body,
verify_github_signature,
@@ -88,7 +86,6 @@ from .utils.slack import (
format_slack_messages_for_prompt,
get_slack_user_info,
get_slack_user_names,
- parse_github_pr_url,
post_slack_thread_reply,
post_slack_trace_reply,
resolve_slack_links_in_context,
@@ -1163,33 +1160,6 @@ async def process_slack_mention(event_data: dict[str, Any], repo_config: dict[st
)
-async def process_slack_pr_review_request(
- pr_ref: GitHubPrRef, channel_id: str, thread_ts: str
-) -> None:
- await set_slack_assistant_status(channel_id, thread_ts)
- result = await trigger_pr_review_from_ref(
- pr_ref,
- source="slack",
- slack_channel_id=channel_id,
- slack_thread_ts=thread_ts,
- )
- if result.get("success"):
- thread_id = result.get("thread_id")
- if isinstance(thread_id, str) and thread_id:
- await post_slack_trace_reply(
- channel_id, thread_ts, thread_id, include_dashboard_link=False
- )
- await set_slack_assistant_status(channel_id, thread_ts)
- return
-
- await post_slack_thread_reply(
- channel_id,
- thread_ts,
- f"Could not start review for <{pr_ref.url}|{pr_ref.owner}/{pr_ref.repo}#{pr_ref.number}>: "
- f"{result.get('error', 'unknown error')}.",
- )
-
-
def verify_linear_signature(body: bytes, signature: str, secret: str) -> bool:
"""Verify the Linear webhook signature.
@@ -1494,7 +1464,6 @@ _SUPPORTED_GH_EVENTS = frozenset(
_SUPPORTED_GH_ISSUE_ACTIONS = frozenset(["edited", "opened", "reopened"])
_SUPPORTED_GH_PULL_REQUEST_ACTIONS = frozenset(
[
- "review_requested",
"opened",
"ready_for_review",
"converted_to_draft",
@@ -1619,12 +1588,6 @@ async def _trigger_or_queue_run(
logger.info("LangGraph run created for thread %s from GitHub PR comment", thread_id)
-def _is_open_swe_reviewer_request(payload: dict[str, Any]) -> bool:
- reviewer = payload.get("requested_reviewer") or {}
- login = reviewer.get("login", "") if isinstance(reviewer, dict) else ""
- return login.lower() == OPEN_SWE_BOT_NAME.lower()
-
-
def build_github_pr_review_prompt(
repo_config: dict[str, str],
pr_number: int,
@@ -2005,11 +1968,6 @@ async def _dispatch_first_review_from_pr_payload(payload: dict[str, Any], *, sou
logger.info("Reviewer run created for thread %s (source=%s)", thread_id, source)
-async def process_github_pr_review_request(payload: dict[str, Any]) -> None:
- """Trigger the reviewer agent when the Open SWE bot is requested on a PR."""
- await _dispatch_first_review_from_pr_payload(payload, source="github")
-
-
async def process_github_pr_ready(payload: dict[str, Any]) -> None:
"""Auto-review a PR that has just been opened or marked ready-for-review.
@@ -2033,75 +1991,6 @@ async def process_github_pr_ready(payload: dict[str, Any]) -> None:
await _dispatch_first_review_from_pr_payload(payload, source="github")
-async def process_github_pr_review_command(
- payload: dict[str, Any],
- event_type: str,
- pr_url_override: str | None,
-) -> None:
- """Trigger the reviewer when a PR comment contains ``@open-swe review``.
-
- ``pr_url_override`` is the optional URL token that followed ``review``. If
- set, the review targets that PR; otherwise the comment's own PR is used.
- """
- repo = payload.get("repository", {})
- repo_config = {
- "owner": repo.get("owner", {}).get("login", ""),
- "name": repo.get("name", ""),
- }
- pr_data = payload.get("pull_request") or payload.get("issue", {})
- sender = payload.get("sender", {})
- github_login = sender.get("login", "")
- github_user_id = sender.get("id")
-
- pr_ref: GitHubPrRef | None = None
- if pr_url_override:
- pr_ref = parse_github_pr_url(pr_url_override)
- if pr_ref is None:
- logger.info("Ignoring @open-swe review with unparseable URL %s", pr_url_override)
- return
- else:
- pr_number = pr_data.get("number")
- if not pr_number:
- logger.warning("@open-swe review command missing pr_number, skipping")
- return
- pr_ref = GitHubPrRef(
- owner=repo_config["owner"],
- repo=repo_config["name"],
- number=pr_number,
- url=pr_data.get("html_url", "") or pr_data.get("url", ""),
- )
-
- comment = payload.get("comment") or payload.get("review", {})
- comment_id = comment.get("id")
- node_id = comment.get("node_id") if event_type == "pull_request_review" else None
- if comment_id:
- app_token = await get_github_app_installation_token()
- if app_token:
- await react_to_github_comment(
- repo_config,
- comment_id,
- event_type=event_type,
- token=app_token,
- pull_number=pr_data.get("number"),
- node_id=node_id,
- )
-
- result = await trigger_pr_review_from_ref(
- pr_ref,
- source="github",
- github_login=github_login,
- github_user_id=github_user_id,
- )
- if not result.get("success"):
- logger.warning(
- "Failed to trigger reviewer from @open-swe review on %s/%s#%s: %s",
- pr_ref.owner,
- pr_ref.repo,
- pr_ref.number,
- result.get("error"),
- )
-
-
async def _fetch_open_pr_for_branch(
repo_config: dict[str, str], head_ref: str, *, token: str
) -> dict[str, Any] | None:
@@ -2541,20 +2430,9 @@ async def process_github_pr_comment(payload: dict[str, Any], event_type: str) ->
else:
logger.warning("Failed to persist branch_name metadata for thread %s", thread_id)
- comment = payload.get("comment") or payload.get("review", {})
- is_review_request, _pr_url_override = parse_github_review_command(comment.get("body") or "")
email = await email_for_login(github_login) or ""
if email:
github_token = await _get_or_resolve_thread_github_token(thread_id, email)
- elif is_review_request:
- github_token, expires_at = await get_github_app_installation_token_with_expiry()
- if github_token:
- try:
- await persist_encrypted_github_token(thread_id, github_token, expires_at=expires_at)
- except Exception:
- logger.warning(
- "Could not persist bot token for PR review request thread %s", thread_id
- )
else:
logger.warning("No email mapping for GitHub user '%s', skipping", github_login)
return
@@ -3011,24 +2889,11 @@ async def github_webhook(request: Request, background_tasks: BackgroundTasks) ->
logger.info("Accepted GitHub PR %s webhook, scheduling auto-review task", action)
background_tasks.add_task(process_github_pr_ready, payload)
return {"status": "accepted", "message": f"Processing PR {action} for auto-review"}
- if not _is_open_swe_reviewer_request(payload):
- logger.info("Ignoring PR review request for a different reviewer")
- return {"status": "ignored", "reason": "Review request is not for open-swe bot"}
- if not await _is_repo_enabled_for_review(webhook_repo_config):
- logger.warning(
- "Rejecting GitHub reviewer webhook: repo '%s/%s' not enabled for review",
- webhook_repo_config.get("owner"),
- webhook_repo_config.get("name"),
- )
- return {"status": "ignored", "reason": "Repository not enabled for review"}
-
- gate_rejection = await _enforce_public_repo_org_gate(payload, "pull_request")
- if gate_rejection is not None:
- return gate_rejection
-
- logger.info("Accepted GitHub PR review request webhook, scheduling reviewer task")
- background_tasks.add_task(process_github_pr_review_request, payload)
- return {"status": "accepted", "message": "Processing GitHub PR review request"}
+ logger.info("Ignoring unsupported GitHub pull_request action: %s", action)
+ return {
+ "status": "ignored",
+ "reason": f"Unsupported GitHub pull_request action: {action}",
+ }
if event_type == "push":
if not await _is_repo_enabled_for_review(webhook_repo_config):
diff --git a/tests/test_github_issue_webhook.py b/tests/test_github_issue_webhook.py
index acc61193..da6cb868 100644
--- a/tests/test_github_issue_webhook.py
+++ b/tests/test_github_issue_webhook.py
@@ -11,7 +11,6 @@ from fastapi.testclient import TestClient
from agent import webapp
from agent.tools import request_pr_review as request_pr_review_tool
-from agent.utils import github_comments
from agent.utils import slack as slack_utils
from agent.utils.slack import GitHubPrRef
@@ -501,23 +500,8 @@ def test_github_webhook_ignores_unsupported_comment_action(monkeypatch) -> None:
}
-def test_github_webhook_blocks_reviewer_repo_not_enabled_in_dashboard(monkeypatch) -> None:
- called = False
-
- async def fake_process_github_pr_review_request(payload: dict[str, object]) -> None:
- nonlocal called
- called = True
-
- monkeypatch.setattr(
- webapp, "process_github_pr_review_request", fake_process_github_pr_review_request
- )
+def test_github_webhook_ignores_review_requested(monkeypatch) -> None:
monkeypatch.setattr(webapp, "GITHUB_WEBHOOK_SECRET", _TEST_WEBHOOK_SECRET)
-
- async def fake_is_review_repo_enabled(_owner: str, _name: str) -> bool:
- return False
-
- monkeypatch.setattr(webapp, "is_review_repo_enabled", fake_is_review_repo_enabled)
-
client = TestClient(webapp.app)
response = _post_github_webhook(
client,
@@ -537,77 +521,10 @@ def test_github_webhook_blocks_reviewer_repo_not_enabled_in_dashboard(monkeypatc
)
assert response.status_code == 200
- assert response.json() == {"status": "ignored", "reason": "Repository not enabled for review"}
- assert called is False
-
-
-def test_github_webhook_accepts_open_swe_review_requested(monkeypatch) -> None:
- called: dict[str, object] = {}
-
- async def fake_process_github_pr_review_request(payload: dict[str, object]) -> None:
- called["payload"] = payload
-
- monkeypatch.setattr(
- webapp, "process_github_pr_review_request", fake_process_github_pr_review_request
- )
- monkeypatch.setattr(webapp, "GITHUB_WEBHOOK_SECRET", _TEST_WEBHOOK_SECRET)
-
- client = TestClient(webapp.app)
- response = _post_github_webhook(
- client,
- "pull_request",
- {
- "action": "review_requested",
- "requested_reviewer": {"login": "open-swe[bot]"},
- "pull_request": {
- "number": 1244,
- "html_url": "https://github.com/langchain-ai/open-swe/pull/1244",
- "base": {"sha": "base-sha"},
- "head": {"sha": "head-sha", "ref": "feature-branch"},
- },
- "repository": {"owner": {"login": "langchain-ai"}, "name": "open-swe"},
- "sender": {"login": "octocat"},
- },
- )
-
- assert response.status_code == 200
- assert response.json()["status"] == "accepted"
- assert called["payload"]["requested_reviewer"]["login"] == "open-swe[bot]"
-
-
-def test_github_webhook_ignores_review_requested_for_other_reviewer(monkeypatch) -> None:
- called = False
-
- async def fake_process_github_pr_review_request(payload: dict[str, object]) -> None:
- nonlocal called
- called = True
-
- monkeypatch.setattr(
- webapp, "process_github_pr_review_request", fake_process_github_pr_review_request
- )
- monkeypatch.setattr(webapp, "GITHUB_WEBHOOK_SECRET", _TEST_WEBHOOK_SECRET)
-
- client = TestClient(webapp.app)
- response = _post_github_webhook(
- client,
- "pull_request",
- {
- "action": "review_requested",
- "requested_reviewer": {"login": "someone-else"},
- "pull_request": {
- "number": 1244,
- "html_url": "https://github.com/langchain-ai/open-swe/pull/1244",
- "base": {"sha": "base-sha"},
- "head": {"sha": "head-sha", "ref": "feature-branch"},
- },
- "repository": {"owner": {"login": "langchain-ai"}, "name": "open-swe"},
- "sender": {"login": "octocat"},
- },
- )
-
- assert response.status_code == 200
- assert response.json()["status"] == "ignored"
- assert called is False
+ assert response.json() == {
+ "status": "ignored",
+ "reason": "Unsupported GitHub pull_request action: review_requested",
+ }
def test_slack_webhook_routes_review_command_to_agent(monkeypatch) -> None:
@@ -816,76 +733,9 @@ def test_slack_webhook_threaded_followup_uses_parent_thread_ts(monkeypatch) -> N
assert event_data["event_ts"] == "1700000000.000200"
-def test_process_slack_pr_review_request_posts_trace_reply(monkeypatch) -> None:
+def test_process_github_pr_ready_creates_reviewer_run(monkeypatch) -> None:
captured: dict[str, object] = {}
- async def fake_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 = "",
- ) -> dict[str, object]:
- captured["pr_ref"] = pr_ref
- captured["source"] = source
- captured["slack_channel_id"] = slack_channel_id
- captured["slack_thread_ts"] = slack_thread_ts
- return {"success": True, "thread_id": "reviewer-thread-id", "pr_url": pr_ref.url}
-
- async def fake_post_slack_trace_reply(
- channel_id: str, thread_ts: str, thread_id: str, *, include_dashboard_link: bool = True
- ) -> None:
- captured["trace_reply"] = {
- "channel_id": channel_id,
- "thread_ts": thread_ts,
- "thread_id": thread_id,
- "include_dashboard_link": include_dashboard_link,
- }
-
- async def fake_set_slack_assistant_status(channel_id: str, thread_ts: str) -> bool:
- captured.setdefault("status_calls", []).append((channel_id, thread_ts))
- return True
-
- monkeypatch.setattr(webapp, "trigger_pr_review_from_ref", fake_trigger_pr_review_from_ref)
- monkeypatch.setattr(webapp, "post_slack_trace_reply", fake_post_slack_trace_reply)
- monkeypatch.setattr(webapp, "set_slack_assistant_status", fake_set_slack_assistant_status)
-
- asyncio.run(
- webapp.process_slack_pr_review_request(
- GitHubPrRef(
- owner="langchain-ai",
- repo="open-swe",
- number=1244,
- url="https://github.com/langchain-ai/open-swe/pull/1244",
- ),
- "C123",
- "1700000000.000100",
- )
- )
-
- assert captured["source"] == "slack"
- assert captured["slack_channel_id"] == "C123"
- assert captured["slack_thread_ts"] == "1700000000.000100"
- assert captured["trace_reply"] == {
- "channel_id": "C123",
- "thread_ts": "1700000000.000100",
- "thread_id": "reviewer-thread-id",
- "include_dashboard_link": False,
- }
- assert captured["status_calls"] == [
- ("C123", "1700000000.000100"),
- ("C123", "1700000000.000100"),
- ]
-
-
-def test_process_github_pr_review_request_creates_reviewer_run(monkeypatch) -> None:
- captured: dict[str, object] = {}
-
- async def fake_get_github_app_installation_token() -> str | None:
- return "app-token"
-
async def fake_get_github_app_installation_token_with_expiry() -> tuple[str | None, str | None]:
return "app-token", None
@@ -919,9 +769,6 @@ def test_process_github_pr_review_request_creates_reviewer_run(monkeypatch) -> N
captured["set_metadata_thread_id"] = thread_id
captured["set_metadata_kwargs"] = kwargs
- monkeypatch.setattr(
- webapp, "get_github_app_installation_token", fake_get_github_app_installation_token
- )
monkeypatch.setattr(
webapp,
"get_github_app_installation_token_with_expiry",
@@ -935,10 +782,9 @@ def test_process_github_pr_review_request_creates_reviewer_run(monkeypatch) -> N
monkeypatch.setattr(webapp, "get_client", lambda url: _FakeLangGraphClient())
asyncio.run(
- webapp.process_github_pr_review_request(
+ webapp.process_github_pr_ready(
{
- "action": "review_requested",
- "requested_reviewer": {"login": "open-swe[bot]"},
+ "action": "opened",
"pull_request": {
"number": 1244,
"html_url": "https://github.com/langchain-ai/open-swe/pull/1244",
@@ -1158,7 +1004,7 @@ def test_request_pr_review_tool_uses_shared_trigger(monkeypatch) -> None:
assert result["success"] is True
-def test_process_github_pr_comment_review_request_without_email_uses_app_token(
+def test_process_github_pr_comment_without_email_skips(
monkeypatch,
) -> None:
captured: dict[str, object] = {}
@@ -1174,15 +1020,6 @@ def test_process_github_pr_comment_review_request_without_email_uses_app_token(
None,
)
- async def fake_get_app_token_with_expiry() -> tuple[str, str]:
- return "app-token", "2026-01-01T00:00:00Z"
-
- async def fake_persist_token(
- thread_id: str, token: str, *, expires_at: str | None = None
- ) -> str:
- captured["persisted"] = {"thread_id": thread_id, "token": token, "expires_at": expires_at}
- return "encrypted"
-
async def fake_react(*args, **kwargs) -> bool:
captured["reaction_token"] = kwargs["token"]
return True
@@ -1196,10 +1033,6 @@ def test_process_github_pr_comment_review_request_without_email_uses_app_token(
monkeypatch.setattr(webapp, "extract_pr_context", fake_extract_pr_context)
monkeypatch.setattr(webapp, "email_for_login", lambda login: asyncio.sleep(0, result=None))
- monkeypatch.setattr(
- webapp, "get_github_app_installation_token_with_expiry", fake_get_app_token_with_expiry
- )
- monkeypatch.setattr(webapp, "persist_encrypted_github_token", fake_persist_token)
monkeypatch.setattr(webapp, "react_to_github_comment", fake_react)
monkeypatch.setattr(webapp, "fetch_pr_comments_since_last_tag", fake_fetch_comments)
monkeypatch.setattr(webapp, "_trigger_or_queue_run", fake_trigger_or_queue_run)
@@ -1214,14 +1047,7 @@ def test_process_github_pr_comment_review_request_without_email_uses_app_token(
)
)
- assert captured["reaction_token"] == "app-token"
- assert captured["fetch_token"] == "app-token"
- assert captured["persisted"] == {
- "thread_id": "00000000-0000-0000-0000-000000000001",
- "token": "app-token",
- "expires_at": "2026-01-01T00:00:00Z",
- }
- assert captured["triggered"]
+ assert captured == {}
def test_process_github_issue_uses_resolved_user_token_for_reaction(monkeypatch) -> None:
@@ -1394,50 +1220,6 @@ def test_process_github_issue_existing_thread_uses_followup_prompt(monkeypatch)
assert "## Repository" not in captured["prompt"]
-def test_parse_github_review_command_standalone() -> None:
- is_review, url = github_comments.parse_github_review_command("@open-swe review")
- assert is_review is True
- assert url is None
-
-
-def test_parse_github_review_command_with_url() -> None:
- is_review, url = github_comments.parse_github_review_command(
- "@open-swe review https://github.com/langchain-ai/open-swe/pull/1244"
- )
- assert is_review is True
- assert url == "https://github.com/langchain-ai/open-swe/pull/1244"
-
-
-def test_parse_github_review_command_case_insensitive_and_aliases() -> None:
- assert github_comments.parse_github_review_command("@OpenSWE Review") == (True, None)
- assert github_comments.parse_github_review_command("@openswe review") == (True, None)
- assert github_comments.parse_github_review_command("@openswe-dev review") == (True, None)
-
-
-def test_parse_github_review_command_freeform_does_not_match() -> None:
- assert github_comments.parse_github_review_command("@open-swe review my code") == (False, None)
- assert github_comments.parse_github_review_command("@open-swe please review") == (False, None)
- assert github_comments.parse_github_review_command("@open-swe fix this") == (False, None)
- assert github_comments.parse_github_review_command("") == (False, None)
-
-
-def test_parse_github_review_command_does_not_swallow_trailing_text() -> None:
- # Trailing text after `review` (on a new line, with punctuation, or extra
- # words) must NOT be parsed as a URL — otherwise the comment would be
- # silently dropped instead of falling through to the regular handler.
- assert github_comments.parse_github_review_command("@open-swe review\nthanks!") == (
- False,
- None,
- )
- assert github_comments.parse_github_review_command("@open-swe review please") == (False, None)
- assert github_comments.parse_github_review_command("@open-swe review now") == (False, None)
- # Non-http schemes are not URLs we can route to a PR.
- assert github_comments.parse_github_review_command("@open-swe review ftp://x/y/pull/1") == (
- False,
- None,
- )
-
-
def test_github_webhook_routes_pr_comment_review_to_agent(monkeypatch) -> None:
captured: dict[str, object] = {}
@@ -1445,13 +1227,7 @@ def test_github_webhook_routes_pr_comment_review_to_agent(monkeypatch) -> None:
captured["payload"] = payload
captured["event_type"] = event_type
- async def fake_process_review_command(
- payload: dict[str, object], event_type: str, pr_url_override: str | None
- ) -> None:
- raise AssertionError("review commands should route through the main agent")
-
monkeypatch.setattr(webapp, "process_github_pr_comment", fake_process_pr_comment)
- monkeypatch.setattr(webapp, "process_github_pr_review_command", fake_process_review_command)
monkeypatch.setattr(webapp, "GITHUB_WEBHOOK_SECRET", _TEST_WEBHOOK_SECRET)
monkeypatch.setattr(webapp, "ALLOWED_GITHUB_ORGS", frozenset({"langchain-ai"}))
@@ -1508,105 +1284,3 @@ def test_github_webhook_routes_pr_review_request_comment_to_agent(monkeypatch) -
assert response.status_code == 200
assert response.json() == {"status": "accepted", "message": "Processing issue_comment event"}
assert captured["event_type"] == "issue_comment"
-
-
-def test_process_github_pr_review_command_uses_payload_pr(monkeypatch) -> None:
- captured: dict[str, object] = {}
-
- async def fake_get_app_token() -> str:
- return "app-token"
-
- async def fake_react(*args, **kwargs) -> None:
- captured["reacted"] = True
-
- async def fake_trigger(
- pr_ref: GitHubPrRef,
- *,
- source: str,
- github_login: str = "",
- github_user_id: int | None = None,
- slack_channel_id: str = "",
- slack_thread_ts: str = "",
- ) -> dict[str, object]:
- captured["pr_ref"] = pr_ref
- captured["source"] = source
- captured["github_login"] = github_login
- captured["github_user_id"] = github_user_id
- return {"success": True, "thread_id": "tid", "pr_url": pr_ref.url}
-
- monkeypatch.setattr(webapp, "get_github_app_installation_token", fake_get_app_token)
- monkeypatch.setattr(webapp, "react_to_github_comment", fake_react)
- monkeypatch.setattr(webapp, "trigger_pr_review_from_ref", fake_trigger)
-
- asyncio.run(
- webapp.process_github_pr_review_command(
- {
- "issue": {
- "number": 1244,
- "html_url": "https://github.com/langchain-ai/open-swe/pull/1244",
- "pull_request": {"url": "..."},
- },
- "comment": {"id": 9, "body": "@open-swe review"},
- "repository": {"owner": {"login": "langchain-ai"}, "name": "open-swe"},
- "sender": {"login": "octocat", "id": 123},
- },
- "issue_comment",
- None,
- )
- )
-
- pr_ref = captured["pr_ref"]
- assert isinstance(pr_ref, GitHubPrRef)
- assert pr_ref.owner == "langchain-ai"
- assert pr_ref.repo == "open-swe"
- assert pr_ref.number == 1244
- assert pr_ref.url == "https://github.com/langchain-ai/open-swe/pull/1244"
- assert captured["source"] == "github"
- assert captured["github_login"] == "octocat"
- assert captured["github_user_id"] == 123
- assert captured.get("reacted") is True
-
-
-def test_process_github_pr_review_command_uses_url_override(monkeypatch) -> None:
- captured: dict[str, object] = {}
-
- async def fake_get_app_token() -> str:
- return "app-token"
-
- async def fake_react(*args, **kwargs) -> None:
- return None
-
- async def fake_trigger(
- pr_ref: GitHubPrRef,
- *,
- source: str,
- github_login: str = "",
- github_user_id: int | None = None,
- slack_channel_id: str = "",
- slack_thread_ts: str = "",
- ) -> dict[str, object]:
- captured["pr_ref"] = pr_ref
- return {"success": True, "thread_id": "tid", "pr_url": pr_ref.url}
-
- monkeypatch.setattr(webapp, "get_github_app_installation_token", fake_get_app_token)
- monkeypatch.setattr(webapp, "react_to_github_comment", fake_react)
- monkeypatch.setattr(webapp, "trigger_pr_review_from_ref", fake_trigger)
-
- asyncio.run(
- webapp.process_github_pr_review_command(
- {
- "issue": {"number": 99, "pull_request": {"url": "..."}},
- "comment": {"id": 1, "body": "@open-swe review https://github.com/x/y/pull/7"},
- "repository": {"owner": {"login": "x"}, "name": "y"},
- "sender": {"login": "octocat", "id": 1},
- },
- "issue_comment",
- "https://github.com/x/y/pull/7",
- )
- )
-
- pr_ref = captured["pr_ref"]
- assert isinstance(pr_ref, GitHubPrRef)
- assert pr_ref.number == 7
- assert pr_ref.owner == "x"
- assert pr_ref.repo == "y"
diff --git a/tests/test_public_repo_org_gate.py b/tests/test_public_repo_org_gate.py
index fa843e7a..4741bd85 100644
--- a/tests/test_public_repo_org_gate.py
+++ b/tests/test_public_repo_org_gate.py
@@ -54,15 +54,9 @@ def test_gate_blocks_non_member_on_public_pr_comment(monkeypatch) -> None:
_common_setup(monkeypatch)
seen = _install_membership_stub(monkeypatch, members={"insider"})
- async def fake_process_github_pr_review_command(*_args, **_kwargs) -> None:
- raise AssertionError("should not be called")
-
async def fake_process_github_pr_comment(*_args, **_kwargs) -> None:
raise AssertionError("should not be called")
- monkeypatch.setattr(
- webapp, "process_github_pr_review_command", fake_process_github_pr_review_command
- )
monkeypatch.setattr(webapp, "process_github_pr_comment", fake_process_github_pr_comment)
client = TestClient(webapp.app)
@@ -254,16 +248,9 @@ def test_gate_blocks_non_member_on_public_issue(monkeypatch) -> None:
assert "not a member" in body["reason"]
-def test_gate_blocks_non_member_on_public_review_requested(monkeypatch) -> None:
+def test_review_requested_is_unsupported_before_public_repo_gate(monkeypatch) -> None:
_common_setup(monkeypatch)
- _install_membership_stub(monkeypatch, members={"insider"})
-
- async def fake_process_github_pr_review_request(*_args, **_kwargs) -> None:
- raise AssertionError("should not be called")
-
- monkeypatch.setattr(
- webapp, "process_github_pr_review_request", fake_process_github_pr_review_request
- )
+ seen = _install_membership_stub(monkeypatch, members={"insider"})
client = TestClient(webapp.app)
response = _post_github_webhook(
@@ -288,9 +275,11 @@ def test_gate_blocks_non_member_on_public_review_requested(monkeypatch) -> None:
)
assert response.status_code == 200
- body = response.json()
- assert body["status"] == "ignored"
- assert "not a member" in body["reason"]
+ assert response.json() == {
+ "status": "ignored",
+ "reason": "Unsupported GitHub pull_request action: review_requested",
+ }
+ assert seen["calls"] == []
def test_gate_allows_internal_bot_sender(monkeypatch) -> None:
diff --git a/tests/test_slack_context.py b/tests/test_slack_context.py
index 9a65bafb..973a8f22 100644
--- a/tests/test_slack_context.py
+++ b/tests/test_slack_context.py
@@ -8,9 +8,7 @@ from agent.utils.slack import (
TRACE_REPLY_TIPS,
convert_mentions_to_slack_format,
format_slack_messages_for_prompt,
- looks_like_slack_pr_review_command,
parse_github_pr_url,
- parse_slack_review_command,
post_slack_trace_reply,
replace_bot_mention_with_username,
select_slack_context_messages,
@@ -155,52 +153,6 @@ def test_parse_github_pr_url_slack_formatted_link() -> None:
assert pr_ref.number == 1244
-def test_parse_slack_review_command_requires_exact_review_command() -> None:
- pr_ref = parse_slack_review_command("review https://github.com/langchain-ai/open-swe/pull/1244")
-
- assert pr_ref is not None
- assert pr_ref.owner == "langchain-ai"
- assert pr_ref.repo == "open-swe"
- assert pr_ref.number == 1244
- assert (
- parse_slack_review_command(
- "please review https://github.com/langchain-ai/open-swe/pull/1244"
- )
- is None
- )
- assert (
- parse_slack_review_command("review https://github.com/langchain-ai/open-swe/issues/1244")
- is None
- )
-
-
-def test_parse_slack_review_command_supports_slack_link() -> None:
- pr_ref = parse_slack_review_command(
- "review "
- )
-
- assert pr_ref is not None
- assert pr_ref.url == "https://github.com/langchain-ai/open-swe/pull/1244"
-
-
-def test_parse_slack_review_command_supports_slack_wrapped_raw_link() -> None:
- pr_ref = parse_slack_review_command(
- "review "
- )
-
- assert pr_ref is not None
- assert pr_ref.url == "https://github.com/langchain-ai/open-swe/pull/1244"
-
-
-def test_looks_like_slack_pr_review_command_validates_github_host() -> None:
- assert looks_like_slack_pr_review_command(
- "review https://github.com/langchain-ai/open-swe/issues/1244"
- )
- assert not looks_like_slack_pr_review_command(
- "review https://example.com/redirect?next=https://github.com/langchain-ai/open-swe/pull/1244"
- )
-
-
def test_format_slack_messages_for_prompt_uses_name_and_id() -> None:
formatted = format_slack_messages_for_prompt(
[{"ts": "1.0", "text": "hello", "user": "U123"}],