Streaming multiple payloads through a response on swift Vapor 4

33 Views Asked by At

I need a way to send data to my client ios app from vapor backend on stream. I'm using openAI chat complation.

I used these code on my vapor backend, but these just retrieve reponse on a single payload.

    func chatSteram(req: Request) async throws -> Response {
        let chats = try req.content.decode([ChatQuery.ChatCompletionMessageParam].self)
        let userName = req.headers.first(name: "userName")
        guard (req.headers.first(name: "deviceUniqueId") != nil) else { throw Abort(.custom(code: 511, reasonPhrase: "user id required"))}
        let query = ChatQuery(messages: chats, model: .gpt4_0125_preview, n: 1, temperature: 1, user: userName)
        let body = Response.Body(stream: { writer in
        let encoder = JSONEncoder()
            Task {
                do {
                    for try await res in req.openAI.chatsStream(query: query) {
                        if let data = try? encoder.encode(res), let string = String(data: data, encoding: .utf8) {
                            print("string response is \(string)")
                            _ = writer.write(.buffer(.init(string: string)))
                        }
                    }
                } catch {
                    req.logger.error("Stream Error: \(error)")
                }
                _ = writer.write(.end)
            }
        })
        let res = Response(status: .ok, body: body)
        return res
    }

but when I change do block to these

do {             
    for try await res in req.openAI.chatsStream(query: query) {
                        if let next = res.choices.first?.delta.content {
                            print("string response is \(string)")
                            _ = writer.write(.buffer(.init(string: string)))
                        }
                    }
                }

these works as I exppected. but in my client side I need whole object, not just message.

0

There are 0 best solutions below