My agentic slop goes here. Not intended for anyone else!
1open Ezjsonm
2
3let src = Logs.Src.create "claude.options" ~doc:"Claude configuration options"
4module Log = (val Logs.src_log src : Logs.LOG)
5
6type setting_source = User | Project | Local
7
8type t = {
9 allowed_tools : string list;
10 disallowed_tools : string list;
11 max_thinking_tokens : int;
12 system_prompt : string option;
13 append_system_prompt : string option;
14 permission_mode : Permissions.Mode.t option;
15 permission_callback : Permissions.callback option;
16 model : Model.t option;
17 cwd : Eio.Fs.dir_ty Eio.Path.t option;
18 env : (string * string) list;
19 continue_conversation : bool;
20 resume : string option;
21 max_turns : int option;
22 permission_prompt_tool_name : string option;
23 settings : string option;
24 add_dirs : string list;
25 extra_args : (string * string option) list;
26 debug_stderr : Eio.Flow.sink_ty Eio.Flow.sink option;
27 hooks : Hooks.config option;
28 max_budget_usd : float option;
29 fallback_model : Model.t option;
30 setting_sources : setting_source list option;
31 max_buffer_size : int option;
32 user : string option;
33 output_format : Structured_output.t option;
34}
35
36let default = {
37 allowed_tools = [];
38 disallowed_tools = [];
39 max_thinking_tokens = 8000;
40 system_prompt = None;
41 append_system_prompt = None;
42 permission_mode = None;
43 permission_callback = Some Permissions.default_allow_callback;
44 model = None;
45 cwd = None;
46 env = [];
47 continue_conversation = false;
48 resume = None;
49 max_turns = None;
50 permission_prompt_tool_name = None;
51 settings = None;
52 add_dirs = [];
53 extra_args = [];
54 debug_stderr = None;
55 hooks = None;
56 max_budget_usd = None;
57 fallback_model = None;
58 setting_sources = None;
59 max_buffer_size = None;
60 user = None;
61 output_format = None;
62}
63
64let create
65 ?(allowed_tools = [])
66 ?(disallowed_tools = [])
67 ?(max_thinking_tokens = 8000)
68 ?system_prompt
69 ?append_system_prompt
70 ?permission_mode
71 ?permission_callback
72 ?model
73 ?cwd
74 ?(env = [])
75 ?(continue_conversation = false)
76 ?resume
77 ?max_turns
78 ?permission_prompt_tool_name
79 ?settings
80 ?(add_dirs = [])
81 ?(extra_args = [])
82 ?debug_stderr
83 ?hooks
84 ?max_budget_usd
85 ?fallback_model
86 ?setting_sources
87 ?max_buffer_size
88 ?user
89 ?output_format
90 () =
91 { allowed_tools; disallowed_tools; max_thinking_tokens;
92 system_prompt; append_system_prompt; permission_mode;
93 permission_callback; model; cwd; env;
94 continue_conversation; resume; max_turns;
95 permission_prompt_tool_name; settings; add_dirs;
96 extra_args; debug_stderr; hooks;
97 max_budget_usd; fallback_model; setting_sources;
98 max_buffer_size; user; output_format }
99
100let allowed_tools t = t.allowed_tools
101let disallowed_tools t = t.disallowed_tools
102let max_thinking_tokens t = t.max_thinking_tokens
103let system_prompt t = t.system_prompt
104let append_system_prompt t = t.append_system_prompt
105let permission_mode t = t.permission_mode
106let permission_callback t = t.permission_callback
107let model t = t.model
108let cwd t = t.cwd
109let env t = t.env
110let continue_conversation t = t.continue_conversation
111let resume t = t.resume
112let max_turns t = t.max_turns
113let permission_prompt_tool_name t = t.permission_prompt_tool_name
114let settings t = t.settings
115let add_dirs t = t.add_dirs
116let extra_args t = t.extra_args
117let debug_stderr t = t.debug_stderr
118let hooks t = t.hooks
119let max_budget_usd t = t.max_budget_usd
120let fallback_model t = t.fallback_model
121let setting_sources t = t.setting_sources
122let max_buffer_size t = t.max_buffer_size
123let user t = t.user
124let output_format t = t.output_format
125
126let with_allowed_tools tools t = { t with allowed_tools = tools }
127let with_disallowed_tools tools t = { t with disallowed_tools = tools }
128let with_max_thinking_tokens tokens t = { t with max_thinking_tokens = tokens }
129let with_system_prompt prompt t = { t with system_prompt = Some prompt }
130let with_append_system_prompt prompt t = { t with append_system_prompt = Some prompt }
131let with_permission_mode mode t = { t with permission_mode = Some mode }
132let with_permission_callback callback t = { t with permission_callback = Some callback }
133let with_model model t = { t with model = Some model }
134let with_model_string model t = { t with model = Some (Model.of_string model) }
135let with_cwd cwd t = { t with cwd = Some cwd }
136let with_env env t = { t with env }
137let with_continue_conversation continue t = { t with continue_conversation = continue }
138let with_resume session_id t = { t with resume = Some session_id }
139let with_max_turns turns t = { t with max_turns = Some turns }
140let with_permission_prompt_tool_name tool t = { t with permission_prompt_tool_name = Some tool }
141let with_settings path t = { t with settings = Some path }
142let with_add_dirs dirs t = { t with add_dirs = dirs }
143let with_extra_args args t = { t with extra_args = args }
144let with_debug_stderr sink t = { t with debug_stderr = Some sink }
145let with_hooks hooks t = { t with hooks = Some hooks }
146let with_max_budget_usd budget t = { t with max_budget_usd = Some budget }
147let with_fallback_model model t = { t with fallback_model = Some model }
148let with_fallback_model_string model t = { t with fallback_model = Some (Model.of_string model) }
149let with_setting_sources sources t = { t with setting_sources = Some sources }
150let with_no_settings t = { t with setting_sources = Some [] }
151let with_max_buffer_size size t = { t with max_buffer_size = Some size }
152let with_user user t = { t with user = Some user }
153let with_output_format format t = { t with output_format = Some format }
154
155let to_json t =
156 let fields = [] in
157 let fields =
158 if t.allowed_tools <> [] then
159 ("allowed_tools", `A (List.map (fun s -> `String s) t.allowed_tools)) :: fields
160 else fields
161 in
162 let fields =
163 if t.disallowed_tools <> [] then
164 ("disallowed_tools", `A (List.map (fun s -> `String s) t.disallowed_tools)) :: fields
165 else fields
166 in
167 let fields =
168 if t.max_thinking_tokens <> 8000 then
169 ("max_thinking_tokens", `Float (float_of_int t.max_thinking_tokens)) :: fields
170 else fields
171 in
172 let fields = match t.system_prompt with
173 | Some p -> ("system_prompt", `String p) :: fields
174 | None -> fields
175 in
176 let fields = match t.append_system_prompt with
177 | Some p -> ("append_system_prompt", `String p) :: fields
178 | None -> fields
179 in
180 let fields = match t.permission_mode with
181 | Some m -> ("permission_mode", Permissions.Mode.to_json m) :: fields
182 | None -> fields
183 in
184 let fields = match t.model with
185 | Some m -> ("model", `String (Model.to_string m)) :: fields
186 | None -> fields
187 in
188 let fields =
189 if t.env <> [] then
190 let env_obj = `O (List.map (fun (k, v) -> (k, `String v)) t.env) in
191 ("env", env_obj) :: fields
192 else fields
193 in
194 `O fields
195
196let of_json = function
197 | `O fields ->
198 let allowed_tools =
199 try get_list get_string (List.assoc "allowed_tools" fields)
200 with Not_found -> []
201 in
202 let disallowed_tools =
203 try get_list get_string (List.assoc "disallowed_tools" fields)
204 with Not_found -> []
205 in
206 let max_thinking_tokens =
207 try int_of_float (get_float (List.assoc "max_thinking_tokens" fields))
208 with Not_found -> 8000
209 in
210 let system_prompt =
211 try Some (get_string (List.assoc "system_prompt" fields))
212 with Not_found -> None
213 in
214 let append_system_prompt =
215 try Some (get_string (List.assoc "append_system_prompt" fields))
216 with Not_found -> None
217 in
218 let permission_mode =
219 try Some (Permissions.Mode.of_json (List.assoc "permission_mode" fields))
220 with Not_found -> None
221 in
222 let model =
223 try Some (Model.of_string (get_string (List.assoc "model" fields)))
224 with Not_found -> None
225 in
226 let env =
227 try
228 match List.assoc "env" fields with
229 | `O pairs -> List.map (fun (k, v) -> (k, get_string v)) pairs
230 | _ -> []
231 with Not_found -> []
232 in
233 { allowed_tools; disallowed_tools; max_thinking_tokens;
234 system_prompt; append_system_prompt; permission_mode;
235 permission_callback = Some Permissions.default_allow_callback;
236 model; cwd = None; env;
237 continue_conversation = false;
238 resume = None;
239 max_turns = None;
240 permission_prompt_tool_name = None;
241 settings = None;
242 add_dirs = [];
243 extra_args = [];
244 debug_stderr = None;
245 hooks = None;
246 max_budget_usd = None;
247 fallback_model = None;
248 setting_sources = None;
249 max_buffer_size = None;
250 user = None;
251 output_format = None; }
252 | _ -> raise (Invalid_argument "Options.of_json: expected object")
253
254let pp fmt t =
255 Fmt.pf fmt "@[<v>Options {@ \
256 allowed_tools = %a;@ \
257 disallowed_tools = %a;@ \
258 max_thinking_tokens = %d;@ \
259 system_prompt = %a;@ \
260 append_system_prompt = %a;@ \
261 permission_mode = %a;@ \
262 model = %a;@ \
263 env = %a@ \
264 }@]"
265 Fmt.(list string) t.allowed_tools
266 Fmt.(list string) t.disallowed_tools
267 t.max_thinking_tokens
268 Fmt.(option string) t.system_prompt
269 Fmt.(option string) t.append_system_prompt
270 Fmt.(option Permissions.Mode.pp) t.permission_mode
271 Fmt.(option Model.pp) t.model
272 Fmt.(list (pair string string)) t.env
273
274let log_options t =
275 Log.debug (fun m -> m "Claude options: %a" pp t)