use anyhow::Result; use assistant_tooling::{LanguageModelTool, ProjectContext, ToolOutput}; use editor::Editor; use gpui::{prelude::*, Model, Task, View, WeakView}; use project::Project; use schemars::JsonSchema; use serde::Deserialize; use ui::prelude::*; use util::ResultExt; use workspace::Workspace; pub struct CreateBufferTool { workspace: WeakView, project: Model, } impl CreateBufferTool { pub fn new(workspace: WeakView, project: Model) -> Self { Self { workspace, project } } } #[derive(Debug, Deserialize, JsonSchema)] pub struct CreateBufferInput { /// The contents of the buffer. text: String, /// The name of the language to use for the buffer. /// /// This should be a human-readable name, like "Rust", "JavaScript", or "Python". language: String, } impl LanguageModelTool for CreateBufferTool { type Input = CreateBufferInput; type Output = (); type View = CreateBufferView; fn name(&self) -> String { "create_buffer".to_string() } fn description(&self) -> String { "Create a new buffer in the current codebase".to_string() } fn execute(&self, input: &Self::Input, cx: &mut WindowContext) -> Task> { cx.spawn({ let workspace = self.workspace.clone(); let project = self.project.clone(); let text = input.text.clone(); let language_name = input.language.clone(); |mut cx| async move { let language = cx .update(|cx| { project .read(cx) .languages() .language_for_name(&language_name) })? .await?; let buffer = cx .update(|cx| project.update(cx, |project, cx| project.create_buffer(cx)))? .await?; buffer.update(&mut cx, |buffer, cx| { buffer.edit([(0..0, text)], None, cx); buffer.set_language(Some(language), cx) })?; workspace .update(&mut cx, |workspace, cx| { workspace.add_item_to_active_pane( Box::new( cx.new_view(|cx| Editor::for_buffer(buffer, Some(project), cx)), ), None, cx, ); }) .log_err(); Ok(()) } }) } fn output_view( input: Self::Input, output: Result, cx: &mut WindowContext, ) -> View { cx.new_view(|_cx| CreateBufferView { language: input.language, output, }) } } pub struct CreateBufferView { language: String, output: Result<()>, } impl Render for CreateBufferView { fn render(&mut self, _cx: &mut ViewContext) -> impl IntoElement { div().child("Opening a buffer") } } impl ToolOutput for CreateBufferView { fn generate(&self, _: &mut ProjectContext, _: &mut WindowContext) -> String { match &self.output { Ok(_) => format!("Created a new {} buffer", self.language), Err(err) => format!("Failed to create buffer: {err:?}"), } } }