Просмотр исходного кода

feat: support regex-prefixed ignored upstream models

Seefs 1 месяц назад
Родитель
Сommit
45f65c297b

+ 9 - 5
controller/channel_upstream_update.go

@@ -3,6 +3,7 @@ package controller
 import (
 	"fmt"
 	"net/http"
+	"regexp"
 	"slices"
 	"strings"
 	"sync"
@@ -169,10 +170,7 @@ func collectPendingUpstreamModelChangesFromModels(
 		upstreamSet[modelName] = struct{}{}
 	}
 
-	ignoredSet := make(map[string]struct{})
-	for _, modelName := range normalizeModelNames(ignoredModels) {
-		ignoredSet[modelName] = struct{}{}
-	}
+	normalizedIgnoredModels := normalizeModelNames(ignoredModels)
 
 	redirectSourceSet := make(map[string]struct{}, len(modelMapping))
 	redirectTargetSet := make(map[string]struct{}, len(modelMapping))
@@ -193,7 +191,13 @@ func collectPendingUpstreamModelChangesFromModels(
 		if _, ok := coveredUpstreamSet[modelName]; ok {
 			return false
 		}
-		if _, ok := ignoredSet[modelName]; ok {
+		if lo.ContainsBy(normalizedIgnoredModels, func(ignoredModel string) bool {
+			if regexBody, ok := strings.CutPrefix(ignoredModel, "regex:"); ok {
+				matched, err := regexp.MatchString(strings.TrimSpace(regexBody), modelName)
+				return err == nil && matched
+			}
+			return ignoredModel == modelName
+		}) {
 			return false
 		}
 		return true

+ 12 - 0
controller/channel_upstream_update_test.go

@@ -111,6 +111,18 @@ func TestCollectPendingUpstreamModelChangesFromModels_WithModelMapping(t *testin
 	require.Equal(t, []string{"stale-model"}, pendingRemoveModels)
 }
 
+func TestCollectPendingUpstreamModelChangesFromModels_WithIgnoredRegexPatterns(t *testing.T) {
+	pendingAddModels, pendingRemoveModels := collectPendingUpstreamModelChangesFromModels(
+		[]string{"gpt-4o"},
+		[]string{"gpt-4o", "claude-3-5-sonnet", "sora-video", "gpt-4.1"},
+		[]string{"regex:^sora-.*$", "gpt-4.1"},
+		nil,
+	)
+
+	require.Equal(t, []string{"claude-3-5-sonnet"}, pendingAddModels)
+	require.Equal(t, []string{}, pendingRemoveModels)
+}
+
 func TestBuildUpstreamModelUpdateTaskNotificationContent_OmitOverflowDetails(t *testing.T) {
 	channelSummaries := make([]upstreamModelUpdateChannelSummary, 0, 12)
 	for i := 0; i < 12; i++ {

+ 6 - 1
web/src/components/table/channels/modals/EditChannelModal.jsx

@@ -3294,7 +3294,12 @@ const EditChannelModal = (props) => {
                         <Form.Input
                           field='upstream_model_update_ignored_models'
                           label={t('已忽略模型')}
-                          placeholder={t('例如:gpt-4.1-nano,gpt-4o-mini')}
+                          placeholder={t(
+                            '例如:gpt-4.1-nano,regex:^claude-.*$,regex:^sora-.*$',
+                          )}
+                          extraText={t(
+                            '支持精确匹配;使用 regex: 开头可按正则匹配。',
+                          )}
                           onChange={(value) =>
                             handleInputChange(
                               'upstream_model_update_ignored_models',

+ 3 - 1
web/src/i18n/locales/en.json

@@ -3337,6 +3337,8 @@
     "输入价格:{{symbol}}{{price}} / 1M tokens": "Input Price: {{symbol}}{{price}} / 1M tokens",
     "输出价格 {{symbol}}{{price}} / 1M tokens": "Output Price {{symbol}}{{price}} / 1M tokens",
     "输出价格:{{symbol}}{{price}} / 1M tokens": "Output Price: {{symbol}}{{price}} / 1M tokens",
-    "输出价格:{{symbol}}{{total}} / 1M tokens": "Output Price: {{symbol}}{{total}} / 1M tokens"
+    "输出价格:{{symbol}}{{total}} / 1M tokens": "Output Price: {{symbol}}{{total}} / 1M tokens",
+    "例如:gpt-4.1-nano,regex:^claude-.*$,regex:^sora-.*$": "Example: gpt-4.1-nano,regex:^claude-.*$,regex:^sora-.*$",
+    "支持精确匹配;使用 regex: 开头可按正则匹配。": "Supports exact matching. Use a regex: prefix for regex matching."
   }
 }