LLM Client wrapper supporting multiple providers. This class provides a unified interface for different LLM providers. It automatically instantiates the correct underlying client based on the provider parameter. For MiniMax API (api.minimax.io or api.minimaxi.com), it appends the
| 16 | |
| 17 | |
| 18 | class LLMClient: |
| 19 | """LLM Client wrapper supporting multiple providers. |
| 20 | |
| 21 | This class provides a unified interface for different LLM providers. |
| 22 | It automatically instantiates the correct underlying client based on |
| 23 | the provider parameter. |
| 24 | |
| 25 | For MiniMax API (api.minimax.io or api.minimaxi.com), it appends the |
| 26 | appropriate endpoint suffix based on provider: |
| 27 | - anthropic: /anthropic |
| 28 | - openai: /v1 |
| 29 | |
| 30 | For third-party APIs, it uses the api_base as-is. |
| 31 | """ |
| 32 | |
| 33 | # MiniMax API domains that need automatic suffix handling |
| 34 | MINIMAX_DOMAINS = ("api.minimax.io", "api.minimaxi.com") |
| 35 | |
| 36 | def __init__( |
| 37 | self, |
| 38 | api_key: str, |
| 39 | provider: LLMProvider = LLMProvider.ANTHROPIC, |
| 40 | api_base: str = "https://api.minimaxi.com", |
| 41 | model: str = "MiniMax-M2.5", |
| 42 | retry_config: RetryConfig | None = None, |
| 43 | ): |
| 44 | """Initialize LLM client with specified provider. |
| 45 | |
| 46 | Args: |
| 47 | api_key: API key for authentication |
| 48 | provider: LLM provider (anthropic or openai) |
| 49 | api_base: Base URL for the API (default: https://api.minimaxi.com) |
| 50 | For MiniMax API, suffix is auto-appended based on provider. |
| 51 | For third-party APIs (e.g., https://api.siliconflow.cn/v1), used as-is. |
| 52 | model: Model name to use |
| 53 | retry_config: Optional retry configuration |
| 54 | """ |
| 55 | self.provider = provider |
| 56 | self.api_key = api_key |
| 57 | self.model = model |
| 58 | self.retry_config = retry_config or RetryConfig() |
| 59 | |
| 60 | # Normalize api_base (remove trailing slash) |
| 61 | api_base = api_base.rstrip("/") |
| 62 | |
| 63 | # Check if this is a MiniMax API endpoint |
| 64 | is_minimax = any(domain in api_base for domain in self.MINIMAX_DOMAINS) |
| 65 | |
| 66 | if is_minimax: |
| 67 | # For MiniMax API, ensure correct suffix based on provider |
| 68 | # Strip any existing suffix first |
| 69 | api_base = api_base.replace("/anthropic", "").replace("/v1", "") |
| 70 | if provider == LLMProvider.ANTHROPIC: |
| 71 | full_api_base = f"{api_base}/anthropic" |
| 72 | elif provider == LLMProvider.OPENAI: |
| 73 | full_api_base = f"{api_base}/v1" |
| 74 | else: |
| 75 | raise ValueError(f"Unsupported provider: {provider}") |
no outgoing calls