feat: complete production hardening implementation, specialty canonicalization, google-genai migration, voice reliability, sqlite concurrency, and test suite consolidation

This commit is contained in:
2026-09-07 12:57:54 +05:30
parent c23d979338
commit 92fa71ae4a
99 changed files with 5167 additions and 3550 deletions
@@ -0,0 +1,9 @@
"""
Providers package.
"""
from app.ai.providers.base import LLMProvider
from app.ai.providers.openai import OpenAIProvider
from app.ai.providers.gemini import GeminiProvider
__all__ = ["LLMProvider", "OpenAIProvider", "GeminiProvider"]
@@ -0,0 +1,30 @@
"""
Base LLM Provider interface with hard async timeout enforcement.
"""
import asyncio
from abc import ABC, abstractmethod
from typing import Optional
class LLMProvider(ABC):
"""
Abstract LLM Provider interface.
Enforces a strict hard timeout (default 4 seconds).
"""
def __init__(self, timeout_seconds: float = 4.0):
self.timeout_seconds = timeout_seconds
async def generate_response_with_timeout(self, system_prompt: str, user_message: str) -> Optional[str]:
try:
return await asyncio.wait_for(
self._generate_internal(system_prompt, user_message),
timeout=self.timeout_seconds
)
except (asyncio.TimeoutError, Exception) as e:
print(f"[{self.__class__.__name__} Failed / Timed out]: {e}")
return None
@abstractmethod
async def _generate_internal(self, system_prompt: str, user_message: str) -> Optional[str]:
pass
@@ -0,0 +1,19 @@
"""
Gemini LLM Provider.
"""
from typing import Optional
from app.ai.providers.base import LLMProvider
from app.ai.gemini_client import GeminiClient
class GeminiProvider(LLMProvider):
def __init__(self, timeout_seconds: float = 4.0):
super().__init__(timeout_seconds=timeout_seconds)
self.client = GeminiClient()
async def _generate_internal(self, system_prompt: str, user_message: str) -> Optional[str]:
api_key = getattr(self.client, "api_key", None)
if not api_key or api_key in ["your_gemini_key", "your_gemini_api_key", ""]:
return None
return await self.client.generate_response(system_prompt, user_message)
@@ -0,0 +1,19 @@
"""
OpenAI LLM Provider.
"""
from typing import Optional
from app.ai.providers.base import LLMProvider
from app.ai.openai_client import OpenAIClient
class OpenAIProvider(LLMProvider):
def __init__(self, timeout_seconds: float = 4.0):
super().__init__(timeout_seconds=timeout_seconds)
self.client = OpenAIClient()
async def _generate_internal(self, system_prompt: str, user_message: str) -> Optional[str]:
api_key = getattr(self.client, "api_key", None)
if not api_key or api_key in ["your_openai_key", "your_openai_api_key", ""]:
return None
return await self.client.generate_response(system_prompt, user_message)