feat: classifier bucket mapping + dispatcher seed group
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

Classifier: When complexity_threshold is set (e.g. 10), uses it as the
rating scale and maps ratings proportionally to target buckets instead
of 1:1. Formula: idx = rating * len(targets) / (threshold + 1).

With threshold=10 and 3 targets: 1-3→target[0], 4-7→target[1], 8-10→target[2].

Seed: Added 'dispatcher' group (classifier, threshold=10, selector=deepseek-v4-flash)
that auto-routes to fast-flow/standard-pro/heavy-logic by complexity score.

Combined with hierarchical routing, this enables two-level dispatch:
  dispatcher scores 1-10 → routes to tier group → tier picks concrete model.
This commit is contained in:
2026-05-07 13:18:35 -04:00
parent 7517307c11
commit 3c0b59622e
2 changed files with 39 additions and 11 deletions
+19 -10
View File
@@ -195,20 +195,21 @@ func (db *DB) RunMigrations() error {
// Seed default model groups
defaultGroups := []struct {
id, strategy, targets string
logicLevel *int
id, strategy, targets, selectorModel string
complexityThreshold, logicLevel *int
primaryUse *string
}{
{"deepseek-auto", "heuristic", `["deepseek-chat","deepseek-reasoner"]`, nil, nil},
{"openai-auto", "heuristic", `["gpt-4o-mini","gpt-4o"]`, nil, nil},
{"gemini-auto", "heuristic", `["gemini-2.0-flash","gemini-2.5-pro"]`, nil, nil},
{"heavy-logic", "heuristic", `["grok-4.3","kimi-k2.5","deepseek-v4-pro"]`, intPtr(9), strPtr("Complex Coding, Logic, Agents.")},
{"standard-pro", "heuristic", `["gpt-5.4-mini","gemini-3-flash"]`, intPtr(5), strPtr("General Assistant, Long Docs.")},
{"fast-flow", "heuristic", `["deepseek-v4-flash","gpt-5.4-nano"]`, intPtr(2), strPtr("Classification, JSON, Basic Q&A.")},
{"deepseek-auto", "heuristic", `["deepseek-chat","deepseek-reasoner"]`, "", nil, nil, nil},
{"openai-auto", "heuristic", `["gpt-4o-mini","gpt-4o"]`, "", nil, nil, nil},
{"gemini-auto", "heuristic", `["gemini-2.0-flash","gemini-2.5-pro"]`, "", nil, nil, nil},
{"heavy-logic", "heuristic", `["grok-4.3","kimi-k2.5","deepseek-v4-pro"]`, "", nil, intPtr(9), strPtr("Complex Coding, Logic, Agents.")},
{"standard-pro", "heuristic", `["gpt-5.4-mini","gemini-3-flash"]`, "", nil, intPtr(5), strPtr("General Assistant, Long Docs.")},
{"fast-flow", "heuristic", `["deepseek-v4-flash","gpt-5.4-nano"]`, "", nil, intPtr(2), strPtr("Classification, JSON, Basic Q&A.")},
{"dispatcher", "classifier", `["fast-flow","standard-pro","heavy-logic"]`, "deepseek-v4-flash", intPtr(10), nil, strPtr("Auto-dispatches to tier groups by complexity.")},
}
for _, g := range defaultGroups {
db.Exec(`INSERT OR IGNORE INTO model_groups (id, strategy, targets, logic_level, primary_use) VALUES (?, ?, ?, ?, ?)`,
g.id, g.strategy, g.targets, g.logicLevel, g.primaryUse)
db.Exec(`INSERT OR IGNORE INTO model_groups (id, strategy, targets, selector_model, complexity_threshold, logic_level, primary_use) VALUES (?, ?, ?, ?, ?, ?, ?)`,
g.id, g.strategy, g.targets, nilStr(g.selectorModel), g.complexityThreshold, g.logicLevel, g.primaryUse)
}
return nil
@@ -312,3 +313,11 @@ type ModelGroup struct {
func intPtr(v int) *int { return &v }
func strPtr(v string) *string { return &v }
// nilStr returns a *string for non-empty strings, nil for empty.
func nilStr(v string) *string {
if v == "" {
return nil
}
return &v
}