From 2471a2c4a4659a23df53e7a96655f5276511a453 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Mon, 13 Apr 2026 19:54:38 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E5=B7=A5=E5=85=B7=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E5=AD=98=E5=82=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/llm_models/model_client/openai_client.py | 12 ++++++++++-- src/services/database_service.py | 14 ++++++++------ src/services/memory_flow_service.py | 5 ----- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/llm_models/model_client/openai_client.py b/src/llm_models/model_client/openai_client.py index 2a3bf8a4..8a02e37c 100644 --- a/src/llm_models/model_client/openai_client.py +++ b/src/llm_models/model_client/openai_client.py @@ -6,6 +6,7 @@ import json import re from dataclasses import dataclass, field from typing import Any, Callable, Coroutine, Dict, List, Tuple, cast +from uuid import uuid4 from json_repair import repair_json from openai import APIConnectionError, APIStatusError, AsyncOpenAI, AsyncStream @@ -119,6 +120,13 @@ OpenAIResponseParser = Callable[[ChatCompletion], Tuple[APIResponse, UsageTuple """OpenAI 非流式响应解析函数类型。""" +def _build_fallback_tool_call_id(prefix: str) -> str: + """为缺失原始调用 ID 的工具调用生成唯一兜底标识。""" + + normalized_prefix = str(prefix).strip() or "tool_call" + return f"{normalized_prefix}_{uuid4().hex}" + + def _normalize_reasoning_parse_mode(parse_mode: str | ReasoningParseMode) -> ReasoningParseMode: """将配置中的推理解析模式收敛为枚举值。 @@ -609,7 +617,7 @@ def _extract_xml_tool_calls( arguments = _parse_tool_arguments(raw_arguments, parse_mode, response) if raw_arguments else {} tool_calls.append( ToolCall( - call_id=f"xml_tool_call_{len(tool_calls) + 1}", + call_id=_build_fallback_tool_call_id("xml_tool_call"), func_name=function_name, args=arguments, ) @@ -855,7 +863,7 @@ class _OpenAIStreamAccumulator: if raw_arguments else None ) - call_id = state.call_id or f"tool_call_{index}" + call_id = state.call_id or _build_fallback_tool_call_id(f"tool_call_{index}") response.tool_calls.append(ToolCall(call_id=call_id, func_name=state.function_name, args=arguments)) response.raw_data = {"model": self.model_name} if self.model_name else None diff --git a/src/services/database_service.py b/src/services/database_service.py index 5e41f2c6..57215878 100644 --- a/src/services/database_service.py +++ b/src/services/database_service.py @@ -4,16 +4,18 @@ import json import time import traceback from datetime import datetime -from typing import Any, Optional, cast +from typing import TYPE_CHECKING, Any, Optional, cast -from sqlalchemy import delete, func, select -from sqlmodel import SQLModel +from sqlalchemy import delete, func +from sqlmodel import SQLModel, select -from src.chat.message_receive.chat_manager import BotChatSession from src.common.database.database import get_db_session from src.common.database.database_model import ToolRecord from src.common.logger import get_logger +if TYPE_CHECKING: + from src.chat.message_receive.chat_manager import BotChatSession + logger = get_logger("database_service") @@ -158,7 +160,7 @@ async def db_count(model_class: type[SQLModel], filters: Optional[dict[str, Any] async def store_tool_info( - chat_stream: BotChatSession, + chat_stream: "BotChatSession", builtin_prompt: Optional[str] = None, display_prompt: str = "", tool_id: str = "", @@ -191,7 +193,7 @@ async def store_tool_info( async def store_action_info( - chat_stream: BotChatSession, + chat_stream: "BotChatSession", builtin_prompt: Optional[str] = None, display_prompt: str = "", thinking_id: str = "", diff --git a/src/services/memory_flow_service.py b/src/services/memory_flow_service.py index 8b7d8aa4..969b8a23 100644 --- a/src/services/memory_flow_service.py +++ b/src/services/memory_flow_service.py @@ -227,11 +227,6 @@ class MemoryAutomationService: await self.fact_writeback.shutdown() self._started = False - async def on_incoming_message(self, message: Any) -> None: - del message - if not self._started: - await self.start() - async def on_message_sent(self, message: Any) -> None: if not self._started: await self.start()