fix(core): 将空 list modalities 视为未配置,修复图片无法传递到模型的问题#8451
Open
Sisyphbaous-DT-Project wants to merge 3 commits into
Open
fix(core): 将空 list modalities 视为未配置,修复图片无法传递到模型的问题#8451Sisyphbaous-DT-Project wants to merge 3 commits into
Sisyphbaous-DT-Project wants to merge 3 commits into
Conversation
migra_helper 将未配置的 modalities 迁移为空 list [],而新增的 _provider_supports_modality()、_assemble_request_context_for_provider()、 _should_fix_modalities_for_provider()、_func_tool_for_provider() 四个函数 对 [] 和 None 的处理不一致,导致所有未在 WebUI 手动配置 modalities 的 provider 无法传递图片、引用图片被跳过、工具被错误清除。 修改策略:将 [] 与 None 统一视为未配置状态,保持向后兼容。 仅在 modalities 为非空 list 时才启用过滤和修复逻辑。 - _provider_supports_modality: [] 返回 True,默认支持 - _assemble_request_context_for_provider: [] 不过滤图片 - _should_fix_modalities_for_provider: [] 不触发历史上下文修复 - _func_tool_for_provider: [] 不清除工具 复现脚本已确认 Bug 不再复现,82 个相关单元测试全部通过。
上一笔 commit 遗漏了 tool_loop_agent_runner.py 第 917 行对 cached images 的 modalities 检查,当 modalities=[] 时,tool call 返回的图片不会被追加到消息中,导致模型看不到 tool 结果中的图片。 修复方式与主修复一致:not modalities or image in modalities 复现脚本和 82 个单元测试全部通过。
Contributor
There was a problem hiding this comment.
Code Review
This pull request updates the handling of provider modalities to treat an empty list or None as unconfigured, defaulting to supporting all modalities for backward compatibility. However, in astrbot/core/astr_main_agent.py, the _provider_supports_modality function treats None and [] inconsistently, where None returns False and [] returns True. It is recommended to update this function to return True for both cases to ensure consistent behavior and prevent unnecessary fallback switches.
Contributor
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The logic for treating an empty modalities list as "unconfigured" is duplicated in several places; consider extracting a small helper (e.g.,
is_unconfigured_modalities(modalities)) to centralize this backward-compatibility rule and avoid drift in future changes. - In
_provider_supports_modalityyou checkmodalities == []while other call sites usenot modalities; aligning on one approach (and clearly documenting it) would make the semantics around empty lists vs. other falsy values easier to reason about.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The logic for treating an empty modalities list as "unconfigured" is duplicated in several places; consider extracting a small helper (e.g., `is_unconfigured_modalities(modalities)`) to centralize this backward-compatibility rule and avoid drift in future changes.
- In `_provider_supports_modality` you check `modalities == []` while other call sites use `not modalities`; aligning on one approach (and clearly documenting it) would make the semantics around empty lists vs. other falsy values easier to reason about.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
修复 modalities=[] 导致 cached images 分支变为可达后,暴露 了 test_tool_result_includes_all_calltoolresult_content 中 fake_save_image mock 不完整的问题:返回的 SimpleNamespace 缺少 mime_type 属性,而实际 tool_image_cache.save_image() 始终包含该字段。
Soulter
approved these changes
May 31, 2026
4 tasks
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题描述
从 v4.24.5 升级到 v4.25.2 后,所有未在 WebUI 中手动配置模型能力(modalities) 的 provider 出现以下问题:
event.request_llm(image_urls=...)主动调用 LLM 时,传入的图片被静默丢弃而 v4.24.5 中一切正常。
根本原因分析
问题的根源是
modalities字段的语义不一致,由两个因素叠加导致:因素一:配置迁移将未配置的
modalities写为[]migra_helper.py在迁移 provider 配置时,对未设置modalities的 provider 统一写入空列表:升级前
modalities字段不存在时为None,升级后被改写为[]。因素二:多处代码对
[]与None的处理不一致v4.25.2 新增的
_provider_supports_modality()以及原有的_assemble_request_context_for_provider()等函数,对[]和None存在两种截然不同的分支:modalities值_provider_supports_modality("image")_assemble_request_context_for_providerNoneFalseisinstance(None, list)→False→ 保留图片[]Falseisinstance([], list)→True→"image" in []→False→ 清空图片在 v4.24.5 中,
modalities通常为None(字段未定义),图片能正常传递。升级后变为[],上述函数进入「明确配置了不支持图片」的分支,导致image_urls被静默清空、工具被错误清除。完整因果链:
修复方案
将空列表
[]视为「未配置」,与None保持一致行为。只有当modalities为非空 list 时,才启用过滤/修复逻辑。涉及以下 5 处修改(共 2 个文件):
astrbot/core/astr_main_agent.py_provider_supports_modality(): 对空列表返回True(默认支持),而非Falseastrbot/core/agent/runners/tool_loop_agent_runner.py_assemble_request_context_for_provider():not isinstance(modalities, list)→not modalities,空列表也走「保留图片」分支_should_fix_modalities_for_provider(): 增加and modalities条件,空列表不触发历史上下文修复_func_tool_for_provider(): 增加and modalities条件,空列表不清除工具tool loop 中 cached images 处理:
"image" in modalities→not modalities or "image" in modalities验证步骤
1. 复现脚本验证
编写了独立的复现脚本
reproduce_issue.py,模拟从ProviderRequest到最终上下文的完整链路修复前
modalities=[]的image_urls为[](已清空),修复后正确保留。2. 单元测试
所有现有测试通过,其中包括
_provider_supports_modality相关的边界条件测试。3. 各场景行为对比
modalities[][][][]["text"]["text"]["text","image"]["text","image"]Screenshots or Test Results / 运行截图或测试结果
修复前(当前版本)


修复后
ProviderRequest到最终上下文的完整链路。修复前modalities=[]时image_urls被清空为[],修复后正确保留所有传入的图片路径,Bug 不再复现。ruff check和ruff format --check全部通过,无格式或 lint 问题。pytest tests/unit/test_astr_main_agent.py82 项全部通过,覆盖了_provider_supports_modality的边界条件测试。Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 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.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by Sourcery
Treat empty provider modality lists as unconfigured to restore backward-compatible multimodal behavior and image handling.
Bug Fixes:
Enhancements: