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}