from typing import Optional, Dict, Any from abc import ABC, abstractmethod import httpx class BaseAIProvider(ABC): def __init__(self, api_key: str, model_name: str, base_url: str = None): self.api_key = api_key self.model_name = model_name self.base_url = base_url @abstractmethod async def generate_content(self, prompt: str, system_instruction: str = None) -> str: pass class GeminiProvider(BaseAIProvider): async def generate_content(self, prompt: str, system_instruction: str = None) -> str: # Placeholder for Gemini API Implementation # https://generativelanguage.googleapis.com/v1beta/models/... return f"Gemini Response to: {prompt}" class OpenAIProvider(BaseAIProvider): async def generate_content(self, prompt: str, system_instruction: str = None) -> str: # Placeholder for OpenAI API return f"OpenAI Response to: {prompt}" class OllamaProvider(BaseAIProvider): """ Ollama (Local LLM), compatible with OpenAI client usually, or direct /api/generate """ async def generate_content(self, prompt: str, system_instruction: str = None) -> str: # Placeholder for Ollama API url = f"{self.base_url}/api/generate" payload = { "model": self.model_name, "prompt": prompt, "stream": False } if system_instruction: payload["system"] = system_instruction try: async with httpx.AsyncClient() as client: resp = await client.post(url, json=payload, timeout=60.0) resp.raise_for_status() data = resp.json() return data.get("response", "") except Exception as e: return f"Error: {e}" class AIFactory: @staticmethod def get_provider(provider_type: str, api_key: str, model_name: str, base_url: str = None) -> BaseAIProvider: if provider_type.lower() == "gemini": return GeminiProvider(api_key, model_name, base_url) elif provider_type.lower() == "openai": return OpenAIProvider(api_key, model_name, base_url) elif provider_type.lower() == "ollama": return OllamaProvider(api_key, model_name, base_url) else: raise ValueError(f"Unknown Provider: {provider_type}")