diff --git a/pr_agent/tools/pr_code_suggestions.py b/pr_agent/tools/pr_code_suggestions.py index 0fdc8019fe..5fbee9f202 100644 --- a/pr_agent/tools/pr_code_suggestions.py +++ b/pr_agent/tools/pr_code_suggestions.py @@ -333,12 +333,16 @@ def _extract_link(comment_text: str): pr_comment_updated += f"{prev_suggestion_table}\n" get_logger().info(f"Persistent mode - updating comment {comment_url} to latest {name} message") - if progress_response: # publish to 'progress_response' comment, because it refreshes immediately - git_provider.edit_comment(progress_response, pr_comment_updated) - git_provider.remove_comment(comment) - comment = progress_response - else: - git_provider.edit_comment(comment, pr_comment_updated) + git_provider.edit_comment(comment, pr_comment_updated) + if progress_response: + # best-effort: propagating would re-trigger the duplicate-thread fallback below + try: + git_provider.edit_comment(progress_response, "Code suggestions published in the persistent thread above.") + git_provider.remove_comment(progress_response) + except Exception as cleanup_error: + get_logger().warning( + f"Failed to clean up progress note after persistent update, leaving it in place: {cleanup_error}" + ) return comment except Exception as e: get_logger().exception(f"Failed to update persistent review, error: {e}") diff --git a/tests/unittest/test_pr_code_suggestions_core.py b/tests/unittest/test_pr_code_suggestions_core.py index 0522c1fb9f..1a20a9f74c 100644 --- a/tests/unittest/test_pr_code_suggestions_core.py +++ b/tests/unittest/test_pr_code_suggestions_core.py @@ -180,3 +180,30 @@ async def test_push_inline_code_suggestions_falls_back_to_individual_publish_cal assert second_retry[0]["relevant_lines_start"] == 2 assert second_retry[0]["relevant_lines_end"] == 2 assert "```suggestion\n return new_worker()" in second_retry[0]["body"] + + +def test_persistent_update_survives_progress_cleanup_failure(): + """A failing progress-note cleanup must not abort the persistent update: + if the cleanup error propagated, the caller would fall back to publishing + a new suggestions thread, re-creating the duplicate-thread bug.""" + initial_header = "## PR Code Suggestions" + existing = MagicMock() + existing.body = f"{initial_header}\n\n