(
&self,
request: LlmRequest,
)
| 320 | } |
| 321 | |
| 322 | async fn stream( |
| 323 | &self, |
| 324 | request: LlmRequest, |
| 325 | ) -> GraphBitResult<Box<dyn Stream<Item = GraphBitResult<LlmResponse>> + Unpin + Send>> { |
| 326 | let url = format!("{}/messages", self.base_url); |
| 327 | |
| 328 | let enable_caching = request.enable_prompt_caching; |
| 329 | let (system_prompt, messages) = Self::convert_messages(&request.messages, enable_caching); |
| 330 | |
| 331 | // Convert tools to `Anthropic` format |
| 332 | let tools: Option<Vec<AnthropicTool>> = if request.tools.is_empty() { |
| 333 | None |
| 334 | } else { |
| 335 | let last_idx = request.tools.len() - 1; |
| 336 | Some( |
| 337 | request |
| 338 | .tools |
| 339 | .iter() |
| 340 | .enumerate() |
| 341 | .map(|(i, t)| Self::convert_tool(t, enable_caching && i == last_idx)) |
| 342 | .collect(), |
| 343 | ) |
| 344 | }; |
| 345 | |
| 346 | let body = AnthropicStreamRequest { |
| 347 | model: self.model.clone(), |
| 348 | max_tokens: request.max_tokens.unwrap_or(4096), |
| 349 | messages, |
| 350 | system: system_prompt, |
| 351 | temperature: request.temperature, |
| 352 | top_p: request.top_p, |
| 353 | tools, |
| 354 | stream: true, // Enable streaming |
| 355 | }; |
| 356 | |
| 357 | // Timeout constants for different phases of the request |
| 358 | const CONNECTION_TIMEOUT: Duration = Duration::from_secs(60); |
| 359 | const ERROR_BODY_TIMEOUT: Duration = Duration::from_secs(10); |
| 360 | const CHUNK_TIMEOUT: Duration = Duration::from_secs(30); |
| 361 | |
| 362 | // Apply timeout to initial connection |
| 363 | let mut stream_req = self |
| 364 | .client |
| 365 | .post(&url) |
| 366 | .header("x-api-key", &self.api_key) |
| 367 | .header("Content-Type", "application/json") |
| 368 | .header("anthropic-version", "2023-06-01"); |
| 369 | |
| 370 | if enable_caching { |
| 371 | stream_req = |
| 372 | stream_req.header("anthropic-beta", "prompt-caching-2024-07-31"); |
| 373 | } |
| 374 | |
| 375 | let response = timeout(CONNECTION_TIMEOUT, stream_req.json(&body).send()) |
| 376 | .await |
| 377 | .map_err(|_| { |
| 378 | GraphBitError::llm_provider( |
| 379 | "anthropic", |
nothing calls this directly
no test coverage detected