Skip to content

Commit a57c2ac

Browse files
fim completion request
1 parent c38c806 commit a57c2ac

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

Sources/DeepSwiftSeek/DeepSeekService.swift

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,69 @@ public final class DeepSeekClient: DeepSeekService, Sendable {
4141
self.serializer = DeepSeekRequestSerializer(configuration: configuration)
4242
}
4343

44+
public func fimCompletionStream(
45+
messages: () -> [ChatMessageRequest],
46+
model: DeepSeekModel,
47+
parameters: ChatParameters
48+
) async throws -> AsyncThrowingStream<String, any Error> {
49+
let streamParameters = parameters.withStream(true)
50+
51+
let request = try serializer.serializeFIMCompletionRequest(
52+
messages: messages(),
53+
model: model,
54+
parameters: streamParameters
55+
)
56+
57+
return AsyncThrowingStream { @Sendable continuation in
58+
Task {
59+
do {
60+
let (bytes, response) = try await session.bytes(for: request)
61+
62+
guard let httpResponse = response as? HTTPURLResponse else {
63+
continuation.finish(throwing: DeepSeekError.invalidFormat(message: "Invalid Response from the server"))
64+
return
65+
}
66+
67+
guard (200...299).contains(httpResponse.statusCode) else {
68+
var errorData = Data()
69+
for try await byte in bytes {
70+
errorData.append(byte)
71+
}
72+
73+
if let errorResponse = try? JSONDecoder().decode(DeepSeekErrorResponse.self, from: errorData) {
74+
continuation.finish(throwing: DeepSeekError.from(errorResponse, statusCode: httpResponse.statusCode))
75+
} else {
76+
continuation.finish(throwing: DeepSeekError.unknown(statusCode: httpResponse.statusCode, message: "Unknown streaming error"))
77+
}
78+
return
79+
}
80+
81+
for try await line in bytes.lines {
82+
guard !line.isEmpty else { continue }
83+
84+
if line.contains("[DONE]") {
85+
continuation.finish()
86+
return
87+
}
88+
89+
let jsonString = line.hasPrefix("data: ") ? String(line.dropFirst(6)) : line
90+
91+
if let data = jsonString.data(using: .utf8),
92+
let streamResponse = try? JSONDecoder().decode(ChatCompletionResponse.self, from: data)
93+
{
94+
let content = streamResponse.choices[0].message.content
95+
continuation.yield(content)
96+
}
97+
}
98+
99+
continuation.finish()
100+
} catch {
101+
continuation.finish(throwing: error)
102+
}
103+
}
104+
}
105+
}
106+
44107
@available(iOS 15.0, *)
45108
public func chatCompletionStream(
46109
messages: () -> [ChatMessageRequest],
@@ -120,6 +183,37 @@ public final class DeepSeekClient: DeepSeekService, Sendable {
120183
return try JSONDecoder().decode(DeepSeekModelsList.self, from: data)
121184
}
122185

186+
public func fimCompletions(
187+
messages: () -> [ChatMessageRequest],
188+
model: DeepSeekModel,
189+
parameters: ChatParameters
190+
) async throws -> ChatCompletionResponse {
191+
let request = try serializer.serializeFIMCompletionRequest(
192+
messages: messages(),
193+
model: model,
194+
parameters: parameters
195+
)
196+
197+
do {
198+
let (data, response) = try await session.data(for: request)
199+
200+
guard let httpResponse = response as? HTTPURLResponse else {
201+
throw DeepSeekError.invalidFormat(message: "Invalid Response from the server")
202+
}
203+
204+
guard (200...299).contains(httpResponse.statusCode) else {
205+
throw DeepSeekError.from(statusCode: httpResponse.statusCode, message: nil)
206+
}
207+
208+
return try JSONDecoder().decode(ChatCompletionResponse.self, from: data)
209+
} catch {
210+
if let deepSeekError = error as? DeepSeekError {
211+
throw deepSeekError
212+
}
213+
throw DeepSeekError.unknown(statusCode: 0, message: error.localizedDescription)
214+
}
215+
}
216+
123217
public func chatCompletions(
124218
messages: () -> [ChatMessageRequest],
125219
model: DeepSeekModel,

0 commit comments

Comments
 (0)