diff --git a/astrbot/core/provider/func_tool_manager.py b/astrbot/core/provider/func_tool_manager.py index efe2674cb..b82ec6db7 100644 --- a/astrbot/core/provider/func_tool_manager.py +++ b/astrbot/core/provider/func_tool_manager.py @@ -121,7 +121,8 @@ class FuncCall: tools.append(func_declaration) - declarations["function_declarations"] = tools + if tools: + declarations["function_declarations"] = tools return declarations diff --git a/astrbot/core/provider/sources/gemini_source.py b/astrbot/core/provider/sources/gemini_source.py index 83d5c27f2..2b2a9916f 100644 --- a/astrbot/core/provider/sources/gemini_source.py +++ b/astrbot/core/provider/sources/gemini_source.py @@ -181,6 +181,9 @@ class ProviderGoogleGenAI(Provider): ) logger.debug(f"result: {result}") + if "candidates" not in result: + raise Exception("Gemini 返回异常结果: " + str(result)) + candidates = result["candidates"][0]['content']['parts'] llm_response = LLMResponse("assistant") for candidate in candidates: @@ -222,11 +225,9 @@ class ProviderGoogleGenAI(Provider): "messages": context_query, **self.provider_config.get("model_config", {}) } - + llm_response = None try: llm_response = await self._query(payloads, func_tool) - await self.save_history(contexts, new_record, session_id, llm_response) - return llm_response except Exception as e: if "maximum context length" in str(e): retry_cnt = 10 @@ -241,8 +242,22 @@ class ProviderGoogleGenAI(Provider): retry_cnt -= 1 else: raise e + if retry_cnt == 0: + llm_response = LLMResponse("err", "err: 请尝试 /reset 重置会话") + elif "Function calling is not enabled" in str(e): + logger.info(f"{self.get_model()} 不支持函数调用工具调用,已经自动去除") + if 'tools' in payloads: + del payloads['tools'] + llm_response = await self._query(payloads, None) else: + logger.error(f"发生了错误(gemini_source)。Provider 配置如下: {self.provider_config}") + raise e + + if kwargs.get("persist", True) and llm_response: + await self.save_history(contexts, new_record, session_id, llm_response) + + return llm_response async def save_history(self, contexts: List, new_record: dict, session_id: str, llm_response: LLMResponse): if llm_response.role == "assistant" and session_id: diff --git a/astrbot/core/provider/sources/openai_source.py b/astrbot/core/provider/sources/openai_source.py index ef0b74a32..d299986e8 100644 --- a/astrbot/core/provider/sources/openai_source.py +++ b/astrbot/core/provider/sources/openai_source.py @@ -187,15 +187,15 @@ class ProviderOpenAIOfficial(Provider): llm_response = LLMResponse("err", "err: 请尝试 /reset 清除会话记录。") elif "The model is not a VLM" in str(e): # siliconcloud # 尝试删除所有 image - print(context_query) new_contexts = await self._remove_image_from_context(context_query) - print(new_contexts) payloads['messages'] = new_contexts llm_response = await self._query(payloads, func_tool) + # openai, ollama, gemini openai, siliconcloud 的错误提示与 code 不统一,只能通过字符串匹配 elif 'does not support Function Calling' in str(e) \ or 'does not support tools' in str(e) \ or 'Function call is not supported' in str(e) \ + or 'Function calling is not enabled' in str(e) \ or 'Tool calling is not supported' in str(e): # siliconcloud logger.info(f"{self.get_model()} 不支持函数调用工具调用,已经自动去除") if 'tools' in payloads: