|
|
""" |
|
|
Chat engine for FleetMind |
|
|
Main orchestrator for AI-powered conversations with multi-provider support |
|
|
""" |
|
|
|
|
|
import os |
|
|
import logging |
|
|
from typing import Tuple, List, Dict |
|
|
|
|
|
from chat.providers import ClaudeProvider, GeminiProvider |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
class ChatEngine: |
|
|
"""Main orchestrator for AI chat conversations with multi-provider support""" |
|
|
|
|
|
def __init__(self): |
|
|
|
|
|
provider_name = os.getenv("AI_PROVIDER", "anthropic").lower() |
|
|
|
|
|
logger.info(f"ChatEngine: Selected provider: {provider_name}") |
|
|
|
|
|
|
|
|
if provider_name == "gemini": |
|
|
self.provider = GeminiProvider() |
|
|
logger.info("ChatEngine: Using Gemini provider") |
|
|
elif provider_name == "anthropic": |
|
|
self.provider = ClaudeProvider() |
|
|
logger.info("ChatEngine: Using Claude provider") |
|
|
else: |
|
|
|
|
|
logger.warning(f"ChatEngine: Unknown provider '{provider_name}', defaulting to Claude") |
|
|
self.provider = ClaudeProvider() |
|
|
|
|
|
|
|
|
self.selected_provider = provider_name |
|
|
|
|
|
def is_available(self) -> bool: |
|
|
"""Check if the chat engine is available""" |
|
|
return self.provider.is_available() |
|
|
|
|
|
def get_status(self) -> str: |
|
|
"""Get status message for UI""" |
|
|
provider_status = self.provider.get_status() |
|
|
provider_name = self.provider.get_provider_name() |
|
|
|
|
|
return f"**{provider_name}:** {provider_status}" |
|
|
|
|
|
def get_provider_name(self) -> str: |
|
|
"""Get the active provider name""" |
|
|
return self.provider.get_provider_name() |
|
|
|
|
|
def get_model_name(self) -> str: |
|
|
"""Get the active model name""" |
|
|
return self.provider.get_model_name() |
|
|
|
|
|
def process_message( |
|
|
self, |
|
|
user_message: str, |
|
|
conversation |
|
|
) -> Tuple[str, List[Dict]]: |
|
|
""" |
|
|
Process user message and return AI response |
|
|
|
|
|
Args: |
|
|
user_message: User's message |
|
|
conversation: ConversationManager instance |
|
|
|
|
|
Returns: |
|
|
Tuple of (assistant_response, tool_calls_made) |
|
|
""" |
|
|
return self.provider.process_message(user_message, conversation) |
|
|
|
|
|
def get_welcome_message(self) -> str: |
|
|
"""Get welcome message for new conversations""" |
|
|
return self.provider.get_welcome_message() |
|
|
|
|
|
def get_full_status(self) -> Dict[str, str]: |
|
|
""" |
|
|
Get detailed status for all providers |
|
|
|
|
|
Returns: |
|
|
Dict with status for each provider |
|
|
""" |
|
|
|
|
|
claude_key = os.getenv("ANTHROPIC_API_KEY", "") |
|
|
gemini_key = os.getenv("GOOGLE_API_KEY", "") |
|
|
|
|
|
claude_available = bool(claude_key and not claude_key.startswith("your_")) |
|
|
gemini_available = bool(gemini_key and not gemini_key.startswith("your_")) |
|
|
|
|
|
claude_status = "β
Connected - Model: claude-3-5-sonnet-20241022" if claude_available else "β οΈ Not configured (add ANTHROPIC_API_KEY)" |
|
|
gemini_status = f"β
Connected - Model: {self.provider.get_model_name()}" if (self.selected_provider == "gemini" and gemini_available) else "β οΈ Not configured (add GOOGLE_API_KEY)" if not gemini_available else "β
Configured" |
|
|
|
|
|
return { |
|
|
"selected": self.selected_provider, |
|
|
"claude": { |
|
|
"name": "Claude (Anthropic)", |
|
|
"status": claude_status, |
|
|
"available": claude_available |
|
|
}, |
|
|
"gemini": { |
|
|
"name": "Gemini (Google)", |
|
|
"status": gemini_status, |
|
|
"available": gemini_available |
|
|
} |
|
|
} |
|
|
|