mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 10:23:14 +00:00
* fix(reviewer): inject existing PR review threads into reviewer context The reviewer agent was filing the same inline comment on every re-review because it only saw findings recorded on its own thread metadata — not the live PR review-thread state on GitHub. When a previous finding was still open (code unchanged, or a human reply explained it), the agent rediscovered the same defect on the next push and called `add_finding` again, producing duplicate comments. This change fetches the PR's review threads (across all reviewers, with replies and isResolved status) via GraphQL and renders them into the first-review and re-review contexts as a "Pre-existing PR review threads" block. The system prompt now lists overlap with that block as a hard "Do NOT file" rule, and treats threads addressed by a human reply as resolved. This also gives the reviewer comment-awareness on its very first run on a PR, so it skips findings already raised by another reviewer or bot. * fix(reviewer): wrap PR review threads in untrusted-data XML block Addresses the reviewer comment on this PR (https://github.com/langchain-ai/open-swe/pull/1331#discussion_r3295497533): PR review comment bodies are attacker-controlled (anyone who can comment on the PR can put anything in them), and they were being concatenated into the reviewer's system prompt with instruction-priority. Switches the existing-threads section from a Markdown block to an XML data block: <pr_review_threads> <thread location="path:line" status="open"> <comment author="open-swe[bot]"> <body>...</body> </comment> <comment author="romain-priour-lc"> <body>We added defaults in the template</body> </comment> </thread> </pr_review_threads> The system prompt now explicitly names the wrapper, tells the agent that everything inside it is untrusted data from the PR (not instructions), and that prompt-injection payloads inside bodies must be disregarded. We keep the bodies so the agent can actually read engineer replies — that's the whole point of comment-awareness — but they're delimited as data, not concatenated as prose. Modern frontier models are well-trained to honor this contract. Additional defenses: - Author logins are validated against the GitHub username grammar; any unexpected value is rendered as "unknown" so the `author` attribute can't smuggle freeform text. - Literal closing tags (`</body>`, `</pr_review_threads>`, etc.) in bodies are neutered so a body can't break out of its wrapper. - Body length is capped at 4000 chars per comment to bound the prompt. --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| middleware | ||
| conftest.py | ||
| test_anthropic_effort.py | ||
| test_auth_sources.py | ||
| test_dashboard_message_adapter.py | ||
| test_daytona_integration.py | ||
| test_encryption.py | ||
| test_ensure_no_empty_msg.py | ||
| test_github_comment_prompts.py | ||
| test_github_issue_webhook.py | ||
| test_github_oauth_refresh.py | ||
| test_github_token_ttl.py | ||
| test_google_model.py | ||
| test_http_security.py | ||
| test_langsmith_sandbox_config.py | ||
| test_messages_reducer_patch.py | ||
| test_model_fallback_middleware.py | ||
| test_multimodal.py | ||
| test_normalize_repo.py | ||
| test_notify_step_limit_middleware.py | ||
| test_pr_ready_auto_review.py | ||
| test_proxy_auth.py | ||
| test_public_repo_org_gate.py | ||
| test_recent_comments.py | ||
| test_refresh_slack_status_middleware.py | ||
| test_repo_extraction.py | ||
| test_review_style_collector.py | ||
| test_review_style_sync.py | ||
| test_review_styles_store.py | ||
| test_reviewer.py | ||
| test_reviewer_diff.py | ||
| test_reviewer_eval_run.py | ||
| test_reviewer_eval_target.py | ||
| test_reviewer_findings.py | ||
| test_reviewer_publish.py | ||
| test_reviewer_tools.py | ||
| test_reviewer_watch.py | ||
| test_sandbox_paths.py | ||
| test_sanitize_tool_inputs.py | ||
| test_slack_assistants_status.py | ||
| test_slack_context.py | ||
| test_slack_feedback.py | ||