package claude import ( "strings" "unicode" ) var ( effortLowMediumHigh = []string{"low", "medium", "high"} effortLowMediumHighMax = []string{"low", "medium", "high", "max"} effortLowMediumHighXHighMax = []string{"low", "medium", "high", "xhigh", "max"} ) var effortFamilies = []struct { family string levels []string }{ {family: "claude-mythos-preview", levels: effortLowMediumHighMax}, {family: "claude-mythos-5", levels: effortLowMediumHighXHighMax}, {family: "claude-fable-5", levels: effortLowMediumHighXHighMax}, {family: "claude-sonnet-4-6", levels: effortLowMediumHighMax}, {family: "claude-sonnet-5", levels: effortLowMediumHighXHighMax}, {family: "claude-opus-4-8", levels: effortLowMediumHighXHighMax}, {family: "claude-opus-4-7", levels: effortLowMediumHighXHighMax}, {family: "claude-opus-4-6", levels: effortLowMediumHighMax}, {family: "claude-opus-4-5", levels: effortLowMediumHigh}, {family: "claude-opus-5", levels: effortLowMediumHighXHighMax}, } // EffortLevelsForModel returns the output_config.effort values accepted by a // Claude model, ordered from the lightest to the deepest reasoning level. func EffortLevelsForModel(model string) []string { id := normalizeEffortModelID(model) for _, entry := range effortFamilies { if id == entry.family || strings.HasPrefix(id, entry.family+"-") { return append([]string(nil), entry.levels...) } } return nil } func normalizeEffortModelID(model string) string { id := strings.ToLower(strings.TrimSpace(model)) id = strings.TrimPrefix(id, "models/") if slash := strings.IndexByte(id, '/'); slash >= 0 { id = strings.TrimPrefix(strings.TrimSpace(id[slash+1:]), "models/") } id = strings.TrimPrefix(id, "anthropic.") id = strings.TrimSuffix(id, "-thinking") if mapped, ok := ModelIDReverseOverrides[id]; ok { id = mapped } if len(id) >= 9 { suffix := id[len(id)-9:] if suffix[0] == '-' { digits := true for _, r := range suffix[1:] { if !unicode.IsDigit(r) { digits = false break } } if digits { id = id[:len(id)-9] } } } return id }