#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FrontendFacadeMethod {
Describe,
Attach,
SendInput,
Submit,
Interrupt,
Steer,
Respond,
Invoke,
Lease,
TakeControl,
Heartbeat,
Detach,
Close,
}
impl FrontendFacadeMethod {
pub const ALL: [Self; 13] = [
Self::Describe,
Self::Attach,
Self::SendInput,
Self::Submit,
Self::Interrupt,
Self::Steer,
Self::Respond,
Self::Invoke,
Self::Lease,
Self::TakeControl,
Self::Heartbeat,
Self::Detach,
Self::Close,
];
pub const fn id(self) -> &'static str {
match self {
Self::Describe => "describe",
Self::Attach => "attach",
Self::SendInput => "send_input",
Self::Submit => "submit",
Self::Interrupt => "interrupt",
Self::Steer => "steer",
Self::Respond => "respond",
Self::Invoke => "invoke",
Self::Lease => "lease",
Self::TakeControl => "take_control",
Self::Heartbeat => "heartbeat",
Self::Detach => "detach",
Self::Close => "close",
}
}
pub const fn wire_name(self) -> &'static str {
match self {
Self::Describe => "frontend.v2.describe",
Self::Attach => "frontend.v2.attach",
Self::SendInput => "frontend.v2.send_input",
Self::Submit => "frontend.v2.submit",
Self::Interrupt => "frontend.v2.interrupt",
Self::Steer => "frontend.v2.steer",
Self::Respond => "frontend.v2.respond",
Self::Invoke => "frontend.v2.invoke",
Self::Lease => "frontend.v2.lease",
Self::TakeControl => "frontend.v2.take_control",
Self::Heartbeat => "frontend.v2.heartbeat",
Self::Detach => "frontend.v2.detach",
Self::Close => "frontend.v2.close",
}
}
pub const fn sdk_action(self) -> &'static str {
match self {
Self::Describe => "resume",
Self::Attach => "events",
Self::SendInput => "input",
Self::Submit => "input",
Self::Interrupt => "interrupt",
Self::Steer => "steer",
Self::Respond => "respond",
Self::Invoke => "input",
Self::Lease => "events",
Self::TakeControl => "input",
Self::Heartbeat => "events",
Self::Detach => "events",
Self::Close => "close",
}
}
pub fn from_wire_name(value: &str) -> Option<Self> {
match value {
"frontend.v2.describe" => Some(Self::Describe),
"frontend.v2.attach" => Some(Self::Attach),
"frontend.v2.send_input" => Some(Self::SendInput),
"frontend.v2.submit" => Some(Self::Submit),
"frontend.v2.interrupt" => Some(Self::Interrupt),
"frontend.v2.steer" => Some(Self::Steer),
"frontend.v2.respond" => Some(Self::Respond),
"frontend.v2.invoke" => Some(Self::Invoke),
"frontend.v2.lease" => Some(Self::Lease),
"frontend.v2.take_control" => Some(Self::TakeControl),
"frontend.v2.heartbeat" => Some(Self::Heartbeat),
"frontend.v2.detach" => Some(Self::Detach),
"frontend.v2.close" => Some(Self::Close),
"frontend.describe" => Some(Self::Describe),
"frontend.attach" => Some(Self::Attach),
"frontend.send_input" => Some(Self::SendInput),
"frontend.invoke" => Some(Self::Invoke),
"frontend.lease" => Some(Self::Lease),
"frontend.take_control" => Some(Self::TakeControl),
"frontend.heartbeat" => Some(Self::Heartbeat),
"frontend.detach" => Some(Self::Detach),
"frontend.close" => Some(Self::Close),
"submit" => Some(Self::Submit),
"interrupt" => Some(Self::Interrupt),
"steer" => Some(Self::Steer),
"respond" => Some(Self::Respond),
_ => None,
}
}
}
pub trait FrontendFacadeTransport: Send + Sync {
fn call<'a>(
&'a self,
method: FrontendFacadeMethod,
params: serde_json::Value,
) -> std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<serde_json::Value, crate::FrontendRuntimeError>>
+ Send
+ 'a,
>,
>;
}
pub struct GeneratedFrontendClient<T> {
transport: T,
}
impl<T> GeneratedFrontendClient<T> {
pub const fn new(transport: T) -> Self {
Self { transport }
}
}
impl<T: FrontendFacadeTransport> GeneratedFrontendClient<T> {
pub async fn describe(
&self,
) -> Result<crate::FrontendRuntimeDescriptor, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::Describe, serde_json::json!({}))
.await?;
serde_json::from_value::<crate::FrontendRuntimeDescriptor>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn attach(
&self,
limit: u64,
after_sequence: Option<u64>,
) -> Result<crate::FrontendAttachSnapshot, crate::FrontendRuntimeError> {
let mut params = serde_json::json!({"limit": limit});
if let Some(value) = after_sequence {
params["after_sequence"] = serde_json::json!(value);
}
let value = self
.transport
.call(FrontendFacadeMethod::Attach, params)
.await?;
serde_json::from_value::<crate::FrontendAttachSnapshot>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn send_input(
&self,
prompt: String,
image_urls: Option<Vec<String>>,
) -> Result<bool, crate::FrontendRuntimeError> {
let mut params = serde_json::json!({"prompt": prompt});
if let Some(value) = image_urls {
params["image_urls"] = serde_json::json!(value);
}
let value = self
.transport
.call(FrontendFacadeMethod::SendInput, params)
.await?;
value
.get("accepted")
.and_then(serde_json::Value::as_bool)
.ok_or_else(|| {
crate::FrontendRuntimeError::Transport(
"invalid frontend.v2.send_input result".into(),
)
})
}
pub async fn submit(
&self,
prompt: String,
image_urls: Option<Vec<String>>,
) -> Result<String, crate::FrontendRuntimeError> {
let mut params = serde_json::json!({"prompt": prompt});
if let Some(value) = image_urls {
params["image_urls"] = serde_json::json!(value);
}
let value = self
.transport
.call(FrontendFacadeMethod::Submit, params)
.await?;
value
.get("reply")
.and_then(serde_json::Value::as_str)
.map(|value| value.to_string())
.ok_or_else(|| {
crate::FrontendRuntimeError::Transport("invalid frontend.v2.submit result".into())
})
}
pub async fn interrupt(&self) -> Result<bool, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::Interrupt, serde_json::json!({}))
.await?;
value
.get("interrupted")
.and_then(serde_json::Value::as_bool)
.ok_or_else(|| {
crate::FrontendRuntimeError::Transport(
"invalid frontend.v2.interrupt result".into(),
)
})
}
pub async fn steer(&self, prompt: String) -> Result<bool, crate::FrontendRuntimeError> {
let value = self
.transport
.call(
FrontendFacadeMethod::Steer,
serde_json::json!({"prompt": prompt}),
)
.await?;
value
.get("queued")
.and_then(serde_json::Value::as_bool)
.ok_or_else(|| {
crate::FrontendRuntimeError::Transport("invalid frontend.v2.steer result".into())
})
}
pub async fn respond(
&self,
response: crate::FrontendResponse,
) -> Result<bool, crate::FrontendRuntimeError> {
let value = self
.transport
.call(
FrontendFacadeMethod::Respond,
serde_json::json!({"response": response}),
)
.await?;
value
.get("accepted")
.and_then(serde_json::Value::as_bool)
.ok_or_else(|| {
crate::FrontendRuntimeError::Transport("invalid frontend.v2.respond result".into())
})
}
pub async fn invoke(
&self,
operation: crate::FrontendOperationInvocation,
) -> Result<crate::FrontendOperationResult, crate::FrontendRuntimeError> {
let value = self
.transport
.call(
FrontendFacadeMethod::Invoke,
serde_json::json!({"operation": operation}),
)
.await?;
serde_json::from_value::<crate::FrontendOperationResult>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn lease(&self) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::Lease, serde_json::json!({}))
.await?;
serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn take_control(
&self,
) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::TakeControl, serde_json::json!({}))
.await?;
serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn heartbeat(
&self,
) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::Heartbeat, serde_json::json!({}))
.await?;
serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn detach(&self) -> Result<crate::RuntimeLeaseSnapshot, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::Detach, serde_json::json!({}))
.await?;
serde_json::from_value::<crate::RuntimeLeaseSnapshot>(value)
.map_err(|error| crate::FrontendRuntimeError::Transport(error.to_string()))
}
pub async fn close(&self) -> Result<bool, crate::FrontendRuntimeError> {
let value = self
.transport
.call(FrontendFacadeMethod::Close, serde_json::json!({}))
.await?;
value
.get("closed")
.and_then(serde_json::Value::as_bool)
.ok_or_else(|| {
crate::FrontendRuntimeError::Transport("invalid frontend.v2.close result".into())
})
}
}