package router import ( "context" "fmt" "strconv" "strings" "gophergate/internal/db" ) const classifierSystemPrompt = `You are a task complexity classifier. Rate the following user message on a scale of 1 to %d, where: 1 = trivial/simple (basic facts, greetings, simple math) %d = highly complex (multi-step reasoning, code generation, architecture design) Reply with ONLY the number. No explanation.` func routeClassifier(ctx context.Context, classify ClassifierFunc, group db.ModelGroup, targets []string, userMessage string) (*Decision, error) { maxRating := len(targets) if maxRating < 2 { maxRating = 2 } prompt := fmt.Sprintf(classifierSystemPrompt, maxRating, maxRating) ratingStr, err := classify(ctx, getSelectorModel(group, targets), prompt, userMessage) if err != nil { // Classifier failed — fall back to heuristic return routeHeuristic(group, targets, userMessage) } rating, err := strconv.Atoi(strings.TrimSpace(ratingStr)) if err != nil || rating < 1 { rating = 1 } if rating > maxRating { rating = maxRating } idx := rating - 1 // 0-based index into targets return &Decision{ SelectedModel: targets[idx], Strategy: "classifier", Reason: fmt.Sprintf("complexity rating: %d/%d", rating, maxRating), }, nil } func getSelectorModel(group db.ModelGroup, targets []string) string { if group.SelectorModel != nil && *group.SelectorModel != "" { return *group.SelectorModel } // Default: use the first (cheapest) target model as the selector return targets[0] }