diff --git a/README.md b/README.md
index c84fb1d..e0b5ecf 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,11 @@ The APIs remain identical between all supported providers / models:
"ollama" |
"llama3.2" |
+
+ | MiniMax |
+ "minimax" / "minimax-anthropic" |
+ "MiniMax-M3" |
+
| OpenAI's GPT |
"openai" |
@@ -70,6 +75,8 @@ The APIs remain identical between all supported providers / models:
+MiniMax supports the `MiniMax-M3` and `MiniMax-M2.7` model IDs. The `minimax` provider uses its OpenAI-compatible API and `minimax-anthropic` uses its Anthropic-compatible API. Set `MINIMAX_API_REGION` to `global_en` (the default) for `https://api.minimax.io/v1` and `https://api.minimax.io/anthropic`, or to `cn_zh` for `https://api.minimaxi.com/v1` and `https://api.minimaxi.com/anthropic`. See the [global](https://platform.minimax.io/docs) or [mainland China](https://platform.minimaxi.com/docs) documentation for details.
+
To specify a specific provider or model, you can use the `llm_provider` and `llm_model` parameters when calling: `generate_text`, `generate_data`, or `create_conversation`.
If you want to see Simplemind support additional providers or models, please send a pull request!
@@ -88,7 +95,7 @@ First, authenticate your API keys by setting them in the environment variables:
$ export OPENAI_API_KEY="sk-..."
```
-This pattern allows you to keep your API keys private and out of your codebase. Other supported environment variables: `ANTHROPIC_API_KEY`, `XAI_API_KEY`, `DEEPSEEK_API_KEY`, `GROQ_API_KEY`, and `GEMINI_API_KEY`.
+This pattern allows you to keep your API keys private and out of your codebase. Other supported environment variables: `ANTHROPIC_API_KEY`, `XAI_API_KEY`, `DEEPSEEK_API_KEY`, `GROQ_API_KEY`, `GEMINI_API_KEY`, and `MINIMAX_API_KEY`.
Next, import Simplemind and start using it:
diff --git a/pyproject.toml b/pyproject.toml
index 3da756e..98acd25 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,6 +21,7 @@ gemini = ["google-generativeai", "jsonref"]
groq = ["groq"]
ollama = ["openai"]
openai = ["openai"]
+minimax = ["openai", "anthropic"]
xai = ["openai"]
deepseek = ["openai"]
diff --git a/simplemind/providers/__init__.py b/simplemind/providers/__init__.py
index c588b5a..a2cbf94 100644
--- a/simplemind/providers/__init__.py
+++ b/simplemind/providers/__init__.py
@@ -6,6 +6,7 @@
from .anthropic import Anthropic
from .gemini import Gemini
from .groq import Groq
+from .minimax import MiniMax, MiniMaxAnthropic
from .ollama import Ollama
from .openai import OpenAI
from .xai import XAI
@@ -20,6 +21,8 @@
XAI,
Amazon,
Deepseek,
+ MiniMax,
+ MiniMaxAnthropic,
]
__all__ = [
@@ -33,5 +36,7 @@
"providers",
"BaseProvider",
"BaseTool",
- "Deepseek"
+ "Deepseek",
+ "MiniMax",
+ "MiniMaxAnthropic",
]
diff --git a/simplemind/providers/minimax.py b/simplemind/providers/minimax.py
new file mode 100644
index 0000000..6fe48d1
--- /dev/null
+++ b/simplemind/providers/minimax.py
@@ -0,0 +1,74 @@
+from functools import cached_property
+
+from ..settings import settings
+from .anthropic import Anthropic
+from .openai import OpenAI
+
+
+class _MiniMaxConfig:
+ MODEL_IDS = ("MiniMax-M3", "MiniMax-M2.7")
+ ENDPOINTS = {
+ "global_en": {
+ "openai": "https://api.minimax.io/v1",
+ "anthropic": "https://api.minimax.io/anthropic",
+ },
+ "cn_zh": {
+ "openai": "https://api.minimaxi.com/v1",
+ "anthropic": "https://api.minimaxi.com/anthropic",
+ },
+ }
+
+ def _configure(self, api_key: str | None, region: str | None) -> None:
+ self.api_key = api_key or settings.get_api_key("minimax")
+ self.region = region or settings.MINIMAX_API_REGION
+ if self.region not in self.ENDPOINTS:
+ regions = ", ".join(self.ENDPOINTS)
+ raise ValueError(f"MiniMax API region must be one of: {regions}")
+
+
+class MiniMax(_MiniMaxConfig, OpenAI):
+ NAME = "minimax"
+ DEFAULT_MODEL = "MiniMax-M3"
+
+ def __init__(self, api_key: str | None = None, region: str | None = None):
+ self._configure(api_key, region)
+
+ @cached_property
+ def client(self):
+ """The raw OpenAI-compatible MiniMax client."""
+ if not self.api_key:
+ raise ValueError("MiniMax API key is required")
+ try:
+ import openai as oa
+ except ImportError as exc:
+ raise ImportError(
+ "Please install the `openai` package: `pip install openai`"
+ ) from exc
+ return oa.OpenAI(
+ api_key=self.api_key,
+ base_url=self.ENDPOINTS[self.region]["openai"],
+ )
+
+
+class MiniMaxAnthropic(_MiniMaxConfig, Anthropic):
+ NAME = "minimax-anthropic"
+ DEFAULT_MODEL = "MiniMax-M3"
+
+ def __init__(self, api_key: str | None = None, region: str | None = None):
+ self._configure(api_key, region)
+
+ @cached_property
+ def client(self):
+ """The raw Anthropic-compatible MiniMax client."""
+ if not self.api_key:
+ raise ValueError("MiniMax API key is required")
+ try:
+ import anthropic
+ except ImportError as exc:
+ raise ImportError(
+ "Please install the `anthropic` package: `pip install anthropic`"
+ ) from exc
+ return anthropic.Anthropic(
+ api_key=self.api_key,
+ base_url=self.ENDPOINTS[self.region]["anthropic"],
+ )
diff --git a/simplemind/settings.py b/simplemind/settings.py
index de69339..e9904db 100644
--- a/simplemind/settings.py
+++ b/simplemind/settings.py
@@ -50,6 +50,10 @@ class Settings(BaseSettings):
GROQ_API_KEY: Optional[SecretStr] = Field(None, description="API key for Groq")
GEMINI_API_KEY: Optional[SecretStr] = Field(None, description="API key for Gemini")
OPENAI_API_KEY: Optional[SecretStr] = Field(None, description="API key for OpenAI")
+ MINIMAX_API_KEY: Optional[SecretStr] = Field(None, description="API key for MiniMax")
+ MINIMAX_API_REGION: str = Field(
+ "global_en", description="MiniMax API region (global_en or cn_zh)"
+ )
OLLAMA_HOST_URL: Optional[str] = Field(
"http://127.0.0.1:11434", description="Fully qualified host URL for Ollama"
)
diff --git a/tests/test_minimax.py b/tests/test_minimax.py
new file mode 100644
index 0000000..7164388
--- /dev/null
+++ b/tests/test_minimax.py
@@ -0,0 +1,41 @@
+import pytest
+
+from simplemind.providers import MiniMax, MiniMaxAnthropic, providers
+from simplemind.utils import find_provider
+
+
+@pytest.mark.parametrize(
+ ("provider_cls", "protocol", "region", "expected_url"),
+ [
+ (MiniMax, "openai", "global_en", "https://api.minimax.io/v1"),
+ (MiniMax, "openai", "cn_zh", "https://api.minimaxi.com/v1"),
+ (
+ MiniMaxAnthropic,
+ "anthropic",
+ "global_en",
+ "https://api.minimax.io/anthropic",
+ ),
+ (
+ MiniMaxAnthropic,
+ "anthropic",
+ "cn_zh",
+ "https://api.minimaxi.com/anthropic",
+ ),
+ ],
+)
+def test_minimax_endpoints(provider_cls, protocol, region, expected_url):
+ provider = provider_cls(api_key="test-key", region=region)
+
+ assert provider.MODEL_IDS == ("MiniMax-M3", "MiniMax-M2.7")
+ assert provider.ENDPOINTS[region][protocol] == expected_url
+
+
+@pytest.mark.parametrize("provider_cls", [MiniMax, MiniMaxAnthropic])
+def test_minimax_registered(provider_cls):
+ assert provider_cls in providers
+ assert isinstance(find_provider(provider_cls.NAME), provider_cls)
+
+
+def test_minimax_rejects_unknown_region():
+ with pytest.raises(ValueError, match="MiniMax API region must be one of"):
+ MiniMax(api_key="test-key", region="unknown")