Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions internal/router/scenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,18 @@ func latestUserMessages(messages []MessageContent) []MessageContent {
return nil
}

// hasComplexPattern looks for complex operations that need more capable models.
// This includes tool-based operations (executing functions, writing/editing files, etc.)
// hasComplexPattern looks for truly complex or architectural operations that need
// the most capable models. It is intentionally narrow: common coding/debugging
// tasks ("build", "debug", "create file", "bash") are NOT complex, because they
// appear constantly in tool results and ordinary conversation and would otherwise
// route every turn to the complex model.
func hasComplexPattern(messages []MessageContent) bool {
complexKeywords := []string{
// Architectural
// Architectural / large-scale design
"architect", "architecture", "refactor", "redesign",
"complex", "difficult", "challenging",
"optimize", "performance", "efficiency",
"design pattern", "best practice",
"bug", "debug", "error", "exception", "stack trace",
// Tool-related keywords indicate complex operations
"execute", "run command", "bash", "shell",
"implement", "build", "create", "add feature",
"write to", "edit file", "create file",
}

for _, msg := range messages {
Expand Down
12 changes: 8 additions & 4 deletions internal/router/scenarios_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,17 @@ func TestDetectScenario_LatestTextVisualIntentWithoutNewImageStaysNonVision(t *t
}
}

func TestDetectScenario_DebugWithoutVisualIntentStaysTextComplex(t *testing.T) {
func TestDetectScenario_DebugWithoutVisualIntentStaysTextDefault(t *testing.T) {
// "debug" was removed from complexKeywords because tool_result content
// constantly contains it, routing every turn to complex by accident.
messages := []MessageContent{
{Role: "user", Content: "Cosa vedi?", HasImage: true, ImageHashes: []string{"img1"}},
{Role: "assistant", Content: "Vedo una schermata."},
{Role: "user", Content: "debug questo codice", HasImage: false},
}
result := DetectScenario(messages, 100, mockConfig())
if result.Scenario != ScenarioComplex {
t.Errorf("Expected ScenarioComplex, got %s", result.Scenario)
if result.Scenario != ScenarioDefault {
t.Errorf("Expected ScenarioDefault (debug is no longer a complex trigger), got %s", result.Scenario)
}
}

Expand All @@ -230,8 +232,10 @@ func TestDetectScenario_VisionLongContextTakesPriorityOverVisionComplex(t *testi
}

func TestRouteForStreaming_VisionComplexKeepsVisionComplexScenario(t *testing.T) {
// "bug" was removed from complexKeywords; use a retained architectural
// keyword ("refactor") to exercise the vision_complex path.
messages := []MessageContent{
{Role: "user", Content: "Find the bug in this screenshot", HasImage: true},
{Role: "user", Content: "Refactor the code shown in this screenshot", HasImage: true},
}
result := RouteForStreaming(messages, 100, mockConfig())
if result.Scenario != ScenarioVisionComplex {
Expand Down
Loading