use motosan_agent_tool::ToolResult;
use serde_json::Value;
#[derive(Debug, Clone)]
pub enum ProgressChunk {
Stdout(Vec<u8>),
Stderr(Vec<u8>),
Status(String),
}
impl From<crate::tools::ToolProgressChunk> for ProgressChunk {
fn from(c: crate::tools::ToolProgressChunk) -> Self {
use crate::tools::ToolProgressChunk as TPC;
match c {
TPC::Stdout(b) => Self::Stdout(b),
TPC::Stderr(b) => Self::Stderr(b),
TPC::Status(s) => Self::Status(s),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PermissionResolution {
pub tool: String,
pub args: serde_json::Value,
pub choice: PermissionChoice,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PermissionChoice {
AllowOnce,
AllowSession,
Deny,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Command {
SendUserMessage(String),
CancelAgent,
Quit,
ResolvePermission(PermissionResolution),
}
#[derive(Debug)]
pub enum UiEvent {
AgentTurnStarted,
AgentThinking,
AgentTextDelta(String),
AgentMessageComplete(String),
ToolCallStarted {
id: String,
name: String,
args: Value,
},
ToolCallProgress {
id: String,
chunk: ProgressChunk,
},
ToolCallCompleted {
id: String,
result: UiToolResult,
},
AgentTurnComplete,
PermissionRequested {
tool: String,
args: serde_json::Value,
resolver: tokio::sync::oneshot::Sender<crate::permissions::Decision>,
},
Error(String),
}
#[derive(Debug, Clone)]
pub struct UiToolResult {
pub is_error: bool,
pub text: String,
}
impl From<&ToolResult> for UiToolResult {
fn from(r: &ToolResult) -> Self {
Self {
is_error: r.is_error,
text: format!("{r:?}"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn permission_protocol_variants_are_constructible() {
let command = Command::ResolvePermission(PermissionResolution {
tool: "bash".into(),
args: serde_json::json!({"command": "echo hi"}),
choice: PermissionChoice::AllowSession,
});
assert!(format!("{command:?}").contains("ResolvePermission"));
assert!(format!("{command:?}").contains("AllowSession"));
let (resolver, _rx) = tokio::sync::oneshot::channel::<crate::permissions::Decision>();
let event = UiEvent::PermissionRequested {
tool: "bash".into(),
args: serde_json::json!({"command": "echo hi"}),
resolver,
};
assert!(format!("{event:?}").contains("PermissionRequested"));
}
}