mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-19 04:40:52 +08:00
feat(cliproxy): support wildcard exclusions for models
This commit is contained in:
@@ -917,28 +917,81 @@ func applyExcludedModels(models []*ModelInfo, excluded []string) []*ModelInfo {
|
|||||||
if len(models) == 0 || len(excluded) == 0 {
|
if len(models) == 0 || len(excluded) == 0 {
|
||||||
return models
|
return models
|
||||||
}
|
}
|
||||||
blocked := make(map[string]struct{}, len(excluded))
|
|
||||||
|
patterns := make([]string, 0, len(excluded))
|
||||||
for _, item := range excluded {
|
for _, item := range excluded {
|
||||||
if trimmed := strings.TrimSpace(item); trimmed != "" {
|
if trimmed := strings.TrimSpace(item); trimmed != "" {
|
||||||
blocked[strings.ToLower(trimmed)] = struct{}{}
|
patterns = append(patterns, strings.ToLower(trimmed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(blocked) == 0 {
|
if len(patterns) == 0 {
|
||||||
return models
|
return models
|
||||||
}
|
}
|
||||||
|
|
||||||
filtered := make([]*ModelInfo, 0, len(models))
|
filtered := make([]*ModelInfo, 0, len(models))
|
||||||
for _, model := range models {
|
for _, model := range models {
|
||||||
if model == nil {
|
if model == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, blockedModel := blocked[strings.ToLower(strings.TrimSpace(model.ID))]; blockedModel {
|
modelID := strings.ToLower(strings.TrimSpace(model.ID))
|
||||||
continue
|
blocked := false
|
||||||
|
for _, pattern := range patterns {
|
||||||
|
if matchWildcard(pattern, modelID) {
|
||||||
|
blocked = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !blocked {
|
||||||
|
filtered = append(filtered, model)
|
||||||
}
|
}
|
||||||
filtered = append(filtered, model)
|
|
||||||
}
|
}
|
||||||
return filtered
|
return filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// matchWildcard performs case-insensitive wildcard matching where '*' matches any substring.
|
||||||
|
func matchWildcard(pattern, value string) bool {
|
||||||
|
if pattern == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast path for exact match (no wildcard present).
|
||||||
|
if !strings.Contains(pattern, "*") {
|
||||||
|
return pattern == value
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(pattern, "*")
|
||||||
|
// Handle prefix.
|
||||||
|
if prefix := parts[0]; prefix != "" {
|
||||||
|
if !strings.HasPrefix(value, prefix) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
value = value[len(prefix):]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle suffix.
|
||||||
|
if suffix := parts[len(parts)-1]; suffix != "" {
|
||||||
|
if !strings.HasSuffix(value, suffix) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
value = value[:len(value)-len(suffix)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle middle segments in order.
|
||||||
|
for i := 1; i < len(parts)-1; i++ {
|
||||||
|
segment := parts[i]
|
||||||
|
if segment == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
idx := strings.Index(value, segment)
|
||||||
|
if idx < 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
value = value[idx+len(segment):]
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func buildClaudeConfigModels(entry *config.ClaudeKey) []*ModelInfo {
|
func buildClaudeConfigModels(entry *config.ClaudeKey) []*ModelInfo {
|
||||||
if entry == nil || len(entry.Models) == 0 {
|
if entry == nil || len(entry.Models) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user