Files
luma/Sources/LumaCore/Agentic/ServerSentEvents.swift

46 lines
1.6 KiB
Swift

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
struct ServerSentEventStream {
let http: HTTPURLResponse
let lines: AsyncThrowingStream<String, Error>
}
func openServerSentEventStream(session: URLSession, request: URLRequest) async throws -> ServerSentEventStream {
#if canImport(FoundationNetworking)
let (data, response) = try await session.data(for: request)
guard let http = response as? HTTPURLResponse else {
throw LumaCoreError.protocolViolation("Server sent an invalid HTTP response.")
}
let body = String(decoding: data, as: UTF8.self)
let lines = AsyncThrowingStream<String, Error> { continuation in
for line in body.split(separator: "\n", omittingEmptySubsequences: false) {
continuation.yield(String(line))
}
continuation.finish()
}
return ServerSentEventStream(http: http, lines: lines)
#else
let (bytes, response) = try await session.bytes(for: request)
guard let http = response as? HTTPURLResponse else {
throw LumaCoreError.protocolViolation("Server sent an invalid HTTP response.")
}
let lines = AsyncThrowingStream<String, Error> { continuation in
let task = Task {
do {
for try await line in bytes.lines {
continuation.yield(line)
}
continuation.finish()
} catch {
continuation.finish(throwing: error)
}
}
continuation.onTermination = { _ in task.cancel() }
}
return ServerSentEventStream(http: http, lines: lines)
#endif
}