···
3
+
(* Utility functions for JSON parsing *)
5
+
(* Extract a string field from JSON object or raise an error *)
6
+
let get_string_field fields name json =
7
+
match List.assoc_opt name fields with
8
+
| Some (`String s) -> s
9
+
| _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json))
11
+
(* Extract an optional string field from JSON object *)
12
+
let get_optional_string_field fields name =
13
+
List.assoc_opt name fields |> Option.map (function
15
+
| j -> raise (Json.Of_json (Printf.sprintf "Expected string for %s" name, j))
18
+
(* Extract an int field from JSON object or raise an error *)
19
+
let get_int_field fields name json =
20
+
match List.assoc_opt name fields with
21
+
| Some (`Int i) -> i
22
+
| _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json))
24
+
(* Extract a float field from JSON object or raise an error *)
25
+
let get_float_field fields name json =
26
+
match List.assoc_opt name fields with
27
+
| Some (`Float f) -> f
28
+
| _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json))
30
+
(* Extract a boolean field from JSON object or raise an error *)
31
+
let get_bool_field fields name json =
32
+
match List.assoc_opt name fields with
33
+
| Some (`Bool b) -> b
34
+
| _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json))
36
+
(* Extract an object field from JSON object or raise an error *)
37
+
let get_object_field fields name json =
38
+
match List.assoc_opt name fields with
39
+
| Some (`Assoc obj) -> obj
40
+
| _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json))
42
+
(* Extract a list field from JSON object or raise an error *)
43
+
let get_list_field fields name json =
44
+
match List.assoc_opt name fields with
45
+
| Some (`List items) -> items
46
+
| _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json))
48
+
(* Verify a specific string value in a field *)
49
+
let verify_string_field fields name expected_value json =
50
+
match List.assoc_opt name fields with
51
+
| Some (`String s) when s = expected_value -> ()
52
+
| _ -> raise (Json.Of_json (Printf.sprintf "Field '%s' missing or not equal to '%s'" name expected_value, json))
(* Error codes for JSON-RPC *)
module ErrorCode = struct
···
let t_of_yojson = function
211
-
let text = match List.assoc_opt "text" fields with
212
-
| Some (`String s) -> s
213
-
| _ -> raise (Json.Of_json ("Missing or invalid 'text' field", `Assoc fields))
215
-
let _ = match List.assoc_opt "type" fields with
216
-
| Some (`String "text") -> ()
217
-
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
262
+
| `Assoc fields as json ->
263
+
let text = Util.get_string_field fields "text" json in
264
+
Util.verify_string_field fields "type" "text" json;
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
| j -> raise (Json.Of_json ("Expected object for TextContent", j))
···
let t_of_yojson = function
245
-
let data = match List.assoc_opt "data" fields with
246
-
| Some (`String s) -> s
247
-
| _ -> raise (Json.Of_json ("Missing or invalid 'data' field", `Assoc fields))
249
-
let mime_type = match List.assoc_opt "mimeType" fields with
250
-
| Some (`String s) -> s
251
-
| _ -> raise (Json.Of_json ("Missing or invalid 'mimeType' field", `Assoc fields))
253
-
let _ = match List.assoc_opt "type" fields with
254
-
| Some (`String "image") -> ()
255
-
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
290
+
| `Assoc fields as json ->
291
+
let data = Util.get_string_field fields "data" json in
292
+
let mime_type = Util.get_string_field fields "mimeType" json in
293
+
Util.verify_string_field fields "type" "image" json;
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
{ data; mime_type; annotations }
| j -> raise (Json.Of_json ("Expected object for ImageContent", j))
···
let t_of_yojson = function
283
-
let data = match List.assoc_opt "data" fields with
284
-
| Some (`String s) -> s
285
-
| _ -> raise (Json.Of_json ("Missing or invalid 'data' field", `Assoc fields))
287
-
let mime_type = match List.assoc_opt "mimeType" fields with
288
-
| Some (`String s) -> s
289
-
| _ -> raise (Json.Of_json ("Missing or invalid 'mimeType' field", `Assoc fields))
291
-
let _ = match List.assoc_opt "type" fields with
292
-
| Some (`String "audio") -> ()
293
-
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
319
+
| `Assoc fields as json ->
320
+
let data = Util.get_string_field fields "data" json in
321
+
let mime_type = Util.get_string_field fields "mimeType" json in
322
+
Util.verify_string_field fields "type" "audio" json;
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
{ data; mime_type; annotations }
| j -> raise (Json.Of_json ("Expected object for AudioContent", j))
···
let t_of_yojson = function
318
-
let uri = match List.assoc_opt "uri" fields with
319
-
| Some (`String s) -> s
320
-
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
322
-
let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
324
-
| j -> raise (Json.Of_json ("Expected string for mimeType", j))
345
+
| `Assoc fields as json ->
346
+
let uri = Util.get_string_field fields "uri" json in
347
+
let mime_type = Util.get_optional_string_field fields "mimeType" in
| j -> raise (Json.Of_json ("Expected object for ResourceContents", j))
···
let t_of_yojson = function
350
-
let uri = match List.assoc_opt "uri" fields with
351
-
| Some (`String s) -> s
352
-
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
354
-
let text = match List.assoc_opt "text" fields with
355
-
| Some (`String s) -> s
356
-
| _ -> raise (Json.Of_json ("Missing or invalid 'text' field", `Assoc fields))
358
-
let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
360
-
| j -> raise (Json.Of_json ("Expected string for mimeType", j))
371
+
| `Assoc fields as json ->
372
+
let uri = Util.get_string_field fields "uri" json in
373
+
let text = Util.get_string_field fields "text" json in
374
+
let mime_type = Util.get_optional_string_field fields "mimeType" in
| j -> raise (Json.Of_json ("Expected object for TextResourceContents", j))
···
let t_of_yojson = function
386
-
let uri = match List.assoc_opt "uri" fields with
387
-
| Some (`String s) -> s
388
-
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
390
-
let blob = match List.assoc_opt "blob" fields with
391
-
| Some (`String s) -> s
392
-
| _ -> raise (Json.Of_json ("Missing or invalid 'blob' field", `Assoc fields))
394
-
let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
396
-
| j -> raise (Json.Of_json ("Expected string for mimeType", j))
398
+
| `Assoc fields as json ->
399
+
let uri = Util.get_string_field fields "uri" json in
400
+
let blob = Util.get_string_field fields "blob" json in
401
+
let mime_type = Util.get_optional_string_field fields "mimeType" in
| j -> raise (Json.Of_json ("Expected object for BlobResourceContents", j))
···
let t_of_yojson = function
425
-
let _ = match List.assoc_opt "type" fields with
426
-
| Some (`String "resource") -> ()
427
-
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
428
+
| `Assoc fields as json ->
429
+
Util.verify_string_field fields "type" "resource" json;
430
+
let resource_fields = match List.assoc_opt "resource" fields with
431
+
| Some (`Assoc res_fields) -> res_fields
432
+
| _ -> raise (Json.Of_json ("Missing or invalid 'resource' field", json))
429
-
let resource = match List.assoc_opt "resource" fields with
430
-
| Some (`Assoc res_fields) ->
431
-
if List.mem_assoc "text" res_fields then
432
-
`Text (TextResourceContents.t_of_yojson (`Assoc res_fields))
433
-
else if List.mem_assoc "blob" res_fields then
434
-
`Blob (BlobResourceContents.t_of_yojson (`Assoc res_fields))
436
-
raise (Json.Of_json ("Invalid resource content", `Assoc res_fields))
437
-
| _ -> raise (Json.Of_json ("Missing or invalid 'resource' field", `Assoc fields))
435
+
if List.mem_assoc "text" resource_fields then
436
+
`Text (TextResourceContents.t_of_yojson (`Assoc resource_fields))
437
+
else if List.mem_assoc "blob" resource_fields then
438
+
`Blob (BlobResourceContents.t_of_yojson (`Assoc resource_fields))
440
+
raise (Json.Of_json ("Invalid resource content", `Assoc resource_fields))
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
{ resource; annotations }
···
let t_of_yojson = function
484
+
| `Assoc fields as json ->
let role = match List.assoc_opt "role" fields with
| Some json -> Role.t_of_yojson json
484
-
| None -> raise (Json.Of_json ("Missing role field", `Assoc fields))
487
+
| None -> raise (Json.Of_json ("Missing role field", json))
let content = match List.assoc_opt "content" fields with
| Some json -> content_of_yojson json
488
-
| None -> raise (Json.Of_json ("Missing content field", `Assoc fields))
491
+
| None -> raise (Json.Of_json ("Missing content field", json))
| j -> raise (Json.Of_json ("Expected object for PromptMessage", j))
···
let t_of_yojson = function
515
+
| `Assoc fields as json ->
let role = match List.assoc_opt "role" fields with
| Some json -> Role.t_of_yojson json
515
-
| None -> raise (Json.Of_json ("Missing role field", `Assoc fields))
518
+
| None -> raise (Json.Of_json ("Missing role field", json))
517
-
let content = match List.assoc_opt "content" fields with
518
-
| Some (`Assoc content_fields) ->
519
-
(match List.assoc_opt "type" content_fields with
520
-
| Some (`String "text") -> `Text (TextContent.t_of_yojson (`Assoc content_fields))
521
-
| Some (`String "image") -> `Image (ImageContent.t_of_yojson (`Assoc content_fields))
522
-
| Some (`String "audio") -> `Audio (AudioContent.t_of_yojson (`Assoc content_fields))
523
-
| _ -> raise (Json.Of_json ("Invalid content type", `Assoc content_fields)))
524
-
| _ -> raise (Json.Of_json ("Missing or invalid content field", `Assoc fields))
520
+
let content_obj = match List.assoc_opt "content" fields with
521
+
| Some (`Assoc content_fields) -> content_fields
522
+
| _ -> raise (Json.Of_json ("Missing or invalid content field", json))
524
+
let content_type = match List.assoc_opt "type" content_obj with
525
+
| Some (`String ty) -> ty
526
+
| _ -> raise (Json.Of_json ("Missing or invalid content type", `Assoc content_obj))
529
+
match content_type with
530
+
| "text" -> `Text (TextContent.t_of_yojson (`Assoc content_obj))
531
+
| "image" -> `Image (ImageContent.t_of_yojson (`Assoc content_obj))
532
+
| "audio" -> `Audio (AudioContent.t_of_yojson (`Assoc content_obj))
533
+
| _ -> raise (Json.Of_json (Printf.sprintf "Invalid content type: %s" content_type, `Assoc content_obj))
| j -> raise (Json.Of_json ("Expected object for SamplingMessage", j))
···
let t_of_yojson = function
546
-
let name = match List.assoc_opt "name" fields with
547
-
| Some (`String s) -> s
548
-
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
550
-
let version = match List.assoc_opt "version" fields with
551
-
| Some (`String s) -> s
552
-
| _ -> raise (Json.Of_json ("Missing or invalid 'version' field", `Assoc fields))
554
+
| `Assoc fields as json ->
555
+
let name = Util.get_string_field fields "name" json in
556
+
let version = Util.get_string_field fields "version" json in
| j -> raise (Json.Of_json ("Expected object for Implementation", j))
···
let t_of_yojson = function
782
+
| `Assoc fields as json ->
let capabilities = match List.assoc_opt "capabilities" fields with
782
-
| None -> raise (Json.Of_json ("Missing capabilities field", `Assoc fields))
785
+
| None -> raise (Json.Of_json ("Missing capabilities field", json))
let client_info = match List.assoc_opt "clientInfo" fields with
| Some json -> Implementation.t_of_yojson json
786
-
| None -> raise (Json.Of_json ("Missing clientInfo field", `Assoc fields))
789
+
| None -> raise (Json.Of_json ("Missing clientInfo field", json))
788
-
let protocol_version = match List.assoc_opt "protocolVersion" fields with
789
-
| Some (`String s) -> s
790
-
| _ -> raise (Json.Of_json ("Missing or invalid protocolVersion field", `Assoc fields))
791
+
let protocol_version = Util.get_string_field fields "protocolVersion" json in
{ capabilities; client_info; protocol_version }
| j -> raise (Json.Of_json ("Expected object for InitializeRequest", j))
···
let t_of_yojson = function
829
+
| `Assoc fields as json ->
let capabilities = match List.assoc_opt "capabilities" fields with
832
-
| None -> raise (Json.Of_json ("Missing capabilities field", `Assoc fields))
832
+
| None -> raise (Json.Of_json ("Missing capabilities field", json))
let server_info = match List.assoc_opt "serverInfo" fields with
| Some json -> Implementation.t_of_yojson json
836
-
| None -> raise (Json.Of_json ("Missing serverInfo field", `Assoc fields))
838
-
let protocol_version = match List.assoc_opt "protocolVersion" fields with
839
-
| Some (`String s) -> s
840
-
| _ -> raise (Json.Of_json ("Missing or invalid protocolVersion field", `Assoc fields))
842
-
let instructions = match List.assoc_opt "instructions" fields with
843
-
| Some (`String s) -> Some s
836
+
| None -> raise (Json.Of_json ("Missing serverInfo field", json))
838
+
let protocol_version = Util.get_string_field fields "protocolVersion" json in
839
+
let instructions = Util.get_optional_string_field fields "instructions" in
let meta = List.assoc_opt "_meta" fields in
{ capabilities; server_info; protocol_version; instructions; meta }
| j -> raise (Json.Of_json ("Expected object for InitializeResult", j))