diff --git a/README.md b/README.md index 7a133bb..751fbd9 100644 --- a/README.md +++ b/README.md @@ -240,8 +240,7 @@ provider_server_address = # Typically ignored or can be left blank when is_local | Hugging Face | `huggingface` | No | Use models from Hugging Face Inference API. | [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) | | TogetherAI | `togetherAI` | No | Use various open-source models via TogetherAI API.| [api.together.ai/settings/api-keys](https://api.together.ai/settings/api-keys) | | OpenRouter | `openrouter` | No | Use OpenRouter Models| [https://openrouter.ai/](https://openrouter.ai/) | -| Anthropic | `anthropic` | No | Use Claude models via Anthropic's API. | [console.anthropic.com](https://console.anthropic.com/) | -| MiniMax | `minimax` | No | Use MiniMax M2.5 series models (e.g., MiniMax-M2.5).| [platform.minimax.io](https://platform.minimax.io/user-center/basic-information) | +| MiniMax | `minimax` | No | Use MiniMax models (e.g., MiniMax-M2.7, MiniMax-M2.5).| [platform.minimax.io](https://platform.minimax.io/user-center/basic-information) | *Note:* * We advise against using `gpt-4o` or other OpenAI models for complex web browsing and task planning as current prompt optimizations are geared towards models like Deepseek. diff --git a/README_CHS.md b/README_CHS.md index d505131..d37c3af 100644 --- a/README_CHS.md +++ b/README_CHS.md @@ -230,7 +230,7 @@ provider_server_address = # 当 is_local = False 时,对于大多数 API 通 | Hugging Face | `huggingface` | 否 | 使用 Hugging Face Inference API 中的模型。 | [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) | | TogetherAI | `togetherAI` | 否 | 通过 TogetherAI API 使用各种开源模型。| [api.together.ai/settings/api-keys](https://api.together.ai/settings/api-keys) | | OpenRouter | `openrouter` | No | 通过 OpenRouter 使用各种开源模型| [https://openrouter.ai/](https://openrouter.ai/) | -| MiniMax | `minimax` | 否 | 使用 MiniMax 的 M2.5 系列模型(如 MiniMax-M2.5)。 | [platform.minimax.io](https://platform.minimax.io/user-center/basic-information) | +| MiniMax | `minimax` | 否 | 使用 MiniMax 模型(如 MiniMax-M2.7、MiniMax-M2.5)。 | [platform.minimax.io](https://platform.minimax.io/user-center/basic-information) | *注意:* * 我们不建议将 `gpt-4o` 或其他 OpenAI 模型用于复杂的网页浏览和任务规划,因为当前的提示优化针对 Deepseek 等模型。 diff --git a/api.py b/api.py index 288e108..56d3154 100755 --- a/api.py +++ b/api.py @@ -278,8 +278,11 @@ async def process_query(request: QueryRequest): return JSONResponse(status_code=200, content=query_resp.jsonify()) except Exception as e: logger.error(f"An error occurred: {str(e)}") - sys.exit(1) + query_resp.answer = f"An error occurred: {str(e)}" + query_resp.reasoning = f"Error: {str(e)}" + return JSONResponse(status_code=500, content=query_resp.jsonify()) finally: + is_generating = False logger.info("Processing finished") if config.getboolean('MAIN', 'save_session'): interaction.save_session() diff --git a/sources/agents/planner_agent.py b/sources/agents/planner_agent.py index ff6cba4..ada8c07 100644 --- a/sources/agents/planner_agent.py +++ b/sources/agents/planner_agent.py @@ -147,17 +147,23 @@ class PlannerAgent(Agent): pretty_print(f"{task['agent']} -> {task['task']}", color="info") pretty_print("▔▗ E N D ▖▔", color="status") - async def make_plan(self, prompt: str) -> str: + async def make_plan(self, prompt: str, max_retries: int = 4) -> str: """ Asks the LLM to make a plan. Args: prompt (str): The prompt to be sent to the LLM. + max_retries (int): Maximum number of retries before giving up. Returns: str: The plan made by the LLM. """ ok = False answer = None + retries = 0 while not ok: + if retries >= max_retries: + pretty_print(f"Failed to make a plan after {max_retries} attempts. Giving up.", color="failure") + self.logger.warning(f"make_plan exceeded max retries ({max_retries}).") + return [] animate_thinking("Thinking...", color="status") self.memory.push('user', prompt) answer, reasoning = await self.llm_request() @@ -168,6 +174,7 @@ class PlannerAgent(Agent): self.show_plan(agents_tasks, answer) prompt = f"Failed to parse the tasks. Please write down your task followed by a json plan within ```json. Do not ask for clarification.\n" pretty_print("Failed to make plan. Retrying...", color="warning") + retries += 1 continue self.show_plan(agents_tasks, answer) ok = True diff --git a/sources/llm_provider.py b/sources/llm_provider.py index afd6d83..7a2e7ef 100644 --- a/sources/llm_provider.py +++ b/sources/llm_provider.py @@ -419,11 +419,13 @@ class Provider: def minimax_fn(self, history, verbose=False): """ Use MiniMax API to generate text via OpenAI-compatible interface. - + Supported models: + - 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 model (~60 tps), 204,800 context window - MiniMax-M2.5-highspeed: Same performance, faster (~100 tps) - + Note: temperature must be in range (0.0, 1.0], default is 1.0 """ load_dotenv() diff --git a/tests/test_minimax_provider.py b/tests/test_minimax_provider.py index 15453c3..0b7a041 100644 --- a/tests/test_minimax_provider.py +++ b/tests/test_minimax_provider.py @@ -155,6 +155,42 @@ class TestMiniMaxProvider(unittest.TestCase): class TestMiniMaxProviderModels(unittest.TestCase): """Test cases for MiniMax provider model configurations.""" + @patch('sources.llm_provider.OpenAI') + @patch.dict(os.environ, {'MINIMAX_API_KEY': 'test-key'}) + def test_minimax_m27_model(self, mock_openai_class): + """Test MiniMax-M2.7 model.""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + mock_response = MagicMock() + mock_response.choices = [MagicMock(message=MagicMock(content="Response"))] + mock_client.chat.completions.create.return_value = mock_response + + with patch.object(Provider, 'get_api_key', return_value='test-key'): + provider = Provider("minimax", "MiniMax-M2.7", is_local=False) + history = [{"role": "user", "content": "Hello"}] + provider.minimax_fn(history) + + call_kwargs = mock_client.chat.completions.create.call_args[1] + self.assertEqual(call_kwargs['model'], "MiniMax-M2.7") + + @patch('sources.llm_provider.OpenAI') + @patch.dict(os.environ, {'MINIMAX_API_KEY': 'test-key'}) + def test_minimax_m27_highspeed_model(self, mock_openai_class): + """Test MiniMax-M2.7-highspeed model.""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + mock_response = MagicMock() + mock_response.choices = [MagicMock(message=MagicMock(content="Response"))] + mock_client.chat.completions.create.return_value = mock_response + + with patch.object(Provider, 'get_api_key', return_value='test-key'): + provider = Provider("minimax", "MiniMax-M2.7-highspeed", is_local=False) + history = [{"role": "user", "content": "Hello"}] + provider.minimax_fn(history) + + call_kwargs = mock_client.chat.completions.create.call_args[1] + self.assertEqual(call_kwargs['model'], "MiniMax-M2.7-highspeed") + @patch('sources.llm_provider.OpenAI') @patch.dict(os.environ, {'MINIMAX_API_KEY': 'test-key'}) def test_minimax_m25_model(self, mock_openai_class):