open-swe/agent/tools/list_findings.py
Johannes du Plessis 8461979b0d
fix: honest publish_review reporting + structured thread-not-found errors (#1481)
* fix: honest publish_review reporting + structured thread-not-found errors

- Document skipped_empty_re_review and dry_run in the publish_review
  docstring and add a closing-summary contract to the reviewer prompt so
  the agent never claims a review was published when review_id is null.
- Raise ReviewerThreadMissingError from replace_findings on SDK
  NotFoundError; add_finding/update_finding/publish_review return a
  structured do-not-retry result instead of raising, so the agent reports
  the blocker after one failure instead of retrying 10-30 times.

* fix: translate thread 404s across all reviewer tool boundaries

get_thread_metadata now raises ReviewerThreadMissingError instead of
swallowing a missing thread as {} (which produced misleading 'No finding
found' results), set_reviewer_thread_metadata translates the SDK 404 the
same way, and every reviewer tool entrypoint (add/update/list findings,
publish_review incl. eval dry-run, resolve/reply thread) returns the
structured do-not-retry result.

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-06-10 10:44:13 -07:00

41 lines
1.4 KiB
Python

"""Tool: ``list_findings``. Return findings persisted on the reviewer thread."""
from __future__ import annotations
import asyncio
from typing import Any
from ..reviewer_findings import (
ReviewerThreadMissingError,
get_thread_id_from_runtime,
thread_missing_tool_result,
)
from ..reviewer_findings import (
list_findings as list_findings_async,
)
def list_findings(status_filter: str | None = None) -> dict[str, Any]:
"""List findings on the reviewer thread, optionally filtered by status.
Most useful on a re-review run to inspect what existed before deciding
which findings the new commits resolved.
Args:
status_filter: One of ``open``, ``resolved``, ``dismissed``. ``None``
(default) returns every finding regardless of status.
Returns:
Dictionary with ``findings`` (list) and ``count`` (int).
"""
if status_filter is not None and status_filter not in {"open", "resolved", "dismissed"}:
return {"findings": [], "count": 0, "error": f"Invalid status_filter: {status_filter}"}
thread_id = get_thread_id_from_runtime()
try:
findings = asyncio.run(list_findings_async(thread_id))
except ReviewerThreadMissingError as exc:
return thread_missing_tool_result(exc)
if status_filter is not None:
findings = [f for f in findings if f.get("status") == status_filter]
return {"findings": findings, "count": len(findings)}