| 1391 | } |
| 1392 | |
| 1393 | pub async fn do_stream(&self, options: StreamOptions) -> Result<StreamResult, ProviderError> { |
| 1394 | let mut prepared = self.get_args(&options.generate).await?; |
| 1395 | let body_obj = prepared.body.as_object_mut().ok_or_else(|| { |
| 1396 | ProviderError::InvalidRequest("invalid responses request".to_string()) |
| 1397 | })?; |
| 1398 | body_obj.insert("stream".to_string(), Value::Bool(true)); |
| 1399 | |
| 1400 | let url = (self.config.url)("/responses", &self.model_id); |
| 1401 | let headers = self.build_headers("text/event-stream"); |
| 1402 | let request_body = serde_json::to_string(&prepared.body) |
| 1403 | .map_err(|e| ProviderError::InvalidRequest(format!("failed to encode body: {}", e)))?; |
| 1404 | let text_stream: Pin<Box<dyn Stream<Item = Result<String, ProviderError>> + Send>> = |
| 1405 | if let Some(proxy) = get_custom_fetch_proxy(&self.config.provider) { |
| 1406 | let response = proxy |
| 1407 | .fetch_stream(CustomFetchRequest { |
| 1408 | url, |
| 1409 | method: "POST".to_string(), |
| 1410 | headers: headers.clone(), |
| 1411 | body: Some(request_body), |
| 1412 | }) |
| 1413 | .await?; |
| 1414 | if response.status >= 400 { |
| 1415 | return Err(ProviderError::ApiErrorWithStatus { |
| 1416 | message: format!( |
| 1417 | "custom fetch stream request failed with status {}", |
| 1418 | response.status |
| 1419 | ), |
| 1420 | status_code: response.status, |
| 1421 | }); |
| 1422 | } |
| 1423 | response.stream |
| 1424 | } else { |
| 1425 | let client = self.config.client.clone().unwrap_or_default(); |
| 1426 | let mut request = client.post(url); |
| 1427 | for (k, v) in &headers { |
| 1428 | request = request.header(k, v); |
| 1429 | } |
| 1430 | let response = request |
| 1431 | .body(request_body) |
| 1432 | .send() |
| 1433 | .await |
| 1434 | .map_err(|e| ProviderError::NetworkError(e.to_string()))?; |
| 1435 | let status = response.status(); |
| 1436 | if !status.is_success() { |
| 1437 | let body = response.text().await.unwrap_or_default(); |
| 1438 | return Err(ProviderError::ApiErrorWithStatus { |
| 1439 | message: body, |
| 1440 | status_code: status.as_u16(), |
| 1441 | }); |
| 1442 | } |
| 1443 | Box::pin( |
| 1444 | response |
| 1445 | .bytes_stream() |
| 1446 | .map(|chunk_result| match chunk_result { |
| 1447 | Ok(bytes) => Ok(String::from_utf8_lossy(&bytes).to_string()), |
| 1448 | Err(err) => Err(ProviderError::StreamError(err.to_string())), |
| 1449 | }), |
| 1450 | ) |