From 5c8f8b49018094a34256d632c46568e60e1d372c Mon Sep 17 00:00:00 2001 From: CaIon <1808837298@qq.com> Date: Thu, 1 Feb 2024 18:52:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E6=97=B6=E8=87=AA=E5=8A=A8=E5=90=AF=E7=94=A8=E9=80=9A=E9=81=93?= =?UTF-8?q?=E5=8A=9F=E8=83=BD,=20close=20#27?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/constants.go | 1 + controller/channel-test.go | 29 +++++++++++++++++++------- controller/relay-utils.go | 13 ++++++++++++ model/option.go | 3 +++ web/src/components/ChannelsTable.js | 4 ++-- web/src/components/OperationSetting.js | 7 +++++++ 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/common/constants.go b/common/constants.go index 06986e5..f5a1e27 100644 --- a/common/constants.go +++ b/common/constants.go @@ -87,6 +87,7 @@ var QuotaForInviter = 0 var QuotaForInvitee = 0 var ChannelDisableThreshold = 5.0 var AutomaticDisableChannelEnabled = false +var AutomaticEnableChannelEnabled = false var QuotaRemindThreshold = 1000 var PreConsumedQuota = 500 diff --git a/controller/channel-test.go b/controller/channel-test.go index 1409e41..20288ad 100644 --- a/controller/channel-test.go +++ b/controller/channel-test.go @@ -78,6 +78,9 @@ func testChannel(channel *model.Channel, request ChatRequest) (err error, openai return err, nil } if response.Usage.CompletionTokens == 0 { + if response.Error.Message == "" { + response.Error.Message = "补全 tokens 非预期返回 0" + } return errors.New(fmt.Sprintf("type %s, code %v, message %s", response.Error.Type, response.Error.Code, response.Error.Message)), &response.Error } return nil, nil @@ -146,12 +149,23 @@ var testAllChannelsRunning bool = false // disable & notify func disableChannel(channelId int, channelName string, reason string) { - if common.RootUserEmail == "" { - common.RootUserEmail = model.GetRootUserEmail() - } model.UpdateChannelStatusById(channelId, common.ChannelStatusAutoDisabled) subject := fmt.Sprintf("通道「%s」(#%d)已被禁用", channelName, channelId) content := fmt.Sprintf("通道「%s」(#%d)已被禁用,原因:%s", channelName, channelId, reason) + notifyRootUser(subject, content) +} + +func enableChannel(channelId int, channelName string) { + model.UpdateChannelStatusById(channelId, common.ChannelStatusEnabled) + subject := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId) + content := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId) + notifyRootUser(subject, content) +} + +func notifyRootUser(subject string, content string) { + if common.RootUserEmail == "" { + common.RootUserEmail = model.GetRootUserEmail() + } err := common.SendEmail(subject, common.RootUserEmail, content) if err != nil { common.SysError(fmt.Sprintf("failed to send email: %s", err.Error())) @@ -180,9 +194,7 @@ func testAllChannels(notify bool) error { } go func() { for _, channel := range channels { - if channel.Status != common.ChannelStatusEnabled { - continue - } + isChannelEnabled := channel.Status == common.ChannelStatusEnabled tik := time.Now() err, openaiErr := testChannel(channel, *testRequest) tok := time.Now() @@ -201,9 +213,12 @@ func testAllChannels(notify bool) error { if channel.AutoBan != nil && *channel.AutoBan == 0 { ban = false } - if shouldDisableChannel(openaiErr, -1) && ban { + if isChannelEnabled && shouldDisableChannel(openaiErr, -1) && ban { disableChannel(channel.Id, channel.Name, err.Error()) } + if !isChannelEnabled && shouldEnableChannel(err, openaiErr) { + enableChannel(channel.Id, channel.Name) + } channel.UpdateResponseTime(milliseconds) time.Sleep(common.RequestInterval) } diff --git a/controller/relay-utils.go b/controller/relay-utils.go index ceecf40..2efc1de 100644 --- a/controller/relay-utils.go +++ b/controller/relay-utils.go @@ -258,6 +258,19 @@ func shouldDisableChannel(err *OpenAIError, statusCode int) bool { return false } +func shouldEnableChannel(err error, openAIErr *OpenAIError) bool { + if !common.AutomaticEnableChannelEnabled { + return false + } + if err != nil { + return false + } + if openAIErr != nil { + return false + } + return true +} + func setEventStreamHeaders(c *gin.Context) { c.Writer.Header().Set("Content-Type", "text/event-stream") c.Writer.Header().Set("Cache-Control", "no-cache") diff --git a/model/option.go b/model/option.go index 94b5bee..a651b85 100644 --- a/model/option.go +++ b/model/option.go @@ -34,6 +34,7 @@ func InitOptionMap() { common.OptionMap["TurnstileCheckEnabled"] = strconv.FormatBool(common.TurnstileCheckEnabled) common.OptionMap["RegisterEnabled"] = strconv.FormatBool(common.RegisterEnabled) common.OptionMap["AutomaticDisableChannelEnabled"] = strconv.FormatBool(common.AutomaticDisableChannelEnabled) + common.OptionMap["AutomaticEnableChannelEnabled"] = strconv.FormatBool(common.AutomaticEnableChannelEnabled) common.OptionMap["LogConsumeEnabled"] = strconv.FormatBool(common.LogConsumeEnabled) common.OptionMap["DisplayInCurrencyEnabled"] = strconv.FormatBool(common.DisplayInCurrencyEnabled) common.OptionMap["DisplayTokenStatEnabled"] = strconv.FormatBool(common.DisplayTokenStatEnabled) @@ -158,6 +159,8 @@ func updateOptionMap(key string, value string) (err error) { common.EmailDomainRestrictionEnabled = boolValue case "AutomaticDisableChannelEnabled": common.AutomaticDisableChannelEnabled = boolValue + case "AutomaticEnableChannelEnabled": + common.AutomaticEnableChannelEnabled = boolValue case "LogConsumeEnabled": common.LogConsumeEnabled = boolValue case "DisplayInCurrencyEnabled": diff --git a/web/src/components/ChannelsTable.js b/web/src/components/ChannelsTable.js index 47b5131..3fcd502 100644 --- a/web/src/components/ChannelsTable.js +++ b/web/src/components/ChannelsTable.js @@ -478,7 +478,7 @@ const ChannelsTable = () => { const res = await API.get(`/api/channel/test`); const {success, message} = res.data; if (success) { - showInfo('已成功开始测试所有已启用通道,请刷新页面查看结果。'); + showInfo('已成功开始测试所有通道,请刷新页面查看结果。'); } else { showError(message); } @@ -702,7 +702,7 @@ const ChannelsTable = () => { onConfirm={testAllChannels} position={isMobile()?'top':'top'} > - + { ChatLink2: '', // 添加的新状态变量 QuotaPerUnit: 0, AutomaticDisableChannelEnabled: '', + AutomaticEnableChannelEnabled: '', ChannelDisableThreshold: 0, LogConsumeEnabled: '', DisplayInCurrencyEnabled: '', @@ -332,6 +333,12 @@ const OperationSetting = () => { name='AutomaticDisableChannelEnabled' onChange={handleInputChange} /> + { submitConfig('monitor').then();