-
-
Notifications
You must be signed in to change notification settings - Fork 121
/
openai.liq
152 lines (141 loc) · 3.34 KB
/
openai.liq
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
let error.openai = error.register("openai")
openai = ()
# @flag hidden
def parse_openai_error(ans, err) =
try
let json.parse (e : {error: {message: string, type: string}}) = ans
e = e.error
error.raise(
error.openai,
"#{e.type}: #{e.message}"
)
catch _ do
error.raise(err)
end
end
# Query ChatGPT API.
# @param ~base_url Base URL for the API query
# @param ~key OpenAI API key.
# @param ~model Language model.
# @param ~timeout Timeout for network operations in seconds.
# @param messages Messages initially exchanged.
# @category Internet
# @flag extra
def openai.chat(
~key,
~base_url="https://api.openai.com",
~model="gpt-3.5-turbo",
~timeout=null(30.),
(
messages:
[
{
role: string,
content: string,
name?: string,
tool_calls?: [
{id: string, type: string, function: {name: string, arguments: string}}
],
tool_call_id?: string
}
]
)
) =
payload = {model=model, messages=messages}
ans =
http.post(
data=json.stringify(payload),
timeout=timeout,
headers=
[
("Content-Type", "application/json"),
(
"Authorization",
"Bearer #{(key : string)}"
)
],
"#{base_url}/v1/chat/completions"
)
if
ans.status_code != 200
then
error.raise(
error.http,
"#{ans.status_code}: #{ans.status_message}"
)
end
try
let json.parse (ans :
{
choices: [
{
finish_reason: string,
index: int,
message: {content: string, role: string}
}
],
created: int,
model: string,
object: string,
usage: {completion_tokens: int, prompt_tokens: int, total_tokens: int}
}
) = ans
ans
catch err : [error.json] do
parse_openai_error(ans, err)
end
end
# Generate speech using openai. Returns the encoded audio data.
# @param ~base_url Base URL for the API query
# @param ~key OpenAI API key.
# @param ~model Language model.
# @param ~timeout Timeout for network operations in seconds.
# @param ~voice The voice to use when generating the audio. Supported voices are `"alloy"`, `"echo"`, `"fable"`, `"onyx"`, `"nova"`, and `"shimmer"`
# @param ~response_format The format to audio in. Supported formats are: `"mp3"`, `"opus"`, `"aac"`, and `"flac"`.
# @param ~speed The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is the default.
# @params ~on_data Function executed when receiving the audio data.
# @category Internet
# @flag extra
def openai.speech(
~key,
~base_url="https://api.openai.com",
~model="tts-1",
~timeout=null(30.),
~voice,
~response_format="mp3",
~speed=1.,
~on_data,
(input:string)
) =
payload =
{
model=model,
input=input,
voice=(voice : string),
response_format=response_format,
speed=speed
}
ans =
http.post.stream(
data=json.stringify(payload),
timeout=timeout,
headers=
[
("Content-Type", "application/json"),
(
"Authorization",
"Bearer #{(key : string)}"
)
],
on_body_data=on_data,
"#{base_url}/v1/audio/speech"
)
if
ans.status_code != 200
then
error.raise(
error.http,
"#{ans.status_code}: #{ans.status_message}"
)
end
end