Private
Public Access
0
0

refactor(ai_client): migrate 3 run_tier4_* sites to Result[T] (Phase 10 sites 7+8+9)

All 3 run_tier4_* functions had the same pattern:
  try: ... AI call ...
  except Exception as e: return '[XXX FAILED] {e}' (or None)

Per TIER1_REVIEW: empty-default return = MIGRATE to Result[T].

New helpers:
- _run_tier4_analysis_result(stderr: str) -> Result[str]
  Returns Result(data=analysis) on success, Result(data='', errors=[ErrorInfo])
  on SDK failure. Empty stderr short-circuits to Result(data='').
- _run_tier4_patch_callback_result(stderr: str, base_dir: str) -> Result[Optional[str]]
  Returns Result(data=patch) on valid diff, Result(data=None) when no
  valid diff, Result(data=None, errors=[ErrorInfo]) on SDK failure.
- _run_tier4_patch_generation_result(error: str, file_context: str) -> Result[str]
  Returns Result(data=patch) on success, Result(data='', errors=[ErrorInfo])
  on SDK failure. Empty error short-circuits to Result(data='').

Legacy wrappers delegate to _result helpers and return result.data,
preserving original signatures (str for sites 7,9; Optional[str] for site 8).

Existing tier4 tests pass (13/13 in test_tier4_patch_generation +
test_tier4_interceptor).

Audit: ai_client BC 3 -> 0. All 9 Phase 10 BC sites migrated.
This commit is contained in:
2026-06-20 13:17:41 -04:00
parent 5822ea8e65
commit 40a60e63d6
2 changed files with 115 additions and 21 deletions
+61 -21
View File
@@ -2970,17 +2970,22 @@ def _get_llama_cost_tracking() -> bool:
#region: Tier 4 Analysis
def run_tier4_analysis(stderr: str) -> str:
def _run_tier4_analysis_result(stderr: str) -> Result[str]:
"""Tier 4 QA agent: analyze stderr and propose a fix in ~20 words.
Returns Result(data=analysis) on success, Result(data="", errors=[ErrorInfo])
on SDK failure. The legacy caller (run_tier4_analysis) returns result.data
(preserving the original str signature; failures surface as empty string
to keep the qa_callback contract).
"""
"""
genai = _require_warmed("google.genai")
types = genai.types
if not stderr or not stderr.strip():
return ""
return Result(data="")
try:
_ensure_gemini_client()
if not _gemini_client:
return ""
return Result(data="")
genai = _require_warmed("google.genai")
types = genai.types
prompt = (
f"You are a Tier 4 QA Agent specializing in error analysis.\n"
f"Analyze the following stderr output from a PowerShell command:\n\n"
@@ -2997,15 +3002,29 @@ def run_tier4_analysis(stderr: str) -> str:
)
)
analysis = resp.text.strip() if resp.text else ""
return analysis
return Result(data=analysis)
except Exception as e:
return f"[QA ANALYSIS FAILED] {e}"
return Result(
data="",
errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=f"[QA ANALYSIS FAILED] {e}", source="ai_client._run_tier4_analysis_result", original=e)],
)
def run_tier4_analysis(stderr: str) -> str:
return _run_tier4_analysis_result(stderr).data
#endregion: Tier 4 Analysis
#region: Session & Public API
def run_tier4_patch_callback(stderr: str, base_dir: str) -> Optional[str]:
def _run_tier4_patch_callback_result(stderr: str, base_dir: str) -> Result[Optional[str]]:
"""Tier 4 QA agent: propose a unified-diff patch for the stderr.
Returns Result(data=patch) when a valid diff is produced, Result(data=None)
when no valid diff, Result(data=None, errors=[ErrorInfo]) on SDK failure.
The legacy caller (run_tier4_patch_callback) returns result.data
(preserving the original Optional[str] signature).
"""
try:
file_items = project_manager.get_current_file_items()
file_context = ""
@@ -3015,23 +3034,34 @@ def run_tier4_patch_callback(stderr: str, base_dir: str) -> Optional[str]:
file_context += f"\n\nFile: {path}\n```\n{content}\n```\n"
patch = run_tier4_patch_generation(stderr, file_context)
if patch and "---" in patch and "+++" in patch:
return patch
return None
return Result(data=patch)
return Result(data=None)
except Exception as e:
return None
return Result(
data=None,
errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=f"tier4 patch callback failed: {e}", source="ai_client._run_tier4_patch_callback_result", original=e)],
)
def run_tier4_patch_generation(error: str, file_context: str) -> str:
def run_tier4_patch_callback(stderr: str, base_dir: str) -> Optional[str]:
return _run_tier4_patch_callback_result(stderr, base_dir).data
def _run_tier4_patch_generation_result(error: str, file_context: str) -> Result[str]:
"""Tier 4 QA agent: generate a unified-diff patch for the given error.
Returns Result(data=patch) on success, Result(data="", errors=[ErrorInfo])
on SDK failure. The legacy caller (run_tier4_patch_generation) returns
result.data (preserving the original str signature; failures surface as
empty string to keep callers' downstream code working).
"""
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_calls_ai, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_empty_error, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_returns_diff]
"""
genai = _require_warmed("google.genai")
types = genai.types
if not error or not error.strip():
return ""
return Result(data="")
try:
_ensure_gemini_client()
if not _gemini_client:
return ""
return Result(data="")
genai = _require_warmed("google.genai")
types = genai.types
prompt = (
f"{mma_prompts.TIER4_PATCH_PROMPT}\n\n"
f"Error:\n```\n{error}\n```\n\n"
@@ -3047,9 +3077,19 @@ def run_tier4_patch_generation(error: str, file_context: str) -> str:
)
)
patch = resp.text.strip() if resp.text else ""
return patch
return Result(data=patch)
except Exception as e:
return f"[PATCH GENERATION FAILED] {e}"
return Result(
data="",
errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=f"[PATCH GENERATION FAILED] {e}", source="ai_client._run_tier4_patch_generation_result", original=e)],
)
def run_tier4_patch_generation(error: str, file_context: str) -> str:
"""
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_calls_ai, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_empty_error, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_returns_diff]
"""
return _run_tier4_patch_generation_result(error, file_context).data
def get_token_stats(md_content: str) -> dict[str, Any]:
"""
+54
View File
@@ -0,0 +1,54 @@
"""Phase 10 sites 7+8+9: run_tier4_* Result helpers.
Site 7 (run_tier4_analysis): returns str with '[QA ANALYSIS FAILED]' on error.
Site 8 (run_tier4_patch_callback): returns Optional[str] with None on error.
Site 9 (run_tier4_patch_generation): returns str with '[PATCH GENERATION FAILED]' on error.
All 3 follow the same pattern:
try: ...AI call...
except Exception as e: return "[XXX FAILED] {e}" (or None)
Migrate via Result[str] / Result[Optional[str]] helpers.
"""
import sys
sys.path.insert(0, ".")
def test_phase10_sites789_run_tier4_analysis_result_exists():
import src.ai_client
assert hasattr(src.ai_client, "_run_tier4_analysis_result"), \
"_run_tier4_analysis_result helper missing"
def test_phase10_sites789_run_tier4_patch_callback_result_exists():
import src.ai_client
assert hasattr(src.ai_client, "_run_tier4_patch_callback_result"), \
"_run_tier4_patch_callback_result helper missing"
def test_phase10_sites789_run_tier4_patch_generation_result_exists():
import src.ai_client
assert hasattr(src.ai_client, "_run_tier4_patch_generation_result"), \
"_run_tier4_patch_generation_result helper missing"
def test_phase10_sites789_all_helpers_return_result():
import src.ai_client
import inspect
for name in ("_run_tier4_analysis_result",
"_run_tier4_patch_callback_result",
"_run_tier4_patch_generation_result"):
fn = getattr(src.ai_client, name)
sig = inspect.signature(fn)
assert "Result" in str(sig.return_annotation), \
f"{name} return must be Result, got {sig.return_annotation}"
def test_phase10_sites789_legacy_unchanged():
"""Legacy functions must still exist + be callable."""
import src.ai_client
for name in ("run_tier4_analysis",
"run_tier4_patch_callback",
"run_tier4_patch_generation"):
assert hasattr(src.ai_client, name), f"{name} missing"
assert callable(getattr(src.ai_client, name)), f"{name} not callable"