(
provider: &crate::models::Provider,
model: &str,
messages: &[Value],
)
| 973 | } |
| 974 | |
| 975 | async fn generate_title_anthropic( |
| 976 | provider: &crate::models::Provider, |
| 977 | model: &str, |
| 978 | messages: &[Value], |
| 979 | ) -> AppResult<String> { |
| 980 | // Extract system message and user/assistant messages |
| 981 | let system = messages |
| 982 | .first() |
| 983 | .and_then(|m| m["content"].as_str()) |
| 984 | .unwrap_or(""); |
| 985 | |
| 986 | let non_system: Vec<Value> = messages |
| 987 | .iter() |
| 988 | .filter(|m| m["role"].as_str() != Some("system")) |
| 989 | .cloned() |
| 990 | .collect(); |
| 991 | |
| 992 | let payload = serde_json::json!({ |
| 993 | "model": model, |
| 994 | "max_tokens": 20, |
| 995 | "system": system, |
| 996 | "messages": non_system, |
| 997 | "temperature": 0.3, |
| 998 | }); |
| 999 | |
| 1000 | // Resolve endpoint: same logic as send_anthropic |
| 1001 | let endpoint = if provider.provider_type == "anthropic" { |
| 1002 | "https://api.anthropic.com/v1/messages".to_string() |
| 1003 | } else if provider.provider_type == "enowxlabs" { |
| 1004 | format!("{}/messages", provider.base_url.trim_end_matches('/').trim_end_matches("/v1")) |
| 1005 | } else { |
| 1006 | format!("{}/messages", provider.base_url.trim_end_matches('/')) |
| 1007 | }; |
| 1008 | |
| 1009 | let client = http_client::request_client()?; |
| 1010 | let mut request = client |
| 1011 | .post(&endpoint) |
| 1012 | .header(CONTENT_TYPE, "application/json") |
| 1013 | .header("anthropic-version", "2023-06-01") |
| 1014 | .json(&payload); |
| 1015 | |
| 1016 | // Auth: x-api-key for Anthropic direct, Bearer for gateways |
| 1017 | if let Some(key) = provider.api_key.as_deref().filter(|k| !k.trim().is_empty()) { |
| 1018 | if provider.provider_type == "anthropic" { |
| 1019 | request = request.header("x-api-key", key); |
| 1020 | } else { |
| 1021 | request = request.header(AUTHORIZATION, format!("Bearer {key}")); |
| 1022 | } |
| 1023 | } |
| 1024 | |
| 1025 | let response = request.send().await?; |
| 1026 | if !response.status().is_success() { |
| 1027 | let status = response.status(); |
| 1028 | let body = response.text().await.unwrap_or_default(); |
| 1029 | return Err(AppError::Http(format!("{status}: {body}"))); |
| 1030 | } |
| 1031 | |
| 1032 | let body: Value = response.json().await?; |
no test coverage detected