My agentic slop goes here. Not intended for anyone else!

more

+1 -1
claudeio/lib/client.ml
···
(* Extract session ID from system messages *)
(match msg with
| Message.System sys ->
-
(match Message.System.Data.session_id (Message.System.data sys) with
+
(match Message.System.session_id sys with
| Some session_id ->
t.session_id <- Some session_id;
Log.debug (fun m -> m "Stored session ID: %s" session_id)
+1 -29
claudeio/lib/content_block.ml
···
module Text = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
text : string;
unknown : Unknown.t;
···
let of_json json = json
end
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
id : string;
name : string;
···
end
module Tool_result = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
tool_use_id : string;
content : string option;
···
end
module Thinking = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
thinking : string;
signature : string;
···
Log.debug (fun m -> m "Received content block: %a" pp t)
let log_sending t =
-
Log.debug (fun m -> m "Sending content block: %a" pp t)
+
Log.debug (fun m -> m "Sending content block: %a" pp t)
+13 -29
claudeio/lib/content_block.mli
···
module Text : sig
(** Plain text content blocks. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of text blocks. *)
···
val text : t -> string
(** [text t] returns the text content of the block. *)
+
+
val unknown : t -> Unknown.t
+
(** [unknown t] returns any unknown fields from JSON parsing. *)
val jsont : t Jsont.t
(** [jsont] is the Jsont codec for text blocks. *)
···
(** [of_json json] parses from JSON. Internal use only. *)
end
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of tool use blocks. *)
···
val input : t -> Input.t
(** [input t] returns the input parameters for the tool. *)
+
+
val unknown : t -> Unknown.t
+
(** [unknown t] returns any unknown fields from JSON parsing. *)
val jsont : t Jsont.t
(** [jsont] is the Jsont codec for tool use blocks. *)
···
module Tool_result : sig
(** Results from tool invocations. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of tool result blocks. *)
···
val is_error : t -> bool option
(** [is_error t] returns whether this result represents an error. *)
+
val unknown : t -> Unknown.t
+
(** [unknown t] returns any unknown fields from JSON parsing. *)
+
val jsont : t Jsont.t
(** [jsont] is the Jsont codec for tool result blocks. *)
···
module Thinking : sig
(** Assistant's internal reasoning blocks. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of thinking blocks. *)
···
val signature : t -> string
(** [signature t] returns the cryptographic signature. *)
+
+
val unknown : t -> Unknown.t
+
(** [unknown t] returns any unknown fields from JSON parsing. *)
val jsont : t Jsont.t
(** [jsont] is the Jsont codec for thinking blocks. *)
···
(** [log_received t] logs that a content block was received. *)
val log_sending : t -> unit
-
(** [log_sending t] logs that a content block is being sent. *)
+
(** [log_sending t] logs that a content block is being sent. *)
-7
claudeio/lib/control.ml
···
in
Fmt.string fmt s
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
request_id : string;
subtype : string;
-8
claudeio/lib/control.mli
···
(** The log source for control message operations *)
val src : Logs.Src.t
-
(** Unknown field preservation *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of control messages. *)
+22 -99
claudeio/lib/hooks.ml
···
(** Context provided to hook callbacks *)
module Context = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
signal: unit option; (* Future: abort signal support *)
unknown : Unknown.t;
···
]
(** Generic hook result *)
-
module Result_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type result = {
decision: decision option;
system_message: string option;
hook_specific_output: Jsont.json option;
-
unknown : Result_unknown.t;
+
unknown : Unknown.t;
}
let result_jsont : result Jsont.t =
···
(** {1 PreToolUse Hook} *)
module PreToolUse = struct
-
module Input_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type input = {
session_id: string;
transcript_path: string;
tool_name: string;
tool_input: Jsont.json;
-
unknown : Input_unknown.t;
+
unknown : Unknown.t;
}
type t = input
···
"ask", `Ask;
]
-
module Output_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type output = {
permission_decision: permission_decision option;
permission_decision_reason: string option;
updated_input: Jsont.json option;
-
unknown : Output_unknown.t;
+
unknown : Unknown.t;
}
let output_jsont : output Jsont.t =
···
| Ok json -> json
| Error msg -> failwith ("PreToolUse.output_to_json: " ^ msg)
-
let allow ?reason ?updated_input ?(unknown = Output_unknown.empty) () =
+
let allow ?reason ?updated_input ?(unknown = Unknown.empty) () =
{ permission_decision = Some `Allow; permission_decision_reason = reason;
updated_input; unknown }
-
let deny ?reason ?(unknown = Output_unknown.empty) () =
+
let deny ?reason ?(unknown = Unknown.empty) () =
{ permission_decision = Some `Deny; permission_decision_reason = reason;
updated_input = None; unknown }
-
let ask ?reason ?(unknown = Output_unknown.empty) () =
+
let ask ?reason ?(unknown = Unknown.empty) () =
{ permission_decision = Some `Ask; permission_decision_reason = reason;
updated_input = None; unknown }
-
let continue ?(unknown = Output_unknown.empty) () =
+
let continue ?(unknown = Unknown.empty) () =
{ permission_decision = None; permission_decision_reason = None;
updated_input = None; unknown }
end
(** {1 PostToolUse Hook} *)
module PostToolUse = struct
-
module Input_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type input = {
session_id: string;
transcript_path: string;
tool_name: string;
tool_input: Jsont.json;
tool_response: Jsont.json;
-
unknown : Input_unknown.t;
+
unknown : Unknown.t;
}
type t = input
···
| Ok v -> v
| Error msg -> raise (Invalid_argument ("PostToolUse: " ^ msg))
-
module Output_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type output = {
decision: decision option;
reason: string option;
additional_context: string option;
-
unknown : Output_unknown.t;
+
unknown : Unknown.t;
}
let output_jsont : output Jsont.t =
···
| Ok json -> json
| Error msg -> failwith ("PostToolUse.output_to_json: " ^ msg)
-
let continue ?additional_context ?(unknown = Output_unknown.empty) () =
+
let continue ?additional_context ?(unknown = Unknown.empty) () =
{ decision = None; reason = None; additional_context; unknown }
-
let block ?reason ?additional_context ?(unknown = Output_unknown.empty) () =
+
let block ?reason ?additional_context ?(unknown = Unknown.empty) () =
{ decision = Some Block; reason; additional_context; unknown }
end
(** {1 UserPromptSubmit Hook} *)
module UserPromptSubmit = struct
-
module Input_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type input = {
session_id: string;
transcript_path: string;
prompt: string;
-
unknown : Input_unknown.t;
+
unknown : Unknown.t;
}
type t = input
···
| Ok v -> v
| Error msg -> raise (Invalid_argument ("UserPromptSubmit: " ^ msg))
-
module Output_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type output = {
decision: decision option;
reason: string option;
additional_context: string option;
-
unknown : Output_unknown.t;
+
unknown : Unknown.t;
}
let output_jsont : output Jsont.t =
···
| Ok json -> json
| Error msg -> failwith ("UserPromptSubmit.output_to_json: " ^ msg)
-
let continue ?additional_context ?(unknown = Output_unknown.empty) () =
+
let continue ?additional_context ?(unknown = Unknown.empty) () =
{ decision = None; reason = None; additional_context; unknown }
-
let block ?reason ?(unknown = Output_unknown.empty) () =
+
let block ?reason ?(unknown = Unknown.empty) () =
{ decision = Some Block; reason; additional_context = None; unknown }
end
(** {1 Stop Hook} *)
module Stop = struct
-
module Input_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type input = {
session_id: string;
transcript_path: string;
stop_hook_active: bool;
-
unknown : Input_unknown.t;
+
unknown : Unknown.t;
}
type t = input
···
| Ok v -> v
| Error msg -> raise (Invalid_argument ("Stop: " ^ msg))
-
module Output_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type output = {
decision: decision option;
reason: string option;
-
unknown : Output_unknown.t;
+
unknown : Unknown.t;
}
let output_jsont : output Jsont.t =
···
| Ok json -> json
| Error msg -> failwith ("Stop.output_to_json: " ^ msg)
-
let continue ?(unknown = Output_unknown.empty) () = { decision = None; reason = None; unknown }
-
let block ?reason ?(unknown = Output_unknown.empty) () = { decision = Some Block; reason; unknown }
+
let continue ?(unknown = Unknown.empty) () = { decision = None; reason = None; unknown }
+
let block ?reason ?(unknown = Unknown.empty) () = { decision = Some Block; reason; unknown }
end
(** {1 SubagentStop Hook} - Same structure as Stop *)
···
(** {1 PreCompact Hook} *)
module PreCompact = struct
-
module Input_unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type input = {
session_id: string;
transcript_path: string;
-
unknown : Input_unknown.t;
+
unknown : Unknown.t;
}
type t = input
···
type config = (event * matcher list) list
(** {1 Result Builders} *)
-
let continue ?system_message ?hook_specific_output ?(unknown = Result_unknown.empty) () =
+
let continue ?system_message ?hook_specific_output ?(unknown = Unknown.empty) () =
{ decision = None; system_message; hook_specific_output; unknown }
-
let block ?system_message ?hook_specific_output ?(unknown = Result_unknown.empty) () =
+
let block ?system_message ?hook_specific_output ?(unknown = Unknown.empty) () =
{ decision = Some Block; system_message; hook_specific_output; unknown }
(** {1 Matcher Builders} *)
+27 -104
claudeio/lib/hooks.mli
···
(** {1 Context} *)
module Context : sig
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t = {
signal: unit option;
unknown : Unknown.t;
···
(** {1 Generic Hook Result} *)
-
module Result_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
(** Generic result structure for hooks *)
type result = {
decision: decision option;
system_message: string option;
hook_specific_output: Jsont.json option;
-
unknown: Result_unknown.t;
+
unknown: Unknown.t;
}
val result_jsont : result Jsont.t
···
(** PreToolUse hook - fires before tool execution *)
module PreToolUse : sig
-
module Input_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
(** Typed input for PreToolUse hooks *)
type input = {
session_id: string;
transcript_path: string;
tool_name: string;
tool_input: Jsont.json;
-
unknown: Input_unknown.t;
+
unknown: Unknown.t;
}
type t = input
···
val transcript_path : t -> string
val tool_name : t -> string
val tool_input : t -> Jsont.json
-
val unknown : t -> Input_unknown.t
+
val unknown : t -> Unknown.t
val input_jsont : input Jsont.t
···
val permission_decision_jsont : permission_decision Jsont.t
-
module Output_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
(** Typed output for PreToolUse hooks *)
type output = {
permission_decision: permission_decision option;
permission_decision_reason: string option;
updated_input: Jsont.json option;
-
unknown: Output_unknown.t;
+
unknown: Unknown.t;
}
val output_jsont : output Jsont.t
(** {2 Response Builders} *)
-
val allow : ?reason:string -> ?updated_input:Jsont.json -> ?unknown:Output_unknown.t -> unit -> output
-
val deny : ?reason:string -> ?unknown:Output_unknown.t -> unit -> output
-
val ask : ?reason:string -> ?unknown:Output_unknown.t -> unit -> output
-
val continue : ?unknown:Output_unknown.t -> unit -> output
+
val allow : ?reason:string -> ?updated_input:Jsont.json -> ?unknown:Unknown.t -> unit -> output
+
val deny : ?reason:string -> ?unknown:Unknown.t -> unit -> output
+
val ask : ?reason:string -> ?unknown:Unknown.t -> unit -> output
+
val continue : ?unknown:Unknown.t -> unit -> output
(** Convert output to JSON for hook_specific_output *)
val output_to_json : output -> Jsont.json
···
(** PostToolUse hook - fires after tool execution *)
module PostToolUse : sig
-
module Input_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type input = {
session_id: string;
transcript_path: string;
tool_name: string;
tool_input: Jsont.json;
tool_response: Jsont.json;
-
unknown: Input_unknown.t;
+
unknown: Unknown.t;
}
type t = input
···
val tool_name : t -> string
val tool_input : t -> Jsont.json
val tool_response : t -> Jsont.json
-
val unknown : t -> Input_unknown.t
+
val unknown : t -> Unknown.t
val input_jsont : input Jsont.t
-
module Output_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type output = {
decision: decision option;
reason: string option;
additional_context: string option;
-
unknown: Output_unknown.t;
+
unknown: Unknown.t;
}
val output_jsont : output Jsont.t
-
val continue : ?additional_context:string -> ?unknown:Output_unknown.t -> unit -> output
-
val block : ?reason:string -> ?additional_context:string -> ?unknown:Output_unknown.t -> unit -> output
+
val continue : ?additional_context:string -> ?unknown:Unknown.t -> unit -> output
+
val block : ?reason:string -> ?additional_context:string -> ?unknown:Unknown.t -> unit -> output
val output_to_json : output -> Jsont.json
end
(** UserPromptSubmit hook - fires when user submits a prompt *)
module UserPromptSubmit : sig
-
module Input_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type input = {
session_id: string;
transcript_path: string;
prompt: string;
-
unknown: Input_unknown.t;
+
unknown: Unknown.t;
}
type t = input
···
val session_id : t -> string
val transcript_path : t -> string
val prompt : t -> string
-
val unknown : t -> Input_unknown.t
+
val unknown : t -> Unknown.t
val input_jsont : input Jsont.t
-
module Output_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type output = {
decision: decision option;
reason: string option;
additional_context: string option;
-
unknown: Output_unknown.t;
+
unknown: Unknown.t;
}
val output_jsont : output Jsont.t
-
val continue : ?additional_context:string -> ?unknown:Output_unknown.t -> unit -> output
-
val block : ?reason:string -> ?unknown:Output_unknown.t -> unit -> output
+
val continue : ?additional_context:string -> ?unknown:Unknown.t -> unit -> output
+
val block : ?reason:string -> ?unknown:Unknown.t -> unit -> output
val output_to_json : output -> Jsont.json
end
(** Stop hook - fires when conversation stops *)
module Stop : sig
-
module Input_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type input = {
session_id: string;
transcript_path: string;
stop_hook_active: bool;
-
unknown: Input_unknown.t;
+
unknown: Unknown.t;
}
type t = input
···
val session_id : t -> string
val transcript_path : t -> string
val stop_hook_active : t -> bool
-
val unknown : t -> Input_unknown.t
+
val unknown : t -> Unknown.t
val input_jsont : input Jsont.t
-
module Output_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type output = {
decision: decision option;
reason: string option;
-
unknown: Output_unknown.t;
+
unknown: Unknown.t;
}
val output_jsont : output Jsont.t
-
val continue : ?unknown:Output_unknown.t -> unit -> output
-
val block : ?reason:string -> ?unknown:Output_unknown.t -> unit -> output
+
val continue : ?unknown:Unknown.t -> unit -> output
+
val block : ?reason:string -> ?unknown:Unknown.t -> unit -> output
val output_to_json : output -> Jsont.json
end
···
(** PreCompact hook - fires before message compaction *)
module PreCompact : sig
-
module Input_unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type input = {
session_id: string;
transcript_path: string;
-
unknown: Input_unknown.t;
+
unknown: Unknown.t;
}
type t = input
···
val session_id : t -> string
val transcript_path : t -> string
-
val unknown : t -> Input_unknown.t
+
val unknown : t -> Unknown.t
val input_jsont : input Jsont.t
···
(** {1 Generic Result Builders} *)
(** [continue ?system_message ?hook_specific_output ?unknown ()] creates a continue result *)
-
val continue : ?system_message:string -> ?hook_specific_output:Jsont.json -> ?unknown:Result_unknown.t -> unit -> result
+
val continue : ?system_message:string -> ?hook_specific_output:Jsont.json -> ?unknown:Unknown.t -> unit -> result
(** [block ?system_message ?hook_specific_output ?unknown ()] creates a block result *)
-
val block : ?system_message:string -> ?hook_specific_output:Jsont.json -> ?unknown:Result_unknown.t -> unit -> result
+
val block : ?system_message:string -> ?hook_specific_output:Jsont.json -> ?unknown:Unknown.t -> unit -> result
(** {1 Configuration Builders} *)
+82 -199
claudeio/lib/message.ml
···
| String of string
| Blocks of Content_block.t list
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
content : content;
unknown : Unknown.t;
···
("unknown", `Unknown);
]
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
content : Content_block.t list;
model : string;
···
end
module System = struct
-
(** Typed data for system init messages *)
-
module Init = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let _jsont = Jsont.json
-
end
+
(** System messages as a discriminated union on "subtype" field *)
-
type t = {
-
session_id : string option;
-
model : string option;
-
cwd : string option;
-
unknown : Unknown.t;
-
}
+
type init = {
+
session_id : string option;
+
model : string option;
+
cwd : string option;
+
unknown : Unknown.t;
+
}
-
let make session_id model cwd unknown = { session_id; model; cwd; unknown }
-
-
let create ?session_id ?model ?cwd () =
-
{ session_id; model; cwd; unknown = Unknown.empty }
-
-
let session_id t = t.session_id
-
let model t = t.model
-
let cwd t = t.cwd
-
let unknown t = t.unknown
+
type error = {
+
error : string;
+
unknown : Unknown.t;
+
}
-
let jsont : t Jsont.t =
-
Jsont.Object.map ~kind:"SystemInit" make
-
|> Jsont.Object.opt_mem "session_id" Jsont.string ~enc:session_id
-
|> Jsont.Object.opt_mem "model" Jsont.string ~enc:model
-
|> Jsont.Object.opt_mem "cwd" Jsont.string ~enc:cwd
-
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:unknown
-
|> Jsont.Object.finish
-
end
-
-
(** Typed data for system error messages *)
-
module Error = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let _jsont = Jsont.json
-
end
-
-
type t = {
-
error : string;
-
unknown : Unknown.t;
-
}
-
-
let make error unknown = { error; unknown }
-
-
let create ~error = { error; unknown = Unknown.empty }
-
-
let error t = t.error
-
let unknown t = t.unknown
-
-
let jsont : t Jsont.t =
-
Jsont.Object.map ~kind:"SystemError" make
-
|> Jsont.Object.mem "error" Jsont.string ~enc:error
-
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:unknown
-
|> Jsont.Object.finish
-
end
-
-
(** Sum type for system message data *)
-
module Data = struct
-
type t =
-
| Init of Init.t
-
| Error of Error.t
-
| Other of Jsont.json (** Unknown subtypes preserve raw JSON *)
-
-
let init ?session_id ?model ?cwd () = Init (Init.create ?session_id ?model ?cwd ())
-
let error ~error = Error (Error.create ~error)
-
let other json = Other json
-
-
let session_id = function
-
| Init i -> Init.session_id i
-
| _ -> None
-
-
let model = function
-
| Init i -> Init.model i
-
| _ -> None
-
-
let cwd = function
-
| Init i -> Init.cwd i
-
| _ -> None
-
-
let error_msg = function
-
| Error e -> Some (Error.error e)
-
| _ -> None
-
-
let to_json = function
-
| Init i ->
-
(match Jsont.Json.encode Init.jsont i with
-
| Ok json -> json
-
| Error msg -> failwith ("Init.to_json: " ^ msg))
-
| Error e ->
-
(match Jsont.Json.encode Error.jsont e with
-
| Ok json -> json
-
| Error msg -> failwith ("Error.to_json: " ^ msg))
-
| Other json -> json
-
-
let of_json ~subtype json =
-
match subtype with
-
| "init" ->
-
(match Jsont.Json.decode Init.jsont json with
-
| Ok i -> Init i
-
| Error _ -> Other json)
-
| "error" ->
-
(match Jsont.Json.decode Error.jsont json with
-
| Ok e -> Error e
-
| Error _ -> Other json)
-
| _ -> Other json
-
end
-
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
-
type t = {
+
type other = {
subtype : string;
-
data : Data.t;
unknown : Unknown.t;
}
-
let create ~subtype ~data = { subtype; data; unknown = Unknown.empty }
-
let subtype t = t.subtype
-
let data t = t.data
-
let unknown t = t.unknown
+
type t =
+
| Init of init
+
| Error of error
+
| Other of other
+
+
(* Accessors *)
+
let session_id = function Init i -> i.session_id | _ -> None
+
let model = function Init i -> i.model | _ -> None
+
let cwd = function Init i -> i.cwd | _ -> None
+
let error_msg = function Error e -> Some e.error | _ -> None
+
let subtype = function Init _ -> "init" | Error _ -> "error" | Other o -> o.subtype
+
let unknown = function
+
| Init i -> i.unknown
+
| Error e -> e.unknown
+
| Other o -> o.unknown
-
(** Create a system init message *)
+
(* Constructors *)
let init ?session_id ?model ?cwd () =
-
{ subtype = "init";
-
data = Data.init ?session_id ?model ?cwd ();
-
unknown = Unknown.empty }
+
Init { session_id; model; cwd; unknown = Unknown.empty }
-
(** Create a system error message *)
let error ~error =
-
{ subtype = "error";
-
data = Data.error ~error;
-
unknown = Unknown.empty }
+
Error { error; unknown = Unknown.empty }
-
(* Custom jsont that handles both formats:
-
- Old format: {"type":"system","subtype":"init","data":{...}}
-
- New format: {"type":"system","subtype":"init","cwd":"...","session_id":"...",...}
-
When data field is not present, we use the entire object as data *)
+
let other ~subtype =
+
Other { subtype; unknown = Unknown.empty }
+
+
(* Individual record codecs *)
+
let init_jsont : init Jsont.t =
+
let make session_id model cwd unknown : init = { session_id; model; cwd; unknown } in
+
Jsont.Object.map ~kind:"SystemInit" make
+
|> Jsont.Object.opt_mem "session_id" Jsont.string ~enc:(fun (r : init) -> r.session_id)
+
|> Jsont.Object.opt_mem "model" Jsont.string ~enc:(fun (r : init) -> r.model)
+
|> Jsont.Object.opt_mem "cwd" Jsont.string ~enc:(fun (r : init) -> r.cwd)
+
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (r : init) -> r.unknown)
+
|> Jsont.Object.finish
+
+
let error_jsont : error Jsont.t =
+
let make err unknown : error = { error = err; unknown } in
+
Jsont.Object.map ~kind:"SystemError" make
+
|> Jsont.Object.mem "error" Jsont.string ~enc:(fun (r : error) -> r.error)
+
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (r : error) -> r.unknown)
+
|> Jsont.Object.finish
+
+
(* Main codec using case_mem for "subtype" discriminator *)
let jsont : t Jsont.t =
-
let dec json =
-
(* First decode just the subtype *)
-
let subtype_codec = Jsont.Object.map ~kind:"SystemSubtype" Fun.id
-
|> Jsont.Object.mem "subtype" Jsont.string ~enc:Fun.id
+
let case_init = Jsont.Object.Case.map "init" init_jsont ~dec:(fun v -> Init v) in
+
let case_error = Jsont.Object.Case.map "error" error_jsont ~dec:(fun v -> Error v) in
+
let case_other tag =
+
(* For unknown subtypes, create Other with the tag as subtype *)
+
let other_codec : other Jsont.t =
+
let make unknown : other = { subtype = tag; unknown } in
+
Jsont.Object.map ~kind:"SystemOther" make
+
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (r : other) -> r.unknown)
|> Jsont.Object.finish
in
-
match Jsont.Json.decode subtype_codec json with
-
| Error msg -> failwith ("System.jsont: " ^ msg)
-
| Ok subtype ->
-
(* Try to get data field, otherwise use full object *)
-
let data_codec = Jsont.Object.map ~kind:"SystemDataField" Fun.id
-
|> Jsont.Object.opt_mem "data" Jsont.json ~enc:Fun.id
-
|> Jsont.Object.finish
-
in
-
let data_json = match Jsont.Json.decode data_codec json with
-
| Ok (Some d) -> d
-
| _ -> json
-
in
-
let data = Data.of_json ~subtype data_json in
-
{ subtype; data; unknown = Unknown.empty }
+
Jsont.Object.Case.map tag other_codec ~dec:(fun v -> Other v)
in
-
let enc t =
-
Jsont.Json.object' [
-
Jsont.Json.mem (Jsont.Json.name "type") (Jsont.Json.string "system");
-
Jsont.Json.mem (Jsont.Json.name "subtype") (Jsont.Json.string t.subtype);
-
Jsont.Json.mem (Jsont.Json.name "data") (Data.to_json t.data);
-
]
+
let enc_case = function
+
| Init v -> Jsont.Object.Case.value case_init v
+
| Error v -> Jsont.Object.Case.value case_error v
+
| Other v -> Jsont.Object.Case.value (case_other v.subtype) v
in
-
Jsont.map ~kind:"System" ~dec ~enc Jsont.json
+
let cases = Jsont.Object.Case.[
+
make case_init;
+
make case_error;
+
] in
+
Jsont.Object.map ~kind:"System" Fun.id
+
|> Jsont.Object.case_mem "subtype" Jsont.string ~enc:Fun.id ~enc_case cases
+
~tag_to_string:Fun.id ~tag_compare:String.compare
+
|> Jsont.Object.finish
let to_json t =
match Jsont.Json.encode jsont t with
···
| Ok v -> v
| Error msg -> raise (Invalid_argument ("System.of_json: " ^ msg))
-
let pp fmt t =
-
match t.data with
-
| Data.Init i ->
+
let pp fmt = function
+
| Init i ->
Fmt.pf fmt "@[<2>System.init@ { session_id = %a;@ model = %a;@ cwd = %a }@]"
-
Fmt.(option string) (Init.session_id i)
-
Fmt.(option string) (Init.model i)
-
Fmt.(option string) (Init.cwd i)
-
| Data.Error e ->
-
Fmt.pf fmt "@[<2>System.error@ { error = %s }@]" (Error.error e)
-
| Data.Other _ ->
-
Fmt.pf fmt "@[<2>System.%s@ { ... }@]" t.subtype
+
Fmt.(option string) i.session_id
+
Fmt.(option string) i.model
+
Fmt.(option string) i.cwd
+
| Error e ->
+
Fmt.pf fmt "@[<2>System.error@ { error = %s }@]" e.error
+
| Other o ->
+
Fmt.pf fmt "@[<2>System.%s@ { ... }@]" o.subtype
end
module Result = struct
module Usage = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
input_tokens : int option;
output_tokens : int option;
···
| Error msg -> raise (Invalid_argument ("Usage.of_json: " ^ msg))
end
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
subtype : string;
duration_ms : int;
···
let assistant_text ~text ~model ?error () =
Assistant (Assistant.create ~content:[Content_block.text text] ~model ?error ())
-
let system ~subtype ~data = System (System.create ~subtype ~data)
let system_init ~session_id =
System (System.init ~session_id ())
let system_error ~error =
···
| _ -> []
let get_session_id = function
-
| System s -> System.Data.session_id (System.data s)
+
| System s -> System.session_id s
| Result r -> Some (Result.session_id r)
| _ -> None
+53 -122
claudeio/lib/message.mli
···
| Blocks of Content_block.t list (** Complex message with multiple content blocks *)
(** The content of a user message. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of user messages. *)
···
val error_of_string : string -> error
(** [error_of_string s] parses an error string. Unknown strings become [`Unknown]. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t
(** The type of assistant messages. *)
···
(** {1 System Messages} *)
module System : sig
-
(** System control and status messages. *)
+
(** System control and status messages.
-
(** Typed data for system init messages *)
-
module Init : sig
-
type t
-
(** Type of init message data. *)
+
System messages use a discriminated union on the "subtype" field:
+
- "init": Session initialization with session_id, model, cwd
+
- "error": Error messages with error string
+
- Other subtypes are preserved as [Other] *)
-
val create : ?session_id:string -> ?model:string -> ?cwd:string -> unit -> t
-
(** [create ?session_id ?model ?cwd ()] creates init data. *)
+
type init = {
+
session_id : string option;
+
model : string option;
+
cwd : string option;
+
unknown : Unknown.t;
+
}
+
(** Init message fields. *)
-
val session_id : t -> string option
-
(** [session_id t] returns the session ID if present. *)
+
type error = {
+
error : string;
+
unknown : Unknown.t;
+
}
+
(** Error message fields. *)
-
val model : t -> string option
-
(** [model t] returns the model name if present. *)
+
type other = {
+
subtype : string;
+
unknown : Unknown.t;
+
}
+
(** Unknown subtype fields. *)
-
val cwd : t -> string option
-
(** [cwd t] returns the current working directory if present. *)
+
type t =
+
| Init of init
+
| Error of error
+
| Other of other
+
(** The type of system messages. *)
-
val jsont : t Jsont.t
-
(** [jsont] is the Jsont codec for init data. *)
-
end
+
val jsont : t Jsont.t
+
(** [jsont] is the Jsont codec for system messages. *)
-
(** Typed data for system error messages *)
-
module Error : sig
-
type t
-
(** Type of error message data. *)
+
(** {2 Constructors} *)
-
val create : error:string -> t
-
(** [create ~error] creates error data. *)
+
val init : ?session_id:string -> ?model:string -> ?cwd:string -> unit -> t
+
(** [init ?session_id ?model ?cwd ()] creates an init message. *)
-
val error : t -> string
-
(** [error t] returns the error message. *)
+
val error : error:string -> t
+
(** [error ~error] creates an error message. *)
-
val jsont : t Jsont.t
-
(** [jsont] is the Jsont codec for error data. *)
-
end
+
val other : subtype:string -> t
+
(** [other ~subtype] creates a message with unknown subtype. *)
-
(** System message data variants *)
-
module Data : sig
-
type t =
-
| Init of Init.t (** Init message data *)
-
| Error of Error.t (** Error message data *)
-
| Other of Jsont.json (** Unknown subtype data *)
-
(** Variant type for system message data. *)
+
(** {2 Accessors} *)
-
val init : ?session_id:string -> ?model:string -> ?cwd:string -> unit -> t
-
(** [init ?session_id ?model ?cwd ()] creates init data. *)
-
-
val error : error:string -> t
-
(** [error ~error] creates error data. *)
-
-
val other : Jsont.json -> t
-
(** [other json] creates data for unknown subtypes. *)
-
-
val session_id : t -> string option
-
(** [session_id t] extracts session_id from Init data, None otherwise. *)
-
-
val model : t -> string option
-
(** [model t] extracts model from Init data, None otherwise. *)
-
-
val cwd : t -> string option
-
(** [cwd t] extracts cwd from Init data, None otherwise. *)
-
-
val error_msg : t -> string option
-
(** [error_msg t] extracts error from Error data, None otherwise. *)
-
-
val to_json : t -> Jsont.json
-
(** [to_json t] converts to JSON representation. *)
+
val session_id : t -> string option
+
(** [session_id t] returns session_id from Init, None otherwise. *)
-
val of_json : subtype:string -> Jsont.json -> t
-
(** [of_json ~subtype json] parses data based on subtype. *)
-
end
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
+
val model : t -> string option
+
(** [model t] returns model from Init, None otherwise. *)
-
type t
-
(** The type of system messages. *)
+
val cwd : t -> string option
+
(** [cwd t] returns cwd from Init, None otherwise. *)
-
val jsont : t Jsont.t
-
(** [jsont] is the Jsont codec for system messages. *)
-
-
val create : subtype:string -> data:Data.t -> t
-
(** [create ~subtype ~data] creates a system message.
-
@param subtype The subtype of the system message
-
@param data Additional data for the message *)
-
-
val init : ?session_id:string -> ?model:string -> ?cwd:string -> unit -> t
-
(** [init ?session_id ?model ?cwd ()] creates a system init message. *)
-
-
val error : error:string -> t
-
(** [error ~error] creates a system error message. *)
+
val error_msg : t -> string option
+
(** [error_msg t] returns error from Error, None otherwise. *)
val subtype : t -> string
-
(** [subtype t] returns the subtype of the system message. *)
-
-
val data : t -> Data.t
-
(** [data t] returns the additional data of the system message. *)
+
(** [subtype t] returns the subtype string. *)
val unknown : t -> Unknown.t
-
(** [unknown t] returns the unknown fields preserved from JSON. *)
+
(** [unknown t] returns the unknown fields. *)
+
+
(** {2 Conversion} *)
val to_json : t -> Jsont.json
-
(** [to_json t] converts the system message to its JSON representation. *)
+
(** [to_json t] converts to JSON representation. *)
val of_json : Jsont.json -> t
-
(** [of_json json] parses a system message from JSON.
-
@raise Invalid_argument if the JSON is not a valid system message. *)
+
(** [of_json json] parses from JSON.
+
@raise Invalid_argument if invalid. *)
val pp : Format.formatter -> t -> unit
-
(** [pp fmt t] pretty-prints the system message. *)
+
(** [pp fmt t] pretty-prints the message. *)
end
(** {1 Result Messages} *)
···
module Usage : sig
(** Usage statistics for API calls. *)
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
type t
(** Type for usage statistics. *)
···
val of_json : Jsont.json -> t
(** [of_json json] parses from JSON. Internal use only. *)
-
end
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
end
type t
···
val assistant_text : text:string -> model:string -> ?error:Assistant.error -> unit -> t
(** [assistant_text ~text ~model ?error ()] creates an assistant message with only text content. *)
-
-
val system : subtype:string -> data:System.Data.t -> t
-
(** [system ~subtype ~data] creates a system message. *)
val system_init : session_id:string -> t
(** [system_init ~session_id] creates a system init message. *)
-28
claudeio/lib/permissions.ml
···
(** Permission rules *)
module Rule = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
tool_name : string;
rule_content : string option;
···
"addDirectories", Add_directories;
"removeDirectories", Remove_directories;
]
-
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
type t = {
update_type : update_type;
···
(** Permission context for callbacks *)
module Context = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
suggestions : Update.t list;
unknown : Unknown.t;
···
(** Permission results *)
module Result = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t =
| Allow of {
updated_input : Jsont.json option;
-28
claudeio/lib/permissions.mli
···
module Rule : sig
(** Rules define specific permissions for tools. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t = {
tool_name : string; (** Name of the tool *)
rule_content : string option; (** Optional rule specification *)
···
| Add_directories (** Add allowed directories *)
| Remove_directories (** Remove allowed directories *)
(** The type of permission update. *)
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
type t
(** The type of permission updates. *)
···
module Context : sig
(** Context provided to permission callbacks. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type t = {
suggestions : Update.t list; (** Suggested permission updates *)
unknown : Unknown.t; (** Unknown fields *)
···
module Result : sig
(** Results of permission checks. *)
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
type t =
| Allow of {
-28
claudeio/lib/sdk_control.ml
···
end
module Request = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type interrupt = {
subtype : [`Interrupt];
unknown : Unknown.t;
···
end
module Response = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type success = {
subtype : [`Success];
request_id : string;
···
e.request_id e.error
end
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type control_request = {
type_ : [`Control_request];
request_id : string;
···
(** Server information *)
module Server_info = struct
-
module Unknown = struct
-
type t = Jsont.json
-
let empty = Jsont.Object ([], Jsont.Meta.none)
-
let is_empty = function Jsont.Object ([], _) -> true | _ -> false
-
let jsont = Jsont.json
-
end
-
type t = {
version : string;
capabilities : string list;
-28
claudeio/lib/sdk_control.mli
···
module Request : sig
(** SDK control request types. *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type interrupt = {
subtype : [`Interrupt];
unknown : Unknown.t;
···
module Response : sig
(** SDK control response types. *)
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
type success = {
subtype : [`Success];
···
(** {1 Control Messages} *)
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
-
type control_request = {
type_ : [`Control_request];
request_id : string;
···
module Server_info : sig
(** Server information and capabilities. *)
-
-
module Unknown : sig
-
type t = Jsont.json
-
val empty : t
-
val is_empty : t -> bool
-
val jsont : t Jsont.t
-
end
type t = {
version : string;
+20
claudeio/lib/unknown.ml
···
+
(** Unknown fields for capturing extra JSON object members.
+
+
This module provides a type and utilities for preserving unknown/extra
+
fields when parsing JSON objects with jsont. Use with
+
[Jsont.Object.keep_unknown] to capture fields not explicitly defined
+
in your codec. *)
+
+
type t = Jsont.json
+
(** The type of unknown fields - stored as raw JSON. *)
+
+
let empty = Jsont.Object ([], Jsont.Meta.none)
+
(** An empty unknown fields value (empty JSON object). *)
+
+
let is_empty = function
+
| Jsont.Object ([], _) -> true
+
| _ -> false
+
(** [is_empty t] returns [true] if there are no unknown fields. *)
+
+
let jsont = Jsont.json
+
(** Codec for unknown fields. *)
+18
claudeio/lib/unknown.mli
···
+
(** Unknown fields for capturing extra JSON object members.
+
+
This module provides a type and utilities for preserving unknown/extra
+
fields when parsing JSON objects with jsont. Use with
+
[Jsont.Object.keep_unknown] to capture fields not explicitly defined
+
in your codec. *)
+
+
type t = Jsont.json
+
(** The type of unknown fields - stored as raw JSON. *)
+
+
val empty : t
+
(** An empty unknown fields value (empty JSON object). *)
+
+
val is_empty : t -> bool
+
(** [is_empty t] returns [true] if there are no unknown fields. *)
+
+
val jsont : t Jsont.t
+
(** Codec for unknown fields. *)