Merge pull request #1251 from foxplaying/patch-2

Gemini:正式启用HttpOptions对传入参数的处理,优化预算提示,修正文档
This commit is contained in:
UnCLAS-Prommer
2025-09-23 20:10:37 +08:00
committed by GitHub
2 changed files with 51 additions and 25 deletions

View File

@@ -17,6 +17,7 @@ from google.genai.types import (
EmbedContentResponse,
EmbedContentConfig,
SafetySetting,
HttpOptions,
HarmCategory,
HarmBlockThreshold,
)
@@ -345,22 +346,27 @@ class GeminiClient(BaseClient):
def __init__(self, api_provider: APIProvider):
super().__init__(api_provider)
# 增加传入参数处理
http_options_kwargs = {"timeout": api_provider.timeout}
# 秒转换为毫秒传入
if api_provider.timeout is not None:
http_options_kwargs["timeout"] = int(api_provider.timeout * 1000)
# 传入并处理地址和版本(必须为Gemini格式)
if api_provider.base_url:
parts = api_provider.base_url.rstrip("/").rsplit("/", 1)
if len(parts) == 2 and parts[1].startswith("v"):
http_options_kwargs["base_url"] = f"{parts[0]}/"
http_options_kwargs["api_version"] = parts[1]
else:
http_options_kwargs["base_url"] = api_provider.base_url
self.client = genai.Client(
http_options=HttpOptions(**http_options_kwargs),
api_key=api_provider.api_key,
) # 这里和openai不一样gemini会自己决定自己是否需要retry
# 尝试传入自定义base_url(实验性必须为Gemini格式)
if hasattr(api_provider, "base_url") and api_provider.base_url:
base_url = api_provider.base_url.rstrip("/") # 去掉末尾 /
self.client._api_client._http_options.base_url = base_url
# 如果 base_url 已经带了 /v1 或 /v1beta就清掉 SDK 的 api_version
if base_url.endswith("/v1") or base_url.endswith("/v1beta"):
self.client._api_client._http_options.api_version = None
# 让 GeminiClient 内部也能访问底层 api_client
self._api_client = self.client._api_client
@staticmethod
def clamp_thinking_budget(tb: int, model_id: str) -> int:
"""
@@ -380,20 +386,29 @@ class GeminiClient(BaseClient):
limits = THINKING_BUDGET_LIMITS[key]
break
# 特殊值处理
# 预算值处理
if tb == THINKING_BUDGET_AUTO:
return THINKING_BUDGET_AUTO
if tb == THINKING_BUDGET_DISABLED:
if limits and limits.get("can_disable", False):
return THINKING_BUDGET_DISABLED
return limits["min"] if limits else THINKING_BUDGET_AUTO
if limits:
logger.warning(f"模型 {model_id} 不支持禁用思考预算,已回退到最小值 {limits['min']}")
return limits["min"]
return THINKING_BUDGET_AUTO
# 已知模型裁剪到范围
# 已知模型范围裁剪 + 提示
if limits:
return max(limits["min"], min(tb, limits["max"]))
if tb < limits["min"]:
logger.warning(f"模型 {model_id} 的 thinking_budget={tb} 过小,已调整为最小值 {limits['min']}")
return limits["min"]
if tb > limits["max"]:
logger.warning(f"模型 {model_id} 的 thinking_budget={tb} 过大,已调整为最大值 {limits['max']}")
return limits["max"]
return tb
# 未知模型,返回动态模式
logger.warning(f"模型 {model_id} 未在 THINKING_BUDGET_LIMITS 中定义,将使用动态模式 tb=-1 兼容")
# 未知模型 → 默认自动模式
logger.warning(f"模型 {model_id} 未在 THINKING_BUDGET_LIMITS 中定义,已启用模型自动预算兼容")
return THINKING_BUDGET_AUTO
async def get_response(
@@ -448,7 +463,7 @@ class GeminiClient(BaseClient):
try:
tb = int(extra_params["thinking_budget"])
except (ValueError, TypeError):
logger.warning(f"无效的 thinking_budget 值 {extra_params['thinking_budget']},将使用默认动态模式 {tb}")
logger.warning(f"无效的 thinking_budget 值 {extra_params['thinking_budget']},将使用模型自动预算模式 {tb}")
# 裁剪到模型支持的范围
tb = self.clamp_thinking_budget(tb, model_info.model_identifier)