create_buffer.rs

  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.update(|cx| {
 66                    project.update(cx, |project, cx| {
 67                        project.create_buffer(&text, Some(language), cx)
 68                    })
 69                })??;
 70
 71                workspace
 72                    .update(&mut cx, |workspace, cx| {
 73                        workspace.add_item_to_active_pane(
 74                            Box::new(
 75                                cx.new_view(|cx| Editor::for_buffer(buffer, Some(project), cx)),
 76                            ),
 77                            None,
 78                            cx,
 79                        );
 80                    })
 81                    .log_err();
 82
 83                Ok(CreateBufferOutput {})
 84            }
 85        })
 86    }
 87
 88    fn format(input: &Self::Input, output: &Result<Self::Output>) -> String {
 89        match output {
 90            Ok(_) => format!("Created a new {} buffer", input.language),
 91            Err(err) => format!("Failed to create buffer: {err:?}"),
 92        }
 93    }
 94
 95    fn output_view(
 96        _tool_call_id: String,
 97        _input: Self::Input,
 98        _output: Result<Self::Output>,
 99        cx: &mut WindowContext,
100    ) -> View<Self::View> {
101        cx.new_view(|_cx| CreateBufferView {})
102    }
103}
104
105pub struct CreateBufferView {}
106
107impl Render for CreateBufferView {
108    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
109        div().child("Opening a buffer")
110    }
111}