Skip to content

Commit d3c02a1

Browse files
committed
Convert API types to OpenAIService
1 parent fd7f92d commit d3c02a1

2 files changed

Lines changed: 55 additions & 76 deletions

File tree

Tool/Sources/OpenAIService/APIs/OpenAICompletionAPI.swift

Lines changed: 0 additions & 73 deletions
This file was deleted.

Tool/Sources/OpenAIService/APIs/OpenAICompletionStreamAPI.swift renamed to Tool/Sources/OpenAIService/APIs/OpenAIService.swift

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,20 @@ import AsyncAlgorithms
33
import Foundation
44
import Preferences
55

6-
struct OpenAICompletionStreamAPI: ChatCompletionsStreamAPI {
6+
actor OpenAIService: ChatCompletionsStreamAPI, ChatCompletionsAPI {
7+
struct CompletionAPIError: Error, Codable, LocalizedError {
8+
struct E: Codable {
9+
var message: String
10+
var type: String
11+
var param: String
12+
var code: String
13+
}
14+
15+
var error: E
16+
17+
var errorDescription: String? { error.message }
18+
}
19+
720
var apiKey: String
821
var endpoint: URL
922
var requestBody: ChatCompletionsRequestBody
@@ -18,11 +31,13 @@ struct OpenAICompletionStreamAPI: ChatCompletionsStreamAPI {
1831
self.apiKey = apiKey
1932
self.endpoint = endpoint
2033
self.requestBody = requestBody
21-
self.requestBody.stream = true
2234
self.model = model
2335
}
2436

25-
func callAsFunction() async throws -> AsyncThrowingStream<ChatCompletionsStreamDataChunk, Error> {
37+
func callAsFunction() async throws
38+
-> AsyncThrowingStream<ChatCompletionsStreamDataChunk, Error>
39+
{
40+
requestBody.stream = true
2641
var request = URLRequest(url: endpoint)
2742
request.httpMethod = "POST"
2843
let encoder = JSONEncoder()
@@ -81,5 +96,42 @@ struct OpenAICompletionStreamAPI: ChatCompletionsStreamAPI {
8196

8297
return stream
8398
}
99+
100+
func callAsFunction() async throws -> ChatCompletionResponseBody {
101+
requestBody.stream = false
102+
var request = URLRequest(url: endpoint)
103+
request.httpMethod = "POST"
104+
let encoder = JSONEncoder()
105+
request.httpBody = try encoder.encode(requestBody)
106+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
107+
if !apiKey.isEmpty {
108+
switch model.format {
109+
case .openAI, .openAICompatible:
110+
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
111+
case .azureOpenAI:
112+
request.setValue(apiKey, forHTTPHeaderField: "api-key")
113+
case .googleAI:
114+
assertionFailure("Unsupported")
115+
}
116+
}
117+
118+
let (result, response) = try await URLSession.shared.data(for: request)
119+
guard let response = response as? HTTPURLResponse else {
120+
throw ChatGPTServiceError.responseInvalid
121+
}
122+
123+
guard response.statusCode == 200 else {
124+
let error = try? JSONDecoder().decode(CompletionAPIError.self, from: result)
125+
throw error ?? ChatGPTServiceError
126+
.otherError(String(data: result, encoding: .utf8) ?? "Unknown Error")
127+
}
128+
129+
do {
130+
return try JSONDecoder().decode(ChatCompletionResponseBody.self, from: result)
131+
} catch {
132+
dump(error)
133+
throw error
134+
}
135+
}
84136
}
85137

0 commit comments

Comments
 (0)