postStreamRaw method
Make a POST request and return SSE stream
Implementation
Stream<String> postStreamRaw(
String endpoint,
Map<String, dynamic> body,
) async* {
if (config.apiKey.isEmpty) {
throw const AuthError('Missing OpenAI API key');
}
// Reset SSE buffer for new stream
resetSSEBuffer();
try {
if (logger.isLoggable(Level.FINE)) {
logger.fine('OpenAI request: POST /$endpoint (stream)');
logger.fine('OpenAI request headers: ${dio.options.headers}');
}
final response = await dio.post(
endpoint,
data: body,
options: Options(
responseType: ResponseType.stream,
headers: {'Accept': 'text/event-stream'},
),
);
if (response.statusCode != 200) {
_handleErrorResponse(response, endpoint);
}
// Handle ResponseBody properly for streaming
final responseBody = response.data;
Stream<List<int>> stream;
if (responseBody is Stream<List<int>>) {
stream = responseBody;
} else if (responseBody is ResponseBody) {
stream = responseBody.stream;
} else {
throw GenericError(
'Unexpected response type: ${responseBody.runtimeType}');
}
// Use UTF-8 stream decoder to handle incomplete byte sequences
final decoder = Utf8StreamDecoder();
await for (final chunk in stream) {
final decoded = decoder.decode(chunk);
if (decoded.isNotEmpty) {
yield decoded;
}
}
// Flush any remaining bytes
final remaining = decoder.flush();
if (remaining.isNotEmpty) {
yield remaining;
}
} on DioException catch (e) {
throw handleDioError(e);
} catch (e) {
throw GenericError('Unexpected error: $e');
}
}