Skip to content

Instantly share code, notes, and snippets.

@realgenekim
Created November 6, 2023 21:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save realgenekim/e50ad013e798c3c7e012afacf009aef0 to your computer and use it in GitHub Desktop.
Save realgenekim/e50ad013e798c3c7e012afacf009aef0 to your computer and use it in GitHub Desktop.
Simple example of using wkok/openai-clojure library in streaming mode
(ns openai.a01-async-openai
(:require
[com.fulcrologic.guardrails.core :refer [>defn >defn- >def | ? =>]]
[wkok.openai-clojure.api :as api]
[openai.companies :as companies]
[diehard.core :as dh]
[clojure.data.json :as json]
[clojure.edn :as edn]
[clojure.spec.alpha :as s]
[clojure.core.async :as a :refer [<!! >!! <! >!]]
[taoensso.timbre :as log]
[utils.pp :as up]))
; https://github.com/wkok/openai-clojure/blob/main/doc/03-streaming.md
(comment
(def c
(api/create-chat-completion {:model "gpt-3.5-turbo"
:messages [{:role "system" :content "You are a helpful assistant."}
{:role "user" :content "Who won the world series in 2020?"}
{:role "assistant" :content "The Los Angeles Dodgers won the World Series in 2020."}
{:role "user" :content "Where was it played?"}]
:stream true}
companies/secret)))
(defn call-openai!
" returns a channel "
[]
(api/create-chat-completion {:model "gpt-3.5-turbo"
:messages [{:role "system" :content "You are a helpful assistant."}
{:role "user" :content "write 300 words on the principle of parsimony"}]
:stream true}
companies/secret))
; helper function read all characters from the channel c
(defn- read-all!
" helper function for call-and-stream!
output: returns a channel that will contain the result of reading all characters from channel c"
[c]
(let [result-chan (a/chan)]
(a/go
(loop [acc []]
(let [event (a/<! c)]
(if (= :done event)
(do
(println "\n\n===DONE\n\n")
(a/>! result-chan acc) ; Put the current accumulator onto the result channel
(a/close! result-chan)) ; Close the result channel
(do
; If the event is not :done, add it to the accumulator and recur
(print (-> event :choices first :delta :content))
(recur (conj acc event)))))))
; Return the contents of result channel
(<!! result-chan)))
{:id "chatcmpl-8HcW8zRc3701osbNBMixkXPAP4ifi",
:object "chat.completion.chunk",
:created 1699210328,
:model "gpt-3.5-turbo-0613",
:choices [{:index 0, :delta {:content "."}, :finish_reason nil}]};
(defn call-and-stream!
[]
(let [chan (call-openai!)
retval (read-all! chan)]
retval))
(defn extract-text
" given sequence of completions, extract the text "
[coll]
(->> coll
(map #(-> % :choices first :delta :content))
(apply str)))
(comment
(def retval (call-and-stream!))
; (tap> ^{:portal.viewer/default :portal.viewer/hiccup} [:h1 "hello, world"])
;#_(tap> ^{:portal.viewer/default :portal.viewer/markdown}
; "# Heading 1 \n\nparagraph 1 \n\n paragraph 2")
(tap>
(with-meta
[:portal.viewer/markdown "# Heading 1 \n\nparagraph 1 \n\n paragraph 2"]
{:portal.viewer/default :portal.viewer/hiccup}))
(tap> ^{:portal.viewer/default :portal.viewer/markdown} (extract-text retval))
(tap>
(with-meta
[:portal.viewer/markdown (extract-text retval)]
{:portal.viewer/default :portal.viewer/hiccup}))
(tap> retval)
0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment