From 93cef02d9209470c70a86e6430b47d99afad06ef Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Thu, 7 May 2026 17:21:10 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E5=9B=BE=E7=89=87=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E7=9A=84=E6=84=8F=E5=A4=96warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/image_system/image_manager.py | 37 +++++++++++++++++++------- src/config/config.py | 2 +- src/config/official_configs.py | 11 ++++---- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/chat/image_system/image_manager.py b/src/chat/image_system/image_manager.py index 6bfc77d6..537f2f86 100644 --- a/src/chat/image_system/image_manager.py +++ b/src/chat/image_system/image_manager.py @@ -119,7 +119,7 @@ class ImageManager: logger.warning("图片哈希值未找到,且未提供图片字节数据,返回无描述") return "" try: - await self.ensure_image_saved(image_bytes) + saved_image = await self.ensure_image_saved(image_bytes) except Exception as e: logger.error(f"保存图片文件时发生错误: {e}") return "" @@ -127,22 +127,29 @@ class ImageManager: logger.info("未配置 VLM 模型,跳过图片识别") return "" if not wait_for_build: - self._schedule_description_build(hash_str, image_bytes) + self._schedule_description_build(hash_str, image_bytes, saved_image=saved_image) return "" logger.info(f"图片描述未找到,哈希值: {hash_str},准备生成新描述") try: - image = await self.build_image_description(image_bytes) + image = await self.build_image_description(image_bytes, saved_image=saved_image) return image.description except Exception as e: logger.error(f"生成图片描述时发生错误: {e}") return "" - def _schedule_description_build(self, image_hash: str, image_bytes: bytes) -> None: + def _schedule_description_build( + self, + image_hash: str, + image_bytes: bytes, + *, + saved_image: Optional[MaiImage] = None, + ) -> None: """调度图片描述后台构建任务。 Args: image_hash: 图片哈希值。 image_bytes: 图片字节数据。 + saved_image: 已保存的图片对象,避免后台任务重复执行保存流程。 """ if not _is_vlm_task_configured(): logger.info("未配置 VLM 模型,跳过图片后台识别任务") @@ -151,20 +158,27 @@ class ImageManager: if image_hash in self._pending_description_tasks: return - task = asyncio.create_task(self._build_description_in_background(image_hash, image_bytes)) + task = asyncio.create_task(self._build_description_in_background(image_hash, image_bytes, saved_image=saved_image)) self._pending_description_tasks[image_hash] = task task.add_done_callback(lambda finished_task: self._finalize_description_build(image_hash, finished_task)) - async def _build_description_in_background(self, image_hash: str, image_bytes: bytes) -> None: + async def _build_description_in_background( + self, + image_hash: str, + image_bytes: bytes, + *, + saved_image: Optional[MaiImage] = None, + ) -> None: """在后台构建并缓存图片描述。 Args: image_hash: 图片哈希值。 image_bytes: 图片字节数据。 + saved_image: 已保存的图片对象,避免重复查询和更新访问计数。 """ try: logger.info(f"图片描述后台构建已开始,哈希值: {image_hash}") - await self.build_image_description(image_bytes) + await self.build_image_description(image_bytes, saved_image=saved_image) logger.info(f"图片描述后台构建完成,哈希值: {image_hash}") except Exception as exc: logger.warning(f"图片描述后台构建失败,哈希值: {image_hash},错误: {exc}") @@ -315,9 +329,14 @@ class ImageManager: raise RuntimeError(f"保存图片记录到数据库失败: {hash_str}") return mai_image - async def build_image_description(self, image_bytes: bytes) -> MaiImage: + async def build_image_description( + self, + image_bytes: bytes, + *, + saved_image: Optional[MaiImage] = None, + ) -> MaiImage: """在图片已保存的前提下生成或补齐图片描述。""" - mai_image = await self.ensure_image_saved(image_bytes) + mai_image = saved_image or await self.ensure_image_saved(image_bytes) if not mai_image.image_format: await mai_image.calculate_hash_format() if mai_image.vlm_processed and mai_image.description: diff --git a/src/config/config.py b/src/config/config.py index 8859816c..109d9462 100644 --- a/src/config/config.py +++ b/src/config/config.py @@ -57,7 +57,7 @@ MODEL_CONFIG_PATH: Path = (CONFIG_DIR / "model_config.toml").resolve().absolute( LEGACY_ENV_PATH: Path = (PROJECT_ROOT / ".env").resolve().absolute() A_MEMORIX_LEGACY_CONFIG_PATH: Path = (CONFIG_DIR / "a_memorix.toml").resolve().absolute() MMC_VERSION: str = "1.0.0-pre.14" -CONFIG_VERSION: str = "8.10.12" +CONFIG_VERSION: str = "8.10.13" MODEL_CONFIG_VERSION: str = "1.16.0" logger = get_logger("config") diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 0476a4e8..c9d67efb 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -394,7 +394,7 @@ class ChatConfig(ConfigBase): """上下文长度""" max_private_context_size: int = Field( - default=40, + default=60, json_schema_extra={ "label": { "zh_CN": "私聊上下文", @@ -422,20 +422,21 @@ class ChatConfig(ConfigBase): """Planner 连续被新消息打断的最大次数,0 表示不启用打断""" timing_gate_non_continue_cooldown_seconds: float = Field( - default=0, + default=8, ge=0, json_schema_extra={ "label": { - "zh_CN": "Timing Gate 非 continue 冷却", + "zh_CN": "Timing Gate 平滑", "en_US": "Timing Gate non-continue cooldown", "ja_JP": "Timing Gate 非 continue クールダウン", }, "x-widget": "input", "x-icon": "timer", - "advanced": True, + "x-description-display": "icon", + "advanced": False, }, ) - """Timing Gate 返回 no_reply 时的最小窗口秒数,0 表示不启用冷却""" + """这个值决定了 timing gate 判断的频率,值越大,timing gate 的判断越平滑,但也可能导致反应变慢。建议根据实际情况调整,找到一个既能保持反应及时又不过于频繁的平衡点。""" group_chat_prompt: str = Field( default=(