openai_ergonomic/responses/
mod.rs1use openai_client_base::models::{
30 AssistantsNamedToolChoiceFunction, ChatCompletionTool, ChatCompletionToolChoiceOption,
31 CompletionUsage, CreateChatCompletionResponse, CreateChatCompletionStreamResponse,
32 FunctionObject,
33};
34
35pub mod assistants;
36pub mod audio;
37pub mod batch;
38pub mod chat;
39pub mod embeddings;
40pub mod files;
41pub mod fine_tuning;
42pub mod images;
43pub mod moderations;
44pub mod threads;
45pub mod uploads;
46pub mod vector_stores;
47
48pub use chat::*; pub trait Response {
65 fn id(&self) -> Option<&str>;
67
68 fn model(&self) -> Option<&str>;
70
71 fn usage(&self) -> Option<&CompletionUsage>;
73}
74
75#[derive(Debug, Clone)]
77pub struct ChatCompletionResponseWrapper {
78 inner: CreateChatCompletionResponse,
79 base_url: Option<String>,
80}
81
82impl ChatCompletionResponseWrapper {
83 pub fn new(response: CreateChatCompletionResponse) -> Self {
85 Self {
86 inner: response,
87 base_url: None,
88 }
89 }
90
91 pub fn with_base_url(response: CreateChatCompletionResponse, base_url: String) -> Self {
93 Self {
94 inner: response,
95 base_url: Some(base_url),
96 }
97 }
98
99 pub fn content(&self) -> Option<&str> {
101 self.inner.choices.first()?.message.content.as_deref()
102 }
103
104 pub fn choices(
106 &self,
107 ) -> &[openai_client_base::models::CreateChatCompletionResponseChoicesInner] {
108 &self.inner.choices
109 }
110
111 pub fn tool_calls(
113 &self,
114 ) -> Vec<&openai_client_base::models::ChatCompletionMessageToolCallsInner> {
115 self.inner
116 .choices
117 .first()
118 .and_then(|c| c.message.tool_calls.as_ref())
119 .map(|calls| calls.iter().collect())
120 .unwrap_or_default()
121 }
122
123 pub fn is_refusal(&self) -> bool {
125 self.inner
126 .choices
127 .first()
128 .and_then(|c| c.message.refusal.as_ref())
129 .is_some()
130 }
131
132 pub fn refusal(&self) -> Option<&str> {
134 self.inner
135 .choices
136 .first()
137 .and_then(|c| c.message.refusal.as_ref())
138 .map(std::string::String::as_str)
139 }
140
141 pub fn finish_reason(&self) -> Option<String> {
143 use openai_client_base::models::create_chat_completion_response_choices_inner::FinishReason;
144 self.inner.choices.first().map(|c| match &c.finish_reason {
145 FinishReason::Stop => "stop".to_string(),
146 FinishReason::Length => "length".to_string(),
147 FinishReason::ToolCalls => "tool_calls".to_string(),
148 FinishReason::ContentFilter => "content_filter".to_string(),
149 FinishReason::FunctionCall => "function_call".to_string(),
150 })
151 }
152
153 pub fn url(&self) -> Option<String> {
155 self.base_url
156 .as_ref()
157 .map(|base| format!("{}/chat/{}", base, self.inner.id))
158 }
159
160 pub fn inner(&self) -> &CreateChatCompletionResponse {
162 &self.inner
163 }
164}
165
166impl Response for ChatCompletionResponseWrapper {
167 fn id(&self) -> Option<&str> {
168 Some(&self.inner.id)
169 }
170
171 fn model(&self) -> Option<&str> {
172 Some(&self.inner.model)
173 }
174
175 fn usage(&self) -> Option<&CompletionUsage> {
176 self.inner.usage.as_deref()
177 }
178}
179
180#[derive(Debug, Clone)]
182pub struct ChatCompletionStreamResponseWrapper {
183 inner: CreateChatCompletionStreamResponse,
184}
185
186impl ChatCompletionStreamResponseWrapper {
187 pub fn new(response: CreateChatCompletionStreamResponse) -> Self {
189 Self { inner: response }
190 }
191
192 pub fn delta_content(&self) -> Option<&str> {
194 self.inner
195 .choices
196 .first()
197 .and_then(|c| c.delta.content.as_ref())
198 .and_then(|c| c.as_ref())
199 .map(std::string::String::as_str)
200 }
201
202 pub fn delta_tool_calls(
204 &self,
205 ) -> Vec<&openai_client_base::models::ChatCompletionMessageToolCallChunk> {
206 self.inner
207 .choices
208 .first()
209 .and_then(|c| c.delta.tool_calls.as_ref())
210 .map(|calls| calls.iter().collect())
211 .unwrap_or_default()
212 }
213
214 pub fn is_finished(&self) -> bool {
216 use openai_client_base::models::create_chat_completion_stream_response_choices_inner::FinishReason;
217 self.inner.choices.first().is_none_or(|c| {
218 !matches!(
219 c.finish_reason,
220 FinishReason::Stop
221 | FinishReason::Length
222 | FinishReason::ToolCalls
223 | FinishReason::ContentFilter
224 | FinishReason::FunctionCall
225 )
226 })
227 }
228
229 pub fn inner(&self) -> &CreateChatCompletionStreamResponse {
231 &self.inner
232 }
233}
234
235#[must_use]
239pub fn tool_function(
240 name: impl Into<String>,
241 description: impl Into<String>,
242 parameters: serde_json::Value,
243) -> ChatCompletionTool {
244 use std::collections::HashMap;
245
246 let params_map = if let serde_json::Value::Object(map) = parameters {
248 map.into_iter()
249 .collect::<HashMap<String, serde_json::Value>>()
250 } else {
251 HashMap::new()
252 };
253
254 ChatCompletionTool {
255 r#type: openai_client_base::models::chat_completion_tool::Type::Function,
256 function: Box::new(FunctionObject {
257 name: name.into(),
258 description: Some(description.into()),
259 parameters: Some(params_map),
260 strict: None,
261 }),
262 }
263}
264
265#[must_use]
267pub fn tool_web_search() -> ChatCompletionTool {
268 tool_function(
269 "web_search",
270 "Search the web for current information",
271 serde_json::json!({
272 "type": "object",
273 "properties": {
274 "query": {
275 "type": "string",
276 "description": "The search query"
277 }
278 },
279 "required": ["query"],
280 "additionalProperties": false
281 }),
282 )
283}
284
285pub struct ToolChoiceHelper;
287
288impl ToolChoiceHelper {
289 pub fn auto() -> ChatCompletionToolChoiceOption {
291 use openai_client_base::models::chat_completion_tool_choice_option::ChatCompletionToolChoiceOptionAutoEnum;
292 ChatCompletionToolChoiceOption::Auto(ChatCompletionToolChoiceOptionAutoEnum::Auto)
293 }
294
295 pub fn none() -> ChatCompletionToolChoiceOption {
297 use openai_client_base::models::chat_completion_tool_choice_option::ChatCompletionToolChoiceOptionAutoEnum;
298 ChatCompletionToolChoiceOption::Auto(ChatCompletionToolChoiceOptionAutoEnum::None)
299 }
300
301 pub fn required() -> ChatCompletionToolChoiceOption {
303 use openai_client_base::models::chat_completion_tool_choice_option::ChatCompletionToolChoiceOptionAutoEnum;
304 ChatCompletionToolChoiceOption::Auto(ChatCompletionToolChoiceOptionAutoEnum::Required)
305 }
306
307 pub fn specific(name: impl Into<String>) -> ChatCompletionToolChoiceOption {
309 ChatCompletionToolChoiceOption::Chatcompletionnamedtoolchoice(
310 openai_client_base::models::ChatCompletionNamedToolChoice {
311 r#type:
312 openai_client_base::models::chat_completion_named_tool_choice::Type::Function,
313 function: Box::new(AssistantsNamedToolChoiceFunction { name: name.into() }),
314 },
315 )
316 }
317}
318
319pub use openai_client_base::models::{
321 ChatCompletionMessageToolCall as ToolCall,
322 ChatCompletionResponseMessageFunctionCall as FunctionCall, ChatCompletionTool as Tool,
323 ChatCompletionToolChoiceOption as ToolChoice, CompletionUsage as Usage,
324 CreateChatCompletionResponse as ChatResponse,
325 CreateChatCompletionStreamResponse as StreamResponse,
326};
327
328#[derive(Debug, Clone)]
330pub struct ResponseBuilder;
331
332#[derive(Debug, Clone)]
334pub struct ResponsePlaceholder;