test_tools.rs

  1use super::*;
  2use anyhow::Result;
  3use gpui::{App, SharedString, Task};
  4use std::future;
  5
  6/// A tool that echoes its input
  7#[derive(JsonSchema, Serialize, Deserialize)]
  8pub struct EchoToolInput {
  9    /// The text to echo.
 10    text: String,
 11}
 12
 13pub struct EchoTool;
 14
 15impl AgentTool for EchoTool {
 16    type Input = EchoToolInput;
 17    type Output = String;
 18
 19    fn name(&self) -> SharedString {
 20        "echo".into()
 21    }
 22
 23    fn kind(&self) -> acp::ToolKind {
 24        acp::ToolKind::Other
 25    }
 26
 27    fn initial_title(&self, _: Self::Input) -> SharedString {
 28        "Echo".into()
 29    }
 30
 31    fn run(
 32        self: Arc<Self>,
 33        input: Self::Input,
 34        _event_stream: ToolCallEventStream,
 35        _cx: &mut App,
 36    ) -> Task<Result<String>> {
 37        Task::ready(Ok(input.text))
 38    }
 39}
 40
 41/// A tool that waits for a specified delay
 42#[derive(JsonSchema, Serialize, Deserialize)]
 43pub struct DelayToolInput {
 44    /// The delay in milliseconds.
 45    ms: u64,
 46}
 47
 48pub struct DelayTool;
 49
 50impl AgentTool for DelayTool {
 51    type Input = DelayToolInput;
 52    type Output = String;
 53
 54    fn name(&self) -> SharedString {
 55        "delay".into()
 56    }
 57
 58    fn initial_title(&self, input: Self::Input) -> SharedString {
 59        format!("Delay {}ms", input.ms).into()
 60    }
 61
 62    fn kind(&self) -> acp::ToolKind {
 63        acp::ToolKind::Other
 64    }
 65
 66    fn run(
 67        self: Arc<Self>,
 68        input: Self::Input,
 69        _event_stream: ToolCallEventStream,
 70        cx: &mut App,
 71    ) -> Task<Result<String>>
 72    where
 73        Self: Sized,
 74    {
 75        cx.foreground_executor().spawn(async move {
 76            smol::Timer::after(Duration::from_millis(input.ms)).await;
 77            Ok("Ding".to_string())
 78        })
 79    }
 80}
 81
 82#[derive(JsonSchema, Serialize, Deserialize)]
 83pub struct ToolRequiringPermissionInput {}
 84
 85pub struct ToolRequiringPermission;
 86
 87impl AgentTool for ToolRequiringPermission {
 88    type Input = ToolRequiringPermissionInput;
 89    type Output = String;
 90
 91    fn name(&self) -> SharedString {
 92        "tool_requiring_permission".into()
 93    }
 94
 95    fn kind(&self) -> acp::ToolKind {
 96        acp::ToolKind::Other
 97    }
 98
 99    fn initial_title(&self, _input: Self::Input) -> SharedString {
100        "This tool requires permission".into()
101    }
102
103    fn run(
104        self: Arc<Self>,
105        _input: Self::Input,
106        event_stream: ToolCallEventStream,
107        cx: &mut App,
108    ) -> Task<Result<String>> {
109        let auth_check = event_stream.authorize("Authorize?".into());
110        cx.foreground_executor().spawn(async move {
111            auth_check.await?;
112            Ok("Allowed".to_string())
113        })
114    }
115}
116
117#[derive(JsonSchema, Serialize, Deserialize)]
118pub struct InfiniteToolInput {}
119
120pub struct InfiniteTool;
121
122impl AgentTool for InfiniteTool {
123    type Input = InfiniteToolInput;
124    type Output = String;
125
126    fn name(&self) -> SharedString {
127        "infinite".into()
128    }
129
130    fn kind(&self) -> acp::ToolKind {
131        acp::ToolKind::Other
132    }
133
134    fn initial_title(&self, _input: Self::Input) -> SharedString {
135        "This is the tool that never ends... it just goes on and on my friends!".into()
136    }
137
138    fn run(
139        self: Arc<Self>,
140        _input: Self::Input,
141        _event_stream: ToolCallEventStream,
142        cx: &mut App,
143    ) -> Task<Result<String>> {
144        cx.foreground_executor().spawn(async move {
145            future::pending::<()>().await;
146            unreachable!()
147        })
148    }
149}
150
151/// A tool that takes an object with map from letters to random words starting with that letter.
152/// All fiealds are required! Pass a word for every letter!
153#[derive(JsonSchema, Serialize, Deserialize)]
154pub struct WordListInput {
155    /// Provide a random word that starts with A.
156    a: Option<String>,
157    /// Provide a random word that starts with B.
158    b: Option<String>,
159    /// Provide a random word that starts with C.
160    c: Option<String>,
161    /// Provide a random word that starts with D.
162    d: Option<String>,
163    /// Provide a random word that starts with E.
164    e: Option<String>,
165    /// Provide a random word that starts with F.
166    f: Option<String>,
167    /// Provide a random word that starts with G.
168    g: Option<String>,
169}
170
171pub struct WordListTool;
172
173impl AgentTool for WordListTool {
174    type Input = WordListInput;
175    type Output = String;
176
177    fn name(&self) -> SharedString {
178        "word_list".into()
179    }
180
181    fn kind(&self) -> acp::ToolKind {
182        acp::ToolKind::Other
183    }
184
185    fn initial_title(&self, _input: Self::Input) -> SharedString {
186        "List of random words".into()
187    }
188
189    fn run(
190        self: Arc<Self>,
191        _input: Self::Input,
192        _event_stream: ToolCallEventStream,
193        _cx: &mut App,
194    ) -> Task<Result<String>> {
195        Task::ready(Ok("ok".to_string()))
196    }
197}