mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 01:40:15 +08:00
fix: remove unnecessary logging and improve log messages in Gemini source
This commit is contained in:
@@ -186,7 +186,6 @@ class ResultDecorateStage(Stage):
|
||||
|
||||
# 流式输出不执行下面的逻辑
|
||||
if is_stream:
|
||||
logger.info("流式输出已启用,跳过结果装饰阶段")
|
||||
return
|
||||
|
||||
# 需要再获取一次。插件可能直接对 chain 进行了替换。
|
||||
|
||||
@@ -90,7 +90,7 @@ class PipelineScheduler:
|
||||
if isinstance(event, WebChatMessageEvent | WecomAIBotMessageEvent):
|
||||
await event.send(None)
|
||||
|
||||
logger.debug("pipeline 执行完毕。")
|
||||
logger.debug("pipeline execution completed.")
|
||||
finally:
|
||||
event.cleanup_temporary_local_files()
|
||||
active_event_registry.unregister(event)
|
||||
|
||||
@@ -97,7 +97,6 @@ class ProviderGoogleGenAI(Provider):
|
||||
if proxy:
|
||||
async_client_kwargs["proxy"] = proxy
|
||||
async_client_kwargs["trust_env"] = False
|
||||
logger.info("[Gemini] 使用代理")
|
||||
else:
|
||||
async_client_kwargs["trust_env"] = True
|
||||
|
||||
@@ -137,15 +136,18 @@ class ProviderGoogleGenAI(Provider):
|
||||
keys.remove(self.chosen_api_key)
|
||||
if len(keys) > 0:
|
||||
self.set_key(random.choice(keys))
|
||||
logger.info(
|
||||
f"检测到 Key 异常({e.message}),正在尝试更换 API Key 重试... 当前 Key: {self.chosen_api_key[:12]}...",
|
||||
logger.warning(
|
||||
"Retrying with a different API key due to detected key issue: %s. Current key: %s...",
|
||||
e.message,
|
||||
self.chosen_api_key[:12],
|
||||
)
|
||||
await asyncio.sleep(1)
|
||||
return True
|
||||
logger.error(
|
||||
f"检测到 Key 异常({e.message}),且已没有可用的 Key。 当前 Key: {self.chosen_api_key[:12]}...",
|
||||
"No valid API keys remaining. Current key: %s...",
|
||||
self.chosen_api_key[:12],
|
||||
)
|
||||
raise Exception("达到了 Gemini 速率限制, 请稍后再试...")
|
||||
raise Exception("Gemini API rate limit reached or API key issue detected.")
|
||||
|
||||
# 连接错误处理
|
||||
if is_connection_error(e):
|
||||
@@ -172,7 +174,9 @@ class ProviderGoogleGenAI(Provider):
|
||||
self.provider_settings.get("streaming_response", False)
|
||||
and "IMAGE" in modalities
|
||||
):
|
||||
logger.warning("流式输出不支持图片模态,已自动降级为文本模态")
|
||||
logger.warning(
|
||||
"Streaming responses do not support IMAGE modality, falling back to TEXT modality."
|
||||
)
|
||||
modalities = ["TEXT"]
|
||||
|
||||
tool_list: list[types.Tool] | None = []
|
||||
@@ -181,60 +185,28 @@ class ProviderGoogleGenAI(Provider):
|
||||
native_search = self.provider_config.get("gm_native_search", False)
|
||||
url_context = self.provider_config.get("gm_url_context", False)
|
||||
|
||||
if "gemini-2.5" in model_name:
|
||||
if native_coderunner:
|
||||
tool_list.append(types.Tool(code_execution=types.ToolCodeExecution()))
|
||||
if native_search:
|
||||
logger.warning("代码执行工具与搜索工具互斥,已忽略搜索工具")
|
||||
if url_context:
|
||||
logger.warning(
|
||||
"代码执行工具与URL上下文工具互斥,已忽略URL上下文工具",
|
||||
)
|
||||
else:
|
||||
if native_search:
|
||||
tool_list.append(types.Tool(google_search=types.GoogleSearch()))
|
||||
|
||||
if url_context:
|
||||
if hasattr(types, "UrlContext"):
|
||||
tool_list.append(types.Tool(url_context=types.UrlContext()))
|
||||
else:
|
||||
logger.warning(
|
||||
"当前 SDK 版本不支持 URL 上下文工具,已忽略该设置,请升级 google-genai 包",
|
||||
)
|
||||
|
||||
elif "gemini-2.0-lite" in model_name:
|
||||
if "gemini-2.0-lite" in model_name:
|
||||
if native_coderunner or native_search or url_context:
|
||||
logger.warning(
|
||||
"gemini-2.0-lite 不支持代码执行、搜索工具和URL上下文,将忽略这些设置",
|
||||
"gemini-2.0-lite does not support native code execution, search, or URL context tools. These settings will be ignored.",
|
||||
)
|
||||
tool_list = None
|
||||
|
||||
else:
|
||||
if native_coderunner:
|
||||
tool_list.append(types.Tool(code_execution=types.ToolCodeExecution()))
|
||||
if native_search:
|
||||
logger.warning("代码执行工具与搜索工具互斥,已忽略搜索工具")
|
||||
elif native_search:
|
||||
if native_search:
|
||||
tool_list.append(types.Tool(google_search=types.GoogleSearch()))
|
||||
if url_context:
|
||||
tool_list.append(types.Tool(url_context=types.UrlContext()))
|
||||
|
||||
if url_context and not native_coderunner:
|
||||
if hasattr(types, "UrlContext"):
|
||||
tool_list.append(types.Tool(url_context=types.UrlContext()))
|
||||
else:
|
||||
logger.warning(
|
||||
"当前 SDK 版本不支持 URL 上下文工具,已忽略该设置,请升级 google-genai 包",
|
||||
)
|
||||
if tools:
|
||||
func_desc = tools.get_func_desc_google_genai_style()
|
||||
tool_list.append(
|
||||
types.Tool(function_declarations=func_desc["function_declarations"]),
|
||||
)
|
||||
|
||||
if not tool_list:
|
||||
tool_list = None
|
||||
|
||||
if tools and tool_list:
|
||||
logger.warning("已启用原生工具,函数工具将被忽略")
|
||||
elif tools and (func_desc := tools.get_func_desc_google_genai_style()):
|
||||
tool_list = [
|
||||
types.Tool(function_declarations=func_desc["function_declarations"]),
|
||||
]
|
||||
|
||||
tool_config = None
|
||||
has_func_decl = tool_list and any(t.function_declarations for t in tool_list)
|
||||
if has_func_decl:
|
||||
@@ -322,7 +294,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
def create_text_part(text: str) -> types.Part:
|
||||
content_a = text if text else " "
|
||||
if not text:
|
||||
logger.warning("文本内容为空,已添加空格占位")
|
||||
logger.warning("Text content is empty, added a space as placeholder.")
|
||||
return types.Part.from_text(text=content_a)
|
||||
|
||||
def process_image_url(image_url_dict: dict) -> types.Part:
|
||||
@@ -394,11 +366,16 @@ class ProviderGoogleGenAI(Provider):
|
||||
)
|
||||
thinking_signature = None
|
||||
|
||||
if not text and thinking_signature and "tool_calls" in message and any(
|
||||
tool.get("extra_content", {}).get("google", {}).get(
|
||||
"thought_signature"
|
||||
if (
|
||||
not text
|
||||
and thinking_signature
|
||||
and "tool_calls" in message
|
||||
and any(
|
||||
tool.get("extra_content", {})
|
||||
.get("google", {})
|
||||
.get("thought_signature")
|
||||
for tool in message["tool_calls"]
|
||||
)
|
||||
for tool in message["tool_calls"]
|
||||
):
|
||||
# If the main content is empty but tool calls have thought signatures,
|
||||
# skip adding an empty text part to deduplicate the thinking signature in the main content and tool calls.
|
||||
@@ -499,7 +476,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
) -> MessageChain:
|
||||
"""处理内容部分并构建消息链"""
|
||||
if not candidate.content:
|
||||
logger.warning(f"收到的 candidate.content 为空: {candidate}")
|
||||
logger.warning(f"Gemini candidate.content is empty: {candidate}")
|
||||
if validate_output:
|
||||
raise EmptyModelOutputError(
|
||||
"Gemini candidate content is empty. "
|
||||
@@ -512,22 +489,22 @@ class ProviderGoogleGenAI(Provider):
|
||||
result_parts: list[types.Part] | None = candidate.content.parts
|
||||
|
||||
if finish_reason == types.FinishReason.SAFETY:
|
||||
raise Exception("模型生成内容未通过 Gemini 平台的安全检查")
|
||||
raise Exception("The model output failed Gemini platform safety checks.")
|
||||
|
||||
if finish_reason in {
|
||||
types.FinishReason.PROHIBITED_CONTENT,
|
||||
types.FinishReason.SPII,
|
||||
types.FinishReason.BLOCKLIST,
|
||||
}:
|
||||
raise Exception("模型生成内容违反 Gemini 平台政策")
|
||||
raise Exception("The model output violates Gemini platform policy.")
|
||||
|
||||
# 防止旧版本SDK不存在IMAGE_SAFETY
|
||||
if hasattr(types.FinishReason, "IMAGE_SAFETY"):
|
||||
if finish_reason == types.FinishReason.IMAGE_SAFETY:
|
||||
raise Exception("模型生成内容违反 Gemini 平台政策")
|
||||
raise Exception("The model output violates Gemini platform policy.")
|
||||
|
||||
if not result_parts:
|
||||
logger.warning(f"收到的 candidate.content.parts 为空: {candidate}")
|
||||
logger.warning(f"Gemini candidate.content.parts is empty: {candidate}")
|
||||
if validate_output:
|
||||
raise EmptyModelOutputError(
|
||||
"Gemini candidate content parts are empty. "
|
||||
@@ -634,15 +611,19 @@ class ProviderGoogleGenAI(Provider):
|
||||
logger.debug(f"genai result: {result}")
|
||||
|
||||
if not result.candidates:
|
||||
logger.error(f"请求失败, 返回的 candidates 为空: {result}")
|
||||
raise Exception("请求失败, 返回的 candidates 为空。")
|
||||
logger.error(
|
||||
f"Gemini request failed: candidates is empty: {result}"
|
||||
)
|
||||
raise Exception("Gemini request failed: candidates is empty.")
|
||||
|
||||
if result.candidates[0].finish_reason == types.FinishReason.RECITATION:
|
||||
if temperature > 2:
|
||||
raise Exception("温度参数已超过最大值2,仍然发生recitation")
|
||||
raise Exception(
|
||||
"Temperature exceeded the maximum value of 2, but Gemini recitation still occurred."
|
||||
)
|
||||
temperature += 0.2
|
||||
logger.warning(
|
||||
f"发生了recitation,正在提高温度至{temperature:.1f}重试...",
|
||||
f"Gemini recitation detected; increasing temperature to {temperature:.1f} and retrying...",
|
||||
)
|
||||
continue
|
||||
|
||||
@@ -653,11 +634,13 @@ class ProviderGoogleGenAI(Provider):
|
||||
e.message = ""
|
||||
if "Developer instruction is not enabled" in e.message:
|
||||
logger.warning(
|
||||
f"{model} 不支持 system prompt,已自动去除(影响人格设置)",
|
||||
f"{model} does not support system prompts; removing it automatically. This may affect persona settings.",
|
||||
)
|
||||
system_instruction = None
|
||||
elif "Function calling is not enabled" in e.message:
|
||||
logger.warning(f"{model} 不支持函数调用,已自动去除")
|
||||
logger.warning(
|
||||
f"{model} does not support function calling; removing tools automatically."
|
||||
)
|
||||
tools = None
|
||||
elif (
|
||||
"Multi-modal output is not supported" in e.message
|
||||
@@ -666,7 +649,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
or "only supports text output" in e.message
|
||||
):
|
||||
logger.warning(
|
||||
f"{model} 不支持多模态输出,降级为文本模态",
|
||||
f"{model} does not support multimodal output; falling back to TEXT modality.",
|
||||
)
|
||||
modalities = ["TEXT"]
|
||||
else:
|
||||
@@ -717,11 +700,13 @@ class ProviderGoogleGenAI(Provider):
|
||||
e.message = ""
|
||||
if "Developer instruction is not enabled" in e.message:
|
||||
logger.warning(
|
||||
f"{model} 不支持 system prompt,已自动去除(影响人格设置)",
|
||||
f"{model} does not support system prompts; removing it automatically. This may affect persona settings.",
|
||||
)
|
||||
system_instruction = None
|
||||
elif "Function calling is not enabled" in e.message:
|
||||
logger.warning(f"{model} 不支持函数调用,已自动去除")
|
||||
logger.warning(
|
||||
f"{model} does not support function calling; removing tools automatically."
|
||||
)
|
||||
tools = None
|
||||
else:
|
||||
raise
|
||||
@@ -736,10 +721,10 @@ class ProviderGoogleGenAI(Provider):
|
||||
llm_response = LLMResponse("assistant", is_chunk=True)
|
||||
|
||||
if not chunk.candidates:
|
||||
logger.warning(f"收到的 chunk 中 candidates 为空: {chunk}")
|
||||
logger.warning(f"Gemini stream chunk has empty candidates: {chunk}")
|
||||
continue
|
||||
if not chunk.candidates[0].content:
|
||||
logger.warning(f"收到的 chunk 中 content 为空: {chunk}")
|
||||
logger.warning(f"Gemini stream chunk has empty content: {chunk}")
|
||||
continue
|
||||
|
||||
if chunk.candidates[0].content.parts and any(
|
||||
@@ -870,7 +855,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
continue
|
||||
break
|
||||
|
||||
raise Exception("请求失败。")
|
||||
raise Exception("Gemini request failed.")
|
||||
|
||||
async def text_chat_stream(
|
||||
self,
|
||||
@@ -945,7 +930,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
and m.name
|
||||
]
|
||||
except APIError as e:
|
||||
raise Exception(f"获取模型列表失败: {e.message}")
|
||||
raise Exception(f"Failed to fetch Gemini model list: {e.message}")
|
||||
|
||||
def get_current_key(self) -> str:
|
||||
return self.chosen_api_key
|
||||
@@ -972,7 +957,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
media_type="image",
|
||||
)
|
||||
if not image_data:
|
||||
logger.warning("图片预处理结果为空,将忽略。")
|
||||
logger.warning("Image preprocessing returned no data; ignoring it.")
|
||||
return None
|
||||
return {
|
||||
"type": "image_url",
|
||||
@@ -987,11 +972,13 @@ class ProviderGoogleGenAI(Provider):
|
||||
strict=True,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.warning("音频预处理失败,将忽略。错误: %s", exc)
|
||||
logger.warning(
|
||||
"Audio preprocessing failed; ignoring it. Error: %s", exc
|
||||
)
|
||||
return None
|
||||
|
||||
if not audio_data:
|
||||
logger.warning("音频预处理结果为空,将忽略。")
|
||||
logger.warning("Audio preprocessing returned no data; ignoring it.")
|
||||
return None
|
||||
return {
|
||||
"type": "audio_url",
|
||||
@@ -1027,7 +1014,9 @@ class ProviderGoogleGenAI(Provider):
|
||||
if audio_part:
|
||||
content_blocks.append(audio_part)
|
||||
else:
|
||||
raise ValueError(f"不支持的额外内容块类型: {type(part)}")
|
||||
raise ValueError(
|
||||
f"Unsupported extra content part type: {type(part)}"
|
||||
)
|
||||
|
||||
# 3. 图片内容
|
||||
if image_urls:
|
||||
|
||||
Reference in New Issue
Block a user