fix(ai): _call_chat 무동의 Claude egress 자동폴백 제거 (R6)

primary(맥미니) Timeout/ConnectError 시 동의·과금 통제 없이 ai.fallback(Claude API)으로
자동 전환 → 개인 문서/쿼리/메모가 Anthropic 으로 silent egress 되던 프라이버시 결함 봉쇄.
실패는 전파 — 배치 워커는 재시도/StageDeferred(R3), interactive 는 호출자 5xx 표면화
(documents.analyze 이미 502/504). 클라우드는 premium explicit-trigger / call_fallback
명시 호출로만 (자동 진입 금지).

참고: uncoordinated-mlx-semaphores 는 gitea/main 최신에서 digest/briefing 이 이미
acquire_mlx_gate 사용(감사 20커밋 stale 탓 오탐) — 변경 불요. rerank silent-identity 의
rerank_skipped notes 플래그는 시그니처 변경 동반이라 별도 후속(Low).

검증: py_compile 통과.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hyungi
2026-06-16 13:38:46 +09:00
parent cb7c0fdc4f
commit 456dfaa9f2
+10 -7
View File
@@ -289,13 +289,16 @@ class AIClient:
return response.json()
async def _call_chat(self, model_config, prompt: str) -> str:
"""OpenAI 호환 API 호출 + 자동 폴백"""
try:
return await self._request(model_config, prompt)
except (httpx.TimeoutException, httpx.ConnectError):
if model_config == self.ai.primary:
return await self._request(self.ai.fallback, prompt)
raise
"""OpenAI 호환 API 호출 (R6: 무동의 클라우드 폴백 제거).
이전엔 primary(맥미니) TimeoutException/ConnectError 시 동의·과금 통제 없이
self.ai.fallback(Claude API)로 자동 전환 → 개인 문서/쿼리/메모가 Anthropic 으로
silent egress. on-prem 추론 프라이버시 계약 위반이라 봉쇄한다. 실패는 그대로 전파:
배치 워커는 재시도/StageDeferred(R3·queue_consumer), interactive 호출자는 5xx 표면화
(documents.analyze 등 이미 502/504 변환). 클라우드는 premium explicit-trigger
(summarize force_premium) 또는 call_fallback 명시 호출로만 — 자동 진입 금지.
"""
return await self._request(model_config, prompt)
async def _request(self, model_config, prompt: str, system: str | None = None) -> str:
"""단일 모델 API 호출 (OpenAI 호환 + Anthropic Messages API).