fix: resolve retired/preview gemini model routing and test configuration errors
This commit is contained in:
@@ -26,12 +26,13 @@ type ConditionRule struct {
|
||||
|
||||
// Conditions defines the matching parameters for a rule.
|
||||
type Conditions struct {
|
||||
AnyOfTags []string `json:"any_of_tags,omitempty"`
|
||||
MaxInputTokensLt *int `json:"max_input_tokens_lt,omitempty"`
|
||||
RequiresReasoning *bool `json:"requires_reasoning,omitempty"`
|
||||
RequiresToolCalling *bool `json:"requires_tool_calling,omitempty"`
|
||||
HasMultimodalInput *bool `json:"has_multimodal_input,omitempty"`
|
||||
IsDefaultFallback *bool `json:"is_default_fallback,omitempty"`
|
||||
AnyOfTags []string `json:"any_of_tags,omitempty"`
|
||||
MaxInputTokensLt *int `json:"max_input_tokens_lt,omitempty"`
|
||||
RequiresReasoning *bool `json:"requires_reasoning,omitempty"`
|
||||
RequiresToolCalling *bool `json:"requires_tool_calling,omitempty"`
|
||||
IsSoftwareDevelopment *bool `json:"is_software_development,omitempty"`
|
||||
HasMultimodalInput *bool `json:"has_multimodal_input,omitempty"`
|
||||
IsDefaultFallback *bool `json:"is_default_fallback,omitempty"`
|
||||
}
|
||||
|
||||
func routeHeuristic(group db.ModelGroup, targets []string, routeCtx *RouteContext) (*Decision, error) {
|
||||
@@ -198,6 +199,13 @@ func matchConditions(cond Conditions, routeCtx *RouteContext) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Check software development flag
|
||||
if cond.IsSoftwareDevelopment != nil {
|
||||
if routeCtx.IsSoftwareDevelopment != *cond.IsSoftwareDevelopment {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check multimodal flag
|
||||
if cond.HasMultimodalInput != nil {
|
||||
if routeCtx.HasMultimodalInput != *cond.HasMultimodalInput {
|
||||
|
||||
@@ -140,3 +140,65 @@ func TestRouteHeuristic_LegacyRules(t *testing.T) {
|
||||
t.Fatalf("expected kimi-k2.6, got %s", dec2.SelectedModel)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteHeuristic_SoftwareDevelopmentCondition(t *testing.T) {
|
||||
targets := []string{
|
||||
"gemini-3-flash",
|
||||
"kimi-k2.7-code",
|
||||
"deepseek-v4-pro",
|
||||
"mimo-v2.5-pro",
|
||||
}
|
||||
|
||||
rulesJSON := `[
|
||||
{
|
||||
"rule_id": "agentic_code_and_tools",
|
||||
"conditions": {
|
||||
"requires_tool_calling": true,
|
||||
"is_software_development": true
|
||||
},
|
||||
"primary_model": "kimi-k2.7-code",
|
||||
"fallback_model": "deepseek-v4-pro"
|
||||
},
|
||||
{
|
||||
"rule_id": "agentic_general_tasks",
|
||||
"conditions": {
|
||||
"requires_tool_calling": true
|
||||
},
|
||||
"primary_model": "mimo-v2.5-pro"
|
||||
}
|
||||
]`
|
||||
|
||||
group := db.ModelGroup{
|
||||
ID: "dustins_stack",
|
||||
Strategy: "heuristic",
|
||||
HeuristicRules: &rulesJSON,
|
||||
}
|
||||
|
||||
// 1. Tool calling + Software dev should route to kimi-k2.7-code
|
||||
ctx1 := &RouteContext{
|
||||
UserMessage: "Write a python script to parse logs",
|
||||
RequiresToolCalling: true,
|
||||
IsSoftwareDevelopment: true,
|
||||
}
|
||||
dec1, err := routeHeuristic(group, targets, ctx1)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if dec1.SelectedModel != "kimi-k2.7-code" {
|
||||
t.Fatalf("expected kimi-k2.7-code, got %s", dec1.SelectedModel)
|
||||
}
|
||||
|
||||
// 2. Tool calling but NOT Software dev should route to mimo-v2.5-pro
|
||||
ctx2 := &RouteContext{
|
||||
UserMessage: "Search the web for weather in New York",
|
||||
RequiresToolCalling: true,
|
||||
IsSoftwareDevelopment: false,
|
||||
}
|
||||
dec2, err := routeHeuristic(group, targets, ctx2)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if dec2.SelectedModel != "mimo-v2.5-pro" {
|
||||
t.Fatalf("expected mimo-v2.5-pro, got %s (reason: %s)", dec2.SelectedModel, dec2.Reason)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,13 @@ type Decision struct {
|
||||
|
||||
// RouteContext holds metadata of the request to evaluate condition rules.
|
||||
type RouteContext struct {
|
||||
UserMessage string `json:"user_message"`
|
||||
InputTokens int `json:"input_tokens"`
|
||||
HasMultimodalInput bool `json:"has_multimodal_input"`
|
||||
RequiresToolCalling bool `json:"requires_tool_calling"`
|
||||
RequiresReasoning bool `json:"requires_reasoning"`
|
||||
Tags []string `json:"tags"`
|
||||
UserMessage string `json:"user_message"`
|
||||
InputTokens int `json:"input_tokens"`
|
||||
HasMultimodalInput bool `json:"has_multimodal_input"`
|
||||
RequiresToolCalling bool `json:"requires_tool_calling"`
|
||||
RequiresReasoning bool `json:"requires_reasoning"`
|
||||
IsSoftwareDevelopment bool `json:"is_software_development"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// ClassifierFunc is the callback for classifier-based routing.
|
||||
|
||||
Reference in New Issue
Block a user