diff --git a/README.md b/README.md index dde1d3a1..7d77733a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ pip install ace-framework ```bash export OPENAI_API_KEY="your-api-key" +# Or use other providers: +# export MINIMAX_API_KEY="your-minimax-api-key" ``` ### 3. Run diff --git a/ace/llm_providers/litellm_client.py b/ace/llm_providers/litellm_client.py index b2a07b19..e296942d 100644 --- a/ace/llm_providers/litellm_client.py +++ b/ace/llm_providers/litellm_client.py @@ -652,7 +652,9 @@ def _get_provider_from_model(self, model: str) -> str: """Infer provider from model name.""" model_lower = model.lower() - if "gpt" in model_lower or "openai" in model_lower: + if "minimax" in model_lower: + return "minimax" + elif "gpt" in model_lower or "openai" in model_lower: return "openai" elif "claude" in model_lower or "anthropic" in model_lower: return "anthropic" @@ -703,6 +705,10 @@ def list_models(cls) -> List[str]: "mistral-7b", "mistral-medium", "mixtral-8x7b", + # MiniMax (via OpenAI-compatible endpoint) + "openai/MiniMax-M3", + "openai/MiniMax-M2.7", + "openai/MiniMax-M2.7-highspeed", # Note: Many more models are supported # See: https://docs.litellm.ai/docs/providers ] diff --git a/ace_next/providers/litellm.py b/ace_next/providers/litellm.py index d017539b..3cc2f956 100644 --- a/ace_next/providers/litellm.py +++ b/ace_next/providers/litellm.py @@ -537,7 +537,9 @@ def complete_with_stream(self, prompt: str, **kwargs: Any): def _get_provider_from_model(self, model: str) -> str: """Infer provider from model name.""" model_lower = model.lower() - if "gpt" in model_lower or "openai" in model_lower: + if "minimax" in model_lower: + return "minimax" + elif "gpt" in model_lower or "openai" in model_lower: return "openai" elif "claude" in model_lower or "anthropic" in model_lower: return "anthropic" @@ -569,4 +571,8 @@ def list_models(cls) -> List[str]: "llama-2-70b", "mistral-7b", "mixtral-8x7b", + # MiniMax (via OpenAI-compatible endpoint) + "openai/MiniMax-M3", + "openai/MiniMax-M2.7", + "openai/MiniMax-M2.7-highspeed", ] diff --git a/ace_next/providers/registry.py b/ace_next/providers/registry.py index e3832982..a8573e8a 100644 --- a/ace_next/providers/registry.py +++ b/ace_next/providers/registry.py @@ -43,6 +43,7 @@ def _litellm(): "ollama": "ollama/llama2", "azure": "azure/gpt-4", "openrouter": "openrouter/anthropic/claude-3.5-sonnet", + "minimax": "openai/MiniMax-M3", } @@ -208,6 +209,7 @@ def validate_connection(model: str, api_key: str | None = None) -> ValidationRes "huggingface": "HUGGINGFACE_API_KEY", "perplexity": "PERPLEXITYAI_API_KEY", "anyscale": "ANYSCALE_API_KEY", + "minimax": "MINIMAX_API_KEY", } diff --git a/docs/getting-started/setup.md b/docs/getting-started/setup.md index de3382ff..1622fb95 100644 --- a/docs/getting-started/setup.md +++ b/docs/getting-started/setup.md @@ -176,6 +176,7 @@ ACE uses [LiteLLM](https://docs.litellm.ai/) for model access. Any model string | Ollama (local) | `ollama/llama2` | --- | | Azure OpenAI | `azure/gpt-4` | `AZURE_API_KEY` | | OpenRouter | `openrouter/anthropic/claude-3.5-sonnet` | `OPENROUTER_API_KEY` | +| MiniMax | `openai/MiniMax-M3` | `MINIMAX_API_KEY` | 100+ providers supported. Run `ace models` to search the full catalog. diff --git a/docs/integrations/litellm.md b/docs/integrations/litellm.md index f148b8f1..9b5094ce 100644 --- a/docs/integrations/litellm.md +++ b/docs/integrations/litellm.md @@ -137,6 +137,13 @@ agent = ACELiteLLM.from_model("claude-sonnet-4-5-20250929") # Google agent = ACELiteLLM.from_model("gemini-pro") +# MiniMax +agent = ACELiteLLM.from_model( + "openai/MiniMax-M3", + base_url="https://api.minimax.io/v1", + api_key=os.environ["MINIMAX_API_KEY"], +) + # Local (Ollama) agent = ACELiteLLM.from_model("ollama/llama2") @@ -144,6 +151,32 @@ agent = ACELiteLLM.from_model("ollama/llama2") agent = ACELiteLLM.from_model("gpt-4o-mini", base_url="https://your-endpoint.com") ``` +### MiniMax Models + +[MiniMax](https://platform.minimax.io/) provides high-performance models via an OpenAI-compatible API: + +| Model | Description | +|-------|-------------| +| `MiniMax-M3` | Latest flagship model with 512K context window, up to 128K output, and image input support (default) | +| `MiniMax-M2.7` | Previous-generation flagship model with enhanced reasoning and coding | +| `MiniMax-M2.7-highspeed` | High-speed version of M2.7 for low-latency scenarios | + +```bash +export MINIMAX_API_KEY="your-minimax-api-key" +``` + +```python +from ace_next import ACELiteLLM + +# Using MiniMax as the agent model +agent = ACELiteLLM.from_model( + "openai/MiniMax-M3", + base_url="https://api.minimax.io/v1", +) + +answer = agent.ask("Explain quantum computing in simple terms") +``` + ## Opik Observability Enable tracing and cost tracking with a single flag: diff --git a/tests/test_litellm_client.py b/tests/test_litellm_client.py index 891a86c5..38e23eec 100644 --- a/tests/test_litellm_client.py +++ b/tests/test_litellm_client.py @@ -524,5 +524,38 @@ def test_complete_messages_uses_same_config(self, mock_completion): self.assertEqual(call_kwargs["extra_headers"], {"X-Custom": "val"}) +@pytest.mark.unit +class TestProviderDetection(unittest.TestCase): + """Test _get_provider_from_model provider detection.""" + + def test_minimax_provider_detected(self): + """Test that MiniMax models are detected correctly.""" + from ace.llm_providers import LiteLLMClient + + client = LiteLLMClient.__new__(LiteLLMClient) + self.assertEqual(client._get_provider_from_model("MiniMax-M3"), "minimax") + self.assertEqual(client._get_provider_from_model("MiniMax-M2.7"), "minimax") + self.assertEqual( + client._get_provider_from_model("openai/MiniMax-M2.7-highspeed"), + "minimax", + ) + + def test_minimax_in_model_list(self): + """Test that MiniMax models appear in list_models.""" + from ace.llm_providers import LiteLLMClient + + models = LiteLLMClient.list_models() + minimax_models = [m for m in models if "MiniMax" in m] + self.assertGreaterEqual(len(minimax_models), 3) + + def test_minimax_m3_is_default(self): + """Test that MiniMax-M3 is the default MiniMax model.""" + from ace.llm_providers import LiteLLMClient + + models = LiteLLMClient.list_models() + minimax_models = [m for m in models if "MiniMax" in m] + self.assertEqual(minimax_models[0], "openai/MiniMax-M3") + + if __name__ == "__main__": unittest.main()