···
let unknown t = t.unknown
377
+
(* Custom jsont that handles both formats:
378
+
- Old format: {"type":"system","subtype":"init","data":{...}}
379
+
- New format: {"type":"system","subtype":"init","cwd":"...","session_id":"...",...}
380
+
When data field is not present, we use the entire object as data *)
378
-
Jsont.Object.map ~kind:"System" make
382
+
let make_with_optional_data subtype opt_data unknown_json =
383
+
let data = match opt_data with
385
+
| None -> unknown_json (* Use the full unknown object as data *)
387
+
make subtype data Unknown.empty
389
+
Jsont.Object.map ~kind:"System" make_with_optional_data
|> Jsont.Object.mem "subtype" Jsont.string ~enc:subtype
380
-
|> Jsont.Object.mem "data" Data.jsont ~enc:data
381
-
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:unknown
391
+
|> Jsont.Object.opt_mem "data" Data.jsont ~enc:(fun t -> Some (data t))
392
+
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun _ -> Unknown.empty)
···
Result (Result.create ~subtype ~duration_ms ~duration_api_ms ~is_error
~num_turns ~session_id ?total_cost_usd ?usage ?result ?structured_output ())
686
-
(* Jsont codec for the main Message variant type *)
687
-
let jsont : t Jsont.t =
688
-
let case_map kind obj dec = Jsont.Object.Case.map kind obj ~dec in
690
-
let case_user = case_map "user" User.jsont (fun v -> User v) in
691
-
let case_assistant = case_map "assistant" Assistant.jsont (fun v -> Assistant v) in
692
-
let case_system = case_map "system" System.jsont (fun v -> System v) in
693
-
let case_result = case_map "result" Result.jsont (fun v -> Result v) in
695
-
let enc_case = function
696
-
| User v -> Jsont.Object.Case.value case_user v
697
-
| Assistant v -> Jsont.Object.Case.value case_assistant v
698
-
| System v -> Jsont.Object.Case.value case_system v
699
-
| Result v -> Jsont.Object.Case.value case_result v
702
-
let cases = Jsont.Object.Case.[
704
-
make case_assistant;
709
-
Jsont.Object.map ~kind:"Message" Fun.id
710
-
|> Jsont.Object.case_mem "type" Jsont.string ~enc:Fun.id ~enc_case cases
711
-
~tag_to_string:Fun.id ~tag_compare:String.compare
712
-
|> Jsont.Object.finish
| User t -> User.to_json t
| Assistant t -> Assistant.to_json t
···
| None -> raise (Invalid_argument "Message.of_json: missing type field")
| _ -> raise (Invalid_argument "Message.of_json: expected object")
716
+
(* Jsont codec for the main Message variant type.
717
+
Uses a custom decoder to handle both old and new formats. *)
718
+
let jsont : t Jsont.t =
719
+
Jsont.map ~kind:"Message" ~dec:of_json ~enc:to_json Jsont.json
| User t -> User.pp fmt t