package utilimport ( "github.com/router-for-me/CLIProxyAPI/v6/internal/registry")// ModelSupportsThinking reports whether the given model has Thinking capability// according to the model registry metadata (provider-agnostic).func ModelSupportsThinking(model string) bool { if model == "" { return false } if info := registry.GetGlobalRegistry().GetModelInfo(model); info != nil { return info.Thinking != nil } return false}// NormalizeThinkingBudget clamps the requested thinking budget to the// supported range for the specified model using registry metadata only.// If the model is unknown or has no Thinking metadata, returns the original budget.// For dynamic (-1), returns -1 if DynamicAllowed; otherwise approximates mid-range// or min (0 if zero is allowed and mid <= 0).func NormalizeThinkingBudget(model string, budget int) int { if budget == -1 { // dynamic if found, min, max, zeroAllowed, dynamicAllowed := thinkingRangeFromRegistry(model); found { if dynamicAllowed { return -1 } mid := (min + max) / 2 if mid <= 0 && zeroAllowed { return 0 } if mid <= 0 { return min } return mid } return -1 } if found, min, max, zeroAllowed, _ := thinkingRangeFromRegistry(model); found { if budget == 0 { if zeroAllowed { return 0 } return min } if budget < min { return min } if budget > max { return max } return budget } return budget}// thinkingRangeFromRegistry attempts to read thinking ranges from the model registry.func thinkingRangeFromRegistry(model string) (found bool, min int, max int, zeroAllowed bool, dynamicAllowed bool) { if model == "" { return false, 0, 0, false, false } info := registry.GetGlobalRegistry().GetModelInfo(model) if info == nil || info.Thinking == nil { return false, 0, 0, false, false } return true, info.Thinking.Min, info.Thinking.Max, info.Thinking.ZeroAllowed, info.Thinking.DynamicAllowed}
package util
import (
"github.com/router-for-me/CLIProxyAPI/v6/internal/registry"
)
// ModelSupportsThinking reports whether the given model has Thinking capability
// according to the model registry metadata (provider-agnostic).
func ModelSupportsThinking(model string) bool {
if model == "" {
return false
}
if info := registry.GetGlobalRegistry().GetModelInfo(model); info != nil {
return info.Thinking != nil
}
return false
}
// NormalizeThinkingBudget clamps the requested thinking budget to the
// supported range for the specified model using registry metadata only.
// If the model is unknown or has no Thinking metadata, returns the original budget.
// For dynamic (-1), returns -1 if DynamicAllowed; otherwise approximates mid-range
// or min (0 if zero is allowed and mid <= 0).
func NormalizeThinkingBudget(model string, budget int) int {
if budget == -1 { // dynamic
if found, min, max, zeroAllowed, dynamicAllowed := thinkingRangeFromRegistry(model); found {
if dynamicAllowed {
return -1
}
mid := (min + max) / 2
if mid <= 0 && zeroAllowed {
return 0
}
if mid <= 0 {
return min
}
return mid
}
return -1
}
if found, min, max, zeroAllowed, _ := thinkingRangeFromRegistry(model); found {
if budget == 0 {
if zeroAllowed {
return 0
}
return min
}
if budget < min {
return min
}
if budget > max {
return max
}
return budget
}
return budget
}
// thinkingRangeFromRegistry attempts to read thinking ranges from the model registry.
func thinkingRangeFromRegistry(model string) (found bool, min int, max int, zeroAllowed bool, dynamicAllowed bool) {
if model == "" {
return false, 0, 0, false, false
}
info := registry.GetGlobalRegistry().GetModelInfo(model)
if info == nil || info.Thinking == nil {
return false, 0, 0, false, false
}
return true, info.Thinking.Min, info.Thinking.Max, info.Thinking.ZeroAllowed, info.Thinking.DynamicAllowed
}