Skip to content
This repository was archived by the owner on Jul 3, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions scripts/run_monthly_codex_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,32 @@ def extract_anthropic_text(response: dict[str, Any]) -> str:
raise BridgeError("Anthropic response did not include text content")


def summarize_api_http_error(provider: str, status_code: int, detail: str) -> str:
error_code = ""
try:
payload = json.loads(detail)
except json.JSONDecodeError:
payload = {}
if isinstance(payload, dict):
error = payload.get("error")
if isinstance(error, dict):
error_code = str(error.get("code") or error.get("type") or "")
if not error_code:
error_code = str(payload.get("code") or payload.get("type") or "")
suffix = f" ({error_code})" if error_code else ""
return f"{provider} API request failed: HTTP {status_code}{suffix}"


def sanitize_fallback_error(error: object) -> str:
text = str(error).replace("\n", " ").strip()
text = re.sub(r"sk-[^\s\"'`]+", "[redacted-api-key]", text)
text = re.sub(r"(?i)(api[-_ ]?key[^:]*:\s*)[^\s\"'`,}]+", r"\1[redacted]", text)
text = re.sub(r"(?i)(x-api-key[^:]*:\s*)[^\s\"'`,}]+", r"\1[redacted]", text)
if len(text) > 300:
text = text[:297].rstrip() + "..."
return text or "provider request failed"


def request_openai_completion(*, system: str, user: str) -> str:
api_key = env_value("OPENAI_API_KEY")
if not api_key:
Expand Down Expand Up @@ -1256,7 +1282,7 @@ def request_openai_completion(*, system: str, user: str) -> str:
body = response.read().decode("utf-8")
except urllib.error.HTTPError as exc:
detail = exc.read().decode("utf-8", errors="replace")
raise BridgeError(f"OpenAI API request failed: {exc.code} {detail[:600]}") from exc
raise BridgeError(summarize_api_http_error("OpenAI", exc.code, detail)) from exc
return extract_openai_text(json.loads(body))


Expand Down Expand Up @@ -1289,7 +1315,7 @@ def request_anthropic_completion(*, system: str, user: str) -> str:
body = response.read().decode("utf-8")
except urllib.error.HTTPError as exc:
detail = exc.read().decode("utf-8", errors="replace")
raise BridgeError(f"Anthropic API request failed: {exc.code} {detail[:600]}") from exc
raise BridgeError(summarize_api_http_error("Anthropic", exc.code, detail)) from exc
return extract_anthropic_text(json.loads(body))


Expand Down Expand Up @@ -1352,7 +1378,7 @@ def run_configured_api_reviews(
try:
reviews.append((label, runner(source_repo, source_ref, issue, comments)))
except BridgeError as exc:
warnings.append(f"{label} fallback failed: `{exc}`")
warnings.append(f"{label} fallback failed: `{sanitize_fallback_error(exc)}`")
return reviews, warnings


Expand Down Expand Up @@ -1777,7 +1803,7 @@ def attempt(workspace_obj: RemediationWorkspace) -> int:
provider=provider_name,
)
if return_code != 0:
warnings.append(f"{provider_name} patch fallback failed: `{log_text}`")
warnings.append(f"{provider_name} patch fallback failed: `{sanitize_fallback_error(log_text)}`")
continue
note = f"{reason} Applied via API fallback provider `{provider_name}`.".strip()
return publish_remediation(
Expand Down
26 changes: 26 additions & 0 deletions tests/test_run_monthly_codex_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,32 @@ def test_run_configured_api_reviews_reports_missing_optional_reviewer(self) -> N
self.assertEqual(reviews, [("OpenAI", "openai review")])
self.assertEqual(warnings, ["Anthropic Claude fallback skipped because `ANTHROPIC_API_KEY` is not configured."])

def test_run_configured_api_reviews_sanitizes_failed_reviewer_errors(self) -> None:
with (
patch.dict(os.environ, {"OPENAI_API_KEY": "openai-key", "ANTHROPIC_API_KEY": "anthropic-key"}, clear=True),
patch(
"scripts.run_monthly_codex_audit.run_openai_review",
side_effect=BridgeError("Incorrect API key provided: sk-proj-secretTail"),
),
patch(
"scripts.run_monthly_codex_audit.run_anthropic_review",
side_effect=BridgeError("Anthropic API request failed: 401 invalid x-api-key"),
),
):
reviews, warnings = run_configured_api_reviews(
"QuantStrategyLab/CryptoLivePoolPipelines",
"main",
{"title": "Monthly Report", "body": "Body"},
[],
)

warning_text = "\n".join(warnings)
self.assertEqual(reviews, [])
self.assertIn("OpenAI fallback failed", warning_text)
self.assertIn("Anthropic Claude fallback failed", warning_text)
self.assertNotIn("sk-proj", warning_text)
self.assertNotIn("secretTail", warning_text)

def test_format_api_review_comment_combines_reviews(self) -> None:
message = format_api_review_comment(
"Codex failed.",
Expand Down
Loading