修复gemini_client的小错误

pull/1211/head
UnCLAS-Prommer 2025-08-21 23:26:45 +08:00
parent 957f5f93dd
commit 49cb5e9b28
No known key found for this signature in database
1 changed files with 21 additions and 29 deletions

View File

@ -47,10 +47,13 @@ logger = get_logger("Gemini客户端")
# gemini_thinking参数默认范围 # gemini_thinking参数默认范围
# 不同模型的思考预算范围配置 # 不同模型的思考预算范围配置
THINKING_BUDGET_LIMITS = { THINKING_BUDGET_LIMITS = {
"gemini-2.5-flash": {"min": 1, "max": 24576, "can_disable": True}, "gemini-2.5-flash": {"min": 1, "max": 24576, "can_disable": True},
"gemini-2.5-flash-lite": {"min": 512, "max": 24576, "can_disable": True}, "gemini-2.5-flash-lite": {"min": 512, "max": 24576, "can_disable": True},
"gemini-2.5-pro": {"min": 128, "max": 32768, "can_disable": False}, "gemini-2.5-pro": {"min": 128, "max": 32768, "can_disable": False},
} }
# 思维预算特殊值
THINKING_BUDGET_AUTO = -1 # 自动调整思考预算,由模型决定
THINKING_BUDGET_DISABLED = 0 # 禁用思考预算(如果模型允许禁用)
gemini_safe_settings = [ gemini_safe_settings = [
SafetySetting(category=HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold=HarmBlockThreshold.BLOCK_NONE), SafetySetting(category=HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold=HarmBlockThreshold.BLOCK_NONE),
@ -91,9 +94,7 @@ def _convert_messages(
for item in message.content: for item in message.content:
if isinstance(item, tuple): if isinstance(item, tuple):
image_format = "jpeg" if item[0].lower() == "jpg" else item[0].lower() image_format = "jpeg" if item[0].lower() == "jpg" else item[0].lower()
content.append( content.append(Part.from_bytes(data=base64.b64decode(item[1]), mime_type=f"image/{image_format}"))
Part.from_bytes(data=base64.b64decode(item[1]), mime_type=f"image/{image_format}")
)
elif isinstance(item, str): elif isinstance(item, str):
content.append(Part.from_text(text=item)) content.append(Part.from_text(text=item))
else: else:
@ -336,47 +337,40 @@ class GeminiClient(BaseClient):
api_key=api_provider.api_key, api_key=api_provider.api_key,
) # 这里和openai不一样gemini会自己决定自己是否需要retry ) # 这里和openai不一样gemini会自己决定自己是否需要retry
# 思维预算特殊值
THINKING_BUDGET_AUTO = -1 # 自动调整思考预算,由模型决定
THINKING_BUDGET_DISABLED = 0 # 禁用思考预算(如果模型允许禁用)
@staticmethod @staticmethod
def clamp_thinking_budget(tb: int, model_id: str): def clamp_thinking_budget(tb: int, model_id: str) -> int:
""" """
按模型限制思考预算范围仅支持指定的模型支持带数字后缀的新版本 按模型限制思考预算范围仅支持指定的模型支持带数字后缀的新版本
""" """
limits = None limits = None
matched_key = None
# 优先尝试精确匹配 # 优先尝试精确匹配
if model_id in THINKING_BUDGET_LIMITS: if model_id in THINKING_BUDGET_LIMITS:
limits = THINKING_BUDGET_LIMITS[model_id] limits = THINKING_BUDGET_LIMITS[model_id]
matched_key = model_id
else: else:
# 按 key 长度倒序,保证更长的(更具体的,如 -lite优先 # 按 key 长度倒序,保证更长的(更具体的,如 -lite优先
sorted_keys = sorted(THINKING_BUDGET_LIMITS.keys(), key=len, reverse=True) sorted_keys = sorted(THINKING_BUDGET_LIMITS.keys(), key=len, reverse=True)
for key in sorted_keys: for key in sorted_keys:
# 必须满足:完全等于 或者 前缀匹配(带 "-" 边界) # 必须满足:完全等于 或者 前缀匹配(带 "-" 边界)
if model_id == key or model_id.startswith(key + "-"): if model_id == key or model_id.startswith(f"{key}-"):
limits = THINKING_BUDGET_LIMITS[key] limits = THINKING_BUDGET_LIMITS[key]
matched_key = key break
break
# 特殊值处理 # 特殊值处理
if tb == GeminiClient.THINKING_BUDGET_AUTO: if tb == THINKING_BUDGET_AUTO:
return GeminiClient.THINKING_BUDGET_AUTO return THINKING_BUDGET_AUTO
if tb == GeminiClient.THINKING_BUDGET_DISABLED: if tb == THINKING_BUDGET_DISABLED:
if limits and limits.get("can_disable", False): if limits and limits.get("can_disable", False):
return GeminiClient.THINKING_BUDGET_DISABLED return THINKING_BUDGET_DISABLED
return limits["min"] if limits else GeminiClient.THINKING_BUDGET_AUTO return limits["min"] if limits else THINKING_BUDGET_AUTO
# 已知模型裁剪到范围 # 已知模型裁剪到范围
if limits: if limits:
return max(limits["min"], min(tb, limits["max"])) return max(limits["min"], min(tb, limits["max"]))
# 未知模型,返回动态模式 # 未知模型,返回动态模式
logger.warning(f"模型 {model_id} 未在 THINKING_BUDGET_LIMITS 中定义,将使用动态模式 tb=-1 兼容。") logger.warning(f"模型 {model_id} 未在 THINKING_BUDGET_LIMITS 中定义,将使用动态模式 tb=-1 兼容。")
return GeminiClient.THINKING_BUDGET_AUTO return THINKING_BUDGET_AUTO
async def get_response( async def get_response(
self, self,
@ -424,15 +418,13 @@ class GeminiClient(BaseClient):
# 将tool_options转换为Gemini API所需的格式 # 将tool_options转换为Gemini API所需的格式
tools = _convert_tool_options(tool_options) if tool_options else None tools = _convert_tool_options(tool_options) if tool_options else None
tb = GeminiClient.THINKING_BUDGET_AUTO tb = THINKING_BUDGET_AUTO
#空处理 # 空处理
if extra_params and "thinking_budget" in extra_params: if extra_params and "thinking_budget" in extra_params:
try: try:
tb = int(extra_params["thinking_budget"]) tb = int(extra_params["thinking_budget"])
except (ValueError, TypeError): except (ValueError, TypeError):
logger.warning( logger.warning(f"无效的 thinking_budget 值 {extra_params['thinking_budget']},将使用默认动态模式 {tb}")
f"无效的 thinking_budget 值 {extra_params['thinking_budget']},将使用默认动态模式 {tb}"
)
# 裁剪到模型支持的范围 # 裁剪到模型支持的范围
tb = self.clamp_thinking_budget(tb, model_info.model_identifier) tb = self.clamp_thinking_budget(tb, model_info.model_identifier)