My agentic slop goes here. Not intended for anyone else!
at main 3.3 kB view raw
1module Identity = struct 2 type t = { 3 full_name : string; 4 email : string; 5 mention_name : string; 6 } 7 8 let create ~full_name ~email ~mention_name = 9 { full_name; email; mention_name } 10 11 let full_name t = t.full_name 12 let email t = t.email 13 let mention_name t = t.mention_name 14 15 let pp fmt t = 16 Format.fprintf fmt "Bot{email=%s, name=%s}" t.email t.full_name 17end 18 19module Message_context = struct 20 type t = { 21 message_id : int; 22 sender_email : string; 23 sender_full_name : string; 24 content : string; 25 message_type : Zulip.Message_type.t; 26 topic : string option; 27 channel : string option; 28 } 29 30 let create ~message_id ~sender_email ~sender_full_name ~content ~message_type ?topic ?channel () = 31 { message_id; sender_email; sender_full_name; content; message_type; topic; channel } 32 33 let message_id t = t.message_id 34 let sender_email t = t.sender_email 35 let sender_full_name t = t.sender_full_name 36 let content t = t.content 37 let message_type t = t.message_type 38 let topic t = t.topic 39 let channel t = t.channel 40 let is_direct_message t = t.message_type = `Direct 41 let is_channel_message t = t.message_type = `Channel 42 43 let pp fmt t = 44 Format.fprintf fmt "Message{id=%d, from=%s, type=%a}" 45 t.message_id t.sender_email Zulip.Message_type.pp t.message_type 46end 47 48module Response = struct 49 type t = 50 | Reply of string 51 | Send_to_channel of string * string * string (* channel, topic, content *) 52 | Send_direct of string list * string (* users, content *) 53 | React of string (* emoji *) 54 | None 55 56 let reply ~content = Reply content 57 let send_to_channel ~channel ~topic ~content = Send_to_channel (channel, topic, content) 58 let send_direct ~users ~content = Send_direct (users, content) 59 let react ~emoji = React emoji 60 let none = None 61end 62 63module type Bot_handler = sig 64 val initialize : Bot_config.t -> (unit, Zulip.Error.t) result 65 val usage : unit -> string 66 val description : unit -> string 67 val handle_message : 68 config:Bot_config.t -> 69 storage:Bot_storage.t -> 70 identity:Identity.t -> 71 message:Message_context.t -> 72 env:_ -> 73 (Response.t, Zulip.Error.t) result 74end 75 76type t = { 77 module_impl : (module Bot_handler); 78 config : Bot_config.t; 79 storage : Bot_storage.t; 80 identity : Identity.t; 81} 82 83let create module_impl ~config ~storage ~identity = 84 { module_impl; config; storage; identity } 85 86let handle_message t message = 87 (* Mock EIO environment for backwards compatibility *) 88 let mock_env = object 89 method fs = failwith "EIO environment not available - use handle_message_with_env" 90 method net = failwith "EIO environment not available - use handle_message_with_env" 91 method clock = failwith "EIO environment not available - use handle_message_with_env" 92 end in 93 let (module Handler) = t.module_impl in 94 Handler.handle_message ~config:t.config ~storage:t.storage ~identity:t.identity ~message ~env:mock_env 95 96let handle_message_with_env t env message = 97 let (module Handler) = t.module_impl in 98 Handler.handle_message ~config:t.config ~storage:t.storage ~identity:t.identity ~message ~env 99 100let identity t = t.identity 101 102let usage t = 103 let (module Handler) = t.module_impl in 104 Handler.usage () 105 106let description t = 107 let (module Handler) = t.module_impl in 108 Handler.description ()