Run the full stream processing loop with retry support. Returns `ProcessResult` matching the TS "compact" | "stop" | "continue".
(
&mut self,
stream_input: StreamInput,
provider: Arc<dyn Provider>,
)
| 301 | /// Run the full stream processing loop with retry support. |
| 302 | /// Returns `ProcessResult` matching the TS "compact" | "stop" | "continue". |
| 303 | pub async fn process( |
| 304 | &mut self, |
| 305 | stream_input: StreamInput, |
| 306 | provider: Arc<dyn Provider>, |
| 307 | ) -> ProcessResult { |
| 308 | self.needs_compaction = false; |
| 309 | self.model_limits = Some(resolve_model_limits(&stream_input, provider.as_ref())); |
| 310 | |
| 311 | loop { |
| 312 | match self.process_stream(&stream_input, provider.clone()).await { |
| 313 | Ok(()) => {} |
| 314 | Err(e) => { |
| 315 | tracing::error!( |
| 316 | session_id = %self.session_id, |
| 317 | error = %e, |
| 318 | "Stream processing error" |
| 319 | ); |
| 320 | |
| 321 | let error = |
| 322 | crate::message_v2::error_from_anyhow(e, &stream_input.model.provider_id); |
| 323 | |
| 324 | let retry_msg = retry::retryable(&error); |
| 325 | if let Some(retry_message) = retry_msg { |
| 326 | self.attempt += 1; |
| 327 | |
| 328 | let api_info = match &error { |
| 329 | MessageError::ApiError { |
| 330 | message, |
| 331 | is_retryable, |
| 332 | response_headers, |
| 333 | response_body, |
| 334 | .. |
| 335 | } => Some(ApiErrorInfo { |
| 336 | message: message.clone(), |
| 337 | is_retryable: *is_retryable, |
| 338 | response_headers: response_headers.clone(), |
| 339 | response_body: response_body.clone(), |
| 340 | }), |
| 341 | _ => None, |
| 342 | }; |
| 343 | |
| 344 | let delay_ms = retry::delay(self.attempt, api_info.as_ref()); |
| 345 | |
| 346 | tracing::info!( |
| 347 | session_id = %self.session_id, |
| 348 | attempt = self.attempt, |
| 349 | delay_ms = delay_ms, |
| 350 | message = %retry_message, |
| 351 | "Retrying after error" |
| 352 | ); |
| 353 | |
| 354 | // Sleep with cancellation support |
| 355 | let _ = |
| 356 | retry::sleep_with_cancel(delay_ms, stream_input.abort.clone()).await; |
| 357 | |
| 358 | continue; |
| 359 | } |
| 360 |
nothing calls this directly
no test coverage detected