feat: add hierarchical routing — groups can target other groups
RouteToConcrete() recursively resolves group chains until a concrete model is reached, with cycle detection and max depth (10) guard. Example: all-purpose -> fast-flow -> deepseek-v4-flash The dashboard log shows the full chain: 'deepseek-v4-flash (hierarchical: fast-flow (default (first target)) -> deepseek-v4-flash (default (first target)))'
This commit is contained in:
@@ -541,18 +541,20 @@ func (s *Server) handleChatCompletions(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if model is a group and route to a concrete model
|
||||
// Resolve model groups to concrete models (hierarchical — groups can target groups)
|
||||
modelGroup := ""
|
||||
if s.modelRouter != nil && s.modelRouter.IsGroup(modelID) {
|
||||
modelGroup = modelID
|
||||
if s.modelRouter != nil {
|
||||
userMessage := extractUserMessage(req.Messages)
|
||||
decision, err := s.modelRouter.Route(c.Request.Context(), modelID, userMessage)
|
||||
decision, err := s.modelRouter.RouteToConcrete(c.Request.Context(), modelID, userMessage)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("model routing failed: %v", err)})
|
||||
return
|
||||
}
|
||||
if decision.SelectedModel != modelID {
|
||||
modelGroup = modelID
|
||||
}
|
||||
modelID = decision.SelectedModel
|
||||
log.Printf("[ROUTER] %s -> %s (%s: %s)", modelGroup, modelID, decision.Strategy, decision.Reason)
|
||||
log.Printf("[ROUTER] %s (%s: %s)", modelID, decision.Strategy, decision.Reason)
|
||||
}
|
||||
|
||||
// Convert ChatCompletionRequest to UnifiedRequest
|
||||
|
||||
Reference in New Issue
Block a user