diff --git a/.gitignore b/.gitignore
index 4c26c7d6..6aca3a2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,4 +15,5 @@ tiktoken_cache
.aider*
.history/
.kiro/
-.venv
\ No newline at end of file
+.venv
+main
\ No newline at end of file
diff --git a/controller/relay.go b/controller/relay.go
index d3290dcf..8373d974 100644
--- a/controller/relay.go
+++ b/controller/relay.go
@@ -128,7 +128,7 @@ func Relay(c *gin.Context) {
if openaiErr == nil {
// 检查是否实际写入了响应内容
responseWritten := c.GetBool("response_written")
- if !responseWritten && model_setting.GetGlobalSettings().AutoRetryEnabled {
+ if !responseWritten && model_setting.ShouldTreatEmptyResponseAsError() {
// 创建一个表示空回复的错误,以便触发重试
openaiErr = service.OpenAIErrorWrapperLocal(
fmt.Errorf("empty response from upstream"),
@@ -392,8 +392,8 @@ func shouldRetryWithAutoConfig(c *gin.Context, openaiErr *dto.OpenAIErrorWithSta
return false
}
- // 对于空回复的情况,也应该重试
- if openaiErr.Error.Message == "" || strings.Contains(strings.ToLower(openaiErr.Error.Message), "empty") {
+ // 对于空回复的情况,根据配置决定是否重试
+ if model_setting.ShouldTreatEmptyResponseAsError() && (openaiErr.Error.Message == "" || strings.Contains(strings.ToLower(openaiErr.Error.Message), "empty")) {
return true
}
diff --git a/setting/model_setting/global.go b/setting/model_setting/global.go
index e31fa1e3..12ac56c3 100644
--- a/setting/model_setting/global.go
+++ b/setting/model_setting/global.go
@@ -34,6 +34,7 @@ type GlobalSettings struct {
AutoRetryCount int `json:"auto_retry_count"`
AutoRetryForceChannelSwitch bool `json:"auto_retry_force_channel_switch"`
AutoRetryStatusCodes string `json:"auto_retry_status_codes"`
+ EmptyResponseRetryEnabled bool `json:"empty_response_retry_enabled"`
}
// 默认配置
@@ -49,6 +50,7 @@ var defaultOpenaiSettings = GlobalSettings{
AutoRetryCount: 3,
AutoRetryForceChannelSwitch: false,
AutoRetryStatusCodes: "5xx,4xx",
+ EmptyResponseRetryEnabled: false,
}
// 全局实例
@@ -84,6 +86,11 @@ func ShouldForceChannelSwitch() bool {
return globalSettings.AutoRetryEnabled && globalSettings.AutoRetryForceChannelSwitch
}
+// ShouldTreatEmptyResponseAsError 是否将空回复视为错误并触发重试
+func ShouldTreatEmptyResponseAsError() bool {
+ return globalSettings.AutoRetryEnabled && globalSettings.EmptyResponseRetryEnabled
+}
+
// ShouldRetryForStatusCode 检查状态码是否应该重试
func ShouldRetryForStatusCode(statusCode int) bool {
if !globalSettings.AutoRetryEnabled {
diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json
index 07a7d1a1..fc04b4cd 100644
--- a/web/src/i18n/locales/en.json
+++ b/web/src/i18n/locales/en.json
@@ -1525,5 +1525,7 @@
"请先选择要设置标签的渠道!": "Please select the channel to set the tag first!",
"标签不能为空!": "Tag cannot be empty!",
"已为 {{count}} 个渠道设置标签!": "{{count}} channels have been set with tags!",
- "已选择 {{count}} 个渠道": "{{count}} channels selected"
+ "已选择 {{count}} 个渠道": "{{count}} channels selected",
+ "空回复视为错误": "Treat empty responses as errors",
+ "空回复将触发自动重试与渠道切换": "Empty responses trigger automatic retry and channel switching"
}
\ No newline at end of file
diff --git a/web/src/i18n/locales/zh.json b/web/src/i18n/locales/zh.json
index 65df58c1..42f571fb 100644
--- a/web/src/i18n/locales/zh.json
+++ b/web/src/i18n/locales/zh.json
@@ -86,5 +86,7 @@
"已完成": "已完成",
"失败": "失败",
"已取消": "已取消",
- "刷新": "刷新"
+ "刷新": "刷新",
+ "空回复视为错误": "空回复视为错误",
+ "空回复将触发自动重试与渠道切换": "空回复将触发自动重试与渠道切换"
}
\ No newline at end of file
diff --git a/web/src/pages/Setting/Model/SettingGlobalModel.js b/web/src/pages/Setting/Model/SettingGlobalModel.js
index a43f7b8a..b92ffe65 100644
--- a/web/src/pages/Setting/Model/SettingGlobalModel.js
+++ b/web/src/pages/Setting/Model/SettingGlobalModel.js
@@ -44,6 +44,7 @@ export default function SettingGlobalModel(props) {
'global.auto_retry_count': 3,
'global.auto_retry_force_channel_switch': false,
'global.auto_retry_status_codes': '5xx,4xx',
+ 'global.empty_response_retry_enabled': false,
'general_setting.ping_interval_enabled': false,
'general_setting.ping_interval_seconds': 60,
});
@@ -279,6 +280,22 @@ export default function SettingGlobalModel(props) {
/>
+