2api / src /converter /utils.py
lin7zhi's picture
Upload folder using huggingface_hub
69fec20 verified
from typing import Any, Dict
def extract_content_and_reasoning(parts: list) -> tuple:
"""从Gemini响应部件中提取内容和推理内容
Args:
parts: Gemini 响应中的 parts 列表
Returns:
(content, reasoning_content, images): 文本内容、推理内容和图片数据的元组
- content: 文本内容字符串
- reasoning_content: 推理内容字符串
- images: 图片数据列表,每个元素格式为:
{
"type": "image_url",
"image_url": {
"url": "data:{mime_type};base64,{base64_data}"
}
}
"""
content = ""
reasoning_content = ""
images = []
for part in parts:
# 提取文本内容
text = part.get("text", "")
if text:
if part.get("thought", False):
reasoning_content += text
else:
content += text
# 提取图片数据
if "inlineData" in part:
inline_data = part["inlineData"]
mime_type = inline_data.get("mimeType", "image/png")
base64_data = inline_data.get("data", "")
images.append({
"type": "image_url",
"image_url": {
"url": f"data:{mime_type};base64,{base64_data}"
}
})
return content, reasoning_content, images
async def merge_system_messages(request_body: Dict[str, Any]) -> Dict[str, Any]:
"""
根据兼容性模式处理请求体中的system消息
- 兼容性模式关闭(False):将连续的system消息合并为systemInstruction
- 兼容性模式开启(True):将所有system消息转换为user消息
Args:
request_body: OpenAI或Claude格式的请求体,包含messages字段
Returns:
处理后的请求体
Example (兼容性模式关闭):
输入:
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "system", "content": "You are an expert in Python."},
{"role": "user", "content": "Hello"}
]
}
输出:
{
"systemInstruction": {
"parts": [
{"text": "You are a helpful assistant."},
{"text": "You are an expert in Python."}
]
},
"messages": [
{"role": "user", "content": "Hello"}
]
}
Example (兼容性模式开启):
输入:
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello"}
]
}
输出:
{
"messages": [
{"role": "user", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello"}
]
}
Example (Anthropic格式,兼容性模式关闭):
输入:
{
"system": "You are a helpful assistant.",
"messages": [
{"role": "user", "content": "Hello"}
]
}
输出:
{
"systemInstruction": {
"parts": [
{"text": "You are a helpful assistant."}
]
},
"messages": [
{"role": "user", "content": "Hello"}
]
}
"""
from config import get_compatibility_mode_enabled
compatibility_mode = await get_compatibility_mode_enabled()
# 处理 Anthropic 格式的顶层 system 参数
# Anthropic API 规范: system 是顶层参数,不在 messages 中
system_content = request_body.get("system")
if system_content and "systemInstruction" not in request_body:
system_parts = []
if isinstance(system_content, str):
if system_content.strip():
system_parts.append({"text": system_content})
elif isinstance(system_content, list):
# system 可以是包含多个块的列表
for item in system_content:
if isinstance(item, dict):
if item.get("type") == "text" and item.get("text", "").strip():
system_parts.append({"text": item["text"]})
elif isinstance(item, str) and item.strip():
system_parts.append({"text": item})
if system_parts:
if compatibility_mode:
# 兼容性模式:将 system 转换为 user 消息插入到 messages 开头
user_system_message = {
"role": "user",
"content": system_content if isinstance(system_content, str) else
"\n".join(part["text"] for part in system_parts)
}
messages = request_body.get("messages", [])
request_body = request_body.copy()
request_body["messages"] = [user_system_message] + messages
else:
# 非兼容性模式:添加为 systemInstruction
request_body = request_body.copy()
request_body["systemInstruction"] = {"parts": system_parts}
messages = request_body.get("messages", [])
if not messages:
return request_body
compatibility_mode = await get_compatibility_mode_enabled()
if compatibility_mode:
# 兼容性模式开启:将所有system消息转换为user消息
converted_messages = []
for message in messages:
if message.get("role") == "system":
# 创建新的消息对象,将role改为user
converted_message = message.copy()
converted_message["role"] = "user"
converted_messages.append(converted_message)
else:
converted_messages.append(message)
result = request_body.copy()
result["messages"] = converted_messages
return result
else:
# 兼容性模式关闭:提取连续的system消息合并为systemInstruction
system_parts = []
# 如果已经从顶层 system 参数创建了 systemInstruction,获取现有的 parts
if "systemInstruction" in request_body:
existing_instruction = request_body.get("systemInstruction", {})
if isinstance(existing_instruction, dict):
system_parts = existing_instruction.get("parts", []).copy()
remaining_messages = []
collecting_system = True
for message in messages:
role = message.get("role", "")
content = message.get("content", "")
if role == "system" and collecting_system:
# 提取system消息的文本内容
if isinstance(content, str):
if content.strip():
system_parts.append({"text": content})
elif isinstance(content, list):
# 处理列表格式的content
for item in content:
if isinstance(item, dict):
if item.get("type") == "text" and item.get("text", "").strip():
system_parts.append({"text": item["text"]})
elif isinstance(item, str) and item.strip():
system_parts.append({"text": item})
else:
# 遇到非system消息,停止收集
collecting_system = False
remaining_messages.append(message)
# 如果没有找到任何system消息(包括顶层参数和messages中的),返回原始请求体
if not system_parts:
return request_body
# 构建新的请求体
result = request_body.copy()
# 添加或更新systemInstruction
result["systemInstruction"] = {"parts": system_parts}
# 更新messages列表(移除已处理的system消息)
result["messages"] = remaining_messages
return result