I'm looking to create a simple CLI in Swift for working with OpenAI's GPT models. I've tried various approaches. The code below is the simplest version and still not functional -- I believe the closure is not being called.
let endpoint = "https://api.openai.com/v1/completions"
let headers = [
"Content-Type": "application/json",
"Authorization": "Bearer \(oai_key)"
]
let prompt = "Create a simple function in Swift that adds two numbers."
let parameters = [
"model": "text-curie-001",
"prompt": prompt,
"max_tokens": 500,
"temperature": 0.5,
"n": 1
] as [String: Any]
let urlObject = URL(string: endpoint)!
var request = URLRequest(url: urlObject)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters)
} catch {
print(error)
}
func processResponseData(_ data: Data) {
print(String(data: data, encoding: .utf8) ?? "")
}
let newTask = URLSession.shared.dataTask(with: request) {
data, response, error in
print("Completion handler closure called")
if (error != nil) {
print("This error occured: \(String(describing: error))")
} else {
print(String(describing: data))
if let data = data {
processResponseData(data)
}
}
}
print(newTask.state)
newTask.resume()
print(newTask.state)
print(newTask.response)
print(newTask.error)
print(newTask.progress)
The output in the console from executing this is:
NSURLSessionTaskState
NSURLSessionTaskState
nil
nil
<NSProgress: 0x600002c08b80> : Parent: 0x0 (portion: 0) / Fraction completed: 0.0000 / Completed: 0 of 100
<NSProgress: 0x600002c08d80> : Parent: 0x600002c08b80 (portion: 95) / Fraction completed: 0.0000 / Completed: 0 of 100
<NSProgress: 0x600002c08d00> : Parent: 0x600002c08b80 (portion: 5) / Fraction completed: 0.0000 / Completed: 0 of 100
Program ended with exit code: 0
Thanks in advance!
Thanks to @vadian -- a runloop
was a great solution.
I ended up cleaning up the code after the runloop
got it working and then found a semaphore
worked well for my implementation.
Here's the code I landed on:
let openAI = OpenAIAPI()
func getInput() -> String {
print("User:")
if let input = readLine() {
return input
}
return ""
}
func handleCompletion(responseText: String?) {
if let responseText = responseText {
print("Response:\n\(responseText)")
} else {
print("Error: Unable to get response")
}
}
while true {
let prompt = getInput()
if prompt.lowercased() == "finished" {
break
}
let semaphore = DispatchSemaphore(value: 0)
openAI.getCompletion(prompt: prompt) { responseText in
handleCompletion(responseText: responseText)
semaphore.signal()
}
semaphore.wait()
}
Note that I wrapped the previous code I posted in an OpenAIAPI
class and added additional functionality to it.