Changeset 0.22.0.1 (#94)

This commit is contained in:
2026-03-02 01:55:19 +00:00
parent 12e03cec8b
commit 06c4e2a5a1
33 changed files with 1929 additions and 418 deletions

View File

@@ -111,14 +111,16 @@ func InferCapabilities(modelID string) models.ModelCapabilities {
}
// ResolveIntrinsic determines the intrinsic capabilities of a model.
// Priority:
// 1. catalogCaps (from model_catalog DB — synced from provider API)
// 2. Heuristic inference (regex patterns on model ID)
// Priority (highest wins):
// 1. Admin overrides (manual corrections from capability_overrides table)
// 2. Catalog (from model_catalog DB — synced from provider API)
// 3. Heuristic inference (regex patterns on model ID)
//
// The catalog is the source of truth per provider. Heuristics fill gaps
// for models that haven't been synced yet. No hardcoded model table —
// for models that haven't been synced yet. Admin overrides correct
// provider-reported or heuristic errors. No hardcoded model table —
// the same model can have different capabilities on different providers.
func ResolveIntrinsic(modelID string, catalogCaps *models.ModelCapabilities) models.ModelCapabilities {
func ResolveIntrinsic(modelID string, catalogCaps *models.ModelCapabilities, overrides []models.CapabilityOverride) models.ModelCapabilities {
// Start with catalog data if available
var base models.ModelCapabilities
if catalogCaps != nil && catalogCaps.HasProviderData() {
@@ -128,9 +130,56 @@ func ResolveIntrinsic(modelID string, catalogCaps *models.ModelCapabilities) mod
// Fill gaps from heuristic inference
inferred := InferCapabilities(modelID)
mergeGaps(&base, &inferred)
// Apply admin overrides (highest priority — can flip any field)
applyOverrides(&base, overrides)
return base
}
// applyOverrides applies admin capability corrections to the resolved capabilities.
func applyOverrides(caps *models.ModelCapabilities, overrides []models.CapabilityOverride) {
for _, o := range overrides {
boolVal := o.Value == "true" || o.Value == "1"
switch o.Field {
case "streaming":
caps.Streaming = boolVal
case "tool_calling":
caps.ToolCalling = boolVal
case "vision":
caps.Vision = boolVal
case "thinking":
caps.Thinking = boolVal
case "reasoning":
caps.Reasoning = boolVal
case "code_optimized":
caps.CodeOptimized = boolVal
case "web_search":
caps.WebSearch = boolVal
case "max_context":
if n := parseInt(o.Value); n > 0 {
caps.MaxContext = n
}
case "max_output_tokens":
if n := parseInt(o.Value); n > 0 {
caps.MaxOutputTokens = n
}
}
}
}
// parseInt parses a string to int, returning 0 on failure.
func parseInt(s string) int {
n := 0
for _, c := range s {
if c < '0' || c > '9' {
return 0
}
n = n*10 + int(c-'0')
}
return n
}
// ResolveMaxOutput returns the max output tokens for a model.
// Priority: explicit caps → derive from context → 4096 fallback.
func ResolveMaxOutput(modelID string, caps models.ModelCapabilities) int {