package chatoyant
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
OCaml-first LLM SDK with Melange-generated JavaScript
Install
dune-project
Dependency
Authors
Maintainers
Sources
chatoyant-v0.12.2.tbz
sha256=a885dcf4b3c6ede268e2027bedf6955a5c889f7ed01c40b719f8369655957d47
sha512=0bb8dfa12157ba2e482927717c2242c1ea914dce1427801e405987811550afbd6d6b11f07d1e1379259360d17f4ca43ff81963bf407cddb7bedd0dfbb93a55ee
doc/src/chatoyant.runtime/sse.ml.html
Source file sse.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61type event = { event : string option; data : string list } type state = { buffer : string } let empty = { buffer = "" } let normalize_newlines input = input |> String.split_on_char '\r' |> String.concat "" let split_complete_frames buffer = let normalized = normalize_newlines buffer in let rec scan acc start = let rec find_separator index = if index + 1 >= String.length normalized then None else if normalized.[index] = '\n' && normalized.[index + 1] = '\n' then Some index else find_separator (index + 1) in match find_separator start with | None -> ( List.rev acc, String.sub normalized start (String.length normalized - start) ) | Some index -> let frame = String.sub normalized start (index - start) in scan (frame :: acc) (index + 2) in scan [] 0 let parse_line (event, data) line = if line = "" || line.[0] = ':' then (event, data) else match String.index_opt line ':' with | None -> if line = "event" then (Some "", data) else (event, data) | Some index -> let name = String.sub line 0 index in let value_start = if index + 1 < String.length line && line.[index + 1] = ' ' then index + 2 else index + 1 in let value = String.sub line value_start (String.length line - value_start) in if name = "event" then (Some value, data) else if name = "data" then (event, data @ [ value ]) else (event, data) let parse_frame frame = let event, data = frame |> String.split_on_char '\n' |> List.fold_left parse_line (None, []) in { event; data } let feed state chunk = let frames, remaining = split_complete_frames (state.buffer ^ chunk) in ({ buffer = remaining }, List.map parse_frame frames) let finish state = if state.buffer = "" then [] else [ parse_frame state.buffer ] let data_string event = String.concat "\n" event.data let is_done event = String.trim (data_string event) = "[DONE]"
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>