| 544 | #[instrument(skip(self, py), fields(message_count = messages.len()))] |
| 545 | #[pyo3(signature = (messages, max_tokens=None, temperature=None, enable_prompt_caching=false))] |
| 546 | fn chat_optimized<'a>( |
| 547 | &self, |
| 548 | messages: Vec<(String, String)>, |
| 549 | max_tokens: Option<i64>, |
| 550 | temperature: Option<f64>, |
| 551 | enable_prompt_caching: bool, |
| 552 | py: Python<'a>, |
| 553 | ) -> PyResult<Bound<'a, PyAny>> { |
| 554 | // Validate messages |
| 555 | if messages.is_empty() { |
| 556 | return Err(validation_error( |
| 557 | "messages", |
| 558 | None, |
| 559 | "Messages list cannot be empty", |
| 560 | )); |
| 561 | } |
| 562 | |
| 563 | // Validate max_tokens |
| 564 | let validated_max_tokens = if let Some(tokens) = max_tokens { |
| 565 | if tokens <= 0 { |
| 566 | return Err(validation_error( |
| 567 | "max_tokens", |
| 568 | Some(&tokens.to_string()), |
| 569 | "max_tokens must be greater than 0", |
| 570 | )); |
| 571 | } |
| 572 | if tokens > u32::MAX as i64 { |
| 573 | return Err(validation_error( |
| 574 | "max_tokens", |
| 575 | Some(&tokens.to_string()), |
| 576 | "max_tokens is too large", |
| 577 | )); |
| 578 | } |
| 579 | Some(tokens as u32) |
| 580 | } else { |
| 581 | None |
| 582 | }; |
| 583 | |
| 584 | // Validate temperature |
| 585 | let validated_temperature = if let Some(temp) = temperature { |
| 586 | if !(0.0..=2.0).contains(&temp) { |
| 587 | return Err(validation_error( |
| 588 | "temperature", |
| 589 | Some(&temp.to_string()), |
| 590 | "temperature must be between 0.0 and 2.0", |
| 591 | )); |
| 592 | } |
| 593 | Some(temp as f32) |
| 594 | } else { |
| 595 | None |
| 596 | }; |
| 597 | |
| 598 | let provider = Arc::clone(&self.provider); |
| 599 | let circuit_breaker = Arc::clone(&self.circuit_breaker); |
| 600 | let stats = Arc::clone(&self.stats); |
| 601 | let config = self.config.clone(); |
| 602 | |
| 603 | pyo3_async_runtimes::tokio::future_into_py(py, async move { |