1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum FrontendFacadeMethod {
6 Describe,
7 Attach,
8 SendInput,
9 Submit,
10 Interrupt,
11 Steer,
12 Respond,
13 Invoke,
14 Lease,
15 TakeControl,
16 Heartbeat,
17 Detach,
18 Close,
19}
20
21impl FrontendFacadeMethod {
22 pub const ALL: [Self; 13] = [
23 Self::Describe,
24 Self::Attach,
25 Self::SendInput,
26 Self::Submit,
27 Self::Interrupt,
28 Self::Steer,
29 Self::Respond,
30 Self::Invoke,
31 Self::Lease,
32 Self::TakeControl,
33 Self::Heartbeat,
34 Self::Detach,
35 Self::Close,
36 ];
37
38 pub const fn id(self) -> &'static str {
39 match self {
40 Self::Describe => "describe",
41 Self::Attach => "attach",
42 Self::SendInput => "send_input",
43 Self::Submit => "submit",
44 Self::Interrupt => "interrupt",
45 Self::Steer => "steer",
46 Self::Respond => "respond",
47 Self::Invoke => "invoke",
48 Self::Lease => "lease",
49 Self::TakeControl => "take_control",
50 Self::Heartbeat => "heartbeat",
51 Self::Detach => "detach",
52 Self::Close => "close",
53 }
54 }
55
56 pub const fn wire_name(self) -> &'static str {
57 match self {
58 Self::Describe => "frontend.v2.describe",
59 Self::Attach => "frontend.v2.attach",
60 Self::SendInput => "frontend.v2.send_input",
61 Self::Submit => "frontend.v2.submit",
62 Self::Interrupt => "frontend.v2.interrupt",
63 Self::Steer => "frontend.v2.steer",
64 Self::Respond => "frontend.v2.respond",
65 Self::Invoke => "frontend.v2.invoke",
66 Self::Lease => "frontend.v2.lease",
67 Self::TakeControl => "frontend.v2.take_control",
68 Self::Heartbeat => "frontend.v2.heartbeat",
69 Self::Detach => "frontend.v2.detach",
70 Self::Close => "frontend.v2.close",
71 }
72 }
73
74 pub const fn sdk_action(self) -> &'static str {
75 match self {
76 Self::Describe => "resume",
77 Self::Attach => "events",
78 Self::SendInput => "input",
79 Self::Submit => "input",
80 Self::Interrupt => "interrupt",
81 Self::Steer => "steer",
82 Self::Respond => "respond",
83 Self::Invoke => "input",
84 Self::Lease => "events",
85 Self::TakeControl => "input",
86 Self::Heartbeat => "events",
87 Self::Detach => "events",
88 Self::Close => "close",
89 }
90 }
91
92 pub fn from_wire_name(value: &str) -> Option<Self> {
93 match value {
94 "frontend.v2.describe" => Some(Self::Describe),
95 "frontend.v2.attach" => Some(Self::Attach),
96 "frontend.v2.send_input" => Some(Self::SendInput),
97 "frontend.v2.submit" => Some(Self::Submit),
98 "frontend.v2.interrupt" => Some(Self::Interrupt),
99 "frontend.v2.steer" => Some(Self::Steer),
100 "frontend.v2.respond" => Some(Self::Respond),
101 "frontend.v2.invoke" => Some(Self::Invoke),
102 "frontend.v2.lease" => Some(Self::Lease),
103 "frontend.v2.take_control" => Some(Self::TakeControl),
104 "frontend.v2.heartbeat" => Some(Self::Heartbeat),
105 "frontend.v2.detach" => Some(Self::Detach),
106 "frontend.v2.close" => Some(Self::Close),
107 "frontend.describe" => Some(Self::Describe),
108 "frontend.attach" => Some(Self::Attach),
109 "frontend.send_input" => Some(Self::SendInput),
110 "frontend.invoke" => Some(Self::Invoke),
111 "frontend.lease" => Some(Self::Lease),
112 "frontend.take_control" => Some(Self::TakeControl),
113 "frontend.heartbeat" => Some(Self::Heartbeat),
114 "frontend.detach" => Some(Self::Detach),
115 "frontend.close" => Some(Self::Close),
116 "submit" => Some(Self::Submit),
117 "interrupt" => Some(Self::Interrupt),
118 "steer" => Some(Self::Steer),
119 "respond" => Some(Self::Respond),
120 _ => None,
121 }
122 }
123}
124
125pub trait FrontendFacadeTransport: Send + Sync {
127 fn call<'a>(
128 &'a self,
129 method: FrontendFacadeMethod,
130 params: serde_json::Value,
131 ) -> std::pin::Pin<
132 Box<
133 dyn std::future::Future<Output = Result<serde_json::Value, crate::FrontendRuntimeError>>
134 + Send
135 + 'a,
136 >,
137 >;
138}
139
140pub struct GeneratedFrontendClient<T> {
142 transport: T,
143}
144
145impl<T> GeneratedFrontendClient<T> {
146 pub const fn new(transport: T) -> Self {
147 Self { transport }
148 }
149}
150
151impl<T: FrontendFacadeTransport> GeneratedFrontendClient<T> {
152 pub async fn describe(
153 &self,
154 ) -> Result<crate::FrontendRuntimeDescriptor, crate::FrontendRuntimeError> {
155 let value = self
156 .transport
157 .call(FrontendFacadeMethod::Describe, serde_json::json!({}))
158 .await?;
159 serde_json::from_value::<crate::FrontendRuntimeDescriptor>(value)
160 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
161 }
162
163 pub async fn attach(
164 &self,
165 limit: u64,
166 after_sequence: Option<u64>,
167 ) -> Result<crate::FrontendAttachSnapshot, crate::FrontendRuntimeError> {
168 let mut params = serde_json::json!({"limit": limit});
169 if let Some(value) = after_sequence {
170 params["after_sequence"] = serde_json::json!(value);
171 }
172 let value = self
173 .transport
174 .call(FrontendFacadeMethod::Attach, params)
175 .await?;
176 serde_json::from_value::<crate::FrontendAttachSnapshot>(value)
177 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
178 }
179
180 pub async fn send_input(
181 &self,
182 prompt: String,
183 image_urls: Option<Vec<String>>,
184 ) -> Result<bool, crate::FrontendRuntimeError> {
185 let mut params = serde_json::json!({"prompt": prompt});
186 if let Some(value) = image_urls {
187 params["image_urls"] = serde_json::json!(value);
188 }
189 let value = self
190 .transport
191 .call(FrontendFacadeMethod::SendInput, params)
192 .await?;
193 value
194 .get("accepted")
195 .and_then(serde_json::Value::as_bool)
196 .ok_or_else(|| {
197 crate::FrontendRuntimeError::Transport(
198 "invalid frontend.v2.send_input result".into(),
199 )
200 })
201 }
202
203 pub async fn submit(
204 &self,
205 prompt: String,
206 image_urls: Option<Vec<String>>,
207 ) -> Result<String, crate::FrontendRuntimeError> {
208 let mut params = serde_json::json!({"prompt": prompt});
209 if let Some(value) = image_urls {
210 params["image_urls"] = serde_json::json!(value);
211 }
212 let value = self
213 .transport
214 .call(FrontendFacadeMethod::Submit, params)
215 .await?;
216 value
217 .get("reply")
218 .and_then(serde_json::Value::as_str)
219 .map(|value| value.to_string())
220 .ok_or_else(|| {
221 crate::FrontendRuntimeError::Transport("invalid frontend.v2.submit result".into())
222 })
223 }
224
225 pub async fn interrupt(&self) -> Result<bool, crate::FrontendRuntimeError> {
226 let value = self
227 .transport
228 .call(FrontendFacadeMethod::Interrupt, serde_json::json!({}))
229 .await?;
230 value
231 .get("interrupted")
232 .and_then(serde_json::Value::as_bool)
233 .ok_or_else(|| {
234 crate::FrontendRuntimeError::Transport(
235 "invalid frontend.v2.interrupt result".into(),
236 )
237 })
238 }
239
240 pub async fn steer(&self, prompt: String) -> Result<bool, crate::FrontendRuntimeError> {
241 let value = self
242 .transport
243 .call(
244 FrontendFacadeMethod::Steer,
245 serde_json::json!({"prompt": prompt}),
246 )
247 .await?;
248 value
249 .get("queued")
250 .and_then(serde_json::Value::as_bool)
251 .ok_or_else(|| {
252 crate::FrontendRuntimeError::Transport("invalid frontend.v2.steer result".into())
253 })
254 }
255
256 pub async fn respond(
257 &self,
258 response: crate::FrontendResponse,
259 ) -> Result<bool, crate::FrontendRuntimeError> {
260 let value = self
261 .transport
262 .call(
263 FrontendFacadeMethod::Respond,
264 serde_json::json!({"response": response}),
265 )
266 .await?;
267 value
268 .get("accepted")
269 .and_then(serde_json::Value::as_bool)
270 .ok_or_else(|| {
271 crate::FrontendRuntimeError::Transport("invalid frontend.v2.respond result".into())
272 })
273 }
274
275 pub async fn invoke(
276 &self,
277 operation: crate::FrontendOperationInvocation,
278 ) -> Result<crate::FrontendOperationResult, crate::FrontendRuntimeError> {
279 let value = self
280 .transport
281 .call(
282 FrontendFacadeMethod::Invoke,
283 serde_json::json!({"operation": operation}),
284 )
285 .await?;
286 serde_json::from_value::<crate::FrontendOperationResult>(value)
287 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
288 }
289
290 pub async fn lease(&self) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
291 let value = self
292 .transport
293 .call(FrontendFacadeMethod::Lease, serde_json::json!({}))
294 .await?;
295 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
296 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
297 }
298
299 pub async fn take_control(
300 &self,
301 ) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
302 let value = self
303 .transport
304 .call(FrontendFacadeMethod::TakeControl, serde_json::json!({}))
305 .await?;
306 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
307 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
308 }
309
310 pub async fn heartbeat(
311 &self,
312 ) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
313 let value = self
314 .transport
315 .call(FrontendFacadeMethod::Heartbeat, serde_json::json!({}))
316 .await?;
317 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
318 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
319 }
320
321 pub async fn detach(&self) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
322 let value = self
323 .transport
324 .call(FrontendFacadeMethod::Detach, serde_json::json!({}))
325 .await?;
326 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
327 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
328 }
329
330 pub async fn close(&self) -> Result<bool, crate::FrontendRuntimeError> {
331 let value = self
332 .transport
333 .call(FrontendFacadeMethod::Close, serde_json::json!({}))
334 .await?;
335 value
336 .get("closed")
337 .and_then(serde_json::Value::as_bool)
338 .ok_or_else(|| {
339 crate::FrontendRuntimeError::Transport("invalid frontend.v2.close result".into())
340 })
341 }
342}