ai_providers/openai/common/
computer_tool_call_item.rs1use serde::{Deserialize, Serialize};
2
3use crate::openai::common::status::Status;
4use crate::openai::errors::InputError;
5
6#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
7pub struct ClickAction {
8 pub button: String,
9 #[serde(rename = "type")]
10 pub type_field: String,
11 pub x: usize,
12 pub y: usize,
13}
14
15impl ClickAction {
16 const BUTTON: [&'static str; 5] = ["left", "right", "wheel", "back", "forward"];
17
18 pub fn new(button: impl Into<String>, x: usize, y: usize) -> Result<Self, InputError> {
19 let button_str = button.into();
20 if Self::BUTTON.contains(&button_str.as_str()) {
21 Ok(Self {
22 button: button_str,
23 type_field: "click".to_string(),
24 x,
25 y,
26 })
27 } else {
28 Err(InputError::InvalidButton(button_str))
29 }
30 }
31}
32
33#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
34pub struct DoubleClickAction {
35 #[serde(rename = "type")]
36 pub type_field: String,
37 pub x: usize,
38 pub y: usize,
39}
40
41impl DoubleClickAction {
42 pub fn new(x: usize, y: usize) -> Self {
43 Self {
44 type_field: "double_click".to_string(),
45 x,
46 y,
47 }
48 }
49}
50
51#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
52pub struct DragActionPath {
53 pub x: usize,
54 pub y: usize,
55}
56
57impl DragActionPath {
58 pub fn new(x: usize, y: usize) -> Self {
59 Self { x, y }
60 }
61}
62
63#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
64pub struct DragAction {
65 #[serde(rename = "type")]
66 pub type_field: String,
67 pub path: Vec<DragActionPath>,
68}
69
70impl DragAction {
71 pub fn new(path: Vec<DragActionPath>) -> Self {
72 Self {
73 type_field: "drag".to_string(),
74 path,
75 }
76 }
77}
78
79#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
80pub struct KeyPressAction {
81 #[serde(rename = "type")]
82 pub type_field: String,
83 pub keys: Vec<String>,
84}
85
86impl KeyPressAction {
87 pub fn new(keys: Vec<impl Into<String>>) -> Self {
88 Self {
89 type_field: "keypress".to_string(),
90 keys: keys.into_iter().map(|k| k.into()).collect(),
91 }
92 }
93}
94
95#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
96pub struct MoveAction {
97 #[serde(rename = "type")]
98 pub type_field: String,
99 pub x: usize,
100 pub y: usize,
101}
102
103impl MoveAction {
104 pub fn new(x: usize, y: usize) -> Self {
105 Self {
106 type_field: "move".to_string(),
107 x,
108 y,
109 }
110 }
111}
112
113#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
114pub struct ScreenshotAction {
115 #[serde(rename = "type")]
116 pub type_field: String,
117}
118
119impl ScreenshotAction {
120 pub fn new() -> Self {
121 Self {
122 type_field: "screenshot".to_string(),
123 }
124 }
125}
126
127impl Default for ScreenshotAction {
128 fn default() -> Self {
129 Self::new()
130 }
131}
132
133#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
134pub struct ScrollAction {
135 #[serde(rename = "type")]
136 pub type_field: String,
137 pub scroll_x: usize,
138 pub scroll_y: usize,
139 pub x: usize,
140 pub y: usize,
141}
142
143impl ScrollAction {
144 pub fn new(scroll_x: usize, scroll_y: usize, x: usize, y: usize) -> Self {
145 Self {
146 type_field: "scroll".to_string(),
147 scroll_x,
148 scroll_y,
149 x,
150 y,
151 }
152 }
153}
154
155#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
156pub struct TypeAction {
157 #[serde(rename = "type")]
158 pub type_field: String,
159 pub text: String,
160}
161
162impl TypeAction {
163 pub fn new(text: impl Into<String>) -> Self {
164 Self {
165 type_field: "type".to_string(),
166 text: text.into(),
167 }
168 }
169}
170
171#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
172pub struct WaitAction {
173 #[serde(rename = "type")]
174 pub type_field: String,
175}
176
177impl WaitAction {
178 pub fn new() -> Self {
179 Self {
180 type_field: "wait".to_string(),
181 }
182 }
183}
184
185impl Default for WaitAction {
186 fn default() -> Self {
187 Self::new()
188 }
189}
190
191#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
192#[serde(untagged)]
193pub enum ComputerToolAction {
194 Click(ClickAction),
195 DoubleClick(DoubleClickAction),
196 Drag(DragAction),
197 KeyPress(KeyPressAction),
198 Move(MoveAction),
199 Screenshot(ScreenshotAction),
200 Scroll(ScrollAction),
201 Type(TypeAction),
202 Wait(WaitAction),
203}
204
205#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
206pub struct PendingSafetyChecks {
207 pub code: String,
208 pub id: String,
209 pub message: String,
210}
211
212impl PendingSafetyChecks {
213 pub fn new(code: impl Into<String>, id: impl Into<String>, message: impl Into<String>) -> Self {
214 Self {
215 code: code.into(),
216 id: id.into(),
217 message: message.into(),
218 }
219 }
220}
221
222#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
223pub struct ComputerToolCallItem {
224 pub action: ComputerToolAction,
225 pub call_id: String,
226 pub id: String,
227 pub pending_safety_checks: Vec<PendingSafetyChecks>,
228 pub status: Status,
229}
230
231impl ComputerToolCallItem {
232 pub fn new(
233 action: ComputerToolAction,
234 call_id: impl Into<String>,
235 id: impl Into<String>,
236 pending_safety_checks: Vec<PendingSafetyChecks>,
237 status: Status,
238 ) -> Self {
239 Self {
240 action,
241 call_id: call_id.into(),
242 id: id.into(),
243 pending_safety_checks,
244 status,
245 }
246 }
247}