-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Major refactor to use the "Get" package for all the HTTP work, which …
…makes the code much cleaner and focused.
- Loading branch information
1 parent
d8aabcb
commit b1acfe7
Showing
12 changed files
with
165 additions
and
253 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"pins" : [ | ||
{ | ||
"identity" : "get", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/kean/Get", | ||
"state" : { | ||
"revision" : "12830cc64f31789ae6f4352d2d51d03a25fc3741", | ||
"version" : "2.1.6" | ||
} | ||
} | ||
], | ||
"version" : 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,50 @@ | ||
// Created by B.T. Franklin on 12/23/22 | ||
|
||
import Foundation | ||
import Get | ||
|
||
public struct OpenAIAPIConnection { | ||
public class OpenAIAPIConnection { | ||
|
||
private static let CHAT_COMPLETION_PATH = "/v1/chat/completions" | ||
|
||
let urlRequester: URLRequester | ||
let apiKey: String | ||
let organization: String? | ||
let client: APIClient | ||
|
||
private let requestHeaders: [String:String] | ||
|
||
public init(apiKey: String, organization: String? = nil, urlRequester: URLRequester? = nil) { | ||
public init(apiKey: String, organization: String? = nil) { | ||
self.apiKey = apiKey | ||
self.organization = organization | ||
self.urlRequester = urlRequester ?? HTTPURLRequester() | ||
|
||
var urlComponents = URLComponents() | ||
urlComponents.scheme = "https" | ||
urlComponents.host = "api.openai.com" | ||
let openAIChatCompletionURL = urlComponents.url | ||
|
||
let encoder = JSONEncoder() | ||
encoder.keyEncodingStrategy = .convertToSnakeCase | ||
|
||
var clientConfiguration = APIClient.Configuration(baseURL: openAIChatCompletionURL) | ||
clientConfiguration.encoder = encoder | ||
|
||
self.client = APIClient(configuration: clientConfiguration) | ||
|
||
var requestHeaders = [ | ||
"Content-Type": "application/json", | ||
"Authorization": "Bearer \(apiKey)" | ||
] | ||
if let organization { | ||
requestHeaders["OpenAI-Organization"] = organization | ||
} | ||
self.requestHeaders = requestHeaders | ||
} | ||
|
||
func createRequest(for body: Encodable) async throws -> Request<ChatCompletionResponse> { | ||
Request<ChatCompletionResponse>( | ||
path: Self.CHAT_COMPLETION_PATH, | ||
method: .post, | ||
body: body, | ||
headers: self.requestHeaders) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Created by B.T. Franklin on 5/5/23 | ||
|
||
struct ChatCompletionResponse: Codable { | ||
struct Choice: Codable { | ||
let message: ChatMessage | ||
} | ||
let choices: [Choice] | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Created by B.T. Franklin on 5/5/23 | ||
|
||
public struct ChatMessage: Codable { | ||
public enum Role: String, Codable { | ||
case system | ||
case user | ||
case assistant | ||
} | ||
public let role: Role | ||
public let content: String | ||
|
||
public init(role: Role, | ||
content: String) { | ||
self.role = role | ||
self.content = content | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Created by B.T. Franklin on 5/5/23 | ||
|
||
import Get | ||
|
||
extension OpenAIChatThread { | ||
public func complete() async -> ChatMessage? { | ||
|
||
let requestBody = ChatCompletionRequestBody( | ||
model: self.model, | ||
temperature: self.temperature, | ||
topP: self.topP, | ||
stop: self.stop, | ||
presencePenalty: self.presencePenalty, | ||
frequencyPenalty: self.frequencyPenalty, | ||
user: self.user, | ||
messages: self.messages | ||
) | ||
|
||
do { | ||
let request = try await self.connection.createRequest(for: requestBody) | ||
let response = try await self.connection.client.send(request) | ||
let completion = response.value | ||
|
||
return completion.choices.first?.message | ||
} catch { | ||
logger("Error executing request: \(error.localizedDescription)") | ||
return nil | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Created by B.T. Franklin on 5/5/23 | ||
|
||
extension OpenAIChatThread { | ||
public func tokenCount() -> Int { | ||
|
||
let tokenEncoder: TokenEncoder | ||
do { | ||
tokenEncoder = try TokenEncoder() | ||
} catch { | ||
logger("Unable to create token encoder: \(error)") | ||
return -1 | ||
} | ||
|
||
var tokensPerMessage: Int | ||
|
||
switch self.model { | ||
case .gpt35Turbo: | ||
tokensPerMessage = 4 | ||
case .gpt4: | ||
tokensPerMessage = 3 | ||
} | ||
|
||
var numTokens = 0 | ||
for message in messages { | ||
do { | ||
let roleTokens = try tokenEncoder.encode(text: message.role.rawValue).count | ||
let contentTokens = try tokenEncoder.encode(text: message.content).count | ||
|
||
numTokens += roleTokens + contentTokens + tokensPerMessage | ||
} catch { | ||
logger("Error encoding text: \(error)") | ||
} | ||
} | ||
|
||
numTokens += 3 // every reply is primed with assistant | ||
|
||
return numTokens | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.