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(&self, prompt: String) -> Result<bool, crate::FrontendRuntimeError> {
181 let value = self
182 .transport
183 .call(
184 FrontendFacadeMethod::SendInput,
185 serde_json::json!({"prompt": prompt}),
186 )
187 .await?;
188 value
189 .get("accepted")
190 .and_then(serde_json::Value::as_bool)
191 .ok_or_else(|| {
192 crate::FrontendRuntimeError::Transport(
193 "invalid frontend.v2.send_input result".into(),
194 )
195 })
196 }
197
198 pub async fn submit(&self, prompt: String) -> Result<String, crate::FrontendRuntimeError> {
199 let value = self
200 .transport
201 .call(
202 FrontendFacadeMethod::Submit,
203 serde_json::json!({"prompt": prompt}),
204 )
205 .await?;
206 value
207 .get("reply")
208 .and_then(serde_json::Value::as_str)
209 .map(|value| value.to_string())
210 .ok_or_else(|| {
211 crate::FrontendRuntimeError::Transport("invalid frontend.v2.submit result".into())
212 })
213 }
214
215 pub async fn interrupt(&self) -> Result<bool, crate::FrontendRuntimeError> {
216 let value = self
217 .transport
218 .call(FrontendFacadeMethod::Interrupt, serde_json::json!({}))
219 .await?;
220 value
221 .get("interrupted")
222 .and_then(serde_json::Value::as_bool)
223 .ok_or_else(|| {
224 crate::FrontendRuntimeError::Transport(
225 "invalid frontend.v2.interrupt result".into(),
226 )
227 })
228 }
229
230 pub async fn steer(&self, prompt: String) -> Result<bool, crate::FrontendRuntimeError> {
231 let value = self
232 .transport
233 .call(
234 FrontendFacadeMethod::Steer,
235 serde_json::json!({"prompt": prompt}),
236 )
237 .await?;
238 value
239 .get("queued")
240 .and_then(serde_json::Value::as_bool)
241 .ok_or_else(|| {
242 crate::FrontendRuntimeError::Transport("invalid frontend.v2.steer result".into())
243 })
244 }
245
246 pub async fn respond(
247 &self,
248 response: crate::FrontendResponse,
249 ) -> Result<bool, crate::FrontendRuntimeError> {
250 let value = self
251 .transport
252 .call(
253 FrontendFacadeMethod::Respond,
254 serde_json::json!({"response": response}),
255 )
256 .await?;
257 value
258 .get("accepted")
259 .and_then(serde_json::Value::as_bool)
260 .ok_or_else(|| {
261 crate::FrontendRuntimeError::Transport("invalid frontend.v2.respond result".into())
262 })
263 }
264
265 pub async fn invoke(
266 &self,
267 operation: crate::FrontendOperationInvocation,
268 ) -> Result<crate::FrontendOperationResult, crate::FrontendRuntimeError> {
269 let value = self
270 .transport
271 .call(
272 FrontendFacadeMethod::Invoke,
273 serde_json::json!({"operation": operation}),
274 )
275 .await?;
276 serde_json::from_value::<crate::FrontendOperationResult>(value)
277 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
278 }
279
280 pub async fn lease(&self) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
281 let value = self
282 .transport
283 .call(FrontendFacadeMethod::Lease, serde_json::json!({}))
284 .await?;
285 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
286 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
287 }
288
289 pub async fn take_control(
290 &self,
291 ) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
292 let value = self
293 .transport
294 .call(FrontendFacadeMethod::TakeControl, serde_json::json!({}))
295 .await?;
296 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
297 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
298 }
299
300 pub async fn heartbeat(
301 &self,
302 ) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
303 let value = self
304 .transport
305 .call(FrontendFacadeMethod::Heartbeat, serde_json::json!({}))
306 .await?;
307 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
308 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
309 }
310
311 pub async fn detach(&self) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
312 let value = self
313 .transport
314 .call(FrontendFacadeMethod::Detach, serde_json::json!({}))
315 .await?;
316 serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
317 .map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
318 }
319
320 pub async fn close(&self) -> Result<bool, crate::FrontendRuntimeError> {
321 let value = self
322 .transport
323 .call(FrontendFacadeMethod::Close, serde_json::json!({}))
324 .await?;
325 value
326 .get("closed")
327 .and_then(serde_json::Value::as_bool)
328 .ok_or_else(|| {
329 crate::FrontendRuntimeError::Transport("invalid frontend.v2.close result".into())
330 })
331 }
332}