Private
Public Access
refactor(ai_client): extract _delete_gemini_cache_result helper (Phase 10 sites 2+3)
Sites L1680 (cache.delete on context change) and L1692 (cache.delete on
TTL expiry) had identical patterns:
try: _gemini_client.caches.delete(name=_gemini_cache.name)
except Exception as e: _append_comms('OUT', 'request', {'message': f'[CACHE DELETE WARN] {e}'})
Per TIER1_REVIEW: logging is NOT a drain. MIGRATE to Result[T].
Single helper _delete_gemini_cache_result() -> Result[None]:
- Returns Result(data=None) on success
- Returns Result(data=None, errors=[ErrorInfo]) on SDK failure + logs warning to comms
- Caller (_send_gemini) ignores errors (best-effort cleanup)
Audit: ai_client BC 8 -> 6. Both sites migrated.
This commit is contained in:
+21
-6
@@ -1616,6 +1616,25 @@ def _ensure_gemini_client() -> None:
|
|||||||
creds = _load_credentials()
|
creds = _load_credentials()
|
||||||
_gemini_client = genai.Client(api_key=creds["gemini"]["api_key"])
|
_gemini_client = genai.Client(api_key=creds["gemini"]["api_key"])
|
||||||
|
|
||||||
|
def _delete_gemini_cache_result() -> Result[None]:
|
||||||
|
"""Delete the active Gemini cache. Returns Result[None].
|
||||||
|
|
||||||
|
On SDK failure, returns Result(data=None, errors=[ErrorInfo]) and logs
|
||||||
|
a warning to comms. The caller ignores errors (cache-delete is a
|
||||||
|
best-effort cleanup; the caller proceeds to rebuild cache state).
|
||||||
|
"""
|
||||||
|
if _gemini_cache is None or _gemini_client is None:
|
||||||
|
return Result(data=None)
|
||||||
|
try:
|
||||||
|
_gemini_client.caches.delete(name=_gemini_cache.name)
|
||||||
|
return Result(data=None)
|
||||||
|
except Exception as e:
|
||||||
|
_append_comms("OUT", "request", {"message": f"[CACHE DELETE WARN] {e}"})
|
||||||
|
return Result(
|
||||||
|
data=None,
|
||||||
|
errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=f"failed to delete gemini cache: {e}", source="ai_client._delete_gemini_cache_result", original=e)],
|
||||||
|
)
|
||||||
|
|
||||||
def _extract_gemini_thoughts(resp: Any) -> str:
|
def _extract_gemini_thoughts(resp: Any) -> str:
|
||||||
"""
|
"""
|
||||||
Extracts concatenated thinking text from a Gemini response object's parts.
|
Extracts concatenated thinking text from a Gemini response object's parts.
|
||||||
@@ -1675,9 +1694,7 @@ def _send_gemini(md_content: str, user_message: str, base_dir: str,
|
|||||||
if _gemini_chat and _gemini_cache_md_hash != current_md_hash:
|
if _gemini_chat and _gemini_cache_md_hash != current_md_hash:
|
||||||
old_history = list(_get_gemini_history_list(_gemini_chat)) if _get_gemini_history_list(_gemini_chat) else []
|
old_history = list(_get_gemini_history_list(_gemini_chat)) if _get_gemini_history_list(_gemini_chat) else []
|
||||||
if _gemini_cache:
|
if _gemini_cache:
|
||||||
#TODO(Ed): Review(Exception)
|
_delete_gemini_cache_result()
|
||||||
try: _gemini_client.caches.delete(name=_gemini_cache.name)
|
|
||||||
except Exception as e: _append_comms("OUT", "request", {"message": f"[CACHE DELETE WARN] {e}"})
|
|
||||||
_gemini_chat = None
|
_gemini_chat = None
|
||||||
_gemini_cache = None
|
_gemini_cache = None
|
||||||
_gemini_cache_created_at = None
|
_gemini_cache_created_at = None
|
||||||
@@ -1687,9 +1704,7 @@ def _send_gemini(md_content: str, user_message: str, base_dir: str,
|
|||||||
elapsed = time.time() - _gemini_cache_created_at
|
elapsed = time.time() - _gemini_cache_created_at
|
||||||
if elapsed > _GEMINI_CACHE_TTL * 0.9:
|
if elapsed > _GEMINI_CACHE_TTL * 0.9:
|
||||||
old_history = list(_get_gemini_history_list(_gemini_chat)) if _get_gemini_history_list(_gemini_chat) else []
|
old_history = list(_get_gemini_history_list(_gemini_chat)) if _get_gemini_history_list(_gemini_chat) else []
|
||||||
#TODO(Ed): Review(Exception)
|
_delete_gemini_cache_result()
|
||||||
try: _gemini_client.caches.delete(name=_gemini_cache.name)
|
|
||||||
except Exception as e: _append_comms("OUT", "request", {"message": f"[CACHE DELETE WARN] {e}"})
|
|
||||||
_gemini_chat = None
|
_gemini_chat = None
|
||||||
_gemini_cache = None
|
_gemini_cache = None
|
||||||
_gemini_cache_created_at = None
|
_gemini_cache_created_at = None
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"""Phase 10 invariant tests (RED) — sites 2+3: _delete_gemini_cache_result.
|
||||||
|
|
||||||
|
Sites 2 (L1680) and 3 (L1692): both are
|
||||||
|
try: _gemini_client.caches.delete(name=_gemini_cache.name)
|
||||||
|
except Exception as e: _append_comms("OUT", "request", {"message": f"[CACHE DELETE WARN] {e}"})
|
||||||
|
|
||||||
|
Migrate via single helper _delete_gemini_cache_result() -> Result[None].
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, ".")
|
||||||
|
|
||||||
|
|
||||||
|
def test_phase10_site23_delete_gemini_cache_result_exists():
|
||||||
|
import src.ai_client
|
||||||
|
assert hasattr(src.ai_client, "_delete_gemini_cache_result"), \
|
||||||
|
"_delete_gemini_cache_result helper missing"
|
||||||
|
|
||||||
|
|
||||||
|
def test_phase10_site23_delete_gemini_cache_result_returns_result():
|
||||||
|
"""The helper must return Result[None]."""
|
||||||
|
import src.ai_client
|
||||||
|
import inspect
|
||||||
|
fn = src.ai_client._delete_gemini_cache_result
|
||||||
|
sig = inspect.signature(fn)
|
||||||
|
assert "Result" in str(sig.return_annotation), \
|
||||||
|
f"_delete_gemini_cache_result return must be Result, got {sig.return_annotation}"
|
||||||
Reference in New Issue
Block a user