1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
type model_preset = Fast | Cheap | Best | Balanced | Reasoning
type reasoning = Off | Low | Medium | High
type creativity = Precise | Balanced_creativity | Creative | Wild
type reasoning_config = {
openai_effort : string;
anthropic_budget_tokens : int option;
xai_prefer_reasoning_model : bool;
}
open Chatoyant_provider.Provider
let model_preset_of_string = function
| "fast" -> Some Fast
| "cheap" -> Some Cheap
| "best" -> Some Best
| "balanced" -> Some Balanced
| "reasoning" -> Some Reasoning
| _ -> None
let string_of_model_preset = function
| Fast -> "fast"
| Cheap -> "cheap"
| Best -> "best"
| Balanced -> "balanced"
| Reasoning -> "reasoning"
let resolve_model_preset ~provider preset =
match (preset, provider) with
| Fast, Openai -> Some "gpt-4o-mini"
| Fast, Anthropic -> Some "claude-haiku-4-5"
| Fast, Xai -> Some "grok-4-1-fast-non-reasoning"
| Cheap, Openai -> Some "gpt-5.4-mini"
| Cheap, Anthropic -> Some "claude-haiku-4-5"
| Cheap, Xai -> Some "grok-4-1-fast-non-reasoning"
| Best, Openai -> Some "gpt-5.4"
| Best, Anthropic -> Some "claude-opus-4-6"
| Best, Xai -> Some "grok-4.20-0309-reasoning"
| Balanced, Openai -> Some "gpt-5.4-mini"
| Balanced, Anthropic -> Some "claude-sonnet-4-6"
| Balanced, Xai -> Some "grok-4-1-fast-reasoning"
| Reasoning, Openai -> Some "gpt-5.4-pro"
| Reasoning, Anthropic -> Some "claude-opus-4-6"
| Reasoning, Xai -> Some "grok-4.20-0309-reasoning"
| _, (Local | Openrouter) -> None
let temperature_of_creativity = function
| Precise -> 0.0
| Balanced_creativity -> 0.7
| Creative -> 1.0
| Wild -> 1.5
let reasoning_config = function
| Off ->
{
openai_effort = "none";
anthropic_budget_tokens = None;
xai_prefer_reasoning_model = false;
}
| Low ->
{
openai_effort = "low";
anthropic_budget_tokens = Some 2_048;
xai_prefer_reasoning_model = false;
}
| Medium ->
{
openai_effort = "medium";
anthropic_budget_tokens = Some 8_192;
xai_prefer_reasoning_model = true;
}
| High ->
{
openai_effort = "high";
anthropic_budget_tokens = Some 32_768;
xai_prefer_reasoning_model = true;
}
let starts_with ~prefix value =
let prefix_len = String.length prefix in
String.length value >= prefix_len && String.sub value 0 prefix_len = prefix
let supports_openai_reasoning model =
List.exists
(fun prefix -> starts_with ~prefix model)
[ "gpt-5"; "o1"; "o3"; "o4" ]
let adjust_xai_model_for_reasoning ~prefer_reasoning model =
match (model, prefer_reasoning) with
| "grok-4.20-0309-reasoning", false -> "grok-4.20-0309-non-reasoning"
| "grok-4.20-0309-non-reasoning", true -> "grok-4.20-0309-reasoning"
| "grok-4-1-fast-reasoning", false -> "grok-4-1-fast-non-reasoning"
| "grok-4-1-fast-non-reasoning", true -> "grok-4-1-fast-reasoning"
| "grok-4-fast-reasoning", false -> "grok-4-fast-non-reasoning"
| "grok-4-fast-non-reasoning", true -> "grok-4-fast-reasoning"
| _ -> model