openai_ergonomic/responses/mod.rs
1//! Response type wrappers and ergonomic helpers.
2//!
3//! This module provides ergonomic wrappers around `OpenAI` API responses with
4//! convenient methods for common operations. The responses-first approach
5//! makes it easy to work with structured outputs and tool calling.
6//!
7//! # Example
8//!
9//! ```rust,ignore
10//! # use openai_ergonomic::responses::*;
11//! // TODO: Add example once responses are implemented
12//! ```
13
14use serde::{Deserialize, Serialize};
15
16pub mod assistants;
17pub mod audio;
18pub mod batch;
19pub mod chat;
20pub mod embeddings;
21pub mod files;
22pub mod fine_tuning;
23pub mod images;
24pub mod moderations;
25pub mod threads;
26pub mod uploads;
27pub mod vector_stores;
28
29// Re-export response types for convenience
30// NOTE: Re-exports will be enabled as modules are implemented
31// pub use assistants::*;
32// pub use audio::*;
33// pub use batch::*;
34pub use chat::*; // Has implementation
35 // pub use embeddings::*;
36 // pub use files::*;
37 // pub use fine_tuning::*;
38 // pub use images::*;
39 // pub use moderations::*;
40 // pub use threads::*;
41 // pub use uploads::*;
42 // pub use vector_stores::*;
43
44// TODO: Import actual types from openai-client-base once available
45// use openai_client_base::responses::*;
46
47/// Common trait for all response types to provide consistent access patterns.
48pub trait Response {
49 /// Get the unique identifier for this response, if available.
50 fn id(&self) -> Option<&str>;
51
52 /// Get the model that generated this response, if available.
53 fn model(&self) -> Option<&str>;
54
55 /// Get any usage information from the response, if available.
56 fn usage(&self) -> Option<&Usage>;
57}
58
59/// Usage information for API calls.
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct Usage {
62 /// Number of tokens in the prompt
63 pub prompt_tokens: u32,
64 /// Number of tokens in the completion (if applicable)
65 pub completion_tokens: Option<u32>,
66 /// Total number of tokens used
67 pub total_tokens: u32,
68}
69
70/// Tool definition for function calling.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct Tool {
73 /// Type of tool (usually "function")
74 #[serde(rename = "type")]
75 pub tool_type: String,
76 /// Function definition for the tool
77 pub function: ToolFunction,
78}
79
80/// Function definition for tool calling.
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct ToolFunction {
83 /// Name of the function
84 pub name: String,
85 /// Description of what the function does
86 pub description: Option<String>,
87 /// JSON Schema defining the function parameters
88 pub parameters: Option<serde_json::Value>,
89}
90
91/// Tool choice options for responses.
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(untagged)]
94pub enum ToolChoice {
95 /// Let the model decide whether to call tools
96 Auto,
97 /// Disable tool calling
98 None,
99 /// Force the model to call a tool
100 Required,
101 /// Force the model to call a specific function
102 Function {
103 /// The function to call
104 function: ToolFunction,
105 },
106}
107
108/// Builder for responses-first structured output requests.
109#[derive(Debug, Clone)]
110#[allow(dead_code)]
111pub struct ResponseBuilder {
112 model: String,
113 messages: Vec<crate::builders::ChatMessage>,
114 tools: Vec<Tool>,
115 tool_choice: Option<ToolChoice>,
116 response_format: Option<serde_json::Value>,
117}
118
119impl ResponseBuilder {
120 /// Create a new response builder with the specified model.
121 #[must_use]
122 pub fn new(model: impl Into<String>) -> Self {
123 Self {
124 model: model.into(),
125 messages: Vec::new(),
126 tools: Vec::new(),
127 tool_choice: None,
128 response_format: None,
129 }
130 }
131
132 /// Add a message to the conversation.
133 #[must_use]
134 pub fn message(mut self, role: impl Into<String>, content: impl Into<String>) -> Self {
135 self.messages.push(crate::builders::ChatMessage {
136 role: role.into(),
137 content: content.into(),
138 });
139 self
140 }
141
142 /// Add a tool for function calling.
143 #[must_use]
144 pub fn tool(mut self, tool: Tool) -> Self {
145 self.tools.push(tool);
146 self
147 }
148
149 /// Set the tool choice strategy.
150 #[must_use]
151 pub fn tool_choice(mut self, tool_choice: ToolChoice) -> Self {
152 self.tool_choice = Some(tool_choice);
153 self
154 }
155
156 /// Set the response format for structured outputs.
157 #[must_use]
158 pub fn response_format(mut self, format: serde_json::Value) -> Self {
159 self.response_format = Some(format);
160 self
161 }
162}
163
164// Helper functions for common tool patterns
165
166/// Create a web search tool definition.
167#[must_use]
168pub fn tool_web_search() -> Tool {
169 Tool {
170 tool_type: "function".to_string(),
171 function: ToolFunction {
172 name: "web_search".to_string(),
173 description: Some("Search the web for current information".to_string()),
174 parameters: Some(serde_json::json!({
175 "type": "object",
176 "properties": {
177 "query": {
178 "type": "string",
179 "description": "The search query"
180 }
181 },
182 "required": ["query"]
183 })),
184 },
185 }
186}
187
188/// Create a function tool definition with JSON schema parameters.
189#[must_use]
190pub fn tool_function(
191 name: impl Into<String>,
192 description: impl Into<String>,
193 parameters: serde_json::Value,
194) -> Tool {
195 Tool {
196 tool_type: "function".to_string(),
197 function: ToolFunction {
198 name: name.into(),
199 description: Some(description.into()),
200 parameters: Some(parameters),
201 },
202 }
203}