Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ The APIs remain identical between all supported providers / models:
<td><code>"ollama"</code></td>
<td><code>"llama3.2"</code></td>
</tr>
<tr>
<td><a href="https://platform.minimax.io/docs/api-reference/api-overview">MiniMax</a></td>
<td><code>"minimax"</code> / <code>"minimax-anthropic"</code></td>
<td><code>"MiniMax-M3"</code></td>
</tr>
<tr>
<td><a href="https://openai.com/gpt">OpenAI's GPT</a></td>
<td><code>"openai"</code></td>
Expand All @@ -70,6 +75,8 @@ The APIs remain identical between all supported providers / models:
</tbody>
</table>

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!
Expand All @@ -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:

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ gemini = ["google-generativeai", "jsonref"]
groq = ["groq"]
ollama = ["openai"]
openai = ["openai"]
minimax = ["openai", "anthropic"]
xai = ["openai"]
deepseek = ["openai"]

Expand Down
7 changes: 6 additions & 1 deletion simplemind/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -20,6 +21,8 @@
XAI,
Amazon,
Deepseek,
MiniMax,
MiniMaxAnthropic,
]

__all__ = [
Expand All @@ -33,5 +36,7 @@
"providers",
"BaseProvider",
"BaseTool",
"Deepseek"
"Deepseek",
"MiniMax",
"MiniMaxAnthropic",
]
74 changes: 74 additions & 0 deletions simplemind/providers/minimax.py
Original file line number Diff line number Diff line change
@@ -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"],
)
4 changes: 4 additions & 0 deletions simplemind/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down
41 changes: 41 additions & 0 deletions tests/test_minimax.py
Original file line number Diff line number Diff line change
@@ -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")