fix: retry gemini empty parts response#6735
Hidden character warning
fix: retry gemini empty parts response#6735Clhikari wants to merge 3 commits intoAstrBotDevs:masterfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 此拉取请求旨在增强系统与 Gemini API 交互的稳定性。它通过引入一个智能重试机制,解决了 Gemini API 在特定情况下返回空内容但指示完成的边缘问题。这一改进确保了即使在 API 出现瞬时异常响应时,系统也能继续正常运行,从而提升了用户体验和应用的可靠性,而不会改变持续失败时的错误处理行为。 Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
| empty_parts_retry_count = 0 | ||
| max_empty_parts_retries = 3 |
There was a problem hiding this comment.
为了提高代码的可读性和可维护性,建议将最大重试次数 max_empty_parts_retries 和重试延迟(在第 579 行硬编码为 0.2)定义为类级别的常量。
例如,在 ProviderGoogleGenAI 类的顶部定义:
class ProviderGoogleGenAI(Provider):
_MAX_EMPTY_PARTS_RETRIES = 3
_EMPTY_PARTS_RETRY_DELAY_S = 0.2
# ...然后在 _query 方法中通过 self._MAX_EMPTY_PARTS_RETRIES 和 self._EMPTY_PARTS_RETRY_DELAY_S 来引用它们。
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The retry/backoff behavior for empty
candidate.content.partsis fully hardcoded (max 3 retries, 0.2s sleep); consider making retry count and delay configurable via the provider config so operators can tune reliability vs latency for different deployments. - In the STOP+empty-parts retry branch, the warning log currently dumps the entire
candidateobject, which may be large or contain sensitive data; logging theresponse_idand key fields instead would keep logs more compact and safer while still being debuggable.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The retry/backoff behavior for empty `candidate.content.parts` is fully hardcoded (max 3 retries, 0.2s sleep); consider making retry count and delay configurable via the provider config so operators can tune reliability vs latency for different deployments.
- In the STOP+empty-parts retry branch, the warning log currently dumps the entire `candidate` object, which may be large or contain sensitive data; logging the `response_id` and key fields instead would keep logs more compact and safer while still being debuggable.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
修复了 Gemini 提供商的一种异常返回场景:API 返回
finish_reason=STOP,但candidate.content.parts为空。报错日志
在这个改动之前,Gemini 的非流式路径会把这种响应直接当成致命错误处理,导致当前 agent step 提前中断,在依赖工具调用的流程中会直接打断后续执行。这个改动只针对这类明确的上游异常响应增加有限重试,让临时性的空响应可以恢复,同时不改变持续失败时的现有报错行为。
Modifications / 改动点
修改了
astrbot/core/provider/sources/gemini_source.py,在 Gemini 非流式_query()中处理finish_reason=STOP但candidate.content.parts为空的情况。增加了带短暂退避的有限重试逻辑。
当重试耗尽后,仍然沿用现有失败逻辑,不扩大行为变更范围。
新增了回归测试
tests/test_gemini_source.py,验证首次空响应后可以在后续重试中恢复成功。新增 tool-call 场景测试,验证 provider 在空响应后重试,仍能正确恢复并产出函数调用信息。
This is NOT a breaking change. / 这不是一个破坏性变更。
本地已执行以下验证步骤:
测试结果:
新增测试覆盖了以下场景:
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
Handle Gemini non-streaming responses that stop with empty content parts by retrying instead of failing immediately.
Bug Fixes:
Enhancements:
Tests: