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

more

Changed files
+18 -46
stack
zulip
lib
zulip_bot
+18 -46
stack/zulip/lib/zulip_bot/lib/bot_storage.ml
···
(** {1 JSON Codecs for Bot Storage} *)
(* Storage response type - {"storage": {...}} *)
type storage_response = {
-
storage : (string * string) list;
unknown : Jsont.json; (** Unknown/extra JSON fields preserved during parsing *)
}
-
(* Custom codec for storage_response that handles the dictionary *)
let storage_response_jsont : storage_response Jsont.t =
-
let of_string s =
-
match Jsont_bytesrw.decode_string' Jsont.json s with
-
| Error _ -> Error "Failed to decode JSON"
-
| Ok json ->
-
match json with
-
| Jsont.Object (fields, _) ->
-
let assoc = List.map (fun ((k, _), v) -> (k, v)) fields in
-
(match List.assoc_opt "storage" assoc with
-
| Some (Jsont.Object (storage_fields, _)) ->
-
let storage = List.filter_map (fun ((k, _), v) ->
-
match v with
-
| Jsont.String (s, _) -> Some (k, s)
-
| _ -> None
-
) storage_fields in
-
(* Keep unknown fields *)
-
let unknown_fields = List.filter (fun (k, _) -> k <> "storage") assoc in
-
let unknown_mems = List.map (fun (k, v) -> ((k, Jsont.Meta.none), v)) unknown_fields in
-
let unknown = Jsont.Object (unknown_mems, Jsont.Meta.none) in
-
Ok { storage; unknown }
-
| Some _ -> Error "Expected 'storage' field to be an object"
-
| None -> Ok { storage = []; unknown = Jsont.Object ([], Jsont.Meta.none) })
-
| _ -> Error "Expected JSON object for storage response"
-
in
-
let to_string { storage; unknown } =
-
(* Create storage object *)
-
let storage_fields = List.map (fun (k, v) ->
-
((k, Jsont.Meta.none), Jsont.String (v, Jsont.Meta.none))
-
) storage in
-
let storage_obj = Jsont.Object (storage_fields, Jsont.Meta.none) in
-
-
(* Merge with unknown fields *)
-
let storage_mem = (("storage", Jsont.Meta.none), storage_obj) in
-
let unknown_mems = match unknown with
-
| Jsont.Object (fields, _) -> fields
-
| _ -> []
-
in
-
let json = Jsont.Object (storage_mem :: unknown_mems, Jsont.Meta.none) in
-
match Jsont_bytesrw.encode_string' Jsont.json json with
-
| Ok s -> s
-
| Error e -> failwith ("Failed to encode storage response: " ^ Jsont.Error.to_string e)
in
-
Jsont.of_of_string ~kind:"StorageResponse" of_string ~enc:to_string
let create client ~bot_email =
Log.info (fun m -> m "Creating bot storage for %s" bot_email);
···
| Ok json ->
(match Zulip.Encode.from_json storage_response_jsont json with
| Ok response ->
-
List.iter (fun (k, v) ->
Log.debug (fun m -> m "Loaded key from server: %s" k);
Hashtbl.add cache k v
) response.storage
···
| Ok json ->
(match Zulip.Encode.from_json storage_response_jsont json with
| Ok response ->
-
(match List.assoc_opt key response.storage with
| Some value ->
(* Cache the value *)
Log.debug (fun m -> m "Retrieved key from API: %s" key);
···
| Ok json ->
(match Zulip.Encode.from_json storage_response_jsont json with
| Ok response ->
-
let api_keys = List.map fst response.storage in
(* Merge with cache keys *)
let cache_keys = Hashtbl.fold (fun k _ acc -> k :: acc) t.cache [] in
let all_keys = List.sort_uniq String.compare (api_keys @ cache_keys) in
···
(** {1 JSON Codecs for Bot Storage} *)
+
(* String map for storage values *)
+
module String_map = Map.Make (String)
+
(* Storage response type - {"storage": {...}} *)
type storage_response = {
+
storage : string String_map.t;
unknown : Jsont.json; (** Unknown/extra JSON fields preserved during parsing *)
}
+
(* Codec for storage response using Jsont.Object with keep_unknown *)
let storage_response_jsont : storage_response Jsont.t =
+
let make storage unknown = { storage; unknown } in
+
let storage_map_jsont =
+
Jsont.Object.map ~kind:"StorageMap" Fun.id
+
|> Jsont.Object.keep_unknown (Jsont.Object.Mems.string_map Jsont.string) ~enc:Fun.id
+
|> Jsont.Object.finish
in
+
Jsont.Object.map ~kind:"StorageResponse" make
+
|> Jsont.Object.mem "storage" storage_map_jsont ~enc:(fun r -> r.storage)
+
~dec_absent:String_map.empty
+
|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun r -> r.unknown)
+
|> Jsont.Object.finish
let create client ~bot_email =
Log.info (fun m -> m "Creating bot storage for %s" bot_email);
···
| Ok json ->
(match Zulip.Encode.from_json storage_response_jsont json with
| Ok response ->
+
String_map.iter (fun k v ->
Log.debug (fun m -> m "Loaded key from server: %s" k);
Hashtbl.add cache k v
) response.storage
···
| Ok json ->
(match Zulip.Encode.from_json storage_response_jsont json with
| Ok response ->
+
(match String_map.find_opt key response.storage with
| Some value ->
(* Cache the value *)
Log.debug (fun m -> m "Retrieved key from API: %s" key);
···
| Ok json ->
(match Zulip.Encode.from_json storage_response_jsont json with
| Ok response ->
+
let api_keys = String_map.fold (fun k _ acc -> k :: acc) response.storage [] in
(* Merge with cache keys *)
let cache_keys = Hashtbl.fold (fun k _ acc -> k :: acc) t.cache [] in
let all_keys = List.sort_uniq String.compare (api_keys @ cache_keys) in