(&self, request: LlmRequest)
| 447 | } |
| 448 | |
| 449 | async fn complete(&self, request: LlmRequest) -> GraphBitResult<LlmResponse> { |
| 450 | // Models like gpt-5.2-codex use the Responses API, not chat/completions |
| 451 | if self.is_openai_model() { |
| 452 | tracing::debug!( |
| 453 | "Routing '{}' to Responses API (/openai/responses) for all openai models", |
| 454 | self.deployment_name |
| 455 | ); |
| 456 | return self.complete_with_responses_api(request).await; |
| 457 | } |
| 458 | |
| 459 | // Normalize endpoint URL to avoid double slashes |
| 460 | let endpoint = self.endpoint.trim_end_matches('/'); |
| 461 | let url = format!( |
| 462 | "{}/openai/deployments/{}/chat/completions?api-version={}", |
| 463 | endpoint, self.deployment_name, self.api_version |
| 464 | ); |
| 465 | |
| 466 | let messages: Vec<AzureLlmMessage> = |
| 467 | request.messages.iter().map(Self::convert_message).collect(); |
| 468 | |
| 469 | let tools: Option<Vec<AzureLlmTool>> = if request.tools.is_empty() { |
| 470 | None |
| 471 | } else { |
| 472 | Some(request.tools.iter().map(Self::convert_tool).collect()) |
| 473 | }; |
| 474 | |
| 475 | // Use max_completion_tokens for OpenAI models, max_tokens for others (Claude, Llama, etc.) |
| 476 | let (max_tokens, max_completion_tokens) = if self.is_openai_model() { |
| 477 | (None, request.max_tokens) |
| 478 | } else { |
| 479 | (request.max_tokens, None) |
| 480 | }; |
| 481 | |
| 482 | let body = AzureLlmRequest { |
| 483 | messages, |
| 484 | max_tokens, |
| 485 | max_completion_tokens, |
| 486 | temperature: request.temperature, |
| 487 | top_p: request.top_p, |
| 488 | tools: tools.clone(), |
| 489 | tool_choice: if tools.is_some() { |
| 490 | Some("auto".to_string()) |
| 491 | } else { |
| 492 | None |
| 493 | }, |
| 494 | }; |
| 495 | |
| 496 | // Add extra parameters |
| 497 | let mut request_json = serde_json::to_value(&body)?; |
| 498 | if let serde_json::Value::Object(ref mut map) = request_json { |
| 499 | for (key, value) in request.extra_params { |
| 500 | map.insert(key, value); |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | let response = self |
| 505 | .client |
| 506 | .post(&url) |
nothing calls this directly
no test coverage detected