Skip to content

Commit 56fc344

Browse files
committed
feat(monitor_setting): implement automatic channel testing configuration
1 parent ebaaecb commit 56fc344

File tree

8 files changed

+107
-103
lines changed

8 files changed

+107
-103
lines changed

controller/channel-test.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
relayconstant "one-api/relay/constant"
2121
"one-api/relay/helper"
2222
"one-api/service"
23+
"one-api/setting/operation_setting"
2324
"one-api/types"
2425
"strconv"
2526
"strings"
@@ -477,15 +478,26 @@ func TestAllChannels(c *gin.Context) {
477478
return
478479
}
479480

480-
func AutomaticallyTestChannels(frequency int) {
481-
if frequency <= 0 {
482-
common.SysLog("CHANNEL_TEST_FREQUENCY is not set or invalid, skipping automatic channel test")
483-
return
484-
}
485-
for {
486-
time.Sleep(time.Duration(frequency) * time.Minute)
487-
common.SysLog("testing all channels")
488-
_ = testAllChannels(false)
489-
common.SysLog("channel test finished")
490-
}
481+
var autoTestChannelsOnce sync.Once
482+
483+
func AutomaticallyTestChannels() {
484+
autoTestChannelsOnce.Do(func() {
485+
for {
486+
if !operation_setting.GetMonitorSetting().AutoTestChannelEnabled {
487+
time.Sleep(10 * time.Minute)
488+
continue
489+
}
490+
frequency := operation_setting.GetMonitorSetting().AutoTestChannelMinutes
491+
common.SysLog(fmt.Sprintf("automatically test channels with interval %d minutes", frequency))
492+
for {
493+
time.Sleep(time.Duration(frequency) * time.Minute)
494+
common.SysLog("automatically testing all channels")
495+
_ = testAllChannels(false)
496+
common.SysLog("automatically channel test finished")
497+
if !operation_setting.GetMonitorSetting().AutoTestChannelEnabled {
498+
break
499+
}
500+
}
501+
}
502+
})
491503
}

main.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,9 @@ func main() {
9494
}
9595
go controller.AutomaticallyUpdateChannels(frequency)
9696
}
97-
if os.Getenv("CHANNEL_TEST_FREQUENCY") != "" {
98-
frequency, err := strconv.Atoi(os.Getenv("CHANNEL_TEST_FREQUENCY"))
99-
if err != nil {
100-
common.FatalLog("failed to parse CHANNEL_TEST_FREQUENCY: " + err.Error())
101-
}
102-
go controller.AutomaticallyTestChannels(frequency)
103-
}
97+
98+
go controller.AutomaticallyTestChannels()
99+
104100
if common.IsMasterNode && constant.UpdateTask {
105101
gopool.Go(func() {
106102
controller.UpdateMidjourneyTaskBulk()

relay/common/relay_utils.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ package common
22

33
import (
44
"fmt"
5-
"github.com/gin-gonic/gin"
6-
_ "image/gif"
7-
_ "image/jpeg"
8-
_ "image/png"
95
"one-api/constant"
106
"strings"
7+
8+
"github.com/gin-gonic/gin"
119
)
1210

1311
func GetFullRequestURL(baseURL string, requestURL string, channelType int) string {

service/file_decoder.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"encoding/base64"
66
"fmt"
77
"image"
8+
_ "image/gif"
9+
_ "image/jpeg"
10+
_ "image/png"
811
"io"
912
"net/http"
1013
"one-api/common"

service/token_counter.go

Lines changed: 3 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"errors"
66
"fmt"
77
"image"
8+
_ "image/gif"
9+
_ "image/jpeg"
10+
_ "image/png"
811
"log"
912
"math"
1013
"one-api/common"
@@ -357,33 +360,6 @@ func CountRequestToken(c *gin.Context, meta *types.TokenCountMeta, info *relayco
357360
return tkm, nil
358361
}
359362

360-
//func CountTokenChatRequest(info *relaycommon.RelayInfo, request dto.GeneralOpenAIRequest) (int, error) {
361-
// tkm := 0
362-
// msgTokens, err := CountTokenMessages(info, request.Messages, request.Model, request.Stream)
363-
// if err != nil {
364-
// return 0, err
365-
// }
366-
// tkm += msgTokens
367-
// if request.Tools != nil {
368-
// openaiTools := request.Tools
369-
// countStr := ""
370-
// for _, tool := range openaiTools {
371-
// countStr = tool.Function.Name
372-
// if tool.Function.Description != "" {
373-
// countStr += tool.Function.Description
374-
// }
375-
// if tool.Function.Parameters != nil {
376-
// countStr += fmt.Sprintf("%v", tool.Function.Parameters)
377-
// }
378-
// }
379-
// toolTokens := CountTokenInput(countStr, request.Model)
380-
// tkm += 8
381-
// tkm += toolTokens
382-
// }
383-
//
384-
// return tkm, nil
385-
//}
386-
387363
func CountTokenClaudeRequest(request dto.ClaudeRequest, model string) (int, error) {
388364
tkm := 0
389365

@@ -543,56 +519,6 @@ func CountTokenRealtime(info *relaycommon.RelayInfo, request dto.RealtimeEvent,
543519
return textToken, audioToken, nil
544520
}
545521

546-
//func CountTokenMessages(info *relaycommon.RelayInfo, messages []dto.Message, model string, stream bool) (int, error) {
547-
// //recover when panic
548-
// tokenEncoder := getTokenEncoder(model)
549-
// // Reference:
550-
// // https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
551-
// // https://github.com/pkoukk/tiktoken-go/issues/6
552-
// //
553-
// // Every message follows <|start|>{role/name}\n{content}<|end|>\n
554-
// var tokensPerMessage int
555-
// var tokensPerName int
556-
//
557-
// tokensPerMessage = 3
558-
// tokensPerName = 1
559-
//
560-
// tokenNum := 0
561-
// for _, message := range messages {
562-
// tokenNum += tokensPerMessage
563-
// tokenNum += getTokenNum(tokenEncoder, message.Role)
564-
// if message.Content != nil {
565-
// if message.Name != nil {
566-
// tokenNum += tokensPerName
567-
// tokenNum += getTokenNum(tokenEncoder, *message.Name)
568-
// }
569-
// arrayContent := message.ParseContent()
570-
// for _, m := range arrayContent {
571-
// if m.Type == dto.ContentTypeImageURL {
572-
// imageUrl := m.GetImageMedia()
573-
// imageTokenNum, err := getImageToken(info, imageUrl, model, stream)
574-
// if err != nil {
575-
// return 0, err
576-
// }
577-
// tokenNum += imageTokenNum
578-
// log.Printf("image token num: %d", imageTokenNum)
579-
// } else if m.Type == dto.ContentTypeInputAudio {
580-
// // TODO: 音频token数量计算
581-
// tokenNum += 100
582-
// } else if m.Type == dto.ContentTypeFile {
583-
// tokenNum += 5000
584-
// } else if m.Type == dto.ContentTypeVideoUrl {
585-
// tokenNum += 5000
586-
// } else {
587-
// tokenNum += getTokenNum(tokenEncoder, m.Text)
588-
// }
589-
// }
590-
// }
591-
// }
592-
// tokenNum += 3 // Every reply is primed with <|start|>assistant<|message|>
593-
// return tokenNum, nil
594-
//}
595-
596522
func CountTokenInput(input any, model string) int {
597523
switch v := input.(type) {
598524
case string:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package operation_setting
2+
3+
import (
4+
"one-api/setting/config"
5+
"os"
6+
"strconv"
7+
)
8+
9+
type MonitorSetting struct {
10+
AutoTestChannelEnabled bool `json:"auto_test_channel_enabled"`
11+
AutoTestChannelMinutes int `json:"auto_test_channel_minutes"`
12+
}
13+
14+
// 默认配置
15+
var monitorSetting = MonitorSetting{
16+
AutoTestChannelEnabled: false,
17+
AutoTestChannelMinutes: 10,
18+
}
19+
20+
func init() {
21+
// 注册到全局配置管理器
22+
config.GlobalConfig.Register("monitor_setting", &monitorSetting)
23+
}
24+
25+
func GetMonitorSetting() *MonitorSetting {
26+
if os.Getenv("CHANNEL_TEST_FREQUENCY") != "" {
27+
frequency, err := strconv.Atoi(os.Getenv("CHANNEL_TEST_FREQUENCY"))
28+
if err == nil && frequency > 0 {
29+
monitorSetting.AutoTestChannelEnabled = true
30+
monitorSetting.AutoTestChannelMinutes = frequency
31+
}
32+
}
33+
return &monitorSetting
34+
}

web/src/components/settings/OperationSetting.jsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ const OperationSetting = () => {
6868
AutomaticDisableChannelEnabled: false,
6969
AutomaticEnableChannelEnabled: false,
7070
AutomaticDisableKeywords: '',
71+
'monitor_setting.auto_test_channel_enabled': false,
72+
'monitor_setting.auto_test_channel_minutes': 10,
7173
});
7274

7375
let [loading, setLoading] = useState(false);
@@ -78,10 +80,7 @@ const OperationSetting = () => {
7880
if (success) {
7981
let newInputs = {};
8082
data.forEach((item) => {
81-
if (
82-
item.key.endsWith('Enabled') ||
83-
['DefaultCollapseSidebar'].includes(item.key)
84-
) {
83+
if (typeof inputs[item.key] === 'boolean') {
8584
newInputs[item.key] = toBoolean(item.value);
8685
} else {
8786
newInputs[item.key] = item.value;

web/src/pages/Setting/Operation/SettingsMonitoring.jsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export default function SettingsMonitoring(props) {
3838
AutomaticDisableChannelEnabled: false,
3939
AutomaticEnableChannelEnabled: false,
4040
AutomaticDisableKeywords: '',
41+
'monitor_setting.auto_test_channel_enabled': false,
42+
'monitor_setting.auto_test_channel_minutes': 10,
4143
});
4244
const refForm = useRef();
4345
const [inputsRow, setInputsRow] = useState(inputs);
@@ -98,6 +100,40 @@ export default function SettingsMonitoring(props) {
98100
style={{ marginBottom: 15 }}
99101
>
100102
<Form.Section text={t('监控设置')}>
103+
<Row gutter={16}>
104+
<Col xs={24} sm={12} md={8} lg={8} xl={8}>
105+
<Form.Switch
106+
field={'monitor_setting.auto_test_channel_enabled'}
107+
label={t('定时测试所有通道')}
108+
size='default'
109+
checkedText='|'
110+
uncheckedText='〇'
111+
onChange={(value) =>
112+
setInputs({
113+
...inputs,
114+
'monitor_setting.auto_test_channel_enabled': value,
115+
})
116+
}
117+
/>
118+
</Col>
119+
<Col xs={24} sm={12} md={8} lg={8} xl={8}>
120+
<Form.InputNumber
121+
label={t('自动测试所有通道间隔时间')}
122+
step={1}
123+
min={1}
124+
suffix={t('分钟')}
125+
extraText={t('每隔多少分钟测试一次所有通道')}
126+
placeholder={''}
127+
field={'monitor_setting.auto_test_channel_minutes'}
128+
onChange={(value) =>
129+
setInputs({
130+
...inputs,
131+
'monitor_setting.auto_test_channel_minutes': parseInt(value),
132+
})
133+
}
134+
/>
135+
</Col>
136+
</Row>
101137
<Row gutter={16}>
102138
<Col xs={24} sm={12} md={8} lg={8} xl={8}>
103139
<Form.InputNumber

0 commit comments

Comments
 (0)