1use acp_thread::AcpThread;
2use anyhow::Result;
3use context_server::{
4 listener::{McpServerTool, ToolResponse},
5 types::ToolAnnotations,
6};
7use gpui::{AsyncApp, WeakEntity};
8
9use crate::tools::WriteToolParams;
10
11#[derive(Clone)]
12pub struct WriteTool {
13 thread_rx: watch::Receiver<WeakEntity<AcpThread>>,
14}
15
16impl WriteTool {
17 pub fn new(thread_rx: watch::Receiver<WeakEntity<AcpThread>>) -> Self {
18 Self { thread_rx }
19 }
20}
21
22impl McpServerTool for WriteTool {
23 type Input = WriteToolParams;
24 type Output = ();
25
26 const NAME: &'static str = "Write";
27
28 fn annotations(&self) -> ToolAnnotations {
29 ToolAnnotations {
30 title: Some("Write file".to_string()),
31 read_only_hint: Some(false),
32 destructive_hint: Some(false),
33 open_world_hint: Some(false),
34 idempotent_hint: Some(false),
35 }
36 }
37
38 async fn run(
39 &self,
40 input: Self::Input,
41 cx: &mut AsyncApp,
42 ) -> Result<ToolResponse<Self::Output>> {
43 let mut thread_rx = self.thread_rx.clone();
44 let Some(thread) = thread_rx.recv().await?.upgrade() else {
45 anyhow::bail!("Thread closed");
46 };
47
48 thread
49 .update(cx, |thread, cx| {
50 thread.write_text_file(input.abs_path, input.content, cx)
51 })?
52 .await?;
53
54 Ok(ToolResponse {
55 content: vec![],
56 structured_content: (),
57 })
58 }
59}