My agentic slop goes here. Not intended for anyone else!
1(* Example demonstrating structured output with JSON Schema *)
2
3module C = Claude
4
5let () =
6 (* Configure logging to see what's happening *)
7 Logs.set_reporter (Logs_fmt.reporter ());
8 Logs.set_level (Some Logs.Info);
9 Logs.Src.set_level C.Message.src (Some Logs.Debug)
10
11let run_codebase_analysis env =
12 Printf.printf "\n=== Codebase Analysis with Structured Output ===\n\n";
13
14 (* Define the JSON Schema for our expected output structure *)
15 let analysis_schema =
16 let open Jsont in
17 Object ([
18 (("type", Meta.none), String ("object", Meta.none));
19 (("properties", Meta.none), Object ([
20 (("file_count", Meta.none), Object ([
21 (("type", Meta.none), String ("integer", Meta.none));
22 (("description", Meta.none), String ("Total number of files analyzed", Meta.none))
23 ], Meta.none));
24 (("has_tests", Meta.none), Object ([
25 (("type", Meta.none), String ("boolean", Meta.none));
26 (("description", Meta.none), String ("Whether the codebase has test files", Meta.none))
27 ], Meta.none));
28 (("primary_language", Meta.none), Object ([
29 (("type", Meta.none), String ("string", Meta.none));
30 (("description", Meta.none), String ("The primary programming language used", Meta.none))
31 ], Meta.none));
32 (("complexity_rating", Meta.none), Object ([
33 (("type", Meta.none), String ("string", Meta.none));
34 (("enum", Meta.none), Array ([
35 String ("low", Meta.none);
36 String ("medium", Meta.none);
37 String ("high", Meta.none)
38 ], Meta.none));
39 (("description", Meta.none), String ("Overall complexity rating", Meta.none))
40 ], Meta.none));
41 (("key_findings", Meta.none), Object ([
42 (("type", Meta.none), String ("array", Meta.none));
43 (("items", Meta.none), Object ([
44 (("type", Meta.none), String ("string", Meta.none))
45 ], Meta.none));
46 (("description", Meta.none), String ("List of key findings from the analysis", Meta.none))
47 ], Meta.none));
48 ], Meta.none));
49 (("required", Meta.none), Array ([
50 String ("file_count", Meta.none);
51 String ("has_tests", Meta.none);
52 String ("primary_language", Meta.none);
53 String ("complexity_rating", Meta.none);
54 String ("key_findings", Meta.none)
55 ], Meta.none));
56 (("additionalProperties", Meta.none), Bool (false, Meta.none))
57 ], Meta.none)
58 in
59
60 (* Create structured output format from the schema *)
61 let output_format = C.Structured_output.of_json_schema analysis_schema in
62
63 (* Configure Claude with structured output *)
64 let options = C.Options.default
65 |> C.Options.with_output_format output_format
66 |> C.Options.with_allowed_tools ["Read"; "Glob"; "Grep"]
67 |> C.Options.with_system_prompt
68 "You are a code analysis assistant. Analyze codebases and provide \
69 structured output matching the given JSON Schema."
70 in
71
72 Printf.printf "Structured output format configured\n";
73 Printf.printf "Schema: %s\n\n"
74 (Test_json_utils.to_string ~minify:false analysis_schema);
75
76 (* Create Claude client and query *)
77 Eio.Switch.run @@ fun sw ->
78 let process_mgr = Eio.Stdenv.process_mgr env in
79 let client = C.Client.create ~sw ~process_mgr ~options () in
80
81 let prompt =
82 "Please analyze the current codebase structure. Look at the files, \
83 identify the primary language, count files, check for tests, assess \
84 complexity, and provide key findings. Return your analysis in the \
85 structured JSON format I specified."
86 in
87
88 Printf.printf "Sending query: %s\n\n" prompt;
89 C.Client.query client prompt;
90
91 (* Process responses *)
92 let messages = C.Client.receive client in
93 Seq.iter (function
94 | C.Message.Assistant msg ->
95 Printf.printf "\nAssistant response:\n";
96 List.iter (function
97 | C.Content_block.Text text ->
98 Printf.printf " Text: %s\n" (C.Content_block.Text.text text)
99 | C.Content_block.Tool_use tool ->
100 Printf.printf " Using tool: %s\n" (C.Content_block.Tool_use.name tool)
101 | _ -> ()
102 ) (C.Message.Assistant.content msg)
103
104 | C.Message.Result result ->
105 Printf.printf "\n=== Result ===\n";
106 Printf.printf "Duration: %dms\n" (C.Message.Result.duration_ms result);
107 Printf.printf "Cost: $%.4f\n"
108 (Option.value (C.Message.Result.total_cost_usd result) ~default:0.0);
109
110 (* Extract and display structured output *)
111 (match C.Message.Result.structured_output result with
112 | Some output ->
113 Printf.printf "\n=== Structured Output ===\n";
114 Printf.printf "%s\n\n" (Test_json_utils.to_string ~minify:false output);
115
116 (* Parse the structured output *)
117 let file_count = Test_json_utils.get_int output "file_count" |> Option.value ~default:0 in
118 let has_tests = Test_json_utils.get_bool output "has_tests" |> Option.value ~default:false in
119 let language = Test_json_utils.get_string output "primary_language" |> Option.value ~default:"unknown" in
120 let complexity = Test_json_utils.get_string output "complexity_rating" |> Option.value ~default:"unknown" in
121 let findings =
122 match Test_json_utils.get_array output "key_findings" with
123 | Some items ->
124 List.filter_map (fun json ->
125 Test_json_utils.as_string json
126 ) items
127 | None -> []
128 in
129
130 Printf.printf "=== Parsed Analysis ===\n";
131 Printf.printf "File Count: %d\n" file_count;
132 Printf.printf "Has Tests: %b\n" has_tests;
133 Printf.printf "Primary Language: %s\n" language;
134 Printf.printf "Complexity: %s\n" complexity;
135 Printf.printf "Key Findings:\n";
136 List.iter (fun finding ->
137 Printf.printf " - %s\n" finding
138 ) findings
139
140 | None ->
141 Printf.printf "No structured output received\n";
142 (match C.Message.Result.result result with
143 | Some text -> Printf.printf "Text result: %s\n" text
144 | None -> ()))
145
146 | C.Message.System sys ->
147 (match C.Message.System.subtype sys with
148 | "init" ->
149 Printf.printf "Session initialized\n"
150 | _ -> ())
151
152 | _ -> ()
153 ) messages;
154
155 Printf.printf "\nDone!\n"
156
157let () =
158 Eio_main.run @@ fun env ->
159 try
160 run_codebase_analysis env
161 with
162 | C.Transport.CLI_not_found msg ->
163 Printf.eprintf "Error: Claude CLI not found\n%s\n" msg;
164 Printf.eprintf "Make sure 'claude' is installed and in your PATH\n";
165 exit 1
166 | C.Transport.Connection_error msg ->
167 Printf.eprintf "Connection error: %s\n" msg;
168 exit 1
169 | exn ->
170 Printf.eprintf "Unexpected error: %s\n" (Printexc.to_string exn);
171 Printexc.print_backtrace stderr;
172 exit 1