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();