fix: resolve retired/preview gemini model routing and test configuration errors
This commit is contained in:
@@ -49,6 +49,7 @@ func (s *Server) handleGetModels(c *gin.Context) {
|
||||
|
||||
var result []gin.H
|
||||
s.registryMu.RLock()
|
||||
defer s.registryMu.RUnlock()
|
||||
if s.registry != nil {
|
||||
for pID, pInfo := range s.registry.Providers {
|
||||
proxyProvider, allowed := allowedRegistryProviders[pID]
|
||||
@@ -208,6 +209,7 @@ func (s *Server) handleUpdateModel(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
s.registryMu.RUnlock()
|
||||
|
||||
_, err := s.database.Exec(`
|
||||
INSERT INTO model_configs (id, provider_id, enabled, prompt_cost_per_m, completion_cost_per_m, cache_read_cost_per_m, cache_write_cost_per_m, mapping)
|
||||
|
||||
@@ -226,11 +226,11 @@ func (s *Server) handleTestProvider(c *gin.Context) {
|
||||
|
||||
// Adjust model for non-openai providers
|
||||
if name == "gemini" {
|
||||
testReq.Model = "gemini-2.0-flash"
|
||||
testReq.Model = "gemini-2.5-flash"
|
||||
} else if name == "deepseek" {
|
||||
testReq.Model = "deepseek-chat"
|
||||
} else if name == "moonshot" {
|
||||
testReq.Model = "kimi-k2.5"
|
||||
testReq.Model = "kimi-k2.7-code"
|
||||
} else if name == "grok" {
|
||||
testReq.Model = "grok-4-1-fast-non-reasoning"
|
||||
} else if name == "xiaomi" {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package server
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestIsSoftwareDevelopment(t *testing.T) {
|
||||
tests := []struct {
|
||||
message string
|
||||
expected bool
|
||||
}{
|
||||
{"can you check the logs? it looks like a lot of requests are being routed to kimi-k2.7-code when they don't need to be", false},
|
||||
{"it looks like its still routing to kimi when it shouldn't need to", false},
|
||||
{"Write a python script to parse logs", true},
|
||||
{"Search the web for weather in New York", false},
|
||||
{"How to build a compiler in Go", true},
|
||||
{"Check my vscode config", false},
|
||||
{"Let's decode this barcode", false},
|
||||
{"go ahead and email both docxs and the ppt to kayla\n\n<memory-context>... HELPipedia_Telethon_Speaker_Script.docx ... mental health program specialist ...", false},
|
||||
{"academic program development", false},
|
||||
{"write a script for the video presentation", false},
|
||||
{"How to write a bash script", true},
|
||||
{"refactor this sql query", true},
|
||||
{"can you organize Downloads and Documents real quick?\n\n<memory-context>\nCLI wrapper: ~/Projects/rag-engine/rag (bash script activating .venv). Python venv@~/Projects/rag-engine/.venv/.\n</memory-context>", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := isSoftwareDevelopment(tt.message)
|
||||
if result != tt.expected {
|
||||
t.Errorf("isSoftwareDevelopment(%q) = %v; expected %v", tt.message, result, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
-11
@@ -1,12 +1,13 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -57,7 +58,9 @@ func NewServer(cfg *config.Config, database *db.DB) *Server {
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Failed to fetch initial model registry: %v\n", err)
|
||||
} else {
|
||||
s.registryMu.Lock()
|
||||
s.registry = registry
|
||||
s.registryMu.Unlock()
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -976,12 +979,14 @@ func (s *Server) buildRouteContextFromChat(req models.ChatCompletionRequest) *ro
|
||||
strings.Contains(msgLower, "explain in detail")
|
||||
|
||||
routeCtx := &router.RouteContext{
|
||||
UserMessage: userMessage,
|
||||
InputTokens: inputTokens,
|
||||
HasMultimodalInput: hasMultimodal,
|
||||
RequiresToolCalling: requiresToolCalling,
|
||||
RequiresReasoning: requiresReasoning,
|
||||
UserMessage: userMessage,
|
||||
InputTokens: inputTokens,
|
||||
HasMultimodalInput: hasMultimodal,
|
||||
RequiresToolCalling: requiresToolCalling,
|
||||
RequiresReasoning: requiresReasoning,
|
||||
IsSoftwareDevelopment: isSoftwareDevelopment(userMessage),
|
||||
}
|
||||
log.Printf("[DEBUG] RouteContext built: msg=%q, IsSoftwareDevelopment=%v", userMessage, routeCtx.IsSoftwareDevelopment)
|
||||
routeCtx.Tags = s.getRouteCtxTags(routeCtx)
|
||||
return routeCtx
|
||||
}
|
||||
@@ -1034,12 +1039,14 @@ func (s *Server) buildRouteContextFromResponses(req models.ResponsesRequest) *ro
|
||||
strings.Contains(msgLower, "explain in detail")
|
||||
|
||||
routeCtx := &router.RouteContext{
|
||||
UserMessage: userMessage,
|
||||
InputTokens: inputTokens,
|
||||
HasMultimodalInput: hasMultimodal,
|
||||
RequiresToolCalling: requiresToolCalling,
|
||||
RequiresReasoning: requiresReasoning,
|
||||
UserMessage: userMessage,
|
||||
InputTokens: inputTokens,
|
||||
HasMultimodalInput: hasMultimodal,
|
||||
RequiresToolCalling: requiresToolCalling,
|
||||
RequiresReasoning: requiresReasoning,
|
||||
IsSoftwareDevelopment: isSoftwareDevelopment(userMessage),
|
||||
}
|
||||
log.Printf("[DEBUG] RouteContext built: msg=%q, IsSoftwareDevelopment=%v", userMessage, routeCtx.IsSoftwareDevelopment)
|
||||
routeCtx.Tags = s.getRouteCtxTags(routeCtx)
|
||||
return routeCtx
|
||||
}
|
||||
@@ -1102,3 +1109,35 @@ func (s *Server) getRouteCtxTags(routeCtx *router.RouteContext) []string {
|
||||
|
||||
return tags
|
||||
}
|
||||
|
||||
var (
|
||||
modelStripRegex = regexp.MustCompile(`(?i)\b[a-z0-9/._:-]*(code|coder|codex)[a-z0-9/._:-]*\b`)
|
||||
memoryContextRegex = regexp.MustCompile(`(?s)<memory-context>.*?</memory-context>`)
|
||||
softwareDevRegex = regexp.MustCompile(`(?i)\b(code|coding|programmer|programming|software|refactor|refactoring|compile|compiling|compiler|git|github|debug|debugging|repository|repo|unittest|unit test|test suite|test case|test cases|pull request|merge conflict|syntax error|source code|python|golang|javascript|typescript|ruby|php|perl|swift|kotlin|scala|rustlang|bash|powershell|sql|script|snippet|api|endpoint|patch|diff)\b`)
|
||||
)
|
||||
|
||||
func isSoftwareDevelopment(userMessage string) bool {
|
||||
msgLower := strings.ToLower(userMessage)
|
||||
sanitized := memoryContextRegex.ReplaceAllString(msgLower, "")
|
||||
sanitized = modelStripRegex.ReplaceAllString(sanitized, "")
|
||||
|
||||
if strings.Contains(sanitized, "script") {
|
||||
nonCodingScriptTerms := []string{
|
||||
"speaker script", "dialogue script", "movie script", "theatre script",
|
||||
"theater script", "script writing", "script writer", "video script",
|
||||
"audio script", "podcast script", "script for Kayla", "script for the",
|
||||
}
|
||||
hasNonCodingScript := false
|
||||
for _, term := range nonCodingScriptTerms {
|
||||
if strings.Contains(sanitized, strings.ToLower(term)) {
|
||||
hasNonCodingScript = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasNonCodingScript {
|
||||
sanitized = strings.ReplaceAll(sanitized, "script", "")
|
||||
}
|
||||
}
|
||||
|
||||
return softwareDevRegex.MatchString(sanitized)
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ func (s *Server) handleGetSettings(c *gin.Context) {
|
||||
providerCount := 0
|
||||
modelCount := 0
|
||||
s.registryMu.RLock()
|
||||
defer s.registryMu.RUnlock()
|
||||
if s.registry != nil {
|
||||
providerCount = len(s.registry.Providers)
|
||||
for _, p := range s.registry.Providers {
|
||||
|
||||
Reference in New Issue
Block a user