OCaml Claude SDK using Eio and Jsont
at main 90 lines 3.1 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6open Eio.Std 7 8let src = Logs.Src.create "test_permissions" ~doc:"Permission callback test" 9 10module Log = (val Logs.src_log src : Logs.LOG) 11 12(* Simple auto-allow permission callback *) 13let auto_allow_callback ctx = 14 Log.app (fun m -> 15 m "✅ Auto-allowing tool: %s" ctx.Claude.Permissions.tool_name); 16 Claude.Permissions.Decision.allow () 17 18let run_test ~sw ~env = 19 Log.app (fun m -> m "🧪 Testing Permission Callbacks"); 20 Log.app (fun m -> m "================================"); 21 22 (* Create options with custom permission callback *) 23 let options = 24 Claude.Options.default 25 |> Claude.Options.with_model (Claude.Model.of_string "sonnet") 26 |> Claude.Options.with_permission_callback auto_allow_callback 27 in 28 29 Log.app (fun m -> m "Creating client with permission callback..."); 30 let client = 31 Claude.Client.create ~options ~sw ~process_mgr:env#process_mgr 32 ~clock:env#clock () 33 in 34 35 (* Simple query that will trigger tool use *) 36 Log.app (fun m -> m "\n📤 Sending test query..."); 37 Claude.Client.query client "What is 2 + 2? Just give me the number."; 38 39 (* Process response *) 40 let messages = Claude.Client.receive_all client in 41 Log.app (fun m -> m "\n📨 Received %d messages" (List.length messages)); 42 43 List.iter 44 (fun resp -> 45 match resp with 46 | Claude.Response.Text text -> 47 Log.app (fun m -> m "Claude: %s" (Claude.Response.Text.content text)) 48 | Claude.Response.Tool_use t -> 49 Log.app (fun m -> 50 m "🔧 Tool use: %s" (Claude.Response.Tool_use.name t)) 51 | Claude.Response.Complete result -> 52 Log.app (fun m -> m "✅ Success!"); 53 Log.app (fun m -> 54 m "Duration: %dms" (Claude.Response.Complete.duration_ms result)) 55 | Claude.Response.Error err -> 56 Log.err (fun m -> m "❌ Error: %s" (Claude.Response.Error.message err)) 57 | _ -> ()) 58 messages; 59 60 Log.app (fun m -> m "\n================================"); 61 Log.app (fun m -> m "✨ Test complete!") 62 63let main ~env = Switch.run @@ fun sw -> run_test ~sw ~env 64 65(* Command-line interface *) 66open Cmdliner 67 68let main_term env = 69 let setup_log style_renderer level = 70 Fmt_tty.setup_std_outputs ?style_renderer (); 71 Logs.set_level level; 72 Logs.set_reporter (Logs_fmt.reporter ()); 73 if level = None then Logs.set_level (Some Logs.App); 74 match level with 75 | Some Logs.Info | Some Logs.Debug -> 76 Logs.Src.set_level Claude.Client.src (Some Logs.Info) 77 | _ -> () 78 in 79 let run style level = 80 setup_log style level; 81 main ~env 82 in 83 Term.(const run $ Fmt_cli.style_renderer () $ Logs_cli.level ()) 84 85let cmd env = 86 let doc = "Test permission callback functionality" in 87 let info = Cmd.info "test_permissions" ~version:"1.0" ~doc in 88 Cmd.v info (main_term env) 89 90let () = Eio_main.run @@ fun env -> exit (Cmd.eval (cmd env))