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
50 changes: 19 additions & 31 deletions config/config.e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,187 +86,175 @@ classifier:
pii_mapping_path: "models/pii_classifier_modernbert-base_presidio_token_model/pii_type_mapping.json"
categories:
- name: business
use_reasoning: false
reasoning_description: "Business content is typically conversational"
reasoning_effort: low # Business conversations need low reasoning effort
model_scores:
- model: "Model-A"
score: 0.8
use_reasoning: false
reasoning_description: "Business content is typically conversational"
reasoning_effort: low
- model: "Model-B"
score: 0.4
use_reasoning: false
- model: "Model-A"
score: 0.2
use_reasoning: false
- name: law
use_reasoning: false
reasoning_description: "Legal content is typically explanatory"
model_scores:
- model: "Model-B"
score: 0.8
use_reasoning: false
reasoning_description: "Legal content is typically explanatory"
- model: "Model-A"
score: 0.6
use_reasoning: false
- model: "Model-A"
score: 0.4
use_reasoning: false
- name: psychology
use_reasoning: false
reasoning_description: "Psychology content is usually explanatory"
model_scores:
- model: "Model-A"
score: 0.6
use_reasoning: false
reasoning_description: "Psychology content is usually explanatory"
- model: "Model-B"
score: 0.4
use_reasoning: false
- model: "Model-A"
score: 0.4
use_reasoning: false
- name: biology
use_reasoning: true
reasoning_description: "Biological processes benefit from structured analysis"
model_scores:
- model: "Model-A"
score: 0.8
use_reasoning: false
reasoning_description: "Biological processes benefit from structured analysis"
- model: "Model-B"
score: 0.6
use_reasoning: false
- model: "Model-A"
score: 0.2
use_reasoning: false
- name: chemistry
use_reasoning: true
reasoning_description: "Chemical reactions and formulas require systematic thinking"
reasoning_effort: high # Chemistry requires high reasoning effort
model_scores:
- model: "Model-A"
score: 0.8
use_reasoning: true
reasoning_description: "Chemical reactions and formulas require systematic thinking"
reasoning_effort: high
- model: "Model-B"
score: 0.6
use_reasoning: false
- model: "Model-A"
score: 0.6
use_reasoning: false
- name: history
use_reasoning: false
reasoning_description: "Historical content is narrative-based"
model_scores:
- model: "Model-A"
score: 0.8
use_reasoning: false
reasoning_description: "Historical content is narrative-based"
- model: "Model-A"
score: 0.6
use_reasoning: false
- model: "Model-B"
score: 0.4
use_reasoning: false
- name: other
use_reasoning: false
reasoning_description: "General content doesn't require reasoning"
model_scores:
- model: "Model-B"
score: 0.8
use_reasoning: false
reasoning_description: "General content doesn't require reasoning"
- model: "Model-A"
score: 0.6
use_reasoning: false
- model: "Model-A"
score: 0.6
use_reasoning: false
- name: health
use_reasoning: false
reasoning_description: "Health information is typically informational"
model_scores:
- model: "Model-B"
score: 0.8
use_reasoning: false
reasoning_description: "Health information is typically informational"
- model: "Model-A"
score: 0.8
use_reasoning: false
- model: "Model-A"
score: 0.6
use_reasoning: false
- name: economics
use_reasoning: false
reasoning_description: "Economic discussions are usually explanatory"
model_scores:
- model: "Model-B"
score: 0.8
use_reasoning: false
reasoning_description: "Economic discussions are usually explanatory"
- model: "Model-A"
score: 0.8
use_reasoning: false
- model: "Model-A"
score: 0.1
use_reasoning: false
- name: math
use_reasoning: true
reasoning_description: "Mathematical problems require step-by-step reasoning"
reasoning_effort: high # Math problems need high reasoning effort
model_scores:
- model: "Model-B"
score: 1.0
use_reasoning: true
reasoning_description: "Mathematical problems require step-by-step reasoning"
reasoning_effort: high
- model: "Model-A"
score: 0.9
use_reasoning: true
reasoning_description: "Mathematical problems require step-by-step reasoning"
reasoning_effort: high
- model: "Model-A"
score: 0.8
use_reasoning: false
- model: "Model-B"
score: 0.6
use_reasoning: false
- name: physics
use_reasoning: true
reasoning_description: "Physics concepts need logical analysis"
model_scores:
- model: "Model-B"
score: 0.4
use_reasoning: true
reasoning_description: "Physics concepts need logical analysis"
- model: "Model-A"
score: 0.4
use_reasoning: false
- model: "Model-A"
score: 0.4
use_reasoning: false
- name: computer science
use_reasoning: true
reasoning_description: "Programming and algorithms need logical reasoning"
model_scores:
- model: "Model-B"
score: 0.6
use_reasoning: false
reasoning_description: "Programming and algorithms need logical reasoning"
- model: "Model-A"
score: 0.6
use_reasoning: false
- model: "Model-A"
score: 0.1
use_reasoning: false
- name: philosophy
use_reasoning: false
reasoning_description: "Philosophical discussions are conversational"
model_scores:
- model: "Model-A"
score: 0.6
use_reasoning: false
reasoning_description: "Philosophical discussions are conversational"
- model: "Model-B"
score: 0.2
use_reasoning: false
- model: "Model-A"
score: 0.2
use_reasoning: false
- name: engineering
use_reasoning: true
reasoning_description: "Engineering problems require systematic problem-solving"
model_scores:
- model: "Model-B"
score: 0.6
use_reasoning: false
reasoning_description: "Engineering problems require systematic problem-solving"
- model: "Model-A"
score: 0.6
use_reasoning: false
Expand Down
51 changes: 18 additions & 33 deletions dashboard/frontend/src/pages/ConfigPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ interface ModelScore {
model: string
score: number
use_reasoning: boolean
reasoning_description?: string
reasoning_effort?: string
}

interface Category {
name: string
system_prompt?: string
use_reasoning: boolean
reasoning_description: string
reasoning_effort: string
model_scores: ModelScore[]
}

Expand Down Expand Up @@ -1408,14 +1407,21 @@ const ConfigPage: React.FC<ConfigPageProps> = ({ activeSection = 'models' }) =>

{config?.categories && config.categories.length > 0 ? (
<div className={styles.categoryGridTwoColumn}>
{config.categories.map((category, index) => (
{config.categories.map((category, index) => {
// Get reasoning info from best model (first model score)
const bestModel = category.model_scores?.[0]
const useReasoning = bestModel?.use_reasoning || false
const reasoningEffort = bestModel?.reasoning_effort || 'medium'
const reasoningDescription = bestModel?.reasoning_description || ''

return (
<div key={index} className={styles.categoryCard}>
<div className={styles.categoryHeader}>
<span className={styles.categoryName}>{category.name}</span>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
{category.use_reasoning && (
<span className={`${styles.reasoningBadge} ${styles[`reasoning${category.reasoning_effort}`]}`}>
⚡ {category.reasoning_effort}
{useReasoning && (
<span className={`${styles.reasoningBadge} ${styles[`reasoning${reasoningEffort}`]}`}>
⚡ {reasoningEffort}
</span>
)}
<button
Expand All @@ -1424,10 +1430,7 @@ const ConfigPage: React.FC<ConfigPageProps> = ({ activeSection = 'models' }) =>
openEditModal(
`Edit Category: ${category.name}`,
{
system_prompt: category.system_prompt || '',
use_reasoning: category.use_reasoning || false,
reasoning_effort: category.reasoning_effort || 'medium',
reasoning_description: category.reasoning_description || ''
system_prompt: category.system_prompt || ''
},
[
{
Expand All @@ -1436,26 +1439,6 @@ const ConfigPage: React.FC<ConfigPageProps> = ({ activeSection = 'models' }) =>
type: 'textarea',
placeholder: 'Enter system prompt for this category...',
description: 'Instructions for the model when handling this category'
},
{
name: 'use_reasoning',
label: 'Use Reasoning',
type: 'boolean',
description: 'Enable reasoning for this category'
},
{
name: 'reasoning_effort',
label: 'Reasoning Effort',
type: 'select',
options: ['low', 'medium', 'high'],
description: 'Computational effort level for reasoning'
},
{
name: 'reasoning_description',
label: 'Reasoning Description',
type: 'textarea',
placeholder: 'Describe the reasoning approach...',
description: 'Description of how reasoning is applied'
}
],
async (data) => {
Expand Down Expand Up @@ -1484,7 +1467,9 @@ const ConfigPage: React.FC<ConfigPageProps> = ({ activeSection = 'models' }) =>
</div>
)}

<p className={styles.categoryDescription}>{category.reasoning_description}</p>
{reasoningDescription && (
<p className={styles.categoryDescription}>{reasoningDescription}</p>
)}

<div className={styles.categoryModels}>
<div className={styles.categoryModelsHeader}>
Expand Down Expand Up @@ -1635,7 +1620,7 @@ const ConfigPage: React.FC<ConfigPageProps> = ({ activeSection = 'models' }) =>
)}
</div>
</div>
))}
)})}
</div>
) : (
<div className={styles.emptyState}>No categories configured</div>
Expand Down
30 changes: 8 additions & 22 deletions src/semantic-router/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,18 +332,18 @@ func (c *RouterConfig) GetCacheSimilarityThreshold() float32 {

// ModelScore associates an LLM with its selection weight and reasoning flag within a category.
type ModelScore struct {
Model string `yaml:"model"`
Score float64 `yaml:"score"`
UseReasoning *bool `yaml:"use_reasoning"` // Pointer to detect missing field
Model string `yaml:"model"`
Score float64 `yaml:"score"`
UseReasoning *bool `yaml:"use_reasoning"` // Pointer to detect missing field
ReasoningDescription string `yaml:"reasoning_description,omitempty"` // Model-specific reasoning description
ReasoningEffort string `yaml:"reasoning_effort,omitempty"` // Model-specific reasoning effort level (low, medium, high)
}

// Category represents a category for routing queries
type Category struct {
Name string `yaml:"name"`
Description string `yaml:"description,omitempty"`
ReasoningDescription string `yaml:"reasoning_description,omitempty"`
ReasoningEffort string `yaml:"reasoning_effort,omitempty"` // Configurable reasoning effort level (low, medium, high)
ModelScores []ModelScore `yaml:"model_scores"`
Name string `yaml:"name"`
Description string `yaml:"description,omitempty"`
ModelScores []ModelScore `yaml:"model_scores"`
// MMLUCategories optionally maps this generic category to one or more MMLU-Pro categories
// used by the classifier model. When provided, classifier outputs will be translated
// from these MMLU categories to this generic category name.
Expand All @@ -359,8 +359,6 @@ type Category struct {
SystemPromptMode string `yaml:"system_prompt_mode,omitempty"`
}

// Legacy types - can be removed once migration is complete

// GetModelReasoningFamily returns the reasoning family configuration for a given model name
func (rc *RouterConfig) GetModelReasoningFamily(modelName string) *ReasoningFamilyConfig {
if rc == nil || rc.ModelConfig == nil || rc.ReasoningFamilies == nil {
Expand All @@ -382,18 +380,6 @@ func (rc *RouterConfig) GetModelReasoningFamily(modelName string) *ReasoningFami
return &familyConfig
}

// Legacy functions - can be removed once migration is complete

// contains checks if a slice contains a string
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
}

var (
config *RouterConfig
configOnce sync.Once
Expand Down
Loading
Loading