My agentic slop goes here. Not intended for anyone else!
at jsont 9.7 kB view raw
1(** SDK Control Protocol for Claude. 2 3 This module defines the typed SDK control protocol for bidirectional 4 communication between the SDK and the Claude CLI. It handles: 5 6 - Permission requests (tool usage authorization) 7 - Hook callbacks (intercepting and modifying tool execution) 8 - Dynamic control (changing settings mid-conversation) 9 - Server introspection (querying capabilities) 10 11 {2 Protocol Overview} 12 13 The SDK control protocol is a JSON-based request/response protocol that 14 runs alongside the main message stream. It enables: 15 16 1. {b Callbacks}: Claude asks the SDK for permission or hook execution 17 2. {b Control}: SDK changes Claude's behavior dynamically 18 3. {b Introspection}: SDK queries server metadata 19 20 {2 Request/Response Flow} 21 22 {v 23 SDK Claude CLI 24 | | 25 |-- Initialize (with hooks) --> | 26 |<-- Permission Request --------| (for tool usage) 27 |-- Allow/Deny Response ------> | 28 | | 29 |<-- Hook Callback -------------| (pre/post tool) 30 |-- Hook Result -------------> | 31 | | 32 |-- Set Model ---------------> | (dynamic control) 33 |<-- Success Response ----------| 34 | | 35 |-- Get Server Info ----------> | 36 |<-- Server Info Response ------| 37 v} 38 39 {2 Usage} 40 41 Most users won't interact with this module directly. The {!Client} module 42 handles the protocol automatically. However, this module is exposed for: 43 44 - Understanding the control protocol 45 - Implementing custom control logic 46 - Debugging control message flow 47 - Advanced SDK extensions 48 49 {2 Dynamic Control Examples} 50 51 See {!Client.set_permission_mode}, {!Client.set_model}, and 52 {!Client.get_server_info} for high-level APIs that use this protocol. *) 53 54open Ezjsonm 55 56(** The log source for SDK control operations *) 57val src : Logs.Src.t 58 59(** {1 Request Types} *) 60 61module Request : sig 62 (** SDK control request types. *) 63 64 type interrupt = { 65 subtype : [`Interrupt]; 66 } 67 (** Interrupt request to stop execution. *) 68 69 type permission = { 70 subtype : [`Can_use_tool]; 71 tool_name : string; 72 input : value; 73 permission_suggestions : Permissions.Update.t list option; 74 blocked_path : string option; 75 } 76 (** Permission request for tool usage. *) 77 78 type initialize = { 79 subtype : [`Initialize]; 80 hooks : (string * value) list option; (* Hook event to configuration *) 81 } 82 (** Initialize request with optional hook configuration. *) 83 84 type set_permission_mode = { 85 subtype : [`Set_permission_mode]; 86 mode : Permissions.Mode.t; 87 } 88 (** Request to change permission mode. *) 89 90 type hook_callback = { 91 subtype : [`Hook_callback]; 92 callback_id : string; 93 input : value; 94 tool_use_id : string option; 95 } 96 (** Hook callback request. *) 97 98 type mcp_message = { 99 subtype : [`Mcp_message]; 100 server_name : string; 101 message : value; 102 } 103 (** MCP server message request. *) 104 105 type set_model = { 106 subtype : [`Set_model]; 107 model : string; 108 } 109 (** Request to change the AI model. *) 110 111 type get_server_info = { 112 subtype : [`Get_server_info]; 113 } 114 (** Request to get server information. *) 115 116 type t = 117 | Interrupt of interrupt 118 | Permission of permission 119 | Initialize of initialize 120 | Set_permission_mode of set_permission_mode 121 | Hook_callback of hook_callback 122 | Mcp_message of mcp_message 123 | Set_model of set_model 124 | Get_server_info of get_server_info 125 (** The type of SDK control requests. *) 126 127 val interrupt : unit -> t 128 (** [interrupt ()] creates an interrupt request. *) 129 130 val permission : 131 tool_name:string -> 132 input:value -> 133 ?permission_suggestions:Permissions.Update.t list -> 134 ?blocked_path:string -> 135 unit -> t 136 (** [permission ~tool_name ~input ?permission_suggestions ?blocked_path ()] 137 creates a permission request. *) 138 139 val initialize : ?hooks:(string * value) list -> unit -> t 140 (** [initialize ?hooks ()] creates an initialize request. *) 141 142 val set_permission_mode : mode:Permissions.Mode.t -> t 143 (** [set_permission_mode ~mode] creates a permission mode change request. *) 144 145 val hook_callback : 146 callback_id:string -> 147 input:value -> 148 ?tool_use_id:string -> 149 unit -> t 150 (** [hook_callback ~callback_id ~input ?tool_use_id ()] creates a hook callback request. *) 151 152 val mcp_message : server_name:string -> message:value -> t 153 (** [mcp_message ~server_name ~message] creates an MCP message request. *) 154 155 val set_model : model:string -> t 156 (** [set_model ~model] creates a model change request. *) 157 158 val get_server_info : unit -> t 159 (** [get_server_info ()] creates a server info request. *) 160 161 val to_json : t -> value 162 (** [to_json t] converts a request to JSON. *) 163 164 val of_json : value -> t 165 (** [of_json json] parses a request from JSON. 166 @raise Invalid_argument if the JSON is not a valid request. *) 167 168 val pp : Format.formatter -> t -> unit 169 (** [pp fmt t] pretty-prints the request. *) 170end 171 172(** {1 Response Types} *) 173 174module Response : sig 175 (** SDK control response types. *) 176 177 type success = { 178 subtype : [`Success]; 179 request_id : string; 180 response : value option; 181 } 182 (** Successful response. *) 183 184 type error = { 185 subtype : [`Error]; 186 request_id : string; 187 error : string; 188 } 189 (** Error response. *) 190 191 type t = 192 | Success of success 193 | Error of error 194 (** The type of SDK control responses. *) 195 196 val success : request_id:string -> ?response:value -> unit -> t 197 (** [success ~request_id ?response ()] creates a success response. *) 198 199 val error : request_id:string -> error:string -> t 200 (** [error ~request_id ~error] creates an error response. *) 201 202 val to_json : t -> value 203 (** [to_json t] converts a response to JSON. *) 204 205 val of_json : value -> t 206 (** [of_json json] parses a response from JSON. 207 @raise Invalid_argument if the JSON is not a valid response. *) 208 209 val pp : Format.formatter -> t -> unit 210 (** [pp fmt t] pretty-prints the response. *) 211end 212 213(** {1 Control Messages} *) 214 215type control_request = { 216 type_ : [`Control_request]; 217 request_id : string; 218 request : Request.t; 219} 220(** Control request message. *) 221 222type control_response = { 223 type_ : [`Control_response]; 224 response : Response.t; 225} 226(** Control response message. *) 227 228type t = 229 | Request of control_request 230 | Response of control_response 231(** The type of SDK control messages. *) 232 233val create_request : request_id:string -> request:Request.t -> t 234(** [create_request ~request_id ~request] creates a control request message. *) 235 236val create_response : response:Response.t -> t 237(** [create_response ~response] creates a control response message. *) 238 239val to_json : t -> value 240(** [to_json t] converts a control message to JSON. *) 241 242val of_json : value -> t 243(** [of_json json] parses a control message from JSON. 244 @raise Invalid_argument if the JSON is not a valid control message. *) 245 246val pp : Format.formatter -> t -> unit 247(** [pp fmt t] pretty-prints the control message. *) 248 249(** {1 Logging} *) 250 251val log_request : Request.t -> unit 252(** [log_request req] logs an SDK control request. *) 253 254val log_response : Response.t -> unit 255(** [log_response resp] logs an SDK control response. *) 256 257(** {1 Server Information} 258 259 Server information provides metadata about the Claude CLI server, 260 including version, capabilities, available commands, and output styles. 261 262 {2 Use Cases} 263 264 - Feature detection: Check if specific capabilities are available 265 - Version compatibility: Ensure minimum version requirements 266 - Debugging: Log server information for troubleshooting 267 - Dynamic adaptation: Adjust SDK behavior based on capabilities 268 269 {2 Example} 270 271 {[ 272 let info = Client.get_server_info client in 273 Printf.printf "Claude CLI version: %s\n" 274 (Server_info.version info); 275 276 if List.mem "structured-output" (Server_info.capabilities info) then 277 Printf.printf "Structured output is supported\n" 278 else 279 Printf.printf "Structured output not available\n"; 280 ]} *) 281 282module Server_info : sig 283 (** Server information and capabilities. *) 284 285 type t = { 286 version : string; 287 (** Server version string (e.g., "2.0.0") *) 288 289 capabilities : string list; 290 (** Available server capabilities (e.g., "hooks", "structured-output") *) 291 292 commands : string list; 293 (** Available CLI commands *) 294 295 output_styles : string list; 296 (** Supported output formats (e.g., "json", "stream-json") *) 297 } 298 (** Server metadata and capabilities. 299 300 This information is useful for feature detection and debugging. *) 301 302 val create : 303 version:string -> 304 capabilities:string list -> 305 commands:string list -> 306 output_styles:string list -> 307 t 308 (** [create ~version ~capabilities ~commands ~output_styles] creates server info. *) 309 310 val version : t -> string 311 (** [version t] returns the server version. *) 312 313 val capabilities : t -> string list 314 (** [capabilities t] returns the server capabilities. *) 315 316 val commands : t -> string list 317 (** [commands t] returns available commands. *) 318 319 val output_styles : t -> string list 320 (** [output_styles t] returns available output styles. *) 321 322 val of_json : value -> t 323 (** [of_json json] parses server info from JSON. 324 @raise Invalid_argument if the JSON is not valid server info. *) 325 326 val to_json : t -> value 327 (** [to_json t] converts server info to JSON. *) 328 329 val pp : Format.formatter -> t -> unit 330 (** [pp fmt t] pretty-prints the server info. *) 331end