Skip to main content

async_openai/types/responses/
impls.rs

1use crate::types::mcp::MCPTool;
2use crate::types::responses::{
3    AdditionalToolsItemParam, AdditionalToolsItemParamRole, ApplyPatchCallOutputStatus,
4    ApplyPatchCallOutputStatusParam, ApplyPatchCallStatus, ApplyPatchCallStatusParam,
5    ApplyPatchCreateFileOperation, ApplyPatchCreateFileOperationParam,
6    ApplyPatchDeleteFileOperation, ApplyPatchDeleteFileOperationParam, ApplyPatchOperation,
7    ApplyPatchOperationParam, ApplyPatchToolCall, ApplyPatchToolCallItemParam,
8    ApplyPatchToolCallOutput, ApplyPatchToolCallOutputItemParam, ApplyPatchUpdateFileOperation,
9    ApplyPatchUpdateFileOperationParam, CodeInterpreterContainerAuto, CodeInterpreterTool,
10    CodeInterpreterToolCall, CodeInterpreterToolContainer, CompactionBody,
11    CompactionSummaryItemParam, ComputerCallOutputItemParam, ComputerToolCall,
12    ComputerToolCallOutputResource, ComputerUsePreviewTool, ContainerReferenceParam,
13    ContainerReferenceResource, ConversationParam, CustomToolCall, CustomToolCallOutput,
14    CustomToolCallOutputResource, CustomToolParam, EasyInputContent, EasyInputMessage,
15    FileSearchTool, FileSearchToolCall, FunctionCallOutput, FunctionCallOutputItemParam,
16    FunctionCallOutputStatusEnum, FunctionCallStatus, FunctionShellAction,
17    FunctionShellActionParam, FunctionShellCall, FunctionShellCallEnvironment,
18    FunctionShellCallItemEnvironment, FunctionShellCallItemParam, FunctionShellCallItemStatus,
19    FunctionShellCallOutput, FunctionShellCallOutputContent, FunctionShellCallOutputContentParam,
20    FunctionShellCallOutputExitOutcome, FunctionShellCallOutputExitOutcomeParam,
21    FunctionShellCallOutputItemParam, FunctionShellCallOutputOutcome,
22    FunctionShellCallOutputOutcomeParam, FunctionShellCallOutputStatusEnum,
23    FunctionShellCallStatus, FunctionTool, FunctionToolCall, FunctionToolCallOutputResource,
24    ImageGenTool, ImageGenToolCall, InputContent, InputFileContent, InputImageContent, InputItem,
25    InputMessage, InputParam, InputTextContent, Item, ItemReference, ItemReferenceType,
26    LocalEnvironmentParam, LocalShellToolCall, LocalShellToolCallOutput, MCPApprovalRequest,
27    MCPApprovalResponse, MCPListTools, MCPToolCall, MessageItem, MessageType, NamespaceToolParam,
28    OutputItem, OutputMessage, OutputMessageContent, OutputStatus, OutputTextContent, Program,
29    ProgramItemParam, ProgramOutput, ProgramOutputItemParam, ProgramOutputItemStatus,
30    ProgramOutputStatus, Prompt, Reasoning, ReasoningEffort, ReasoningItem, ReasoningSummary,
31    RefusalContent, ResponseFormatJsonSchema, ResponsePromptVariables, ResponseStreamOptions,
32    ResponseTextParam, Role, TextResponseFormatConfiguration, Tool, ToolChoiceCustom,
33    ToolChoiceFunction, ToolChoiceMCP, ToolChoiceOptions, ToolChoiceParam, ToolChoiceTypes,
34    ToolSearchCall, ToolSearchCallItemParam, ToolSearchOutput, ToolSearchOutputItemParam,
35    ToolSearchOutputNamespaceToolParam, ToolSearchOutputTool, ToolSearchToolParam, WebSearchTool,
36    WebSearchToolCall,
37};
38
39impl<S: Into<String>> From<S> for EasyInputMessage {
40    fn from(value: S) -> Self {
41        EasyInputMessage {
42            r#type: MessageType::Message,
43            role: Role::User,
44            content: EasyInputContent::Text(value.into()),
45            phase: None,
46        }
47    }
48}
49
50impl From<EasyInputMessage> for InputItem {
51    fn from(msg: EasyInputMessage) -> Self {
52        InputItem::EasyMessage(msg)
53    }
54}
55
56// InputItem ergonomics
57
58impl From<InputMessage> for InputItem {
59    fn from(msg: InputMessage) -> Self {
60        InputItem::Item(Item::Message(MessageItem::Input(msg)))
61    }
62}
63
64impl From<Item> for InputItem {
65    fn from(item: Item) -> Self {
66        InputItem::Item(item)
67    }
68}
69
70impl From<ItemReference> for InputItem {
71    fn from(item: ItemReference) -> Self {
72        InputItem::ItemReference(item)
73    }
74}
75
76// InputParam ergonomics: from InputItem
77
78impl From<InputItem> for InputParam {
79    fn from(item: InputItem) -> Self {
80        InputParam::Items(vec![item])
81    }
82}
83
84impl From<Item> for InputParam {
85    fn from(item: Item) -> Self {
86        InputParam::Items(vec![InputItem::Item(item)])
87    }
88}
89
90impl From<MessageItem> for InputParam {
91    fn from(item: MessageItem) -> Self {
92        InputParam::Items(vec![InputItem::Item(Item::Message(item))])
93    }
94}
95
96impl From<InputMessage> for InputParam {
97    fn from(msg: InputMessage) -> Self {
98        InputParam::Items(vec![InputItem::Item(Item::Message(MessageItem::Input(
99            msg,
100        )))])
101    }
102}
103
104impl<I: Into<InputItem>> From<Vec<I>> for InputParam {
105    fn from(items: Vec<I>) -> Self {
106        InputParam::Items(items.into_iter().map(|item| item.into()).collect())
107    }
108}
109
110impl<I: Into<InputItem>, const N: usize> From<[I; N]> for InputParam {
111    fn from(items: [I; N]) -> Self {
112        InputParam::Items(items.into_iter().map(|item| item.into()).collect())
113    }
114}
115
116// InputParam ergonomics: from string "family"
117
118impl From<&str> for InputParam {
119    fn from(value: &str) -> Self {
120        InputParam::Text(value.into())
121    }
122}
123
124impl From<String> for InputParam {
125    fn from(value: String) -> Self {
126        InputParam::Text(value)
127    }
128}
129
130impl From<&String> for InputParam {
131    fn from(value: &String) -> Self {
132        InputParam::Text(value.clone())
133    }
134}
135
136// InputParam ergonomics: from vector family
137
138macro_rules! impl_inputparam_easy_from_collection {
139    // Vec<T>
140    ($t:ty, $map:expr, $clone:expr) => {
141        impl From<Vec<$t>> for InputParam {
142            fn from(values: Vec<$t>) -> Self {
143                InputParam::Items(
144                    values
145                        .into_iter()
146                        .map(|value| {
147                            InputItem::EasyMessage(EasyInputMessage {
148                                r#type: MessageType::Message,
149                                role: Role::User,
150                                content: EasyInputContent::Text($map(value)),
151                                phase: None,
152                            })
153                        })
154                        .collect(),
155                )
156            }
157        }
158        // &[T; N]
159        impl<const N: usize> From<[$t; N]> for InputParam {
160            fn from(values: [$t; N]) -> Self {
161                InputParam::Items(
162                    values
163                        .into_iter()
164                        .map(|value| {
165                            InputItem::EasyMessage(EasyInputMessage {
166                                r#type: MessageType::Message,
167                                role: Role::User,
168                                content: EasyInputContent::Text($map(value)),
169                                phase: None,
170                            })
171                        })
172                        .collect(),
173                )
174            }
175        }
176        // &Vec<T>
177        impl From<&Vec<$t>> for InputParam {
178            fn from(values: &Vec<$t>) -> Self {
179                InputParam::Items(
180                    values
181                        .iter()
182                        .map(|value| {
183                            InputItem::EasyMessage(EasyInputMessage {
184                                r#type: MessageType::Message,
185                                role: Role::User,
186                                content: EasyInputContent::Text($clone(value)),
187                                phase: None,
188                            })
189                        })
190                        .collect(),
191                )
192            }
193        }
194    };
195}
196
197// Apply for &str
198impl_inputparam_easy_from_collection!(&str, |v: &str| v.to_string(), |v: &str| v.to_string());
199// Apply for String
200impl_inputparam_easy_from_collection!(String, |v: String| v, |v: &String| v.clone());
201// Apply for &String
202impl_inputparam_easy_from_collection!(&String, |v: &String| v.clone(), |v: &String| v.clone());
203
204// ConversationParam ergonomics
205
206impl<S: Into<String>> From<S> for ConversationParam {
207    fn from(id: S) -> Self {
208        ConversationParam::ConversationID(id.into())
209    }
210}
211
212// ToolChoiceParam ergonomics
213
214impl From<ToolChoiceOptions> for ToolChoiceParam {
215    fn from(mode: ToolChoiceOptions) -> Self {
216        ToolChoiceParam::Option(mode)
217    }
218}
219
220impl From<ToolChoiceTypes> for ToolChoiceParam {
221    fn from(tool_type: ToolChoiceTypes) -> Self {
222        ToolChoiceParam::BuiltIn(tool_type)
223    }
224}
225
226impl<S: Into<String>> From<S> for ToolChoiceParam {
227    fn from(name: S) -> Self {
228        ToolChoiceParam::Function(ToolChoiceFunction { name: name.into() })
229    }
230}
231
232impl From<ToolChoiceFunction> for ToolChoiceParam {
233    fn from(function: ToolChoiceFunction) -> Self {
234        ToolChoiceParam::Function(function)
235    }
236}
237
238impl From<ToolChoiceMCP> for ToolChoiceParam {
239    fn from(mcp: ToolChoiceMCP) -> Self {
240        ToolChoiceParam::Mcp(mcp)
241    }
242}
243
244impl From<ToolChoiceCustom> for ToolChoiceParam {
245    fn from(custom: ToolChoiceCustom) -> Self {
246        ToolChoiceParam::Custom(custom)
247    }
248}
249
250// ResponseTextParam ergonomics
251
252impl From<TextResponseFormatConfiguration> for ResponseTextParam {
253    fn from(format: TextResponseFormatConfiguration) -> Self {
254        ResponseTextParam {
255            format,
256            verbosity: None,
257        }
258    }
259}
260
261impl From<ResponseFormatJsonSchema> for ResponseTextParam {
262    fn from(schema: ResponseFormatJsonSchema) -> Self {
263        ResponseTextParam {
264            format: TextResponseFormatConfiguration::JsonSchema(schema),
265            verbosity: None,
266        }
267    }
268}
269
270// ResponseStreamOptions ergonomics
271
272impl From<bool> for ResponseStreamOptions {
273    fn from(include_obfuscation: bool) -> Self {
274        ResponseStreamOptions {
275            include_obfuscation: Some(include_obfuscation),
276        }
277    }
278}
279
280// Reasoning ergonomics
281
282impl From<ReasoningEffort> for Reasoning {
283    fn from(effort: ReasoningEffort) -> Self {
284        Reasoning {
285            context: None,
286            mode: None,
287            effort: Some(effort),
288            summary: None,
289        }
290    }
291}
292
293impl From<ReasoningSummary> for Reasoning {
294    fn from(summary: ReasoningSummary) -> Self {
295        Reasoning {
296            context: None,
297            mode: None,
298            effort: None,
299            summary: Some(summary),
300        }
301    }
302}
303
304// Prompt ergonomics
305
306impl<S: Into<String>> From<S> for Prompt {
307    fn from(id: S) -> Self {
308        Prompt {
309            id: id.into(),
310            version: None,
311            variables: None,
312        }
313    }
314}
315
316// InputTextContent ergonomics
317
318impl<S: Into<String>> From<S> for InputTextContent {
319    fn from(text: S) -> Self {
320        InputTextContent {
321            prompt_cache_breakpoint: None,
322            text: text.into(),
323        }
324    }
325}
326
327// InputContent ergonomics
328
329impl From<InputTextContent> for InputContent {
330    fn from(content: InputTextContent) -> Self {
331        InputContent::InputText(content)
332    }
333}
334
335impl From<InputImageContent> for InputContent {
336    fn from(content: InputImageContent) -> Self {
337        InputContent::InputImage(content)
338    }
339}
340
341impl From<InputFileContent> for InputContent {
342    fn from(content: InputFileContent) -> Self {
343        InputContent::InputFile(content)
344    }
345}
346
347impl<S: Into<String>> From<S> for InputContent {
348    fn from(text: S) -> Self {
349        InputContent::InputText(InputTextContent {
350            prompt_cache_breakpoint: None,
351            text: text.into(),
352        })
353    }
354}
355
356// ResponsePromptVariables ergonomics
357
358impl From<InputContent> for ResponsePromptVariables {
359    fn from(content: InputContent) -> Self {
360        ResponsePromptVariables::Content(content)
361    }
362}
363
364impl<S: Into<String>> From<S> for ResponsePromptVariables {
365    fn from(text: S) -> Self {
366        ResponsePromptVariables::String(text.into())
367    }
368}
369
370// MessageItem ergonomics
371
372impl From<InputMessage> for MessageItem {
373    fn from(msg: InputMessage) -> Self {
374        MessageItem::Input(msg)
375    }
376}
377
378impl From<OutputMessage> for MessageItem {
379    fn from(msg: OutputMessage) -> Self {
380        MessageItem::Output(msg)
381    }
382}
383
384// FunctionCallOutput ergonomics
385
386impl From<&str> for FunctionCallOutput {
387    fn from(text: &str) -> Self {
388        FunctionCallOutput::Text(text.to_string())
389    }
390}
391
392impl From<String> for FunctionCallOutput {
393    fn from(text: String) -> Self {
394        FunctionCallOutput::Text(text)
395    }
396}
397
398impl From<Vec<InputContent>> for FunctionCallOutput {
399    fn from(content: Vec<InputContent>) -> Self {
400        FunctionCallOutput::Content(content)
401    }
402}
403
404// RefusalContent ergonomics
405
406impl<S: Into<String>> From<S> for RefusalContent {
407    fn from(refusal: S) -> Self {
408        RefusalContent {
409            refusal: refusal.into(),
410        }
411    }
412}
413
414// OutputMessageContent ergonomics
415
416impl From<OutputTextContent> for OutputMessageContent {
417    fn from(content: OutputTextContent) -> Self {
418        OutputMessageContent::OutputText(content)
419    }
420}
421
422impl From<RefusalContent> for OutputMessageContent {
423    fn from(content: RefusalContent) -> Self {
424        OutputMessageContent::Refusal(content)
425    }
426}
427
428// Item ergonomics
429
430impl From<MessageItem> for Item {
431    fn from(item: MessageItem) -> Self {
432        Item::Message(item)
433    }
434}
435
436impl From<FileSearchToolCall> for Item {
437    fn from(call: FileSearchToolCall) -> Self {
438        Item::FileSearchCall(call)
439    }
440}
441
442impl From<ComputerToolCall> for Item {
443    fn from(call: ComputerToolCall) -> Self {
444        Item::ComputerCall(call)
445    }
446}
447
448impl From<ComputerCallOutputItemParam> for Item {
449    fn from(output: ComputerCallOutputItemParam) -> Self {
450        Item::ComputerCallOutput(output)
451    }
452}
453
454impl From<WebSearchToolCall> for Item {
455    fn from(call: WebSearchToolCall) -> Self {
456        Item::WebSearchCall(call)
457    }
458}
459
460impl From<FunctionToolCall> for Item {
461    fn from(call: FunctionToolCall) -> Self {
462        Item::FunctionCall(call)
463    }
464}
465
466impl From<FunctionCallOutputItemParam> for Item {
467    fn from(output: FunctionCallOutputItemParam) -> Self {
468        Item::FunctionCallOutput(output)
469    }
470}
471
472impl From<ReasoningItem> for Item {
473    fn from(item: ReasoningItem) -> Self {
474        Item::Reasoning(item)
475    }
476}
477
478impl From<ImageGenToolCall> for Item {
479    fn from(call: ImageGenToolCall) -> Self {
480        Item::ImageGenerationCall(call)
481    }
482}
483
484impl From<CodeInterpreterToolCall> for Item {
485    fn from(call: CodeInterpreterToolCall) -> Self {
486        Item::CodeInterpreterCall(call)
487    }
488}
489
490impl From<LocalShellToolCall> for Item {
491    fn from(call: LocalShellToolCall) -> Self {
492        Item::LocalShellCall(call)
493    }
494}
495
496impl From<LocalShellToolCallOutput> for Item {
497    fn from(output: LocalShellToolCallOutput) -> Self {
498        Item::LocalShellCallOutput(output)
499    }
500}
501
502impl From<FunctionShellCallItemParam> for Item {
503    fn from(call: FunctionShellCallItemParam) -> Self {
504        Item::ShellCall(call)
505    }
506}
507
508impl From<FunctionShellCallOutputItemParam> for Item {
509    fn from(output: FunctionShellCallOutputItemParam) -> Self {
510        Item::ShellCallOutput(output)
511    }
512}
513
514impl From<ApplyPatchToolCallItemParam> for Item {
515    fn from(call: ApplyPatchToolCallItemParam) -> Self {
516        Item::ApplyPatchCall(call)
517    }
518}
519
520impl From<ApplyPatchToolCallOutputItemParam> for Item {
521    fn from(output: ApplyPatchToolCallOutputItemParam) -> Self {
522        Item::ApplyPatchCallOutput(output)
523    }
524}
525
526impl From<MCPListTools> for Item {
527    fn from(tools: MCPListTools) -> Self {
528        Item::McpListTools(tools)
529    }
530}
531
532impl From<MCPApprovalRequest> for Item {
533    fn from(request: MCPApprovalRequest) -> Self {
534        Item::McpApprovalRequest(request)
535    }
536}
537
538impl From<MCPApprovalResponse> for Item {
539    fn from(response: MCPApprovalResponse) -> Self {
540        Item::McpApprovalResponse(response)
541    }
542}
543
544impl From<MCPToolCall> for Item {
545    fn from(call: MCPToolCall) -> Self {
546        Item::McpCall(call)
547    }
548}
549
550impl From<CustomToolCallOutput> for Item {
551    fn from(output: CustomToolCallOutput) -> Self {
552        Item::CustomToolCallOutput(output)
553    }
554}
555
556impl From<CustomToolCall> for Item {
557    fn from(call: CustomToolCall) -> Self {
558        Item::CustomToolCall(call)
559    }
560}
561
562impl From<ToolSearchCallItemParam> for Item {
563    fn from(call: ToolSearchCallItemParam) -> Self {
564        Item::ToolSearchCall(call)
565    }
566}
567
568impl From<ToolSearchOutputItemParam> for Item {
569    fn from(output: ToolSearchOutputItemParam) -> Self {
570        Item::ToolSearchOutput(output)
571    }
572}
573
574// Tool ergonomics
575
576impl From<FunctionTool> for Tool {
577    fn from(tool: FunctionTool) -> Self {
578        Tool::Function(tool)
579    }
580}
581
582impl From<FileSearchTool> for Tool {
583    fn from(tool: FileSearchTool) -> Self {
584        Tool::FileSearch(tool)
585    }
586}
587
588impl From<ComputerUsePreviewTool> for Tool {
589    fn from(tool: ComputerUsePreviewTool) -> Self {
590        Tool::ComputerUsePreview(tool)
591    }
592}
593
594impl From<WebSearchTool> for Tool {
595    fn from(tool: WebSearchTool) -> Self {
596        Tool::WebSearch(tool)
597    }
598}
599
600impl From<MCPTool> for Tool {
601    fn from(tool: MCPTool) -> Self {
602        Tool::Mcp(tool)
603    }
604}
605
606impl From<CodeInterpreterTool> for Tool {
607    fn from(tool: CodeInterpreterTool) -> Self {
608        Tool::CodeInterpreter(tool)
609    }
610}
611
612impl From<ImageGenTool> for Tool {
613    fn from(tool: ImageGenTool) -> Self {
614        Tool::ImageGeneration(tool)
615    }
616}
617
618impl From<CustomToolParam> for Tool {
619    fn from(tool: CustomToolParam) -> Self {
620        Tool::Custom(tool)
621    }
622}
623
624impl From<NamespaceToolParam> for Tool {
625    fn from(tool: NamespaceToolParam) -> Self {
626        Tool::Namespace(tool)
627    }
628}
629
630impl From<ToolSearchToolParam> for Tool {
631    fn from(tool: ToolSearchToolParam) -> Self {
632        Tool::ToolSearch(tool)
633    }
634}
635
636// Vec<Tool> ergonomics
637
638impl From<Tool> for Vec<Tool> {
639    fn from(tool: Tool) -> Self {
640        vec![tool]
641    }
642}
643
644impl From<FunctionTool> for Vec<Tool> {
645    fn from(tool: FunctionTool) -> Self {
646        vec![Tool::Function(tool)]
647    }
648}
649
650impl From<FileSearchTool> for Vec<Tool> {
651    fn from(tool: FileSearchTool) -> Self {
652        vec![Tool::FileSearch(tool)]
653    }
654}
655
656impl From<ComputerUsePreviewTool> for Vec<Tool> {
657    fn from(tool: ComputerUsePreviewTool) -> Self {
658        vec![Tool::ComputerUsePreview(tool)]
659    }
660}
661
662impl From<WebSearchTool> for Vec<Tool> {
663    fn from(tool: WebSearchTool) -> Self {
664        vec![Tool::WebSearch(tool)]
665    }
666}
667
668impl From<MCPTool> for Vec<Tool> {
669    fn from(tool: MCPTool) -> Self {
670        vec![Tool::Mcp(tool)]
671    }
672}
673
674impl From<CodeInterpreterTool> for Vec<Tool> {
675    fn from(tool: CodeInterpreterTool) -> Self {
676        vec![Tool::CodeInterpreter(tool)]
677    }
678}
679
680impl From<ImageGenTool> for Vec<Tool> {
681    fn from(tool: ImageGenTool) -> Self {
682        vec![Tool::ImageGeneration(tool)]
683    }
684}
685
686impl From<CustomToolParam> for Vec<Tool> {
687    fn from(tool: CustomToolParam) -> Self {
688        vec![Tool::Custom(tool)]
689    }
690}
691
692// EasyInputContent ergonomics
693
694impl Default for EasyInputContent {
695    fn default() -> Self {
696        Self::Text("".to_string())
697    }
698}
699
700impl From<String> for EasyInputContent {
701    fn from(value: String) -> Self {
702        Self::Text(value)
703    }
704}
705
706impl From<&str> for EasyInputContent {
707    fn from(value: &str) -> Self {
708        Self::Text(value.to_owned())
709    }
710}
711
712// Defaults
713
714impl Default for CodeInterpreterToolContainer {
715    fn default() -> Self {
716        Self::Auto(CodeInterpreterContainerAuto::default())
717    }
718}
719
720impl Default for InputParam {
721    fn default() -> Self {
722        Self::Text(String::new())
723    }
724}
725
726impl ItemReference {
727    /// Create a new item reference with the given ID.
728    pub fn new(id: impl Into<String>) -> Self {
729        Self {
730            r#type: Some(ItemReferenceType::ItemReference),
731            id: id.into(),
732        }
733    }
734}
735
736// ──────────────────────────────────────────────────────────────────────────
737// OutputItem -> Item / InputItem (multi-turn responses helpers)
738//
739// The Responses API requires reasoning items to be echoed back into the
740// next request's `input` alongside the function-call items they preceded —
741// otherwise the server rejects the request with
742// `Item 'fc_...' was provided without its required 'reasoning' item: ...`.
743// In the official Python and Node SDKs the canonical pattern is just
744// `input_list += response.output`, since their input/output item types
745// are the same. In Rust the OpenAPI-derived schemas split into Item (input
746// side) and OutputItem (output side), so an explicit conversion is needed.
747//
748// The conversions below give that "just append the output" ergonomic via
749// `From<OutputItem> for InputItem`. For variants where input and output already share a struct
750// the conversion is a one-liner; for the handful of variants where the
751// schemas differ (resource types carry required `id`/`status`, while their
752// input-side `*ItemParam` counterparts have those optional), per-pair
753// `From` impls map the fields so callers don't have to write boilerplate
754// per use site.
755//
756// References:
757//   - https://github.com/64bit/async-openai/issues/492
758//   - https://platform.openai.com/docs/guides/conversation-state
759// ──────────────────────────────────────────────────────────────────────────
760
761// Status enum mappings (resource side → param side).
762
763impl From<FunctionCallOutputStatusEnum> for OutputStatus {
764    fn from(status: FunctionCallOutputStatusEnum) -> Self {
765        match status {
766            FunctionCallOutputStatusEnum::InProgress => OutputStatus::InProgress,
767            FunctionCallOutputStatusEnum::Completed => OutputStatus::Completed,
768            FunctionCallOutputStatusEnum::Incomplete => OutputStatus::Incomplete,
769        }
770    }
771}
772
773impl From<FunctionCallStatus> for OutputStatus {
774    fn from(status: FunctionCallStatus) -> Self {
775        match status {
776            FunctionCallStatus::InProgress => OutputStatus::InProgress,
777            FunctionCallStatus::Completed => OutputStatus::Completed,
778            FunctionCallStatus::Incomplete => OutputStatus::Incomplete,
779        }
780    }
781}
782
783impl From<FunctionShellCallStatus> for FunctionShellCallItemStatus {
784    fn from(status: FunctionShellCallStatus) -> Self {
785        match status {
786            FunctionShellCallStatus::InProgress => FunctionShellCallItemStatus::InProgress,
787            FunctionShellCallStatus::Completed => FunctionShellCallItemStatus::Completed,
788            FunctionShellCallStatus::Incomplete => FunctionShellCallItemStatus::Incomplete,
789        }
790    }
791}
792
793impl From<ApplyPatchCallStatus> for ApplyPatchCallStatusParam {
794    fn from(status: ApplyPatchCallStatus) -> Self {
795        match status {
796            ApplyPatchCallStatus::InProgress => ApplyPatchCallStatusParam::InProgress,
797            ApplyPatchCallStatus::Completed => ApplyPatchCallStatusParam::Completed,
798        }
799    }
800}
801
802impl From<ApplyPatchCallOutputStatus> for ApplyPatchCallOutputStatusParam {
803    fn from(status: ApplyPatchCallOutputStatus) -> Self {
804        match status {
805            ApplyPatchCallOutputStatus::Completed => ApplyPatchCallOutputStatusParam::Completed,
806            ApplyPatchCallOutputStatus::Failed => ApplyPatchCallOutputStatusParam::Failed,
807        }
808    }
809}
810
811// Shell environment / outcome mappings.
812
813impl From<ContainerReferenceResource> for ContainerReferenceParam {
814    fn from(r: ContainerReferenceResource) -> Self {
815        ContainerReferenceParam {
816            container_id: r.container_id,
817        }
818    }
819}
820
821impl From<FunctionShellCallEnvironment> for FunctionShellCallItemEnvironment {
822    fn from(env: FunctionShellCallEnvironment) -> Self {
823        match env {
824            // The response side carries no payload for `Local`; the param
825            // side accepts an optional `skills` list which we leave None
826            // (it's a request-only knob).
827            FunctionShellCallEnvironment::Local => {
828                FunctionShellCallItemEnvironment::Local(LocalEnvironmentParam { skills: None })
829            }
830            FunctionShellCallEnvironment::ContainerReference(r) => {
831                FunctionShellCallItemEnvironment::ContainerReference(r.into())
832            }
833        }
834    }
835}
836
837impl From<FunctionShellCallOutputExitOutcome> for FunctionShellCallOutputExitOutcomeParam {
838    fn from(o: FunctionShellCallOutputExitOutcome) -> Self {
839        FunctionShellCallOutputExitOutcomeParam {
840            exit_code: o.exit_code,
841        }
842    }
843}
844
845impl From<FunctionShellCallOutputOutcome> for FunctionShellCallOutputOutcomeParam {
846    fn from(o: FunctionShellCallOutputOutcome) -> Self {
847        match o {
848            FunctionShellCallOutputOutcome::Timeout => FunctionShellCallOutputOutcomeParam::Timeout,
849            FunctionShellCallOutputOutcome::Exit(e) => {
850                FunctionShellCallOutputOutcomeParam::Exit(e.into())
851            }
852        }
853    }
854}
855
856impl From<FunctionShellCallOutputContent> for FunctionShellCallOutputContentParam {
857    fn from(c: FunctionShellCallOutputContent) -> Self {
858        FunctionShellCallOutputContentParam {
859            stdout: c.stdout,
860            stderr: c.stderr,
861            outcome: c.outcome.into(),
862        }
863    }
864}
865
866impl From<FunctionShellAction> for FunctionShellActionParam {
867    fn from(a: FunctionShellAction) -> Self {
868        FunctionShellActionParam {
869            commands: a.commands,
870            timeout_ms: a.timeout_ms,
871            max_output_length: a.max_output_length,
872        }
873    }
874}
875
876// ApplyPatch operation mappings.
877
878impl From<ApplyPatchCreateFileOperation> for ApplyPatchCreateFileOperationParam {
879    fn from(op: ApplyPatchCreateFileOperation) -> Self {
880        ApplyPatchCreateFileOperationParam {
881            path: op.path,
882            diff: op.diff,
883        }
884    }
885}
886
887impl From<ApplyPatchDeleteFileOperation> for ApplyPatchDeleteFileOperationParam {
888    fn from(op: ApplyPatchDeleteFileOperation) -> Self {
889        ApplyPatchDeleteFileOperationParam { path: op.path }
890    }
891}
892
893impl From<ApplyPatchUpdateFileOperation> for ApplyPatchUpdateFileOperationParam {
894    fn from(op: ApplyPatchUpdateFileOperation) -> Self {
895        ApplyPatchUpdateFileOperationParam {
896            path: op.path,
897            diff: op.diff,
898        }
899    }
900}
901
902impl From<ApplyPatchOperation> for ApplyPatchOperationParam {
903    fn from(op: ApplyPatchOperation) -> Self {
904        match op {
905            ApplyPatchOperation::CreateFile(o) => ApplyPatchOperationParam::CreateFile(o.into()),
906            ApplyPatchOperation::DeleteFile(o) => ApplyPatchOperationParam::DeleteFile(o.into()),
907            ApplyPatchOperation::UpdateFile(o) => ApplyPatchOperationParam::UpdateFile(o.into()),
908        }
909    }
910}
911
912// Per-resource-output → input-param conversions. Required `id` / `status`
913// fields on the resource side become wrapped in `Some(...)` on the input
914// side; status enums fold through the `From` impls above. The `created_by`
915// field exists only on the resource side and is dropped on the way in —
916// it's a server-assigned annotation that the input schema doesn't accept.
917
918impl From<FunctionToolCallOutputResource> for FunctionCallOutputItemParam {
919    fn from(r: FunctionToolCallOutputResource) -> Self {
920        FunctionCallOutputItemParam {
921            caller: r.caller,
922            name: r.name,
923            namespace: r.namespace,
924            call_id: r.call_id,
925            output: r.output,
926            id: Some(r.id),
927            status: Some(r.status.into()),
928        }
929    }
930}
931
932impl From<ComputerToolCallOutputResource> for ComputerCallOutputItemParam {
933    fn from(r: ComputerToolCallOutputResource) -> Self {
934        ComputerCallOutputItemParam {
935            call_id: r.call_id,
936            output: r.output,
937            acknowledged_safety_checks: r.acknowledged_safety_checks,
938            id: Some(r.id),
939            // ComputerCallOutputStatus has a `Failed` variant that
940            // OutputStatus doesn't model. The Responses API silently
941            // accepts a missing status here, so collapse `Failed` to None
942            // rather than fabricate a value the schema can't represent.
943            status: match r.status {
944                crate::types::responses::ComputerCallOutputStatus::InProgress => {
945                    Some(OutputStatus::InProgress)
946                }
947                crate::types::responses::ComputerCallOutputStatus::Completed => {
948                    Some(OutputStatus::Completed)
949                }
950                crate::types::responses::ComputerCallOutputStatus::Incomplete => {
951                    Some(OutputStatus::Incomplete)
952                }
953                crate::types::responses::ComputerCallOutputStatus::Failed => None,
954            },
955        }
956    }
957}
958
959impl From<CustomToolCallOutputResource> for CustomToolCallOutput {
960    fn from(r: CustomToolCallOutputResource) -> Self {
961        CustomToolCallOutput {
962            caller: r.caller,
963            call_id: r.call_id,
964            output: r.output,
965            id: Some(r.id),
966        }
967    }
968}
969
970impl From<FunctionShellCall> for FunctionShellCallItemParam {
971    fn from(c: FunctionShellCall) -> Self {
972        FunctionShellCallItemParam {
973            caller: c.caller,
974            id: Some(c.id),
975            call_id: c.call_id,
976            action: c.action.into(),
977            status: Some(c.status.into()),
978            environment: c.environment.map(Into::into),
979        }
980    }
981}
982
983impl From<FunctionShellCallOutput> for FunctionShellCallOutputItemParam {
984    fn from(o: FunctionShellCallOutput) -> Self {
985        FunctionShellCallOutputItemParam {
986            caller: o.caller,
987            id: Some(o.id),
988            call_id: o.call_id,
989            output: o.output.into_iter().map(Into::into).collect(),
990            max_output_length: o.max_output_length,
991            status: Some(o.status.into()),
992        }
993    }
994}
995
996impl From<FunctionShellCallOutputStatusEnum> for FunctionShellCallItemStatus {
997    fn from(value: FunctionShellCallOutputStatusEnum) -> Self {
998        match value {
999            FunctionShellCallOutputStatusEnum::InProgress => Self::InProgress,
1000            FunctionShellCallOutputStatusEnum::Completed => Self::Completed,
1001            FunctionShellCallOutputStatusEnum::Incomplete => Self::Incomplete,
1002        }
1003    }
1004}
1005
1006impl From<ApplyPatchToolCall> for ApplyPatchToolCallItemParam {
1007    fn from(c: ApplyPatchToolCall) -> Self {
1008        ApplyPatchToolCallItemParam {
1009            caller: c.caller,
1010            id: Some(c.id),
1011            call_id: c.call_id,
1012            status: c.status.into(),
1013            operation: c.operation.into(),
1014        }
1015    }
1016}
1017
1018impl From<ApplyPatchToolCallOutput> for ApplyPatchToolCallOutputItemParam {
1019    fn from(o: ApplyPatchToolCallOutput) -> Self {
1020        ApplyPatchToolCallOutputItemParam {
1021            caller: o.caller,
1022            id: Some(o.id),
1023            call_id: o.call_id,
1024            status: o.status.into(),
1025            output: o.output,
1026        }
1027    }
1028}
1029
1030impl From<CompactionBody> for CompactionSummaryItemParam {
1031    fn from(b: CompactionBody) -> Self {
1032        CompactionSummaryItemParam {
1033            id: Some(b.id),
1034            encrypted_content: b.encrypted_content,
1035        }
1036    }
1037}
1038
1039impl From<ToolSearchCall> for ToolSearchCallItemParam {
1040    fn from(c: ToolSearchCall) -> Self {
1041        ToolSearchCallItemParam {
1042            id: Some(c.id),
1043            call_id: c.call_id,
1044            execution: Some(c.execution),
1045            arguments: c.arguments,
1046            status: Some(c.status.into()),
1047        }
1048    }
1049}
1050
1051impl From<ToolSearchOutput> for ToolSearchOutputItemParam {
1052    fn from(o: ToolSearchOutput) -> Self {
1053        ToolSearchOutputItemParam {
1054            id: Some(o.id),
1055            call_id: o.call_id,
1056            execution: Some(o.execution),
1057            tools: o.tools.into_iter().map(Into::into).collect(),
1058            status: Some(o.status.into()),
1059        }
1060    }
1061}
1062
1063impl From<Program> for ProgramItemParam {
1064    fn from(item: crate::types::responses::Program) -> Self {
1065        Self {
1066            id: item.id,
1067            call_id: item.call_id,
1068            code: item.code,
1069            fingerprint: item.fingerprint,
1070        }
1071    }
1072}
1073
1074impl From<ProgramOutput> for ProgramOutputItemParam {
1075    fn from(item: ProgramOutput) -> Self {
1076        Self {
1077            id: item.id,
1078            call_id: item.call_id,
1079            result: item.result,
1080            status: match item.status {
1081                ProgramOutputStatus::Completed => ProgramOutputItemStatus::Completed,
1082                ProgramOutputStatus::Incomplete => ProgramOutputItemStatus::Incomplete,
1083            },
1084        }
1085    }
1086}
1087
1088// Top-level: any output item rolls into an InputItem. This is the entry
1089// point callers actually want — see the `responses-multi-turn-reasoning`
1090// example for the round-trip pattern.
1091
1092impl From<OutputItem> for InputItem {
1093    fn from(item: OutputItem) -> Self {
1094        match item {
1095            OutputItem::Program(v) => Self::Program(v.into()),
1096            OutputItem::ProgramOutput(v) => Self::ProgramOutput(v.into()),
1097            OutputItem::AdditionalTools(v) => Item::AdditionalTools(AdditionalToolsItemParam {
1098                id: Some(v.id),
1099                role: AdditionalToolsItemParamRole::Developer,
1100                tools: v.tools,
1101            })
1102            .into(),
1103            OutputItem::Message(m) => Item::Message(m.into()).into(),
1104            OutputItem::FileSearchCall(c) => Item::FileSearchCall(c).into(),
1105            OutputItem::FunctionCall(c) => Item::FunctionCall(c).into(),
1106            OutputItem::FunctionCallOutput(o) => Item::FunctionCallOutput(o.into()).into(),
1107            OutputItem::WebSearchCall(c) => Item::WebSearchCall(c).into(),
1108            OutputItem::ComputerCall(c) => Item::ComputerCall(c).into(),
1109            OutputItem::ComputerCallOutput(o) => Item::ComputerCallOutput(o.into()).into(),
1110            OutputItem::Reasoning(r) => Item::Reasoning(r).into(),
1111            OutputItem::Compaction(c) => Item::Compaction(c.into()).into(),
1112            OutputItem::ImageGenerationCall(c) => Item::ImageGenerationCall(c).into(),
1113            OutputItem::CodeInterpreterCall(c) => Item::CodeInterpreterCall(c).into(),
1114            OutputItem::LocalShellCall(c) => Item::LocalShellCall(c).into(),
1115            OutputItem::ShellCall(c) => Item::ShellCall(c.into()).into(),
1116            OutputItem::ShellCallOutput(o) => Item::ShellCallOutput(o.into()).into(),
1117            OutputItem::ApplyPatchCall(c) => Item::ApplyPatchCall(c.into()).into(),
1118            OutputItem::ApplyPatchCallOutput(o) => Item::ApplyPatchCallOutput(o.into()).into(),
1119            OutputItem::McpCall(c) => Item::McpCall(c).into(),
1120            OutputItem::McpListTools(c) => Item::McpListTools(c).into(),
1121            OutputItem::McpApprovalRequest(c) => Item::McpApprovalRequest(c).into(),
1122            OutputItem::CustomToolCall(c) => Item::CustomToolCall(c).into(),
1123            OutputItem::CustomToolCallOutput(o) => Item::CustomToolCallOutput(o.into()).into(),
1124            OutputItem::ToolSearchCall(c) => Item::ToolSearchCall(c.into()).into(),
1125            OutputItem::ToolSearchOutput(o) => Item::ToolSearchOutput(o.into()).into(),
1126        }
1127    }
1128}
1129
1130impl From<Tool> for ToolSearchOutputTool {
1131    fn from(tool: Tool) -> Self {
1132        match tool {
1133            Tool::ProgrammaticToolCalling => Self::ProgrammaticToolCalling,
1134            Tool::LocalShell => Self::LocalShell,
1135            Tool::Function(value) => Self::Function(value),
1136            Tool::FileSearch(value) => Self::FileSearch(value),
1137            Tool::ComputerUsePreview(value) => Self::ComputerUsePreview(value),
1138            Tool::WebSearch(value) => Self::WebSearch(value),
1139            Tool::WebSearch20250826(value) => Self::WebSearch20250826(value),
1140            Tool::Mcp(value) => Self::Mcp(value),
1141            Tool::CodeInterpreter(value) => Self::CodeInterpreter(value),
1142            Tool::ImageGeneration(value) => Self::ImageGeneration(value),
1143            Tool::Shell(value) => Self::Shell(value),
1144            Tool::Custom(value) => Self::Custom(value),
1145            Tool::Computer => Self::Computer,
1146            Tool::Namespace(value) => Self::Namespace(ToolSearchOutputNamespaceToolParam {
1147                name: value.name,
1148                description: value.description,
1149                tools: value.tools,
1150            }),
1151            Tool::ToolSearch(value) => Self::ToolSearch(value),
1152            Tool::WebSearchPreview(value) => Self::WebSearchPreview(value),
1153            Tool::WebSearchPreview20250311(value) => Self::WebSearchPreview20250311(value),
1154            Tool::ApplyPatch(value) => Self::ApplyPatch(value),
1155        }
1156    }
1157}