Skip to main content

gproxy_protocol/protocol/openai/generate_content/response_tools/
definitions.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use super::super::super::common::*;
7use super::super::response_tools::*;
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10#[serde(tag = "type")]
11#[non_exhaustive]
12pub enum ResponseTool {
13    #[serde(rename = "function")]
14    Function {
15        name: String,
16        parameters: JsonSchema,
17        // Some OpenAI-compatible Responses providers echo `strict: null`.
18        #[serde(skip_serializing_if = "Option::is_none")]
19        strict: Option<bool>,
20        #[serde(skip_serializing_if = "Option::is_none")]
21        defer_loading: Option<bool>,
22        #[serde(skip_serializing_if = "Option::is_none")]
23        description: Option<String>,
24        #[serde(skip_serializing_if = "Option::is_none")]
25        allowed_callers: Option<Vec<ToolCaller>>,
26        #[serde(rename = "async", skip_serializing_if = "Option::is_none")]
27        async_: Option<bool>,
28        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
29        extra: Extra,
30    },
31    #[serde(rename = "file_search")]
32    FileSearch {
33        vector_store_ids: Vec<String>,
34        #[serde(skip_serializing_if = "Option::is_none")]
35        filters: Option<FileSearchFilter>,
36        #[serde(skip_serializing_if = "Option::is_none")]
37        max_num_results: Option<u32>,
38        #[serde(skip_serializing_if = "Option::is_none")]
39        ranking_options: Option<FileSearchRankingOptions>,
40        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
41        extra: Extra,
42    },
43    #[serde(rename = "computer")]
44    Computer {
45        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
46        extra: Extra,
47    },
48    #[serde(rename = "computer_use_preview")]
49    ComputerUsePreview {
50        display_height: u32,
51        display_width: u32,
52        environment: ComputerUseEnvironment,
53        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
54        extra: Extra,
55    },
56    #[serde(rename = "web_search")]
57    WebSearch {
58        #[serde(skip_serializing_if = "Option::is_none")]
59        filters: Option<WebSearchFilters>,
60        // gproxy extension: forwarded to Claude web_search `max_uses`; real OpenAI
61        // upstreams do not accept it, so OpenAI-bound transforms never set it.
62        #[serde(skip_serializing_if = "Option::is_none")]
63        max_uses: Option<u64>,
64        #[serde(skip_serializing_if = "Option::is_none")]
65        search_context_size: Option<SearchContextSize>,
66        #[serde(skip_serializing_if = "Option::is_none")]
67        user_location: Option<WebSearchUserLocation>,
68        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
69        extra: Extra,
70    },
71    #[serde(rename = "web_search_2025_08_26")]
72    WebSearch20250826 {
73        #[serde(skip_serializing_if = "Option::is_none")]
74        filters: Option<WebSearchFilters>,
75        // gproxy extension: see `WebSearch::max_uses`.
76        #[serde(skip_serializing_if = "Option::is_none")]
77        max_uses: Option<u64>,
78        #[serde(skip_serializing_if = "Option::is_none")]
79        search_context_size: Option<SearchContextSize>,
80        #[serde(skip_serializing_if = "Option::is_none")]
81        user_location: Option<WebSearchUserLocation>,
82        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
83        extra: Extra,
84    },
85    // gproxy extension: mirrors the Claude web_fetch tool definition so
86    // Responses-format clients can configure fetch behaviour on Claude routes.
87    // Not part of the official OpenAI Responses API.
88    #[serde(rename = "web_fetch")]
89    WebFetch {
90        #[serde(skip_serializing_if = "Option::is_none")]
91        allowed_domains: Option<Vec<String>>,
92        #[serde(skip_serializing_if = "Option::is_none")]
93        blocked_domains: Option<Vec<String>>,
94        #[serde(skip_serializing_if = "Option::is_none")]
95        max_content_tokens: Option<u64>,
96        #[serde(skip_serializing_if = "Option::is_none")]
97        max_uses: Option<u64>,
98        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
99        extra: Extra,
100    },
101    // gproxy extension: mirrors the Claude memory_20250818 tool definition.
102    #[serde(rename = "memory")]
103    Memory {
104        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
105        extra: Extra,
106    },
107    #[serde(rename = "x_search")]
108    XSearch {
109        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
110        extra: Extra,
111    },
112    #[serde(rename = "collections_search")]
113    CollectionsSearch {
114        vector_store_ids: Vec<String>,
115        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
116        extra: Extra,
117    },
118    #[serde(rename = "mcp")]
119    Mcp {
120        server_label: String,
121        #[serde(skip_serializing_if = "Option::is_none")]
122        allowed_tools: Option<McpAllowedTools>,
123        #[serde(skip_serializing_if = "Option::is_none")]
124        authorization: Option<String>,
125        #[serde(skip_serializing_if = "Option::is_none")]
126        connector_id: Option<McpConnectorId>,
127        #[serde(skip_serializing_if = "Option::is_none")]
128        defer_loading: Option<bool>,
129        #[serde(skip_serializing_if = "Option::is_none")]
130        headers: Option<BTreeMap<String, String>>,
131        #[serde(skip_serializing_if = "Option::is_none")]
132        require_approval: Option<McpRequireApproval>,
133        #[serde(skip_serializing_if = "Option::is_none")]
134        server_description: Option<String>,
135        #[serde(skip_serializing_if = "Option::is_none")]
136        server_url: Option<String>,
137        #[serde(skip_serializing_if = "Option::is_none")]
138        tunnel_id: Option<String>,
139        #[serde(skip_serializing_if = "Option::is_none")]
140        allowed_callers: Option<Vec<ToolCaller>>,
141        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
142        extra: Extra,
143    },
144    #[serde(rename = "code_execution")]
145    CodeExecution {
146        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
147        extra: Extra,
148    },
149    #[serde(rename = "code_interpreter")]
150    CodeInterpreter {
151        container: CodeInterpreterContainer,
152        #[serde(skip_serializing_if = "Option::is_none")]
153        allowed_callers: Option<Vec<ToolCaller>>,
154        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
155        extra: Extra,
156    },
157    #[serde(rename = "image_generation")]
158    ImageGeneration {
159        #[serde(skip_serializing_if = "Option::is_none")]
160        action: Option<ImageGenerationAction>,
161        #[serde(skip_serializing_if = "Option::is_none")]
162        background: Option<ImageBackground>,
163        #[serde(skip_serializing_if = "Option::is_none")]
164        input_fidelity: Option<ImageInputFidelity>,
165        #[serde(skip_serializing_if = "Option::is_none")]
166        input_image_mask: Option<ImageMask>,
167        #[serde(skip_serializing_if = "Option::is_none")]
168        model: Option<OpenAiModelId>,
169        #[serde(skip_serializing_if = "Option::is_none")]
170        moderation: Option<ImageModeration>,
171        #[serde(skip_serializing_if = "Option::is_none")]
172        output_compression: Option<u32>,
173        #[serde(skip_serializing_if = "Option::is_none")]
174        output_format: Option<ImageOutputFormat>,
175        #[serde(skip_serializing_if = "Option::is_none")]
176        partial_images: Option<u32>,
177        #[serde(skip_serializing_if = "Option::is_none")]
178        quality: Option<ImageEditQuality>,
179        #[serde(skip_serializing_if = "Option::is_none")]
180        size: Option<ResponseImageGenerationSize>,
181        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
182        extra: Extra,
183    },
184    #[serde(rename = "local_shell")]
185    LocalShell {
186        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
187        extra: Extra,
188    },
189    #[serde(rename = "shell")]
190    Shell {
191        #[serde(skip_serializing_if = "Option::is_none")]
192        environment: Option<ResponseShellEnvironment>,
193        #[serde(skip_serializing_if = "Option::is_none")]
194        allowed_callers: Option<Vec<ToolCaller>>,
195        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
196        extra: Extra,
197    },
198    #[serde(rename = "custom")]
199    Custom {
200        name: String,
201        #[serde(skip_serializing_if = "Option::is_none")]
202        defer_loading: Option<bool>,
203        #[serde(skip_serializing_if = "Option::is_none")]
204        description: Option<String>,
205        #[serde(skip_serializing_if = "Option::is_none")]
206        format: Option<CustomToolInputFormat>,
207        #[serde(skip_serializing_if = "Option::is_none")]
208        allowed_callers: Option<Vec<ToolCaller>>,
209        #[serde(rename = "async", skip_serializing_if = "Option::is_none")]
210        async_: Option<bool>,
211        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
212        extra: Extra,
213    },
214    #[serde(rename = "namespace")]
215    Namespace {
216        description: String,
217        name: String,
218        tools: Vec<ResponseNamespaceTool>,
219        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
220        extra: Extra,
221    },
222    #[serde(rename = "tool_search")]
223    ToolSearch {
224        #[serde(skip_serializing_if = "Option::is_none")]
225        description: Option<String>,
226        #[serde(skip_serializing_if = "Option::is_none")]
227        execution: Option<ToolSearchExecution>,
228        #[serde(skip_serializing_if = "Option::is_none")]
229        parameters: Option<Value>,
230        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
231        extra: Extra,
232    },
233    #[serde(rename = "programmatic_tool_calling")]
234    ProgrammaticToolCalling {
235        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
236        extra: Extra,
237    },
238    #[serde(rename = "web_search_preview")]
239    WebSearchPreview {
240        #[serde(skip_serializing_if = "Option::is_none")]
241        search_content_types: Option<Vec<SearchContentType>>,
242        #[serde(skip_serializing_if = "Option::is_none")]
243        search_context_size: Option<SearchContextSize>,
244        #[serde(skip_serializing_if = "Option::is_none")]
245        user_location: Option<WebSearchPreviewUserLocation>,
246        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
247        extra: Extra,
248    },
249    #[serde(rename = "web_search_preview_2025_03_11")]
250    WebSearchPreview20250311 {
251        #[serde(skip_serializing_if = "Option::is_none")]
252        search_content_types: Option<Vec<SearchContentType>>,
253        #[serde(skip_serializing_if = "Option::is_none")]
254        search_context_size: Option<SearchContextSize>,
255        #[serde(skip_serializing_if = "Option::is_none")]
256        user_location: Option<WebSearchPreviewUserLocation>,
257        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
258        extra: Extra,
259    },
260    #[serde(rename = "apply_patch")]
261    ApplyPatch {
262        #[serde(skip_serializing_if = "Option::is_none")]
263        allowed_callers: Option<Vec<ToolCaller>>,
264        // gproxy extension: forwarded to Claude text_editor `max_characters`.
265        #[serde(skip_serializing_if = "Option::is_none")]
266        max_characters: Option<u64>,
267        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
268        extra: Extra,
269    },
270}
271
272#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
273#[serde(tag = "type")]
274#[non_exhaustive]
275pub enum ResponseNamespaceTool {
276    #[serde(rename = "function")]
277    Function {
278        name: String,
279        #[serde(skip_serializing_if = "Option::is_none")]
280        defer_loading: Option<bool>,
281        #[serde(skip_serializing_if = "Option::is_none")]
282        description: Option<String>,
283        #[serde(skip_serializing_if = "Option::is_none")]
284        parameters: Option<Value>,
285        #[serde(skip_serializing_if = "Option::is_none")]
286        strict: Option<bool>,
287        #[serde(skip_serializing_if = "Option::is_none")]
288        allowed_callers: Option<Vec<ToolCaller>>,
289        #[serde(rename = "async", skip_serializing_if = "Option::is_none")]
290        async_: Option<bool>,
291        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
292        extra: Extra,
293    },
294    #[serde(rename = "custom")]
295    Custom {
296        name: String,
297        #[serde(skip_serializing_if = "Option::is_none")]
298        defer_loading: Option<bool>,
299        #[serde(skip_serializing_if = "Option::is_none")]
300        description: Option<String>,
301        #[serde(skip_serializing_if = "Option::is_none")]
302        format: Option<CustomToolInputFormat>,
303        #[serde(skip_serializing_if = "Option::is_none")]
304        allowed_callers: Option<Vec<ToolCaller>>,
305        #[serde(rename = "async", skip_serializing_if = "Option::is_none")]
306        async_: Option<bool>,
307        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
308        extra: Extra,
309    },
310}