What happened / 发生了什么
在 AstrBot v4.26.6 中,引用一条包含动画 GIF 的消息并唤醒多模态模型后,GIF 会以 data:image/gif;base64,... 的形式进入并持久化到会话历史。
当实际模型只支持 JPEG/PNG/WebP、不支持 GIF(例如部分 Gemini OpenAI-compatible 网关)时,之后即使用户只发送纯文本,每次请求也会继续携带历史 GIF,并持续返回 convert_request_failed。
现场已经开启 provider_settings.sanitize_context_by_modalities=true,但清理器只判断模型是否支持 image 模态,不检查图片的具体 MIME。模型配置包含 image 后,GIF 会被原样保留。
相关代码路径:
astrbot/core/astr_main_agent.py:引用链中的 Image 被加入 req.image_urls。
astrbot/core/provider/modalities.py:只按 text/image/audio/tool_use 清理,不检查 image/gif。
astrbot/core/utils/media_utils.py:当前实现和测试明确保留动画 GIF。
astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py:成功轮次会将包含 GIF 的 all_messages 保存进会话历史。
astrbot/core/provider/sources/openai_source.py:图片降级重试只匹配非 VLM、审核失败、invalid_attachment 等,不匹配 convert_request_failed / mime type is not supported。
这似乎与 v4.26.2 的“保留图片格式”改动有关。v4.26.0 的 ensure_jpeg() 会把非 JPEG(包括 GIF)转为静态 JPEG;v4.26.2+ 则明确保留动画 GIF。
期望行为:
- 在发送给 Provider 前,根据模型支持的图片 MIME 白名单处理图片;不支持 GIF 时可转为首帧 PNG/JPEG或替换为
[Image]。
- 对已经保存到历史中的
data:image/gif 同样进行清理,避免会话持续损坏。
- 遇到
mime type is not supported / convert_request_failed 时,可删除不支持的图片后自动重试一次。
Reproduce / 如何复现?
- 使用 AstrBot v4.26.6,配置一个声明支持
image 的 Gemini/OpenAI-compatible 模型,但该接口实际不接受 image/gif。
- 开启
provider_settings.sanitize_context_by_modalities。
- 在 QQ 群中发送一个动画 GIF。QQ 消息中的文件名可以是
.jpg,真实文件内容为 GIF。
- 引用这条 GIF 消息并 @/唤醒机器人。
- 再发送一条普通纯文本消息。
- 后续请求会携带历史中的 GIF,并持续报错。
用于复现的图片指纹:
GIF89a
240x240
126979 bytes
Base64 prefix: R0lGODlh8ADwAPcAAPxzxu+vcPWy...
AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
- AstrBot: v4.26.6
- Deployment: Linux
- Provider: OpenAI-compatible Gemini (
gemini-3.5-flash)
- Platform: QQ Official;原始 GIF 同时可由 aiocqhttp/QQ 消息产生
sanitize_context_by_modalities: true
- Model modalities:
text, image, audio, tool_use
OS
Linux
Logs / 报错日志
引用消息被识别为包含图片,并直接交给支持图片的主模型:
[Core] [DBUG] Skipping quote image captioning because the main provider supports image input.
GIF 被写入历史后,下一次纯文本请求报错:
[Core] [WARN] Chat Model gemini/gemini-3.5-flash request error:
Error code: 500 - {
"error": {
"message": "mime type is not supported by Gemini: 'image/gif', url: 'base64:data:image/gif;base64,R0lGODlh8ADwAPcAAPxzxu+vcPWy...', supported types are: [image/webp image/heif video/mp4 video/avi image/heic video/mpg video/mpegps video/flv audio/mp3 image/png image/jpg text/plain video/mpeg video/wmv application/pdf audio/mpeg video/mov audio/wav image/jpeg]",
"type": "new_api_error",
"code": "convert_request_failed"
}
}
同一个 Base64 前缀会在后续请求中重复出现,直到会话历史被裁剪或清理。
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct
What happened / 发生了什么
在 AstrBot v4.26.6 中,引用一条包含动画 GIF 的消息并唤醒多模态模型后,GIF 会以
data:image/gif;base64,...的形式进入并持久化到会话历史。当实际模型只支持 JPEG/PNG/WebP、不支持 GIF(例如部分 Gemini OpenAI-compatible 网关)时,之后即使用户只发送纯文本,每次请求也会继续携带历史 GIF,并持续返回
convert_request_failed。现场已经开启
provider_settings.sanitize_context_by_modalities=true,但清理器只判断模型是否支持image模态,不检查图片的具体 MIME。模型配置包含image后,GIF 会被原样保留。相关代码路径:
astrbot/core/astr_main_agent.py:引用链中的Image被加入req.image_urls。astrbot/core/provider/modalities.py:只按text/image/audio/tool_use清理,不检查image/gif。astrbot/core/utils/media_utils.py:当前实现和测试明确保留动画 GIF。astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py:成功轮次会将包含 GIF 的all_messages保存进会话历史。astrbot/core/provider/sources/openai_source.py:图片降级重试只匹配非 VLM、审核失败、invalid_attachment等,不匹配convert_request_failed/mime type is not supported。这似乎与 v4.26.2 的“保留图片格式”改动有关。v4.26.0 的
ensure_jpeg()会把非 JPEG(包括 GIF)转为静态 JPEG;v4.26.2+ 则明确保留动画 GIF。期望行为:
[Image]。data:image/gif同样进行清理,避免会话持续损坏。mime type is not supported/convert_request_failed时,可删除不支持的图片后自动重试一次。Reproduce / 如何复现?
image的 Gemini/OpenAI-compatible 模型,但该接口实际不接受image/gif。provider_settings.sanitize_context_by_modalities。.jpg,真实文件内容为 GIF。用于复现的图片指纹:
AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
gemini-3.5-flash)sanitize_context_by_modalities:truetext,image,audio,tool_useOS
Linux
Logs / 报错日志
引用消息被识别为包含图片,并直接交给支持图片的主模型:
GIF 被写入历史后,下一次纯文本请求报错:
同一个 Base64 前缀会在后续请求中重复出现,直到会话历史被裁剪或清理。
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct