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(&self, _input: Result<Self::Input, serde_json::Value>) -> 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() -> &'static str {
55 "delay"
56 }
57
58 fn initial_title(&self, input: Result<Self::Input, serde_json::Value>) -> SharedString {
59 if let Ok(input) = input {
60 format!("Delay {}ms", input.ms).into()
61 } else {
62 "Delay".into()
63 }
64 }
65
66 fn kind() -> acp::ToolKind {
67 acp::ToolKind::Other
68 }
69
70 fn run(
71 self: Arc<Self>,
72 input: Self::Input,
73 _event_stream: ToolCallEventStream,
74 cx: &mut App,
75 ) -> Task<Result<String>>
76 where
77 Self: Sized,
78 {
79 cx.foreground_executor().spawn(async move {
80 smol::Timer::after(Duration::from_millis(input.ms)).await;
81 Ok("Ding".to_string())
82 })
83 }
84}
85
86#[derive(JsonSchema, Serialize, Deserialize)]
87pub struct ToolRequiringPermissionInput {}
88
89pub struct ToolRequiringPermission;
90
91impl AgentTool for ToolRequiringPermission {
92 type Input = ToolRequiringPermissionInput;
93 type Output = String;
94
95 fn name() -> &'static str {
96 "tool_requiring_permission"
97 }
98
99 fn kind() -> acp::ToolKind {
100 acp::ToolKind::Other
101 }
102
103 fn initial_title(&self, _input: Result<Self::Input, serde_json::Value>) -> SharedString {
104 "This tool requires permission".into()
105 }
106
107 fn run(
108 self: Arc<Self>,
109 _input: Self::Input,
110 event_stream: ToolCallEventStream,
111 cx: &mut App,
112 ) -> Task<Result<String>> {
113 let authorize = event_stream.authorize("Authorize?", cx);
114 cx.foreground_executor().spawn(async move {
115 authorize.await?;
116 Ok("Allowed".to_string())
117 })
118 }
119}
120
121#[derive(JsonSchema, Serialize, Deserialize)]
122pub struct InfiniteToolInput {}
123
124pub struct InfiniteTool;
125
126impl AgentTool for InfiniteTool {
127 type Input = InfiniteToolInput;
128 type Output = String;
129
130 fn name() -> &'static str {
131 "infinite"
132 }
133
134 fn kind() -> acp::ToolKind {
135 acp::ToolKind::Other
136 }
137
138 fn initial_title(&self, _input: Result<Self::Input, serde_json::Value>) -> SharedString {
139 "Infinite Tool".into()
140 }
141
142 fn run(
143 self: Arc<Self>,
144 _input: Self::Input,
145 _event_stream: ToolCallEventStream,
146 cx: &mut App,
147 ) -> Task<Result<String>> {
148 cx.foreground_executor().spawn(async move {
149 future::pending::<()>().await;
150 unreachable!()
151 })
152 }
153}
154
155/// A tool that takes an object with map from letters to random words starting with that letter.
156/// All fiealds are required! Pass a word for every letter!
157#[derive(JsonSchema, Serialize, Deserialize)]
158pub struct WordListInput {
159 /// Provide a random word that starts with A.
160 a: Option<String>,
161 /// Provide a random word that starts with B.
162 b: Option<String>,
163 /// Provide a random word that starts with C.
164 c: Option<String>,
165 /// Provide a random word that starts with D.
166 d: Option<String>,
167 /// Provide a random word that starts with E.
168 e: Option<String>,
169 /// Provide a random word that starts with F.
170 f: Option<String>,
171 /// Provide a random word that starts with G.
172 g: Option<String>,
173}
174
175pub struct WordListTool;
176
177impl AgentTool for WordListTool {
178 type Input = WordListInput;
179 type Output = String;
180
181 fn name() -> &'static str {
182 "word_list"
183 }
184
185 fn kind() -> acp::ToolKind {
186 acp::ToolKind::Other
187 }
188
189 fn initial_title(&self, _input: Result<Self::Input, serde_json::Value>) -> SharedString {
190 "List of random words".into()
191 }
192
193 fn run(
194 self: Arc<Self>,
195 _input: Self::Input,
196 _event_stream: ToolCallEventStream,
197 _cx: &mut App,
198 ) -> Task<Result<String>> {
199 Task::ready(Ok("ok".to_string()))
200 }
201}