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