Skip to content

Conversation

@Dt8333
Copy link
Contributor

@Dt8333 Dt8333 commented Oct 20, 2025

fixes #3112


Motivation / 动机

修复配置中LTM-自动理解图片功能无法关闭,在实际使用中一直启用的问题。

Modifications / 改动点

使能配置项目,合并8d4c176中的判断逻辑,实现在禁用开关或无提示词时自动禁用。

Verification Steps / 验证步骤

开启LTM,关闭自动理解图片。
在群聊中发送图片。
观察LTM是否不再调用LLM。

Screenshots or Test Results / 运行截图或测试结果

Compatibility & Breaking Changes / 兼容性与破坏性变更

  • 这是一个破坏性变更 (Breaking Change)。/ This is a breaking change.
  • 这不是一个破坏性变更。/ This is NOT a breaking change.

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Sourcery 总结

修复 LTM 自动图像理解功能,以尊重用户的禁用设置,并确保它仅在提供了相应的提示和标志时才激活。

错误修复:

  • 允许禁用自动图像解释,方法是在启用前同时检查 image_caption 配置标志和提示的存在。
  • 解决 LTM 图像理解功能在关闭后仍然保持活动状态的问题。

改进:

  • 简化 handle_message 条件,以一致地应用更新后的配置逻辑。
Original summary in English

Sourcery 总结

修复长期记忆中的自动图片理解功能,使其正确遵守用户禁用设置,并且仅在提供者和提示都已配置时才激活。

Bug 修复:

  • 在启用提供者之前,通过检查 image_caption 标志来允许禁用自动图片理解
  • 防止 LTM 在功能关闭或未提供提示时调用图片理解逻辑

增强功能:

  • 简化 handle_message 条件逻辑,以一致地应用更新后的 image_caption 配置
Original summary in English

Summary by Sourcery

Fix the automatic image understanding feature in long-term memory to correctly respect user disable settings and only activate when both the provider and prompt are configured.

Bug Fixes:

  • Allow disabling automatic image understanding by checking the image_caption flag before enabling the provider
  • Prevent LTM from invoking the image understanding logic when the feature is turned off or no prompt is provided

Enhancements:

  • Simplify handle_message conditional logic to consistently apply the updated image_caption configuration

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好 - 我已审阅了你的更改,它们看起来很棒!

AI 代理提示
请解决此代码审查中的评论:

## 独立评论

### 评论 1
<location> `packages/astrbot/long_term_memory.py:113` </location>
<code_context>
     async def handle_message(self, event: AstrMessageEvent):
         """仅支持群聊"""
-        if event.get_message_type() == MessageType.GROUP_MESSAGE:
+        if (event.get_message_type() == MessageType.GROUP_MESSAGE) or True:
             datetime_str = datetime.datetime.now().strftime("%H:%M:%S")

</code_context>

<issue_to_address>
**问题 (bug_risk):** 该条件始终评估为 True,使得消息处理器变为无条件。

'or True' 子句导致此代码块对所有消息类型运行。如果这是为了调试,请明确标记或在合并前删除。否则,可能会导致意外处理。
</issue_to_address>

### 评论 2
<location> `packages/astrbot/long_term_memory.py:32` </location>
<code_context>
    def cfg(self, event: AstrMessageEvent):
        cfg = self.context.get_config(umo=event.unified_msg_origin)
        try:
            max_cnt = int(cfg["provider_ltm_settings"]["group_message_max_cnt"])
        except BaseException as e:
            logger.error(e)
            max_cnt = 300
        image_caption = (
            True
            if cfg["provider_settings"]["default_image_caption_provider_id"]
            and cfg["provider_ltm_settings"]["image_caption"]
            else False
        )
        image_caption_prompt = cfg["provider_settings"]["image_caption_prompt"]
        image_caption_provider_id = cfg["provider_settings"][
            "default_image_caption_provider_id"
        ]
        active_reply = cfg["provider_ltm_settings"]["active_reply"]
        enable_active_reply = active_reply.get("enable", False)
        ar_method = active_reply["method"]
        ar_possibility = active_reply["possibility_reply"]
        ar_prompt = active_reply.get("prompt", "")
        ar_whitelist = active_reply.get("whitelist", [])
        ret = {
            "max_cnt": max_cnt,
            "image_caption": image_caption,
            "image_caption_prompt": image_caption_prompt,
            "image_caption_provider_id": image_caption_provider_id,
            "enable_active_reply": enable_active_reply,
            "ar_method": ar_method,
            "ar_possibility": ar_possibility,
            "ar_prompt": ar_prompt,
            "ar_whitelist": ar_whitelist,
        }
        return ret

</code_context>

<issue_to_address>
**问题 (code-quality):** 我们发现了以下问题:

- 简化布尔 if 表达式 ([`boolean-if-exp-identity`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/boolean-if-exp-identity/))
- 内联立即返回的变量 ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/inline-immediately-returned-variable/))
</issue_to_address>

### 评论 3
<location> `packages/astrbot/long_term_memory.py:111` </location>
<code_context>
    async def handle_message(self, event: AstrMessageEvent):
        """仅支持群聊"""
        if (event.get_message_type() == MessageType.GROUP_MESSAGE) or True:
            datetime_str = datetime.datetime.now().strftime("%H:%M:%S")

            final_message = f"[{event.message_obj.sender.nickname}/{datetime_str}]: "

            cfg = self.cfg(event);

            for comp in event.get_messages():
                if isinstance(comp, Plain):
                    final_message += f" {comp.text}"
                elif isinstance(comp, Image):
                    if cfg["image_caption"]:
                        try:
                            caption = await self.get_image_caption(
                                comp.url if comp.url else comp.file,
                                cfg["image_caption_provider_id"],
                                cfg["image_caption_prompt"],
                            )
                            final_message += f" [Image: {caption}]"
                        except Exception as e:
                            logger.error(f"获取图片描述失败: {e}")
                    else:
                        final_message += " [Image]"
            logger.debug(f"ltm | {event.unified_msg_origin} | {final_message}")
            self.session_chats[event.unified_msg_origin].append(final_message)
            if len(self.session_chats[event.unified_msg_origin]) > cfg["max_cnt"]:
                self.session_chats[event.unified_msg_origin].pop(0)

</code_context>

<issue_to_address>
**问题 (code-quality):** 我们发现了以下问题:

- 添加守卫子句 ([`last-if-guard`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/last-if-guard/))
- 移除或传播冗余布尔表达式 ([`remove-redundant-boolean`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-boolean/))
</issue_to_address>

Sourcery 对开源免费 - 如果您喜欢我们的评论,请考虑分享它们 ✨
帮助我变得更有用!请对每条评论点击 👍 或 👎,我将使用这些反馈来改进你的评论。
Original comment in English

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `packages/astrbot/long_term_memory.py:113` </location>
<code_context>
     async def handle_message(self, event: AstrMessageEvent):
         """仅支持群聊"""
-        if event.get_message_type() == MessageType.GROUP_MESSAGE:
+        if (event.get_message_type() == MessageType.GROUP_MESSAGE) or True:
             datetime_str = datetime.datetime.now().strftime("%H:%M:%S")

</code_context>

<issue_to_address>
**issue (bug_risk):** The condition always evaluates to True, making the message handler unconditional.

The 'or True' clause causes this block to run for every message type. If this is for debugging, please mark it clearly or remove before merging. Otherwise, it may result in unintended processing.
</issue_to_address>

### Comment 2
<location> `packages/astrbot/long_term_memory.py:32` </location>
<code_context>
    def cfg(self, event: AstrMessageEvent):
        cfg = self.context.get_config(umo=event.unified_msg_origin)
        try:
            max_cnt = int(cfg["provider_ltm_settings"]["group_message_max_cnt"])
        except BaseException as e:
            logger.error(e)
            max_cnt = 300
        image_caption = (
            True
            if cfg["provider_settings"]["default_image_caption_provider_id"]
            and cfg["provider_ltm_settings"]["image_caption"]
            else False
        )
        image_caption_prompt = cfg["provider_settings"]["image_caption_prompt"]
        image_caption_provider_id = cfg["provider_settings"][
            "default_image_caption_provider_id"
        ]
        active_reply = cfg["provider_ltm_settings"]["active_reply"]
        enable_active_reply = active_reply.get("enable", False)
        ar_method = active_reply["method"]
        ar_possibility = active_reply["possibility_reply"]
        ar_prompt = active_reply.get("prompt", "")
        ar_whitelist = active_reply.get("whitelist", [])
        ret = {
            "max_cnt": max_cnt,
            "image_caption": image_caption,
            "image_caption_prompt": image_caption_prompt,
            "image_caption_provider_id": image_caption_provider_id,
            "enable_active_reply": enable_active_reply,
            "ar_method": ar_method,
            "ar_possibility": ar_possibility,
            "ar_prompt": ar_prompt,
            "ar_whitelist": ar_whitelist,
        }
        return ret

</code_context>

<issue_to_address>
**issue (code-quality):** We've found these issues:

- Simplify boolean if expression ([`boolean-if-exp-identity`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/boolean-if-exp-identity/))
- Inline variable that is immediately returned ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/inline-immediately-returned-variable/))
</issue_to_address>

### Comment 3
<location> `packages/astrbot/long_term_memory.py:111` </location>
<code_context>
    async def handle_message(self, event: AstrMessageEvent):
        """仅支持群聊"""
        if (event.get_message_type() == MessageType.GROUP_MESSAGE) or True:
            datetime_str = datetime.datetime.now().strftime("%H:%M:%S")

            final_message = f"[{event.message_obj.sender.nickname}/{datetime_str}]: "

            cfg = self.cfg(event)

            for comp in event.get_messages():
                if isinstance(comp, Plain):
                    final_message += f" {comp.text}"
                elif isinstance(comp, Image):
                    if cfg["image_caption"]:
                        try:
                            caption = await self.get_image_caption(
                                comp.url if comp.url else comp.file,
                                cfg["image_caption_provider_id"],
                                cfg["image_caption_prompt"],
                            )
                            final_message += f" [Image: {caption}]"
                        except Exception as e:
                            logger.error(f"获取图片描述失败: {e}")
                    else:
                        final_message += " [Image]"
            logger.debug(f"ltm | {event.unified_msg_origin} | {final_message}")
            self.session_chats[event.unified_msg_origin].append(final_message)
            if len(self.session_chats[event.unified_msg_origin]) > cfg["max_cnt"]:
                self.session_chats[event.unified_msg_origin].pop(0)

</code_context>

<issue_to_address>
**issue (code-quality):** We've found these issues:

- Add guard clause ([`last-if-guard`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/last-if-guard/))
- Removes or propagates redundant boolean expressions ([`remove-redundant-boolean`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-boolean/))
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

使能配置项目,合并8d4c176中的判断逻辑,实现在禁用开关或无提示词时自动禁用。
(Force push because of mistake commit)

AstrBotDevs#3112
@Dt8333 Dt8333 force-pushed the Fix-LTM-image_caption-active-incorrectly branch from d300b4f to fc96721 Compare October 20, 2025 12:32
@Dt8333
Copy link
Contributor Author

Dt8333 commented Oct 20, 2025

#3106 中代码未格式化导致格式检查不通过。
不确定是否应该commit格式化后的版本。
似乎不符合每commit解决一个问题。

@Dt8333
Copy link
Contributor Author

Dt8333 commented Oct 20, 2025

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗨 - 我已经审阅了你的更改,它们看起来很棒!

AI 代理提示
请解决此代码审查中的注释:

## 单独评论

### 评论 1
<location> `packages/astrbot/long_term_memory.py:32` </location>
<code_context>
    def cfg(self, event: AstrMessageEvent):
        cfg = self.context.get_config(umo=event.unified_msg_origin)
        try:
            max_cnt = int(cfg["provider_ltm_settings"]["group_message_max_cnt"])
        except BaseException as e:
            logger.error(e)
            max_cnt = 300
        image_caption = (
            True
            if cfg["provider_settings"]["default_image_caption_provider_id"]
            and cfg["provider_ltm_settings"]["image_caption"]
            else False
        )
        image_caption_prompt = cfg["provider_settings"]["image_caption_prompt"]
        image_caption_provider_id = cfg["provider_settings"][
            "default_image_caption_provider_id"
        ]
        active_reply = cfg["provider_ltm_settings"]["active_reply"]
        enable_active_reply = active_reply.get("enable", False)
        ar_method = active_reply["method"]
        ar_possibility = active_reply["possibility_reply"]
        ar_prompt = active_reply.get("prompt", "")
        ar_whitelist = active_reply.get("whitelist", [])
        ret = {
            "max_cnt": max_cnt,
            "image_caption": image_caption,
            "image_caption_prompt": image_caption_prompt,
            "image_caption_provider_id": image_caption_provider_id,
            "enable_active_reply": enable_active_reply,
            "ar_method": ar_method,
            "ar_possibility": ar_possibility,
            "ar_prompt": ar_prompt,
            "ar_whitelist": ar_whitelist,
        }
        return ret

</code_context>

<issue_to_address>
**issue (code-quality):** 我们发现了这些问题:

- 简化布尔 if 表达式 ([`boolean-if-exp-identity`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/boolean-if-exp-identity/))
- 内联立即返回的变量 ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/inline-immediately-returned-variable/))
</issue_to_address>

Sourcery 对开源免费 - 如果你喜欢我们的评论,请考虑分享它们 ✨
请帮助我变得更有用!请点击每个评论上的 👍 或 👎,我将利用这些反馈来改进你的评论。
Original comment in English

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `packages/astrbot/long_term_memory.py:32` </location>
<code_context>
    def cfg(self, event: AstrMessageEvent):
        cfg = self.context.get_config(umo=event.unified_msg_origin)
        try:
            max_cnt = int(cfg["provider_ltm_settings"]["group_message_max_cnt"])
        except BaseException as e:
            logger.error(e)
            max_cnt = 300
        image_caption = (
            True
            if cfg["provider_settings"]["default_image_caption_provider_id"]
            and cfg["provider_ltm_settings"]["image_caption"]
            else False
        )
        image_caption_prompt = cfg["provider_settings"]["image_caption_prompt"]
        image_caption_provider_id = cfg["provider_settings"][
            "default_image_caption_provider_id"
        ]
        active_reply = cfg["provider_ltm_settings"]["active_reply"]
        enable_active_reply = active_reply.get("enable", False)
        ar_method = active_reply["method"]
        ar_possibility = active_reply["possibility_reply"]
        ar_prompt = active_reply.get("prompt", "")
        ar_whitelist = active_reply.get("whitelist", [])
        ret = {
            "max_cnt": max_cnt,
            "image_caption": image_caption,
            "image_caption_prompt": image_caption_prompt,
            "image_caption_provider_id": image_caption_provider_id,
            "enable_active_reply": enable_active_reply,
            "ar_method": ar_method,
            "ar_possibility": ar_possibility,
            "ar_prompt": ar_prompt,
            "ar_whitelist": ar_whitelist,
        }
        return ret

</code_context>

<issue_to_address>
**issue (code-quality):** We've found these issues:

- Simplify boolean if expression ([`boolean-if-exp-identity`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/boolean-if-exp-identity/))
- Inline variable that is immediately returned ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/inline-immediately-returned-variable/))
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@LIghtJUNction
Copy link
Contributor

#3106 中代码未格式化导致格式检查不通过。 不确定是否应该commit格式化后的版本。 似乎不符合每commit解决一个问题。

项目加了pre-commit,提交前自动格式化,
请随意commit格式化后的版本
最好帮忙完善下类型标注

格式化 astrbot/dashboard/routes/update.py
a0f8f3a 完成了这项工作。
@Dt8333
Copy link
Contributor Author

Dt8333 commented Oct 20, 2025

a0f8f3a 中格式化了代码。撤销此提交中的格式化部分。

Copy link
Contributor

@LIghtJUNction LIghtJUNction left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr很简短,清晰

@Soulter
Copy link
Member

Soulter commented Oct 21, 2025

这个 bug 我已经在 8afefad 已经修复,抱歉之前没看到这个 PR。

@LIghtJUNction
Copy link
Contributor

这个 bug 我已经在 8afefad 已经修复,抱歉之前没看到这个 PR。

这个 bug 我已经在 8afefad 已经修复,抱歉之前没看到这个 PR。

确实,4个小时前修好的

@Dt8333
Copy link
Contributor Author

Dt8333 commented Oct 21, 2025


Soulter特有的埋头苦干。

@Dt8333 Dt8333 closed this Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 扩展功能/自动理解图片 关闭 但依然触发

3 participants