Skip to content

Commit 44b9614

Browse files
committed
feat: add MiniMax as first-class LLM provider
Add MiniMax AI (https://www.minimax.io/) as a directly supported LLM provider alongside OpenAI, Cerebras, and Azure OpenAI. MiniMax's API is OpenAI-compatible, so this uses the OpenAI SDK with MiniMax's base URL for seamless integration. Changes: - Add MINIMAX_API_KEY detection in get_config() with auto base URL - Add temperature clamping for MiniMax: values are clamped to (0, 1] - Update README provider table with MiniMax documentation - Add 17 unit tests covering provider detection, priority, and temp clamping - Add 3 integration tests for live API verification
1 parent 3ccfab6 commit 44b9614

4 files changed

Lines changed: 392 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ We support all major LLM providers and models for inference. You need to set the
206206
|----------|-------------------------------|------------------|
207207
| OptiLLM | `OPTILLM_API_KEY` | Uses the inbuilt local server for inference, supports logprobs and decoding techniques like `cot_decoding` & `entropy_decoding` |
208208
| OpenAI | `OPENAI_API_KEY` | You can use this with any OpenAI compatible endpoint (e.g. OpenRouter) by setting the `base_url` |
209+
| MiniMax | `MINIMAX_API_KEY` | Uses the [MiniMax API](https://www.minimax.io/) (OpenAI-compatible). Supports MiniMax-M2.7 and other models. Temperature is auto-clamped to (0, 1] |
209210
| Cerebras | `CEREBRAS_API_KEY` | You can use this for fast inference with supported models, see [docs for details](https://inference-docs.cerebras.ai/introduction) |
210211
| Azure OpenAI | `AZURE_OPENAI_API_KEY`<br>`AZURE_API_VERSION`<br>`AZURE_API_BASE` | - |
211212
| Azure OpenAI (Managed Identity) | `AZURE_API_VERSION`<br>`AZURE_API_BASE` | Login required using `az login`, see [docs for details](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/managed-identity) |

optillm/server.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ def get_config():
9191
default_client = Cerebras(api_key=API_KEY, base_url=base_url, http_client=http_client)
9292
else:
9393
default_client = Cerebras(api_key=API_KEY, http_client=http_client)
94+
elif os.environ.get("MINIMAX_API_KEY"):
95+
API_KEY = os.environ.get("MINIMAX_API_KEY")
96+
base_url = server_config['base_url']
97+
if base_url == "":
98+
base_url = "https://api.minimax.io/v1"
99+
default_client = OpenAI(api_key=API_KEY, base_url=base_url, http_client=http_client)
100+
logger.info(f"Created MiniMax client with base_url: {base_url}")
94101
elif os.environ.get("OPENAI_API_KEY"):
95102
API_KEY = os.environ.get("OPENAI_API_KEY")
96103
base_url = server_config['base_url']
@@ -759,6 +766,15 @@ def proxy():
759766
base_url = server_config['base_url']
760767
default_client, api_key = get_config()
761768

769+
# Clamp temperature for MiniMax provider: must be in (0.0, 1.0]
770+
if os.environ.get("MINIMAX_API_KEY") and 'temperature' in request_config:
771+
temp = request_config['temperature']
772+
if temp is not None:
773+
if temp <= 0:
774+
request_config['temperature'] = 0.01
775+
elif temp > 1.0:
776+
request_config['temperature'] = 1.0
777+
762778
operation, approaches, model = parse_combined_approach(model, known_approaches, plugin_approaches)
763779

764780
# Start conversation logging if enabled

tests/test_minimax_integration.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
Integration tests for MiniMax provider support in optillm.
3+
4+
These tests verify that the MiniMax provider works end-to-end with the actual
5+
MiniMax API. They require a valid MINIMAX_API_KEY environment variable.
6+
7+
Run with: MINIMAX_API_KEY=your-key pytest tests/test_minimax_integration.py -v
8+
"""
9+
10+
import unittest
11+
import os
12+
import sys
13+
14+
# Add parent directory to path to import optillm modules
15+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
16+
17+
# Skip all tests if MINIMAX_API_KEY is not set
18+
MINIMAX_API_KEY = os.environ.get('MINIMAX_API_KEY', '')
19+
SKIP_REASON = "MINIMAX_API_KEY environment variable not set"
20+
21+
22+
@unittest.skipUnless(MINIMAX_API_KEY, SKIP_REASON)
23+
class TestMiniMaxIntegration(unittest.TestCase):
24+
"""Integration tests that call the actual MiniMax API."""
25+
26+
def setUp(self):
27+
"""Set up OpenAI client pointing to MiniMax API."""
28+
from openai import OpenAI
29+
self.client = OpenAI(
30+
api_key=MINIMAX_API_KEY,
31+
base_url="https://api.minimax.io/v1"
32+
)
33+
34+
def test_basic_completion(self):
35+
"""Test basic chat completion with MiniMax API."""
36+
response = self.client.chat.completions.create(
37+
model="MiniMax-M2.7",
38+
messages=[
39+
{"role": "user", "content": "Say hello in one word."}
40+
],
41+
max_tokens=10,
42+
temperature=0.7
43+
)
44+
45+
assert hasattr(response, 'choices')
46+
assert len(response.choices) > 0
47+
assert response.choices[0].message.content is not None
48+
assert len(response.choices[0].message.content) > 0
49+
50+
def test_temperature_boundary(self):
51+
"""Test that MiniMax API accepts temperature at boundary value 0.01."""
52+
response = self.client.chat.completions.create(
53+
model="MiniMax-M2.7",
54+
messages=[
55+
{"role": "user", "content": "What is 2+2?"}
56+
],
57+
max_tokens=10,
58+
temperature=0.01
59+
)
60+
61+
assert hasattr(response, 'choices')
62+
assert len(response.choices) > 0
63+
64+
def test_streaming_completion(self):
65+
"""Test streaming chat completion with MiniMax API."""
66+
stream = self.client.chat.completions.create(
67+
model="MiniMax-M2.7",
68+
messages=[
69+
{"role": "user", "content": "Count from 1 to 3."}
70+
],
71+
max_tokens=30,
72+
temperature=0.5,
73+
stream=True
74+
)
75+
76+
chunks = list(stream)
77+
assert len(chunks) > 0
78+
content_chunks = [
79+
chunk.choices[0].delta.content
80+
for chunk in chunks
81+
if chunk.choices[0].delta.content
82+
]
83+
assert len(content_chunks) > 0
84+
85+
86+
if __name__ == '__main__':
87+
unittest.main()

0 commit comments

Comments
 (0)