1use std::sync::Arc;
2
3use anyhow::{anyhow, Result};
4use assistant_tool::{ActionLog, Tool};
5use gpui::{App, Entity, Task};
6use language_model::LanguageModelRequestMessage;
7use project::Project;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use ui::IconName;
11
12#[derive(Debug, Serialize, Deserialize, JsonSchema)]
13pub struct ThinkingToolInput {
14 /// Content to think about. This should be a description of what to think about or
15 /// a problem to solve.
16 content: String,
17}
18
19pub struct ThinkingTool;
20
21impl Tool for ThinkingTool {
22 fn name(&self) -> String {
23 "thinking".to_string()
24 }
25
26 fn needs_confirmation(&self) -> bool {
27 false
28 }
29
30 fn description(&self) -> String {
31 include_str!("./thinking_tool/description.md").to_string()
32 }
33
34 fn icon(&self) -> IconName {
35 IconName::Brain
36 }
37
38 fn input_schema(&self) -> serde_json::Value {
39 let schema = schemars::schema_for!(ThinkingToolInput);
40 serde_json::to_value(&schema).unwrap()
41 }
42
43 fn ui_text(&self, _input: &serde_json::Value) -> String {
44 "Thinking".to_string()
45 }
46
47 fn run(
48 self: Arc<Self>,
49 input: serde_json::Value,
50 _messages: &[LanguageModelRequestMessage],
51 _project: Entity<Project>,
52 _action_log: Entity<ActionLog>,
53 _cx: &mut App,
54 ) -> Task<Result<String>> {
55 // This tool just "thinks out loud" and doesn't perform any actions.
56 Task::ready(match serde_json::from_value::<ThinkingToolInput>(input) {
57 Ok(_input) => Ok("Finished thinking.".to_string()),
58 Err(err) => Err(anyhow!(err)),
59 })
60 }
61}