use super::*; use anyhow::Result; use gpui::{App, SharedString, Task}; use std::future; /// A tool that echoes its input #[derive(JsonSchema, Serialize, Deserialize)] pub struct EchoToolInput { /// The text to echo. text: String, } pub struct EchoTool; impl AgentTool for EchoTool { type Input = EchoToolInput; fn name(&self) -> SharedString { "echo".into() } fn kind(&self) -> acp::ToolKind { acp::ToolKind::Other } fn initial_title(&self, _: Self::Input) -> SharedString { "Echo".into() } fn run( self: Arc, input: Self::Input, _event_stream: ToolCallEventStream, _cx: &mut App, ) -> Task> { Task::ready(Ok(input.text)) } } /// A tool that waits for a specified delay #[derive(JsonSchema, Serialize, Deserialize)] pub struct DelayToolInput { /// The delay in milliseconds. ms: u64, } pub struct DelayTool; impl AgentTool for DelayTool { type Input = DelayToolInput; fn name(&self) -> SharedString { "delay".into() } fn initial_title(&self, input: Self::Input) -> SharedString { format!("Delay {}ms", input.ms).into() } fn kind(&self) -> acp::ToolKind { acp::ToolKind::Other } fn run( self: Arc, input: Self::Input, _event_stream: ToolCallEventStream, cx: &mut App, ) -> Task> where Self: Sized, { cx.foreground_executor().spawn(async move { smol::Timer::after(Duration::from_millis(input.ms)).await; Ok("Ding".to_string()) }) } } #[derive(JsonSchema, Serialize, Deserialize)] pub struct ToolRequiringPermissionInput {} pub struct ToolRequiringPermission; impl AgentTool for ToolRequiringPermission { type Input = ToolRequiringPermissionInput; fn name(&self) -> SharedString { "tool_requiring_permission".into() } fn kind(&self) -> acp::ToolKind { acp::ToolKind::Other } fn initial_title(&self, _input: Self::Input) -> SharedString { "This tool requires permission".into() } fn run( self: Arc, _input: Self::Input, event_stream: ToolCallEventStream, cx: &mut App, ) -> Task> { let auth_check = event_stream.authorize("Authorize?".into()); cx.foreground_executor().spawn(async move { auth_check.await?; Ok("Allowed".to_string()) }) } } #[derive(JsonSchema, Serialize, Deserialize)] pub struct InfiniteToolInput {} pub struct InfiniteTool; impl AgentTool for InfiniteTool { type Input = InfiniteToolInput; fn name(&self) -> SharedString { "infinite".into() } fn kind(&self) -> acp::ToolKind { acp::ToolKind::Other } fn initial_title(&self, _input: Self::Input) -> SharedString { "This is the tool that never ends... it just goes on and on my friends!".into() } fn run( self: Arc, _input: Self::Input, _event_stream: ToolCallEventStream, cx: &mut App, ) -> Task> { cx.foreground_executor().spawn(async move { future::pending::<()>().await; unreachable!() }) } } /// A tool that takes an object with map from letters to random words starting with that letter. /// All fiealds are required! Pass a word for every letter! #[derive(JsonSchema, Serialize, Deserialize)] pub struct WordListInput { /// Provide a random word that starts with A. a: Option, /// Provide a random word that starts with B. b: Option, /// Provide a random word that starts with C. c: Option, /// Provide a random word that starts with D. d: Option, /// Provide a random word that starts with E. e: Option, /// Provide a random word that starts with F. f: Option, /// Provide a random word that starts with G. g: Option, } pub struct WordListTool; impl AgentTool for WordListTool { type Input = WordListInput; fn name(&self) -> SharedString { "word_list".into() } fn kind(&self) -> acp::ToolKind { acp::ToolKind::Other } fn initial_title(&self, _input: Self::Input) -> SharedString { "List of random words".into() } fn run( self: Arc, _input: Self::Input, _event_stream: ToolCallEventStream, _cx: &mut App, ) -> Task> { Task::ready(Ok("ok".to_string())) } }