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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion ace/llm_providers/litellm_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
]
8 changes: 7 additions & 1 deletion ace_next/providers/litellm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
]
2 changes: 2 additions & 0 deletions ace_next/providers/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def _litellm():
"ollama": "ollama/llama2",
"azure": "azure/gpt-4",
"openrouter": "openrouter/anthropic/claude-3.5-sonnet",
"minimax": "openai/MiniMax-M3",
}


Expand Down Expand Up @@ -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",
}


Expand Down
1 change: 1 addition & 0 deletions docs/getting-started/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
33 changes: 33 additions & 0 deletions docs/integrations/litellm.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,46 @@ 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")

# Custom endpoint
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:
Expand Down
33 changes: 33 additions & 0 deletions tests/test_litellm_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()