My agentic slop goes here. Not intended for anyone else!
1(** Messages exchanged with Claude.
2
3 This module defines the various types of messages that can be sent to and
4 received from Claude, including user input, assistant responses, system
5 messages, and result metadata. *)
6
7(** The log source for message operations *)
8val src : Logs.Src.t
9
10(** {1 User Messages} *)
11
12module User : sig
13 (** Messages sent by the user. *)
14
15 type content =
16 | String of string (** Simple text message *)
17 | Blocks of Content_block.t list (** Complex message with multiple content blocks *)
18 (** The content of a user message. *)
19
20 type t
21 (** The type of user messages. *)
22
23 val create_string : string -> t
24 (** [create_string s] creates a user message with simple text content. *)
25
26 val create_blocks : Content_block.t list -> t
27 (** [create_blocks blocks] creates a user message with content blocks. *)
28
29 val create_with_tool_result :
30 tool_use_id:string ->
31 content:string ->
32 ?is_error:bool ->
33 unit -> t
34 (** [create_with_tool_result ~tool_use_id ~content ?is_error ()] creates a user
35 message containing a tool result. *)
36
37 val create_mixed : text:string option -> tool_results:(string * string * bool option) list -> t
38 (** [create_mixed ?text ~tool_results] creates a user message with optional text
39 and tool results. Each tool result is (tool_use_id, content, is_error). *)
40
41 val content : t -> content
42 (** [content t] returns the content of the user message. *)
43
44 val as_text : t -> string option
45 (** [as_text t] returns the text content if the message is a simple string, None otherwise. *)
46
47 val get_blocks : t -> Content_block.t list
48 (** [get_blocks t] returns the content blocks, or a single text block if it's a string message. *)
49
50 val to_json : t -> Ezjsonm.value
51 (** [to_json t] converts the user message to its JSON representation. *)
52
53 val of_json : Ezjsonm.value -> t
54 (** [of_json json] parses a user message from JSON.
55 @raise Invalid_argument if the JSON is not a valid user message. *)
56
57 val pp : Format.formatter -> t -> unit
58 (** [pp fmt t] pretty-prints the user message. *)
59end
60
61(** {1 Assistant Messages} *)
62
63module Assistant : sig
64 (** Messages from Claude assistant. *)
65
66 type error = [
67 | `Authentication_failed (** Authentication with Claude API failed *)
68 | `Billing_error (** Billing or account issue *)
69 | `Rate_limit (** Rate limit exceeded *)
70 | `Invalid_request (** Request was invalid *)
71 | `Server_error (** Internal server error *)
72 | `Unknown (** Unknown error type *)
73 ]
74 (** The type of assistant message errors based on Python SDK error types. *)
75
76 val error_to_string : error -> string
77 (** [error_to_string err] converts an error to its string representation. *)
78
79 val error_of_string : string -> error
80 (** [error_of_string s] parses an error string. Unknown strings become [`Unknown]. *)
81
82 type t
83 (** The type of assistant messages. *)
84
85 val create : content:Content_block.t list -> model:string -> ?error:error -> unit -> t
86 (** [create ~content ~model ?error ()] creates an assistant message.
87 @param content List of content blocks in the response
88 @param model The model identifier used for the response
89 @param error Optional error that occurred during message generation *)
90
91 val content : t -> Content_block.t list
92 (** [content t] returns the content blocks of the assistant message. *)
93
94 val model : t -> string
95 (** [model t] returns the model identifier. *)
96
97 val error : t -> error option
98 (** [error t] returns the optional error that occurred during message generation. *)
99
100 val get_text_blocks : t -> string list
101 (** [get_text_blocks t] extracts all text content from the message. *)
102
103 val get_tool_uses : t -> Content_block.Tool_use.t list
104 (** [get_tool_uses t] extracts all tool use blocks from the message. *)
105
106 val get_thinking : t -> Content_block.Thinking.t list
107 (** [get_thinking t] extracts all thinking blocks from the message. *)
108
109 val has_tool_use : t -> bool
110 (** [has_tool_use t] returns true if the message contains any tool use blocks. *)
111
112 val combined_text : t -> string
113 (** [combined_text t] concatenates all text blocks into a single string. *)
114
115 val to_json : t -> Ezjsonm.value
116 (** [to_json t] converts the assistant message to its JSON representation. *)
117
118 val of_json : Ezjsonm.value -> t
119 (** [of_json json] parses an assistant message from JSON.
120 @raise Invalid_argument if the JSON is not a valid assistant message. *)
121
122 val pp : Format.formatter -> t -> unit
123 (** [pp fmt t] pretty-prints the assistant message. *)
124end
125
126(** {1 System Messages} *)
127
128module System : sig
129 (** System control and status messages. *)
130
131 module Data : sig
132 (** System message data. *)
133
134 type t
135 (** Abstract type for system message data. Contains both the raw JSON
136 and typed accessors for common fields. *)
137
138 val empty : t
139 (** [empty] creates empty data. *)
140
141 val of_assoc : (string * Ezjsonm.value) list -> t
142 (** [of_assoc assoc] creates data from an association list. *)
143
144 val get_string : t -> string -> string option
145 (** [get_string t key] returns the string value for [key], if present. *)
146
147 val get_int : t -> string -> int option
148 (** [get_int t key] returns the integer value for [key], if present. *)
149
150 val get_bool : t -> string -> bool option
151 (** [get_bool t key] returns the boolean value for [key], if present. *)
152
153 val get_float : t -> string -> float option
154 (** [get_float t key] returns the float value for [key], if present. *)
155
156 val get_list : t -> string -> Ezjsonm.value list option
157 (** [get_list t key] returns the list value for [key], if present. *)
158
159 val get_field : t -> string -> Ezjsonm.value option
160 (** [get_field t key] returns the raw JSON value for [key], if present. *)
161
162 val raw_json : t -> Ezjsonm.value
163 (** [raw_json t] returns the full underlying JSON data. *)
164
165 val to_json : t -> Ezjsonm.value
166 (** [to_json t] converts to JSON representation. Internal use only. *)
167
168 val of_json : Ezjsonm.value -> t
169 (** [of_json json] parses from JSON. Internal use only. *)
170 end
171
172 type t
173 (** The type of system messages. *)
174
175 val create : subtype:string -> data:Data.t -> t
176 (** [create ~subtype ~data] creates a system message.
177 @param subtype The subtype of the system message
178 @param data Additional data for the message *)
179
180 val subtype : t -> string
181 (** [subtype t] returns the subtype of the system message. *)
182
183 val data : t -> Data.t
184 (** [data t] returns the additional data of the system message. *)
185
186 val to_json : t -> Ezjsonm.value
187 (** [to_json t] converts the system message to its JSON representation. *)
188
189 val of_json : Ezjsonm.value -> t
190 (** [of_json json] parses a system message from JSON.
191 @raise Invalid_argument if the JSON is not a valid system message. *)
192
193 val pp : Format.formatter -> t -> unit
194 (** [pp fmt t] pretty-prints the system message. *)
195end
196
197(** {1 Result Messages} *)
198
199module Result : sig
200 (** Final result messages with metadata about the conversation. *)
201
202 module Usage : sig
203 (** Usage statistics for API calls. *)
204
205 type t
206 (** Abstract type for usage statistics. *)
207
208 val create :
209 ?input_tokens:int ->
210 ?output_tokens:int ->
211 ?total_tokens:int ->
212 ?cache_creation_input_tokens:int ->
213 ?cache_read_input_tokens:int ->
214 unit -> t
215 (** [create ?input_tokens ?output_tokens ?total_tokens ?cache_creation_input_tokens
216 ?cache_read_input_tokens ()] creates usage statistics. *)
217
218 val input_tokens : t -> int option
219 (** [input_tokens t] returns the number of input tokens used. *)
220
221 val output_tokens : t -> int option
222 (** [output_tokens t] returns the number of output tokens generated. *)
223
224 val total_tokens : t -> int option
225 (** [total_tokens t] returns the total number of tokens. *)
226
227 val cache_creation_input_tokens : t -> int option
228 (** [cache_creation_input_tokens t] returns cache creation input tokens. *)
229
230 val cache_read_input_tokens : t -> int option
231 (** [cache_read_input_tokens t] returns cache read input tokens. *)
232
233 val effective_input_tokens : t -> int
234 (** [effective_input_tokens t] returns input tokens minus cached tokens, or 0 if not available. *)
235
236 val total_cost_estimate : t -> input_price:float -> output_price:float -> float option
237 (** [total_cost_estimate t ~input_price ~output_price] estimates the cost based on token
238 prices per million tokens. Returns None if token counts are not available. *)
239
240 val pp : Format.formatter -> t -> unit
241 (** [pp fmt t] pretty-prints the usage statistics. *)
242
243 val to_json : t -> Ezjsonm.value
244 (** [to_json t] converts to JSON representation. Internal use only. *)
245
246 val of_json : Ezjsonm.value -> t
247 (** [of_json json] parses from JSON. Internal use only. *)
248 end
249
250 type t
251 (** The type of result messages. *)
252
253 val create :
254 subtype:string ->
255 duration_ms:int ->
256 duration_api_ms:int ->
257 is_error:bool ->
258 num_turns:int ->
259 session_id:string ->
260 ?total_cost_usd:float ->
261 ?usage:Usage.t ->
262 ?result:string ->
263 ?structured_output:Ezjsonm.value ->
264 unit -> t
265 (** [create ~subtype ~duration_ms ~duration_api_ms ~is_error ~num_turns
266 ~session_id ?total_cost_usd ?usage ?result ()] creates a result message.
267 @param subtype The subtype of the result
268 @param duration_ms Total duration in milliseconds
269 @param duration_api_ms API duration in milliseconds
270 @param is_error Whether the result represents an error
271 @param num_turns Number of conversation turns
272 @param session_id Unique session identifier
273 @param total_cost_usd Optional total cost in USD
274 @param usage Optional usage statistics as JSON
275 @param result Optional result string
276 @param structured_output Optional structured JSON output from Claude *)
277
278 val subtype : t -> string
279 (** [subtype t] returns the subtype of the result. *)
280
281 val duration_ms : t -> int
282 (** [duration_ms t] returns the total duration in milliseconds. *)
283
284 val duration_api_ms : t -> int
285 (** [duration_api_ms t] returns the API duration in milliseconds. *)
286
287 val is_error : t -> bool
288 (** [is_error t] returns whether this result represents an error. *)
289
290 val num_turns : t -> int
291 (** [num_turns t] returns the number of conversation turns. *)
292
293 val session_id : t -> string
294 (** [session_id t] returns the session identifier. *)
295
296 val total_cost_usd : t -> float option
297 (** [total_cost_usd t] returns the optional total cost in USD. *)
298
299 val usage : t -> Usage.t option
300 (** [usage t] returns the optional usage statistics. *)
301
302 val result : t -> string option
303 (** [result t] returns the optional result string. *)
304
305 val structured_output : t -> Ezjsonm.value option
306 (** [structured_output t] returns the optional structured JSON output. *)
307
308 val to_json : t -> Ezjsonm.value
309 (** [to_json t] converts the result message to its JSON representation. *)
310
311 val of_json : Ezjsonm.value -> t
312 (** [of_json json] parses a result message from JSON.
313 @raise Invalid_argument if the JSON is not a valid result message. *)
314
315 val pp : Format.formatter -> t -> unit
316 (** [pp fmt t] pretty-prints the result message. *)
317end
318
319(** {1 Message Union Type} *)
320
321type t =
322 | User of User.t
323 | Assistant of Assistant.t
324 | System of System.t
325 | Result of Result.t
326(** The type of messages, which can be user, assistant, system, or result. *)
327
328val user_string : string -> t
329(** [user_string s] creates a user message with text content. *)
330
331val user_blocks : Content_block.t list -> t
332(** [user_blocks blocks] creates a user message with content blocks. *)
333
334val user_with_tool_result : tool_use_id:string -> content:string -> ?is_error:bool -> unit -> t
335(** [user_with_tool_result ~tool_use_id ~content ?is_error ()] creates a user message
336 containing a tool result. *)
337
338val assistant : content:Content_block.t list -> model:string -> ?error:Assistant.error -> unit -> t
339(** [assistant ~content ~model ?error ()] creates an assistant message. *)
340
341val assistant_text : text:string -> model:string -> ?error:Assistant.error -> unit -> t
342(** [assistant_text ~text ~model ?error ()] creates an assistant message with only text content. *)
343
344val system : subtype:string -> data:System.Data.t -> t
345(** [system ~subtype ~data] creates a system message. *)
346
347val system_init : session_id:string -> t
348(** [system_init ~session_id] creates a system init message. *)
349
350val system_error : error:string -> t
351(** [system_error ~error] creates a system error message. *)
352
353val result :
354 subtype:string ->
355 duration_ms:int ->
356 duration_api_ms:int ->
357 is_error:bool ->
358 num_turns:int ->
359 session_id:string ->
360 ?total_cost_usd:float ->
361 ?usage:Result.Usage.t ->
362 ?result:string ->
363 ?structured_output:Ezjsonm.value ->
364 unit -> t
365(** [result ~subtype ~duration_ms ~duration_api_ms ~is_error ~num_turns
366 ~session_id ?total_cost_usd ?usage ?result ()] creates a result message. *)
367
368val to_json : t -> Ezjsonm.value
369(** [to_json t] converts any message to its JSON representation. *)
370
371val of_json : Ezjsonm.value -> t
372(** [of_json json] parses a message from JSON.
373 @raise Invalid_argument if the JSON is not a valid message. *)
374
375val pp : Format.formatter -> t -> unit
376(** [pp fmt t] pretty-prints any message. *)
377
378(** {1 Message Analysis} *)
379
380val is_user : t -> bool
381(** [is_user t] returns true if the message is from a user. *)
382
383val is_assistant : t -> bool
384(** [is_assistant t] returns true if the message is from the assistant. *)
385
386val is_system : t -> bool
387(** [is_system t] returns true if the message is a system message. *)
388
389val is_result : t -> bool
390(** [is_result t] returns true if the message is a result message. *)
391
392val is_error : t -> bool
393(** [is_error t] returns true if the message represents an error. *)
394
395val extract_text : t -> string option
396(** [extract_text t] attempts to extract text content from any message type. *)
397
398val extract_tool_uses : t -> Content_block.Tool_use.t list
399(** [extract_tool_uses t] extracts tool use blocks from assistant messages. *)
400
401val get_session_id : t -> string option
402(** [get_session_id t] extracts the session ID from system or result messages. *)
403
404(** {1 Logging} *)
405
406val log_received : t -> unit
407(** [log_received t] logs that a message was received. *)
408
409val log_sending : t -> unit
410(** [log_sending t] logs that a message is being sent. *)
411
412val log_error : string -> t -> unit
413(** [log_error msg t] logs an error with the given message and context. *)
414