@@ -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