""" LLM-specific exceptions. Extends the MarkitectError hierarchy for LLM integration errors. """ from typing import Optional, Dict, Any from markitect.exceptions import MarkitectError class LLMError(MarkitectError): """Base exception for all LLM operations.""" pass class LLMConfigurationError(LLMError): """Missing API key, invalid model name, or bad provider config.""" pass class LLMAPIError(LLMError): """HTTP-level failure from an LLM provider API. Attributes: status_code: HTTP status code (e.g. 500, 502). response_body: Raw response body text, if available. """ def __init__( self, message: str, status_code: int = 0, response_body: str = "", cause: Optional[Exception] = None, context: Optional[Dict[str, Any]] = None, ): super().__init__(message, cause=cause, context=context) self.status_code = status_code self.response_body = response_body class LLMRateLimitError(LLMAPIError): """429 Too Many Requests from the provider.""" pass class LLMTimeoutError(LLMError): """Request or subprocess exceeded the configured timeout.""" pass class LLMSubprocessError(LLMError): """Claude Code CLI subprocess failed. Attributes: return_code: Process exit code. stderr: Captured stderr text. """ def __init__( self, message: str, return_code: int = 1, stderr: str = "", cause: Optional[Exception] = None, context: Optional[Dict[str, Any]] = None, ): super().__init__(message, cause=cause, context=context) self.return_code = return_code self.stderr = stderr