-
Notifications
You must be signed in to change notification settings - Fork 55
/
eventsource_ex_chatgpt.exs
86 lines (69 loc) · 1.76 KB
/
eventsource_ex_chatgpt.exs
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Usage: elixir eventsource_ex_chatgpt.exs openai-api-key "prompt"
Mix.install([
{:eventsource_ex, "~> 2.0"},
{:httpoison, "~> 1.5"},
{:jason, "~> 1.4"}
])
defmodule ChatGPTStreamer do
use GenServer
def start_link(state) do
GenServer.start_link(__MODULE__, state)
end
def init(state) do
{:ok, request_completion(state[:api_key], state[:messages], state[:parent_pid])}
end
def handle_info(
%EventsourceEx.Message{
data: "[DONE]",
event: "message"
},
parent_pid
) do
IO.puts("")
send(parent_pid, :done)
{:stop, :normal, nil}
end
def handle_info(
%EventsourceEx.Message{
data: jason_payload,
event: "message"
},
state
) do
jason_payload |> Jason.decode!() |> extract_text() |> IO.write()
{:noreply, state}
end
def extract_text(%{"choices" => choices}) do
for %{"delta" => %{"content" => content}} <- choices, into: "", do: content
end
def extract_text(_) do
""
end
@chat_completion_url "https://api.openai.com/v1/chat/completions"
@model "gpt-3.5-turbo"
defp request_completion(api_key, messages, parent_pid) do
body = %{
model: @model,
messages: messages,
stream: true
}
headers = [
{"Authorization", "Bearer #{api_key}"},
{"Content-Type", "application/json"}
]
options = [method: :post, body: Jason.encode!(body), headers: headers]
{:ok, _pid} = EventsourceEx.new(@chat_completion_url, options)
parent_pid
end
end
Logger.configure(level: :info)
[api_key, prompt] = System.argv()
{:ok, _pid} =
ChatGPTStreamer.start_link(
api_key: api_key,
messages: [%{role: "user", content: prompt}],
parent_pid: self()
)
receive do
:done -> true
end