steer_core/api/openai/
client.rs1use super::OpenAIMode;
2use super::chat;
3use super::responses;
4use crate::api::error::ApiError;
5use crate::api::provider::{CompletionResponse, Provider};
6use crate::app::conversation::Message;
7use crate::config::model::{ModelId, ModelParameters};
8use async_trait::async_trait;
9use steer_tools::ToolSchema;
10use tokio_util::sync::CancellationToken;
11
12pub struct OpenAIClient {
17 responses_client: responses::Client,
18 chat_client: chat::Client,
19 default_mode: OpenAIMode,
20}
21
22impl OpenAIClient {
23 pub fn with_mode(api_key: String, mode: OpenAIMode) -> Self {
25 Self {
26 responses_client: responses::Client::new(api_key.clone()),
27 chat_client: chat::Client::new(api_key),
28 default_mode: mode,
29 }
30 }
31
32 pub fn with_base_url_mode(api_key: String, base_url: Option<String>, mode: OpenAIMode) -> Self {
34 Self {
35 responses_client: responses::Client::with_base_url(api_key.clone(), base_url.clone()),
36 chat_client: chat::Client::with_base_url(api_key, base_url),
37 default_mode: mode,
38 }
39 }
40}
41
42#[async_trait]
43impl Provider for OpenAIClient {
44 fn name(&self) -> &'static str {
45 "openai"
46 }
47
48 async fn complete(
49 &self,
50 model_id: &ModelId,
51 messages: Vec<Message>,
52 system: Option<String>,
53 tools: Option<Vec<ToolSchema>>,
54 call_options: Option<ModelParameters>,
55 token: CancellationToken,
56 ) -> Result<CompletionResponse, ApiError> {
57 match self.default_mode {
58 OpenAIMode::Responses => {
59 self.responses_client
60 .complete(model_id, messages, system, tools, call_options, token)
61 .await
62 }
63 OpenAIMode::Chat => {
64 self.chat_client
65 .complete(model_id, messages, system, tools, call_options, token)
66 .await
67 }
68 }
69 }
70}