feat: 为 OpenAI provider 添加可配置的最大重试次数#7959
feat: 为 OpenAI provider 添加可配置的最大重试次数#7959Blueteemo wants to merge 1 commit intoAstrBotDevs:masterfrom
Conversation
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- Consider validating
max_retriesfromprovider_config(e.g., ensure it is an integer within a sane non-negative range) before using it, to avoid misconfiguration causing unexpected behavior or very long retry loops. - Since
max_retriesis now user-configurable, you may want to explicitly handle edge cases like0(no retries) and negative values, rather than relying on implicit behavior.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider validating `max_retries` from `provider_config` (e.g., ensure it is an integer within a sane non-negative range) before using it, to avoid misconfiguration causing unexpected behavior or very long retry loops.
- Since `max_retries` is now user-configurable, you may want to explicitly handle edge cases like `0` (no retries) and negative values, rather than relying on implicit behavior.
## Individual Comments
### Comment 1
<location path="astrbot/core/provider/sources/openai_source.py" line_range="1192" />
<code_context>
llm_response = None
- max_retries = 10
+ max_retries = self.provider_config.get("max_retries", 10)
available_api_keys = self.api_keys.copy()
chosen_key = random.choice(available_api_keys)
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Validate and bound `max_retries` from config to avoid pathological values.
Because this is now user-configurable, invalid values (0, negative, non-numeric, or very large) could lead to no retries or excessively long retry loops. Consider coercing to `int` and clamping to a safe range (e.g., `max(1, min(configured_value, SOME_UPPER_BOUND))`), or at least validating that it’s numeric and > 0 before use.
Suggested implementation:
```python
llm_response = None
configured_max_retries = self.provider_config.get("max_retries", 10)
try:
max_retries = int(configured_max_retries)
except (TypeError, ValueError):
max_retries = 10
else:
# Clamp to a safe range to avoid pathological values
max_retries = max(1, min(max_retries, 10))
available_api_keys = self.api_keys.copy()
chosen_key = random.choice(available_api_keys)
image_fallback_used = False
```
```python
if func_tool and not func_tool.empty():
payloads["tool_choice"] = tool_choice
configured_max_retries = self.provider_config.get("max_retries", 10)
try:
max_retries = int(configured_max_retries)
except (TypeError, ValueError):
max_retries = 10
else:
# Clamp to a safe range to avoid pathological values
max_retries = max(1, min(max_retries, 10))
available_api_keys = self.api_keys.copy()
chosen_key = random.choice(available_api_keys)
image_fallback_used = False
```
1. If you prefer a different upper bound than `10`, adjust the `min(max_retries, 10)` expression in both places.
2. If this pattern is used in other providers, consider refactoring the coercion/clamping logic into a shared helper (e.g., a method on the base provider) to keep behavior consistent across providers.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request introduces a configurable max_retries setting for OpenAI-compatible providers, updating the default configuration, the source logic, and the dashboard localization files. Feedback includes a bug fix to prevent crashes when max_retries is set to zero or less, a suggestion to refactor the retrieval logic into a helper function to avoid duplication, and a reminder to update the metadata definitions and other provider templates to ensure the new setting is correctly exposed and validated in the dashboard.
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- Consider logging or surfacing a warning when
max_retriesis invalid and the default of 10 is used, so misconfigurations are easier to diagnose in production. - The hardcoded upper bound of 50 in
_get_max_retriesmay be surprising to users; it might be clearer to either document this constraint via a named constant or configuration hint, or avoid clamping unless there's a strong reason.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider logging or surfacing a warning when `max_retries` is invalid and the default of 10 is used, so misconfigurations are easier to diagnose in production.
- The hardcoded upper bound of 50 in `_get_max_retries` may be surprising to users; it might be clearer to either document this constraint via a named constant or configuration hint, or avoid clamping unless there's a strong reason.
## Individual Comments
### Comment 1
<location path="astrbot/core/config/default.py" line_range="2514-2518" />
<code_context>
"type": "int",
"hint": "超时时间,单位为秒。",
},
+ "max_retries": {
+ "description": "最大重试次数",
+ "type": "int",
+ "hint": "API 调用失败时的最大重试次数,默认为 10。",
+ },
"mimo-stt-system-prompt": {
</code_context>
<issue_to_address>
**suggestion:** The hint for `max_retries` doesn't reflect the effective clamping range used in code.
The code clamps `max_retries` to `[1, 50]`, but the hint only states the default (10). Please update the hint to document the valid range so users aren’t surprised when large or non-positive values get clamped.
```suggestion
"max_retries": {
"description": "最大重试次数",
"type": "int",
"hint": "API 调用失败时的最大重试次数,范围为 1~50,默认为 10。",
},
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The
_get_max_retriesdocstring mentions only ensuring a positive integer but the implementation clamps the value to 1–50; consider updating the docstring (or extracting a named constant for the upper bound) so the behavior and limits are clearly aligned. - The default value
10formax_retriesis now duplicated in_get_max_retriesand in the OpenAI provider default config; consider centralizing this default (e.g., a module-level constant) to avoid drift if it changes in the future.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `_get_max_retries` docstring mentions only ensuring a positive integer but the implementation clamps the value to 1–50; consider updating the docstring (or extracting a named constant for the upper bound) so the behavior and limits are clearly aligned.
- The default value `10` for `max_retries` is now duplicated in `_get_max_retries` and in the OpenAI provider default config; consider centralizing this default (e.g., a module-level constant) to avoid drift if it changes in the future.
## Individual Comments
### Comment 1
<location path="astrbot/core/provider/sources/openai_source.py" line_range="498-505" />
<code_context>
self.reasoning_key = "reasoning_content"
+ def _get_max_retries(self) -> int:
+ """获取并验证最大重试次数,确保为正整数。"""
+ raw = self.provider_config.get("max_retries", 10)
+ try:
+ value = int(raw)
+ except (TypeError, ValueError):
+ return 10
+ return max(1, min(value, 50))
+
def _ollama_disable_thinking_enabled(self) -> bool:
</code_context>
<issue_to_address>
**suggestion:** Consider surfacing or logging when `max_retries` is out of range or invalid instead of silently clamping.
Invalid or out-of-range values are silently coerced into `[1, 50]` (or `10` if they can’t be cast). That makes misconfigurations (e.g., 0, negative, or 100) hard to detect and can lead to surprising behavior. Emitting a log or similar signal when clamping or falling back would make these issues easier to diagnose.
```suggestion
def _get_max_retries(self) -> int:
"""获取并验证最大重试次数,确保为正整数。"""
import logging
logger = getattr(self, "logger", None) or logging.getLogger(__name__)
raw = self.provider_config.get("max_retries", 10)
try:
value = int(raw)
except (TypeError, ValueError):
logger.warning(
"Invalid 'max_retries' value %r in provider_config; falling back to default 10.",
raw,
)
return 10
if value < 1 or value > 50:
logger.warning(
"'max_retries' value %d in provider_config is out of range [1, 50]; "
"clamping to the nearest value within range.",
value,
)
return max(1, min(value, 50))
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
87acffd to
86f2d36
Compare
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The allowed range (1–50) for
max_retriesis now duplicated in_MAX_RETRIES_UPPER_BOUNDand the config metadata; consider centralizing this constraint or at least adding a shared constant to avoid divergence in future changes. - If
provider_configis immutable at runtime, you could computeself.max_retriesonce in__init__instead of calling_get_max_retries()for everytext_chat/text_chat_streamcall to simplify the flow and avoid repeated parsing.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The allowed range (1–50) for `max_retries` is now duplicated in `_MAX_RETRIES_UPPER_BOUND` and the config metadata; consider centralizing this constraint or at least adding a shared constant to avoid divergence in future changes.
- If `provider_config` is immutable at runtime, you could compute `self.max_retries` once in `__init__` instead of calling `_get_max_retries()` for every `text_chat`/`text_chat_stream` call to simplify the flow and avoid repeated parsing.
## Individual Comments
### Comment 1
<location path="astrbot/core/provider/sources/openai_source.py" line_range="501-510" />
<code_context>
+ _MAX_RETRIES_DEFAULT = 10
+ _MAX_RETRIES_UPPER_BOUND = 50
+
+ def _get_max_retries(self) -> int:
+ """获取并验证最大重试次数,确保为 1 到 _MAX_RETRIES_UPPER_BOUND 之间的整数。"""
+ raw = self.provider_config.get("max_retries", self._MAX_RETRIES_DEFAULT)
+ try:
+ value = int(raw)
+ except (TypeError, ValueError):
+ logger.warning(
+ "max_retries 配置无效 (%s),使用默认值 %d。",
+ raw,
+ self._MAX_RETRIES_DEFAULT,
+ )
+ return self._MAX_RETRIES_DEFAULT
+ clamped = max(1, min(value, self._MAX_RETRIES_UPPER_BOUND))
+ if clamped != value:
+ logger.warning(
+ "max_retries 配置值 %d 超出范围,已调整为 %d。",
+ value,
+ clamped,
+ )
+ return clamped
+
def _ollama_disable_thinking_enabled(self) -> bool:
</code_context>
<issue_to_address>
**issue (performance):** Avoid repeated warning logs on every call to `_get_max_retries` for a bad config value.
This logic will log a warning on every `text_chat` / `text_chat_stream` call when `max_retries` is invalid, which can flood logs in high-traffic usage and hide other issues. It would be better to validate and normalize this config once (e.g., at initialization), cache the result, and log at most once per process/load instead of per request.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- 在 openai_source.py 中添加 _get_max_retries() 方法,支持 1-50 范围验证 - 在 __init__ 中计算一次 max_retries,避免重复调用 - 在 default.py 的 OpenAI provider 模板中添加 max_retries: 10 - 在 config-metadata.json 中添加中英俄三语翻译(含范围提示) - 无效配置时记录 warning 日志
86f2d36 to
7695435
Compare
问题描述
OpenAI provider 的
max_retries硬编码为 10,导致超时时最长等待 20 分钟。修复方案
添加可配置的
max_retries选项,允许用户控制最大重试次数(范围 1-50)。默认值保持 10。修改内容
openai_source.py:从 provider 配置读取max_retries,不再使用硬编码值default.py:在 OpenAI provider 模板中添加max_retries: 10config-metadata.json:添加中英俄三语翻译关联 Issue
Fixes #7956
Summary by Sourcery
Make the OpenAI provider’s maximum retry count configurable instead of hard-coded.
New Features:
Enhancements:
Documentation: