diff --git a/app/ai/client.py b/app/ai/client.py index 6ff06b5..887c7ff 100644 --- a/app/ai/client.py +++ b/app/ai/client.py @@ -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).