diff --git a/.env.example b/.env.example index 8558e9c4..e1e58477 100644 --- a/.env.example +++ b/.env.example @@ -55,11 +55,22 @@ SERPER_KEY_ID=your_key JINA_API_KEYS=your_key # Summary model API (OpenAI-compatible) for page summarization +# You can use OpenAI, MiniMax, or any OpenAI-compatible provider # Get your key from: https://platform.openai.com/ API_KEY=your_key API_BASE=your_api_base SUMMARY_MODEL_NAME=your_summary_model_name +# MiniMax API for page summarization or as an LLM provider +# Get your key from: https://platform.minimaxi.com/ +# Models: MiniMax-M2.7 (204K context, latest flagship), MiniMax-M2.7-highspeed (204K context), +# MiniMax-M2.5 (204K context), MiniMax-M2.5-highspeed (204K context) +# To use MiniMax as the summary model, set: +# API_KEY=your_minimax_key +# API_BASE=https://api.minimax.io/v1 +# SUMMARY_MODEL_NAME=MiniMax-M2.7 +MINIMAX_API_KEY=your_minimax_key + # Dashscope API for file parsing (PDF, Office, etc.) # Get your key from: https://dashscope.aliyun.com/ # Supports: qwen-omni-turbo, qwen-plus-latest diff --git a/README.md b/README.md index 453f5ae2..2cf89468 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,8 @@ Edit the `.env` file and provide your actual API keys and configuration values: - **SERPER_KEY_ID**: Get your key from [Serper.dev](https://serper.dev/) for web search and Google Scholar - **JINA_API_KEYS**: Get your key from [Jina.ai](https://jina.ai/) for web page reading -- **API_KEY/API_BASE**: OpenAI-compatible API for page summarization from [OpenAI](https://platform.openai.com/) +- **API_KEY/API_BASE**: OpenAI-compatible API for page summarization from [OpenAI](https://platform.openai.com/) or [MiniMax](https://platform.minimaxi.com/) +- **MINIMAX_API_KEY**: (Optional) Get your key from [MiniMax](https://platform.minimaxi.com/) — can be used as the summary model (see [MiniMax Integration](#7-using-minimax-as-the-summary-model)) - **DASHSCOPE_API_KEY**: Get your key from [Dashscope](https://dashscope.aliyun.com/) for file parsing - **SANDBOX_FUSION_ENDPOINT**: Python interpreter sandbox endpoints (see [SandboxFusion](https://github.com/bytedance/SandboxFusion)) - **MODEL_PATH**: Path to your model weights @@ -179,6 +180,49 @@ You need to modify the following in the file [inference/react_agent.py](https:// - Change the model name to alibaba/tongyi-deepresearch-30b-a3b. - Adjust the content concatenation way as described in the comments on lines **88–90.** +### 7. Using MiniMax as the Summary Model + +[MiniMax](https://platform.minimaxi.com/) provides OpenAI-compatible LLM APIs that can be used as the summary model for page summarization. MiniMax models (e.g., `MiniMax-M2.7`, `MiniMax-M2.7-highspeed`) offer 204K context length and enhanced reasoning and coding capabilities, which are well-suited for long document summarization tasks. + +**Option A: Set MiniMax as the summary model directly** + +In your `.env` file: + +```bash +API_KEY=your_minimax_api_key +API_BASE=https://api.minimax.io/v1 +SUMMARY_MODEL_NAME=MiniMax-M2.7 +``` + +**Option B: Use MINIMAX_API_KEY as a fallback** + +If `API_KEY` is not set, the system will automatically fall back to using `MINIMAX_API_KEY` with MiniMax's API endpoint: + +```bash +MINIMAX_API_KEY=your_minimax_api_key +``` + +**Using MiniMax in the qwen-agent framework** + +MiniMax is also registered as an LLM provider in the qwen-agent framework. You can use it by specifying `model_type: 'minimax'` or by using a model name containing "minimax": + +```python +from qwen_agent.llm import get_chat_model + +# Auto-detected by model name +llm = get_chat_model({'model': 'MiniMax-M2.7'}) + +# Or explicitly specify the provider +llm = get_chat_model({ + 'model': 'MiniMax-M2.7', + 'model_type': 'minimax', + 'generate_cfg': { + 'temperature': 0.7, + 'max_tokens': 4096, + } +}) +``` + ## Benchmark Evaluation We provide benchmark evaluation scripts for various datasets. Please refer to the [evaluation scripts](./evaluation/) directory for more details. diff --git a/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/__init__.py b/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/__init__.py index a8f4bb74..825e6a7e 100644 --- a/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/__init__.py +++ b/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/__init__.py @@ -3,6 +3,7 @@ from .azure import TextChatAtAzure from .base import LLM_REGISTRY, BaseChatModel, ModelServiceError +from .minimax import TextChatAtMiniMax from .oai import TextChatAtOAI from .openvino import OpenVINO from .qwen_dashscope import QwenChatAtDS @@ -64,6 +65,10 @@ def get_chat_model(cfg: Union[dict, str] = 'qwen-plus') -> BaseChatModel: model = cfg.get('model', '') + if 'minimax' in model.lower(): + model_type = 'minimax' + return LLM_REGISTRY[model_type](cfg) + if '-vl' in model.lower(): model_type = 'qwenvl_dashscope' return LLM_REGISTRY[model_type](cfg) @@ -84,6 +89,7 @@ def get_chat_model(cfg: Union[dict, str] = 'qwen-plus') -> BaseChatModel: 'QwenChatAtDS', 'TextChatAtOAI', 'TextChatAtAzure', + 'TextChatAtMiniMax', 'QwenVLChatAtDS', 'QwenVLChatAtOAI', 'QwenAudioChatAtDS', diff --git a/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/minimax.py b/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/minimax.py new file mode 100644 index 00000000..1e0b9b94 --- /dev/null +++ b/WebAgent/WebWatcher/infer/vl_search_r1/qwen-agent-o1_search/qwen_agent/llm/minimax.py @@ -0,0 +1,59 @@ +import copy +import os +from typing import Dict, Optional + +from qwen_agent.llm.base import register_llm +from qwen_agent.llm.oai import TextChatAtOAI + +MINIMAX_DEFAULT_API_BASE = 'https://api.minimax.io/v1' + + +@register_llm('minimax') +class TextChatAtMiniMax(TextChatAtOAI): + """LLM provider for MiniMax (OpenAI-compatible API). + + MiniMax provides large language models accessible via an OpenAI-compatible + API. Supported models include MiniMax-M2.7 and MiniMax-M2.7-highspeed + (latest flagship with enhanced reasoning and coding), as well as + MiniMax-M2.5 and MiniMax-M2.5-highspeed, all offering 204K context length. + + Configuration example:: + + llm_cfg = { + 'model': 'MiniMax-M2.7', + 'model_type': 'minimax', + 'generate_cfg': { + 'temperature': 0.7, + 'max_tokens': 4096, + } + } + + Environment variables: + MINIMAX_API_KEY: Your MiniMax API key (required). + """ + + def __init__(self, cfg: Optional[Dict] = None): + cfg = copy.deepcopy(cfg) or {} + + # Set MiniMax defaults before calling parent __init__ + if not cfg.get('model'): + cfg['model'] = 'MiniMax-M2.7' + + # Use MiniMax API base URL if no custom server is specified + if not cfg.get('api_base') and not cfg.get('base_url') and not cfg.get('model_server'): + cfg['model_server'] = MINIMAX_DEFAULT_API_BASE + + # Use MINIMAX_API_KEY env var, fall back to OPENAI_API_KEY + if not cfg.get('api_key'): + api_key = os.getenv('MINIMAX_API_KEY') or os.getenv('OPENAI_API_KEY') + if api_key: + cfg['api_key'] = api_key + + # MiniMax requires temperature > 0 + generate_cfg = cfg.get('generate_cfg', {}) + temp = generate_cfg.get('temperature', None) + if temp is not None and temp <= 0: + generate_cfg['temperature'] = 0.01 + cfg['generate_cfg'] = generate_cfg + + super().__init__(cfg) diff --git a/inference/tool_visit.py b/inference/tool_visit.py index 6a03bac1..fcab930f 100644 --- a/inference/tool_visit.py +++ b/inference/tool_visit.py @@ -97,9 +97,13 @@ def call(self, params: Union[str, dict], **kwargs) -> str: return response.strip() def call_server(self, msgs, max_retries=2): - api_key = os.environ.get("API_KEY") - url_llm = os.environ.get("API_BASE") - model_name = os.environ.get("SUMMARY_MODEL_NAME", "") + api_key = os.environ.get("API_KEY") or os.environ.get("MINIMAX_API_KEY") + url_llm = os.environ.get("API_BASE") or ( + "https://api.minimax.io/v1" if os.environ.get("MINIMAX_API_KEY") and not os.environ.get("API_KEY") else None + ) + model_name = os.environ.get("SUMMARY_MODEL_NAME") or ( + "MiniMax-M2.7" if os.environ.get("MINIMAX_API_KEY") and not os.environ.get("API_KEY") else "" + ) client = OpenAI( api_key=api_key, base_url=url_llm,