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