Files
AIChatRoom/backend/adapters/minimax_adapter.py

252 lines
9.1 KiB
Python
Raw Normal View History

"""
MiniMax适配器
支持MiniMax大模型API
"""
import json
from datetime import datetime
from typing import List, Dict, Any, Optional, AsyncGenerator
from loguru import logger
from .base_adapter import BaseAdapter, ChatMessage, AdapterResponse
from utils.proxy_handler import get_http_client
class MiniMaxAdapter(BaseAdapter):
"""
MiniMax API适配器
支持abab系列模型
"""
DEFAULT_BASE_URL = "https://api.minimax.chat/v1"
def __init__(
self,
api_key: str,
base_url: str = "",
model: str = "abab6.5-chat",
use_proxy: bool = False,
proxy_config: Optional[Dict[str, Any]] = None,
timeout: int = 60,
**kwargs
):
super().__init__(
api_key=api_key,
base_url=base_url or self.DEFAULT_BASE_URL,
model=model,
use_proxy=use_proxy,
proxy_config=proxy_config,
timeout=timeout,
**kwargs
)
# MiniMax需要group_id
self.group_id = kwargs.get("group_id", "")
async def chat(
self,
messages: List[ChatMessage],
temperature: float = 0.7,
max_tokens: int = 2000,
**kwargs
) -> AdapterResponse:
"""发送聊天请求"""
start_time = datetime.utcnow()
try:
async with get_http_client(
use_proxy=self.use_proxy,
proxy_config=self.proxy_config,
timeout=self.timeout
) as client:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
# MiniMax使用特殊的消息格式
minimax_messages = []
bot_setting = []
for msg in messages:
if msg.role == "system":
bot_setting.append({
"bot_name": "assistant",
"content": msg.content
})
else:
minimax_messages.append({
"sender_type": "USER" if msg.role == "user" else "BOT",
"sender_name": msg.name or ("用户" if msg.role == "user" else "assistant"),
"text": msg.content
})
payload = {
"model": self.model,
"messages": minimax_messages,
"bot_setting": bot_setting if bot_setting else [{"bot_name": "assistant", "content": "你是一个有帮助的助手"}],
"temperature": temperature,
"tokens_to_generate": max_tokens,
"mask_sensitive_info": False,
**kwargs
}
url = f"{self.base_url}/text/chatcompletion_v2"
if self.group_id:
url = f"{url}?GroupId={self.group_id}"
response = await client.post(
url,
headers=headers,
json=payload
)
if response.status_code != 200:
error_text = response.text
logger.error(f"MiniMax API错误: {response.status_code} - {error_text}")
return AdapterResponse(
success=False,
error=f"API错误: {response.status_code} - {error_text}",
latency_ms=self._calculate_latency(start_time)
)
data = response.json()
# 检查API返回的错误
if data.get("base_resp", {}).get("status_code", 0) != 0:
error_msg = data.get("base_resp", {}).get("status_msg", "未知错误")
return AdapterResponse(
success=False,
error=f"API错误: {error_msg}",
latency_ms=self._calculate_latency(start_time)
)
reply = data.get("reply", "")
usage = data.get("usage", {})
return AdapterResponse(
success=True,
content=reply,
model=self.model,
finish_reason=data.get("output_sensitive", False) and "content_filter" or "stop",
prompt_tokens=usage.get("prompt_tokens", 0),
completion_tokens=usage.get("completion_tokens", 0),
total_tokens=usage.get("total_tokens", 0),
latency_ms=self._calculate_latency(start_time)
)
except Exception as e:
logger.error(f"MiniMax请求异常: {e}")
return AdapterResponse(
success=False,
error=str(e),
latency_ms=self._calculate_latency(start_time)
)
async def chat_stream(
self,
messages: List[ChatMessage],
temperature: float = 0.7,
max_tokens: int = 2000,
**kwargs
) -> AsyncGenerator[str, None]:
"""发送流式聊天请求"""
try:
async with get_http_client(
use_proxy=self.use_proxy,
proxy_config=self.proxy_config,
timeout=self.timeout
) as client:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
minimax_messages = []
bot_setting = []
for msg in messages:
if msg.role == "system":
bot_setting.append({
"bot_name": "assistant",
"content": msg.content
})
else:
minimax_messages.append({
"sender_type": "USER" if msg.role == "user" else "BOT",
"sender_name": msg.name or ("用户" if msg.role == "user" else "assistant"),
"text": msg.content
})
payload = {
"model": self.model,
"messages": minimax_messages,
"bot_setting": bot_setting if bot_setting else [{"bot_name": "assistant", "content": "你是一个有帮助的助手"}],
"temperature": temperature,
"tokens_to_generate": max_tokens,
"stream": True,
**kwargs
}
url = f"{self.base_url}/text/chatcompletion_v2"
if self.group_id:
url = f"{url}?GroupId={self.group_id}"
async with client.stream(
"POST",
url,
headers=headers,
json=payload
) as response:
async for line in response.aiter_lines():
if line.startswith("data: "):
data_str = line[6:]
if data_str.strip() == "[DONE]":
break
try:
data = json.loads(data_str)
delta = data.get("choices", [{}])[0].get("delta", {})
content = delta.get("content", "")
if content:
yield content
except json.JSONDecodeError:
continue
except Exception as e:
logger.error(f"MiniMax流式请求异常: {e}")
yield f"[错误: {str(e)}]"
async def test_connection(self) -> Dict[str, Any]:
"""测试API连接"""
start_time = datetime.utcnow()
try:
test_messages = [
ChatMessage(role="user", content="你好,请回复'OK'")
]
response = await self.chat(
messages=test_messages,
temperature=0,
max_tokens=10
)
if response.success:
return {
"success": True,
"message": "连接成功",
"model": response.model,
"latency_ms": response.latency_ms
}
else:
return {
"success": False,
"message": response.error,
"latency_ms": response.latency_ms
}
except Exception as e:
return {
"success": False,
"message": str(e),
"latency_ms": self._calculate_latency(start_time)
}