diff --git a/agent/prompt.py b/agent/prompt.py index 9ca415dd..fa5ecb0c 100644 --- a/agent/prompt.py +++ b/agent/prompt.py @@ -6,6 +6,7 @@ from pathlib import Path from .utils.authorship import ( OPEN_SWE_BOT_EMAIL, OPEN_SWE_BOT_NAME, + PR_ATTRIBUTION_FOOTER, CollaboratorIdentity, ) from .utils.github_comments import UNTRUSTED_GITHUB_COMMENT_OPEN_TAG @@ -374,10 +375,10 @@ This run was triggered by **{display_name}**. You author the work **as them** Co-authored-by: open-swe[bot] ``` -- **PR body**: append this line to the bottom of the PR description (separated from the body by a blank line) when you open or update the draft PR. Do not duplicate it if it is already present. If the PR body already contains the legacy footer `_Opened collaboratively by {display_name} and open-swe._`, replace that legacy footer with this line instead of appending a second footer: +- **PR body**: append this line to the bottom of the PR description (separated from the body by a blank line) when you open or update the draft PR. Do not duplicate it if it is already present. If the PR body already contains a legacy footer like `_Opened collaboratively by {display_name} and open-swe._`, replace that legacy footer with this line instead of appending a second footer: ``` - _Opened collaboratively by {pr_attribution_name} and open-swe._ + {pr_attribution_footer} ``` If you forget the trailer on a local commit that has not been pushed, fix it with `git commit --amend` before pushing — do not push without it. If the commit has already been pushed, leave it as-is and add the trailer to your next commit; never rewrite remote history to fix it.""" @@ -388,7 +389,7 @@ def _render_collaboration_section(identity: CollaboratorIdentity | None) -> str: return "" return COLLABORATION_TEMPLATE.format( display_name=identity.display_name, - pr_attribution_name=identity.pr_attribution_name, + pr_attribution_footer=PR_ATTRIBUTION_FOOTER, ) diff --git a/agent/utils/authorship.py b/agent/utils/authorship.py index 9a2c4d69..a5e64534 100644 --- a/agent/utils/authorship.py +++ b/agent/utils/authorship.py @@ -13,6 +13,8 @@ logger = logging.getLogger(__name__) OPEN_SWE_BOT_NAME = "open-swe[bot]" OPEN_SWE_BOT_EMAIL = "open-swe@users.noreply.github.com" +PR_ATTRIBUTION_FOOTER = "Made by [Open SWE](https://openswe.vercel.app)" + @dataclass(frozen=True) class CollaboratorIdentity: @@ -153,24 +155,29 @@ def add_bot_coauthor_trailer(commit_message: str) -> str: def add_pr_collaboration_note( pr_body: str, - identity: CollaboratorIdentity | None, + identity: CollaboratorIdentity | None = None, ) -> str: - """Append a best-effort PR attribution note. + """Append the Open SWE attribution footer to a PR body. - GitHub supports commit co-authors, but not PR co-authors. This note makes - the collaboration explicit in the automatically-opened PR body. + The PR is opened as the triggering user, so the body only credits Open SWE + as the collaborator. Any legacy double-attribution footer is replaced. """ normalized_body = pr_body.rstrip() - if not identity: - return normalized_body - - old_note = f"_Opened collaboratively by {identity.display_name} and open-swe._" - note = f"_Opened collaboratively by {identity.pr_attribution_name} and open-swe._" + note = PR_ATTRIBUTION_FOOTER if note in normalized_body: return normalized_body - if old_note in normalized_body: - return normalized_body.replace(old_note, note) + + legacy_footers: list[str] = [] + if identity is not None: + legacy_footers.append( + f"_Opened collaboratively by {identity.pr_attribution_name} and open-swe._" + ) + legacy_footers.append(f"_Opened collaboratively by {identity.display_name} and open-swe._") + for legacy in legacy_footers: + if legacy in normalized_body: + return normalized_body.replace(legacy, note) + if not normalized_body: return note return f"{normalized_body}\n\n{note}" diff --git a/tests/test_github_comment_prompts.py b/tests/test_github_comment_prompts.py index e0626b4a..a861fcb9 100644 --- a/tests/test_github_comment_prompts.py +++ b/tests/test_github_comment_prompts.py @@ -101,7 +101,7 @@ def test_construct_system_prompt_includes_coauthor_trailer_when_identity_present assert "git config user.name octocat" in prompt assert "git config user.email 1234+octocat@users.noreply.github.com" in prompt assert "Co-authored-by: open-swe[bot] " in prompt - assert "_Opened collaboratively by octocat and open-swe._" in prompt + assert "Made by [Open SWE](https://openswe.vercel.app)" in prompt def test_construct_system_prompt_includes_github_login_in_pr_footer() -> None: @@ -121,7 +121,7 @@ def test_construct_system_prompt_includes_github_login_in_pr_footer() -> None: assert "git config user.name 'Mona Lisa'" in prompt assert "git config user.email 1234+octocat@users.noreply.github.com" in prompt assert "Co-authored-by: open-swe[bot] " in prompt - assert "_Opened collaboratively by Mona Lisa (@octocat) and open-swe._" in prompt + assert "Made by [Open SWE](https://openswe.vercel.app)" in prompt assert ( "replace that legacy footer with this line instead of appending a second footer" in prompt ) @@ -160,7 +160,7 @@ def test_add_pr_collaboration_note_replaces_legacy_footer() -> None: body = "## Description\nDone.\n\n_Opened collaboratively by Mona Lisa and open-swe._" assert add_pr_collaboration_note(body, identity) == ( - "## Description\nDone.\n\n_Opened collaboratively by Mona Lisa (@octocat) and open-swe._" + "## Description\nDone.\n\nMade by [Open SWE](https://openswe.vercel.app)" )