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}