Skip to content
This repository was archived by the owner on Apr 22, 2026. It is now read-only.
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
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Choose **one** of:
- Add your OPENAI_API_KEY in .env
- Custom model:
- See [docs](https://gpt-engineer.readthedocs.io/en/latest/open_models.html), supports local model, azure, etc.
- For MiniMax models: `export MINIMAX_API_KEY=[your api key]`

Check the [Windows README](./WINDOWS_README.md) for Windows usage.

Expand Down Expand Up @@ -102,7 +103,26 @@ E.g. `gpte projects/example-vision gpt-4-vision-preview --prompt_file prompt/tex

### Open source, local and alternative models

By default, gpt-engineer supports OpenAI Models via the OpenAI API or Azure OpenAI API, as well as Anthropic models.
By default, gpt-engineer supports OpenAI Models via the OpenAI API or Azure OpenAI API, as well as Anthropic models and [MiniMax](https://platform.minimax.io) models.

#### MiniMax Models

To use MiniMax models, set the `MINIMAX_API_KEY` environment variable and pass a MiniMax model name:

```bash
export MINIMAX_API_KEY=your-minimax-api-key
gpte my-project -m MiniMax-M2.7
```

Supported MiniMax models:
| Model | Description |
|-------|-------------|
| `MiniMax-M2.7` | Latest flagship model with enhanced reasoning and coding. |
| `MiniMax-M2.7-highspeed` | High-speed version of M2.7 for low-latency scenarios. |
| `MiniMax-M2.5` | Peak Performance. Ultimate Value. 204K context window. |
| `MiniMax-M2.5-highspeed` | Same performance, faster and more agile. 204K context window. |

You can also set a custom API base URL via `MINIMAX_API_BASE` (defaults to `https://api.minimax.io/v1`). For users in China, set it to `https://api.minimaxi.com/v1`.

With a little extra setup, you can also run with open source models like WizardCoder. See the [documentation](https://gpt-engineer.readthedocs.io/en/latest/open_models.html) for example instructions.

Expand Down
7 changes: 7 additions & 0 deletions gpt_engineer/applications/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ def load_env_if_needed():
if os.getenv("ANTHROPIC_API_KEY") is None:
load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))

if os.getenv("MINIMAX_API_KEY") is None:
load_dotenv()
if os.getenv("MINIMAX_API_KEY") is None:
load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))


def concatenate_paths(base_path, sub_path):
# Compute the relative path from base_path to sub_path
Expand Down Expand Up @@ -551,6 +556,8 @@ def main(

if ai.token_usage_log.is_openai_model():
print("Total api cost: $ ", ai.token_usage_log.usage_cost())
elif ai.token_usage_log.is_minimax_model():
print("Total tokens used: ", ai.token_usage_log.total_tokens())
elif os.getenv("LOCAL_MODEL"):
print("Total api cost: $ 0.0 since we are using local LLM.")
else:
Expand Down
20 changes: 20 additions & 0 deletions gpt_engineer/core/ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,26 @@ def _create_chat_model(self) -> BaseChatModel:
streaming=self.streaming,
max_tokens_to_sample=4096,
)
elif "minimax" in self.model_name.lower():
# MiniMax requires temperature in (0.0, 1.0], zero is not accepted
minimax_temperature = max(self.temperature, 0.01)
minimax_api_key = os.getenv("MINIMAX_API_KEY")
if not minimax_api_key:
raise ValueError(
"MINIMAX_API_KEY environment variable is required for MiniMax models. "
"Get your API key at https://platform.minimax.io"
)
minimax_base_url = os.getenv(
"MINIMAX_API_BASE", "https://api.minimax.io/v1"
)
return ChatOpenAI(
model=self.model_name,
temperature=minimax_temperature,
streaming=self.streaming,
callbacks=[StreamingStdOutCallbackHandler()],
openai_api_key=minimax_api_key,
openai_api_base=minimax_base_url,
)
elif self.vision:
return ChatOpenAI(
model=self.model_name,
Expand Down
11 changes: 11 additions & 0 deletions gpt_engineer/core/token_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,17 @@ def is_openai_model(self) -> bool:
"""
return "gpt" in self.model_name.lower()

def is_minimax_model(self) -> bool:
"""
Check if the model is a MiniMax model.

Returns
-------
bool
True if the model is a MiniMax model, False otherwise.
"""
return "minimax" in self.model_name.lower()

def total_tokens(self) -> int:
"""
Return the total number of tokens used in the conversation.
Expand Down
54 changes: 54 additions & 0 deletions tests/core/test_ai.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import os

from unittest.mock import patch

from langchain.chat_models.base import BaseChatModel
from langchain_community.chat_models.fake import FakeListChatModel

Expand Down Expand Up @@ -51,3 +55,53 @@ def test_token_logging(monkeypatch):
# assert
assert usageCostAfterStart > 0
assert usageCostAfterNext > usageCostAfterStart


def test_minimax_model_creation(monkeypatch):
monkeypatch.setattr(AI, "_create_chat_model", mock_create_chat_model)

ai = AI("MiniMax-M2.7")

# act
response_messages = ai.start("system prompt", "user prompt", step_name="step name")

# assert
assert response_messages[-1].content == "response1"
assert ai.token_usage_log.is_minimax_model()
assert not ai.token_usage_log.is_openai_model()


def test_minimax_temperature_constraint():
"""Test that MiniMax temperature is clamped to avoid zero."""
ai_instance = AI.__new__(AI)
ai_instance.temperature = 0.0
ai_instance.model_name = "MiniMax-M2.7"
ai_instance.azure_endpoint = None
ai_instance.streaming = True
ai_instance.vision = False

with patch.dict(os.environ, {"MINIMAX_API_KEY": "test-key"}):
with patch("gpt_engineer.core.ai.ChatOpenAI") as mock_chat:
mock_chat.return_value = FakeListChatModel(responses=["response"])
ai_instance._create_chat_model()
# Verify temperature was clamped above 0
call_kwargs = mock_chat.call_args[1]
assert call_kwargs["temperature"] >= 0.01


def test_minimax_missing_api_key():
"""Test that MiniMax raises error when API key is missing."""
ai_instance = AI.__new__(AI)
ai_instance.temperature = 0.1
ai_instance.model_name = "MiniMax-M2.7"
ai_instance.azure_endpoint = None
ai_instance.streaming = True
ai_instance.vision = False

with patch.dict(os.environ, {}, clear=True):
os.environ.pop("MINIMAX_API_KEY", None)
try:
ai_instance._create_chat_model()
assert False, "Should have raised ValueError"
except ValueError as e:
assert "MINIMAX_API_KEY" in str(e)