""" Claude AI Provider implementation """ import logging import subprocess import shutil from typing import Dict, Any, Optional from ..config import settings from ..core import AIProcessingError from .base_provider import AIProvider class ClaudeProvider(AIProvider): """Claude AI provider using CLI""" def __init__(self): self.logger = logging.getLogger(__name__) self._cli_path = settings.CLAUDE_CLI_PATH or shutil.which("claude") self._token = settings.ZAI_AUTH_TOKEN self._base_url = settings.ZAI_BASE_URL @property def name(self) -> str: return "Claude" def is_available(self) -> bool: """Check if Claude CLI is available""" return bool(self._cli_path and self._token) def _get_env(self) -> Dict[str, str]: """Get environment variables for Claude""" env = { 'ANTHROPIC_AUTH_TOKEN': self._token, 'ANTHROPIC_BASE_URL': self._base_url, 'PYTHONUNBUFFERED': '1' } return env def _run_cli(self, prompt: str, timeout: int = 300) -> str: """Run Claude CLI with prompt""" if not self.is_available(): raise AIProcessingError("Claude CLI not available or not configured") try: cmd = [self._cli_path] process = subprocess.run( cmd, input=prompt, env=self._get_env(), text=True, capture_output=True, timeout=timeout, shell=False ) if process.returncode != 0: error_msg = process.stderr or "Unknown error" raise AIProcessingError(f"Claude CLI failed: {error_msg}") return process.stdout.strip() except subprocess.TimeoutExpired: raise AIProcessingError(f"Claude CLI timed out after {timeout}s") except Exception as e: raise AIProcessingError(f"Claude CLI error: {e}") def summarize(self, text: str, **kwargs) -> str: """Generate summary using Claude""" prompt = f"""Summarize the following text: {text} Provide a clear, concise summary in Spanish.""" return self._run_cli(prompt) def correct_text(self, text: str, **kwargs) -> str: """Correct text using Claude""" prompt = f"""Correct the following text for grammar, spelling, and clarity: {text} Return only the corrected text, nothing else.""" return self._run_cli(prompt) def classify_content(self, text: str, **kwargs) -> Dict[str, Any]: """Classify content using Claude""" categories = ["historia", "analisis_contable", "instituciones_gobierno", "otras_clases"] prompt = f"""Classify the following text into one of these categories: - historia - analisis_contable - instituciones_gobierno - otras_clases Text: {text} Return only the category name, nothing else.""" result = self._run_cli(prompt).lower() # Validate result if result not in categories: result = "otras_clases" return { "category": result, "confidence": 0.9, "provider": self.name }