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