1use anyhow::Result;
2use assistant_tooling::LanguageModelTool;
3use editor::Editor;
4use gpui::{prelude::*, Model, Task, View, WeakView};
5use project::Project;
6use schemars::JsonSchema;
7use serde::Deserialize;
8use ui::prelude::*;
9use util::ResultExt;
10use workspace::Workspace;
11
12pub struct CreateBufferTool {
13 workspace: WeakView<Workspace>,
14 project: Model<Project>,
15}
16
17impl CreateBufferTool {
18 pub fn new(workspace: WeakView<Workspace>, project: Model<Project>) -> Self {
19 Self { workspace, project }
20 }
21}
22
23#[derive(Debug, Deserialize, JsonSchema)]
24pub struct CreateBufferInput {
25 /// The contents of the buffer.
26 text: String,
27
28 /// The name of the language to use for the buffer.
29 ///
30 /// This should be a human-readable name, like "Rust", "JavaScript", or "Python".
31 language: String,
32}
33
34pub struct CreateBufferOutput {}
35
36impl LanguageModelTool for CreateBufferTool {
37 type Input = CreateBufferInput;
38 type Output = CreateBufferOutput;
39 type View = CreateBufferView;
40
41 fn name(&self) -> String {
42 "create_buffer".to_string()
43 }
44
45 fn description(&self) -> String {
46 "Create a new buffer in the current codebase".to_string()
47 }
48
49 fn execute(&self, input: &Self::Input, cx: &mut WindowContext) -> Task<Result<Self::Output>> {
50 cx.spawn({
51 let workspace = self.workspace.clone();
52 let project = self.project.clone();
53 let text = input.text.clone();
54 let language_name = input.language.clone();
55 |mut cx| async move {
56 let language = cx
57 .update(|cx| {
58 project
59 .read(cx)
60 .languages()
61 .language_for_name(&language_name)
62 })?
63 .await?;
64
65 let buffer = cx
66 .update(|cx| project.update(cx, |project, cx| project.create_buffer(cx)))?
67 .await?;
68
69 buffer.update(&mut cx, |buffer, cx| {
70 buffer.edit([(0..0, text)], None, cx);
71 buffer.set_language(Some(language), cx)
72 })?;
73
74 workspace
75 .update(&mut cx, |workspace, cx| {
76 workspace.add_item_to_active_pane(
77 Box::new(
78 cx.new_view(|cx| Editor::for_buffer(buffer, Some(project), cx)),
79 ),
80 None,
81 cx,
82 );
83 })
84 .log_err();
85
86 Ok(CreateBufferOutput {})
87 }
88 })
89 }
90
91 fn format(input: &Self::Input, output: &Result<Self::Output>) -> String {
92 match output {
93 Ok(_) => format!("Created a new {} buffer", input.language),
94 Err(err) => format!("Failed to create buffer: {err:?}"),
95 }
96 }
97
98 fn output_view(
99 _tool_call_id: String,
100 _input: Self::Input,
101 _output: Result<Self::Output>,
102 cx: &mut WindowContext,
103 ) -> View<Self::View> {
104 cx.new_view(|_cx| CreateBufferView {})
105 }
106}
107
108pub struct CreateBufferView {}
109
110impl Render for CreateBufferView {
111 fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
112 div().child("Opening a buffer")
113 }
114}