diff --git a/Cargo.lock b/Cargo.lock index 2cbdc0a2a2..3ac21c7484 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -492,7 +492,6 @@ dependencies = [ "proto", "rand 0.8.5", "rope", - "scripting_tool", "serde", "serde_json", "settings", @@ -4521,12 +4520,6 @@ dependencies = [ "regex", ] -[[package]] -name = "env_home" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" - [[package]] name = "env_logger" version = "0.10.2" @@ -7931,25 +7924,6 @@ dependencies = [ "url", ] -[[package]] -name = "lua-src" -version = "547.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edaf29e3517b49b8b746701e5648ccb5785cde1c119062cbabbc5d5cd115e42" -dependencies = [ - "cc", -] - -[[package]] -name = "luajit-src" -version = "210.5.12+a4f56a4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a8e7962a5368d5f264d045a5a255e90f9aa3fc1941ae15a8d2940d42cac671" -dependencies = [ - "cc", - "which 7.0.2", -] - [[package]] name = "lyon" version = "1.0.1" @@ -8365,34 +8339,6 @@ dependencies = [ "strum", ] -[[package]] -name = "mlua" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f763c1041eff92ffb5d7169968a327e1ed2ebfe425dac0ee5a35f29082534b" -dependencies = [ - "bstr", - "either", - "futures-util", - "mlua-sys", - "num-traits", - "parking_lot", - "rustc-hash 2.1.1", -] - -[[package]] -name = "mlua-sys" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1901c1a635a22fe9250ffcc4fcc937c16b47c2e9e71adba8784af8bca1f69594" -dependencies = [ - "cc", - "cfg-if", - "lua-src", - "luajit-src", - "pkg-config", -] - [[package]] name = "msvc_spectre_libs" version = "0.1.2" @@ -12201,30 +12147,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" -[[package]] -name = "scripting_tool" -version = "0.1.0" -dependencies = [ - "anyhow", - "buffer_diff", - "clock", - "collections", - "futures 0.3.31", - "gpui", - "language", - "log", - "mlua", - "parking_lot", - "project", - "rand 0.8.5", - "regex", - "schemars", - "serde", - "serde_json", - "settings", - "util", -] - [[package]] name = "scrypt" version = "0.11.0" @@ -16186,18 +16108,6 @@ dependencies = [ "winsafe", ] -[[package]] -name = "which" -version = "7.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2774c861e1f072b3aadc02f8ba886c26ad6321567ecc294c935434cad06f1283" -dependencies = [ - "either", - "env_home", - "rustix", - "winsafe", -] - [[package]] name = "whoami" version = "1.5.2" diff --git a/Cargo.toml b/Cargo.toml index da56a70944..6e6e7a4005 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,7 +124,6 @@ members = [ "crates/rope", "crates/rpc", "crates/schema_generator", - "crates/scripting_tool", "crates/search", "crates/semantic_index", "crates/semantic_version", @@ -329,7 +328,6 @@ reqwest_client = { path = "crates/reqwest_client" } rich_text = { path = "crates/rich_text" } rope = { path = "crates/rope" } rpc = { path = "crates/rpc" } -scripting_tool = { path = "crates/scripting_tool" } search = { path = "crates/search" } semantic_index = { path = "crates/semantic_index" } semantic_version = { path = "crates/semantic_version" } diff --git a/crates/assistant2/Cargo.toml b/crates/assistant2/Cargo.toml index 07b214bed0..0fb8911023 100644 --- a/crates/assistant2/Cargo.toml +++ b/crates/assistant2/Cargo.toml @@ -62,7 +62,6 @@ prompt_library.workspace = true prompt_store.workspace = true proto.workspace = true rope.workspace = true -scripting_tool.workspace = true serde.workspace = true serde_json.workspace = true settings.workspace = true diff --git a/crates/assistant2/src/active_thread.rs b/crates/assistant2/src/active_thread.rs index 2d648f7027..6af6e12c7b 100644 --- a/crates/assistant2/src/active_thread.rs +++ b/crates/assistant2/src/active_thread.rs @@ -3,8 +3,9 @@ use crate::thread::{ ThreadEvent, ThreadFeedback, }; use crate::thread_store::ThreadStore; -use crate::tool_use::{PendingToolUseStatus, ToolType, ToolUse, ToolUseStatus}; +use crate::tool_use::{PendingToolUseStatus, ToolUse, ToolUseStatus}; use crate::ui::ContextPill; + use collections::HashMap; use editor::{Editor, MultiBuffer}; use gpui::{ @@ -16,7 +17,6 @@ use gpui::{ use language::{Buffer, LanguageRegistry}; use language_model::{LanguageModelRegistry, LanguageModelToolUseId, Role}; use markdown::{Markdown, MarkdownStyle}; -use scripting_tool::{ScriptingTool, ScriptingToolInput}; use settings::Settings as _; use std::sync::Arc; use std::time::Duration; @@ -37,7 +37,6 @@ pub struct ActiveThread { messages: Vec, list_state: ListState, rendered_messages_by_id: HashMap, - rendered_scripting_tool_uses: HashMap>, rendered_tool_use_labels: HashMap>, editing_message: Option<(MessageId, EditMessageState)>, expanded_tool_uses: HashMap, @@ -233,7 +232,6 @@ impl ActiveThread { save_thread_task: None, messages: Vec::new(), rendered_messages_by_id: HashMap::default(), - rendered_scripting_tool_uses: HashMap::default(), rendered_tool_use_labels: HashMap::default(), expanded_tool_uses: HashMap::default(), expanded_thinking_segments: HashMap::default(), @@ -260,26 +258,6 @@ impl ActiveThread { cx, ); } - - for tool_use in thread - .read(cx) - .scripting_tool_uses_for_message(message.id, cx) - { - this.render_tool_use_label_markdown( - tool_use.id.clone(), - tool_use.ui_text.clone(), - window, - cx, - ); - - this.render_scripting_tool_use_markdown( - tool_use.id.clone(), - tool_use.ui_text.as_ref(), - tool_use.input.clone(), - window, - cx, - ); - } } this @@ -360,36 +338,6 @@ impl ActiveThread { self.rendered_messages_by_id.remove(id); } - /// Renders the input of a scripting tool use to Markdown. - /// - /// Does nothing if the tool use does not correspond to the scripting tool. - fn render_scripting_tool_use_markdown( - &mut self, - tool_use_id: LanguageModelToolUseId, - tool_name: &str, - tool_input: serde_json::Value, - window: &mut Window, - cx: &mut Context, - ) { - if tool_name != ScriptingTool::NAME { - return; - } - - let lua_script = serde_json::from_value::(tool_input) - .map(|input| input.lua_script) - .unwrap_or_default(); - - let lua_script = render_markdown( - format!("```lua\n{lua_script}\n```").into(), - self.language_registry.clone(), - window, - cx, - ); - - self.rendered_scripting_tool_uses - .insert(tool_use_id, lua_script); - } - fn render_tool_use_label_markdown( &mut self, tool_use_id: LanguageModelToolUseId, @@ -476,13 +424,6 @@ impl ActiveThread { window, cx, ); - self.render_scripting_tool_use_markdown( - tool_use.id, - tool_use.name.as_ref(), - tool_use.input.clone(), - window, - cx, - ); } } ThreadEvent::ToolFinished { @@ -725,13 +666,9 @@ impl ActiveThread { let checkpoint = thread.checkpoint_for_message(message_id); let context = thread.context_for_message(message_id); let tool_uses = thread.tool_uses_for_message(message_id, cx); - let scripting_tool_uses = thread.scripting_tool_uses_for_message(message_id, cx); // Don't render user messages that are just there for returning tool results. - if message.role == Role::User - && (thread.message_has_tool_results(message_id) - || thread.message_has_scripting_tool_results(message_id)) - { + if message.role == Role::User && thread.message_has_tool_results(message_id) { return Empty.into_any(); } @@ -996,32 +933,23 @@ impl ActiveThread { ) .child(div().p_2().child(message_content)), ), - Role::Assistant => { - v_flex() - .id(("message-container", ix)) - .ml_2() - .pl_2() - .pr_4() - .border_l_1() - .border_color(cx.theme().colors().border_variant) - .child(message_content) - .when( - !tool_uses.is_empty() || !scripting_tool_uses.is_empty(), - |parent| { - parent.child( - v_flex() - .children( - tool_uses - .into_iter() - .map(|tool_use| self.render_tool_use(tool_use, cx)), - ) - .children(scripting_tool_uses.into_iter().map(|tool_use| { - self.render_scripting_tool_use(tool_use, cx) - })), - ) - }, + Role::Assistant => v_flex() + .id(("message-container", ix)) + .ml_2() + .pl_2() + .pr_4() + .border_l_1() + .border_color(cx.theme().colors().border_variant) + .child(message_content) + .when(!tool_uses.is_empty(), |parent| { + parent.child( + v_flex().children( + tool_uses + .into_iter() + .map(|tool_use| self.render_tool_use(tool_use, cx)), + ), ) - } + }), Role::System => div().id(("message-container", ix)).py_1().px_2().child( v_flex() .bg(colors.editor_background) @@ -1537,145 +1465,6 @@ impl ActiveThread { ) } - fn render_scripting_tool_use( - &self, - tool_use: ToolUse, - cx: &mut Context, - ) -> impl IntoElement { - let is_open = self - .expanded_tool_uses - .get(&tool_use.id) - .copied() - .unwrap_or_default(); - - div().px_2p5().child( - v_flex() - .gap_1() - .rounded_lg() - .border_1() - .border_color(cx.theme().colors().border) - .child( - h_flex() - .justify_between() - .py_0p5() - .pl_1() - .pr_2() - .bg(cx.theme().colors().editor_foreground.opacity(0.02)) - .map(|element| { - if is_open { - element.border_b_1().rounded_t_md() - } else { - element.rounded_md() - } - }) - .border_color(cx.theme().colors().border) - .child( - h_flex() - .gap_1() - .child(Disclosure::new("tool-use-disclosure", is_open).on_click( - cx.listener({ - let tool_use_id = tool_use.id.clone(); - move |this, _event, _window, _cx| { - let is_open = this - .expanded_tool_uses - .entry(tool_use_id.clone()) - .or_insert(false); - - *is_open = !*is_open; - } - }), - )) - .child( - h_flex() - .gap_1p5() - .child( - Icon::new(IconName::Terminal) - .size(IconSize::XSmall) - .color(Color::Muted), - ) - .child( - div() - .text_ui_sm(cx) - .children( - self.rendered_tool_use_labels - .get(&tool_use.id) - .cloned(), - ) - .truncate(), - ), - ), - ) - .child( - Label::new(match tool_use.status { - ToolUseStatus::Pending => "Pending", - ToolUseStatus::Running => "Running", - ToolUseStatus::Finished(_) => "Finished", - ToolUseStatus::Error(_) => "Error", - ToolUseStatus::NeedsConfirmation => "Asking Permission", - }) - .size(LabelSize::XSmall) - .buffer_font(cx), - ), - ) - .map(|parent| { - if !is_open { - return parent; - } - - let lua_script_markdown = - self.rendered_scripting_tool_uses.get(&tool_use.id).cloned(); - - parent.child( - v_flex() - .child( - v_flex() - .gap_0p5() - .py_1() - .px_2p5() - .border_b_1() - .border_color(cx.theme().colors().border) - .child(Label::new("Input:")) - .map(|parent| { - if let Some(markdown) = lua_script_markdown { - parent.child(markdown) - } else { - parent.child(Label::new( - "Failed to render script input to Markdown", - )) - } - }), - ) - .map(|parent| match tool_use.status { - ToolUseStatus::Finished(output) => parent.child( - v_flex() - .gap_0p5() - .py_1() - .px_2p5() - .child(Label::new("Result:")) - .child(Label::new(output)), - ), - ToolUseStatus::Error(err) => parent.child( - v_flex() - .gap_0p5() - .py_1() - .px_2p5() - .child(Label::new("Error:")) - .child(Label::new(err)), - ), - ToolUseStatus::Pending | ToolUseStatus::Running => parent, - ToolUseStatus::NeedsConfirmation => parent.child( - v_flex() - .gap_0p5() - .py_1() - .px_2p5() - .child(Label::new("Asking Permission")), - ), - }), - ) - }), - ) - } - fn render_rules_item(&self, cx: &Context) -> AnyElement { let Some(system_prompt_context) = self.thread.read(cx).system_prompt_context().as_ref() else { @@ -1751,7 +1540,7 @@ impl ActiveThread { c.ui_text.clone(), c.input.clone(), &c.messages, - c.tool_type.clone(), + c.tool.clone(), cx, ); }); @@ -1761,13 +1550,12 @@ impl ActiveThread { fn handle_deny_tool( &mut self, tool_use_id: LanguageModelToolUseId, - tool_type: ToolType, _: &ClickEvent, _window: &mut Window, cx: &mut Context, ) { self.thread.update(cx, |thread, cx| { - thread.deny_tool_use(tool_use_id, tool_type, cx); + thread.deny_tool_use(tool_use_id, cx); }); } @@ -1802,7 +1590,7 @@ impl ActiveThread { thread .tools_needing_confirmation() - .map(|(tool_type, tool)| { + .map(|tool| { div() .m_3() .p_2() @@ -1844,7 +1632,6 @@ impl ActiveThread { move |this, event, window, cx| { this.handle_deny_tool( tool_id.clone(), - tool_type.clone(), event, window, cx, diff --git a/crates/assistant2/src/thread.rs b/crates/assistant2/src/thread.rs index e090ac7fe6..4076b9a435 100644 --- a/crates/assistant2/src/thread.rs +++ b/crates/assistant2/src/thread.rs @@ -23,7 +23,6 @@ use project::{Project, Worktree}; use prompt_store::{ AssistantSystemPromptContext, PromptBuilder, RulesFile, WorktreeInfoForSystemPrompt, }; -use scripting_tool::{ScriptingSession, ScriptingTool}; use serde::{Deserialize, Serialize}; use settings::Settings; use util::{maybe, post_inc, ResultExt as _, TryFutureExt as _}; @@ -34,7 +33,7 @@ use crate::thread_store::{ SerializedMessage, SerializedMessageSegment, SerializedThread, SerializedToolResult, SerializedToolUse, }; -use crate::tool_use::{PendingToolUse, PendingToolUseStatus, ToolType, ToolUse, ToolUseState}; +use crate::tool_use::{PendingToolUse, ToolUse, ToolUseState}; #[derive(Debug, Clone, Copy)] pub enum RequestKind { @@ -188,8 +187,6 @@ pub struct Thread { action_log: Entity, last_restore_checkpoint: Option, pending_checkpoint: Option, - scripting_session: Entity, - scripting_tool_use: ToolUseState, initial_project_snapshot: Shared>>>, cumulative_token_usage: TokenUsage, feedback: Option, @@ -221,8 +218,6 @@ impl Thread { last_restore_checkpoint: None, pending_checkpoint: None, tool_use: ToolUseState::new(tools.clone()), - scripting_session: cx.new(|cx| ScriptingSession::new(project.clone(), cx)), - scripting_tool_use: ToolUseState::new(tools), action_log: cx.new(|_| ActionLog::new()), initial_project_snapshot: { let project_snapshot = Self::project_snapshot(project, cx); @@ -251,14 +246,7 @@ impl Thread { .unwrap_or(0), ); let tool_use = - ToolUseState::from_serialized_messages(tools.clone(), &serialized.messages, |name| { - name != ScriptingTool::NAME - }); - let scripting_tool_use = - ToolUseState::from_serialized_messages(tools.clone(), &serialized.messages, |name| { - name == ScriptingTool::NAME - }); - let scripting_session = cx.new(|cx| ScriptingSession::new(project.clone(), cx)); + ToolUseState::from_serialized_messages(tools.clone(), &serialized.messages, |_| true); Self { id, @@ -297,8 +285,6 @@ impl Thread { tools, tool_use, action_log: cx.new(|_| ActionLog::new()), - scripting_session, - scripting_tool_use, initial_project_snapshot: Task::ready(serialized.initial_project_snapshot).shared(), // TODO: persist token usage? cumulative_token_usage: TokenUsage::default(), @@ -357,37 +343,13 @@ impl Thread { .pending_tool_uses() .into_iter() .find(|tool_use| &tool_use.id == id) - .or_else(|| { - self.scripting_tool_use - .pending_tool_uses() - .into_iter() - .find(|tool_use| &tool_use.id == id) - }) } - pub fn tools_needing_confirmation(&self) -> impl Iterator { + pub fn tools_needing_confirmation(&self) -> impl Iterator { self.tool_use .pending_tool_uses() .into_iter() - .filter_map(|tool_use| { - if let PendingToolUseStatus::NeedsConfirmation(confirmation) = &tool_use.status { - Some((confirmation.tool_type.clone(), tool_use)) - } else { - None - } - }) - .chain( - self.scripting_tool_use - .pending_tool_uses() - .into_iter() - .filter_map(|tool_use| { - if tool_use.status.needs_confirmation() { - Some((ToolType::ScriptingTool, tool_use)) - } else { - None - } - }), - ) + .filter(|tool_use| tool_use.status.needs_confirmation()) } pub fn checkpoint_for_message(&self, id: MessageId) -> Option { @@ -520,25 +482,18 @@ impl Thread { /// Returns whether all of the tool uses have finished running. pub fn all_tools_finished(&self) -> bool { - let mut all_pending_tool_uses = self - .tool_use - .pending_tool_uses() - .into_iter() - .chain(self.scripting_tool_use.pending_tool_uses()); - // If the only pending tool uses left are the ones with errors, then // that means that we've finished running all of the pending tools. - all_pending_tool_uses.all(|tool_use| tool_use.status.is_error()) + self.tool_use + .pending_tool_uses() + .iter() + .all(|tool_use| tool_use.status.is_error()) } pub fn tool_uses_for_message(&self, id: MessageId, cx: &App) -> Vec { self.tool_use.tool_uses_for_message(id, cx) } - pub fn scripting_tool_uses_for_message(&self, id: MessageId, cx: &App) -> Vec { - self.scripting_tool_use.tool_uses_for_message(id, cx) - } - pub fn tool_results_for_message(&self, id: MessageId) -> Vec<&LanguageModelToolResult> { self.tool_use.tool_results_for_message(id) } @@ -547,21 +502,10 @@ impl Thread { self.tool_use.tool_result(id) } - pub fn scripting_tool_results_for_message( - &self, - id: MessageId, - ) -> Vec<&LanguageModelToolResult> { - self.scripting_tool_use.tool_results_for_message(id) - } - pub fn message_has_tool_results(&self, message_id: MessageId) -> bool { self.tool_use.message_has_tool_results(message_id) } - pub fn message_has_scripting_tool_results(&self, message_id: MessageId) -> bool { - self.scripting_tool_use.message_has_tool_results(message_id) - } - pub fn insert_user_message( &mut self, text: impl Into, @@ -682,7 +626,6 @@ impl Thread { tool_uses: this .tool_uses_for_message(message.id, cx) .into_iter() - .chain(this.scripting_tool_uses_for_message(message.id, cx)) .map(|tool_use| SerializedToolUse { id: tool_use.id, name: tool_use.name, @@ -692,7 +635,6 @@ impl Thread { tool_results: this .tool_results_for_message(message.id) .into_iter() - .chain(this.scripting_tool_results_for_message(message.id)) .map(|tool_result| SerializedToolResult { tool_use_id: tool_result.tool_use_id.clone(), is_error: tool_result.is_error, @@ -825,15 +767,6 @@ impl Thread { let mut request = self.to_completion_request(request_kind, cx); request.tools = { let mut tools = Vec::new(); - - if self.tools.is_scripting_tool_enabled() { - tools.push(LanguageModelRequestTool { - name: ScriptingTool::NAME.into(), - description: ScriptingTool::DESCRIPTION.into(), - input_schema: ScriptingTool::input_schema(), - }); - } - tools.extend(self.tools().enabled_tools(cx).into_iter().map(|tool| { LanguageModelRequestTool { name: tool.name(), @@ -894,8 +827,6 @@ impl Thread { RequestKind::Chat => { self.tool_use .attach_tool_results(message.id, &mut request_message); - self.scripting_tool_use - .attach_tool_results(message.id, &mut request_message); } RequestKind::Summarize => { // We don't care about tool use during summarization. @@ -912,8 +843,6 @@ impl Thread { RequestKind::Chat => { self.tool_use .attach_tool_uses(message.id, &mut request_message); - self.scripting_tool_use - .attach_tool_uses(message.id, &mut request_message); } RequestKind::Summarize => { // We don't care about tool use during summarization. @@ -1060,19 +989,11 @@ impl Thread { .iter() .rfind(|message| message.role == Role::Assistant) { - if tool_use.name.as_ref() == ScriptingTool::NAME { - thread.scripting_tool_use.request_tool_use( - last_assistant_message.id, - tool_use, - cx, - ); - } else { - thread.tool_use.request_tool_use( - last_assistant_message.id, - tool_use, - cx, - ); - } + thread.tool_use.request_tool_use( + last_assistant_message.id, + tool_use, + cx, + ); } } } @@ -1237,7 +1158,7 @@ impl Thread { tool_use.ui_text.clone(), tool_use.input.clone(), messages.clone(), - ToolType::NonScriptingTool(tool), + tool, ); } else { self.run_tool( @@ -1245,7 +1166,7 @@ impl Thread { tool_use.ui_text.clone(), tool_use.input.clone(), &messages, - ToolType::NonScriptingTool(tool), + tool, cx, ); } @@ -1255,33 +1176,13 @@ impl Thread { tool_use.ui_text.clone(), tool_use.input.clone(), &messages, - ToolType::NonScriptingTool(tool), + tool, cx, ); } } - let pending_scripting_tool_uses = self - .scripting_tool_use - .pending_tool_uses() - .into_iter() - .filter(|tool_use| tool_use.status.is_idle()) - .cloned() - .collect::>(); - - for scripting_tool_use in pending_scripting_tool_uses.iter() { - self.scripting_tool_use.confirm_tool_use( - scripting_tool_use.id.clone(), - scripting_tool_use.ui_text.clone(), - scripting_tool_use.input.clone(), - messages.clone(), - ToolType::ScriptingTool, - ); - } - pending_tool_uses - .into_iter() - .chain(pending_scripting_tool_uses) } pub fn run_tool( @@ -1290,21 +1191,12 @@ impl Thread { ui_text: impl Into, input: serde_json::Value, messages: &[LanguageModelRequestMessage], - tool_type: ToolType, + tool: Arc, cx: &mut Context<'_, Thread>, ) { - match tool_type { - ToolType::ScriptingTool => { - let task = self.spawn_scripting_tool_use(tool_use_id.clone(), input, cx); - self.scripting_tool_use - .run_pending_tool(tool_use_id, ui_text.into(), task); - } - ToolType::NonScriptingTool(tool) => { - let task = self.spawn_tool_use(tool_use_id.clone(), messages, input, tool, cx); - self.tool_use - .run_pending_tool(tool_use_id, ui_text.into(), task); - } - } + let task = self.spawn_tool_use(tool_use_id.clone(), messages, input, tool, cx); + self.tool_use + .run_pending_tool(tool_use_id, ui_text.into(), task); } fn spawn_tool_use( @@ -1344,60 +1236,6 @@ impl Thread { }) } - fn spawn_scripting_tool_use( - &mut self, - tool_use_id: LanguageModelToolUseId, - input: serde_json::Value, - cx: &mut Context, - ) -> Task<()> { - let task = match ScriptingTool::deserialize_input(input) { - Err(err) => Task::ready(Err(err.into())), - Ok(input) => { - let (script_id, script_task) = - self.scripting_session.update(cx, move |session, cx| { - session.run_script(input.lua_script, cx) - }); - - let session = self.scripting_session.clone(); - cx.spawn(async move |_, cx| { - script_task.await; - - let message = session.read_with(cx, |session, _cx| { - // Using a id to get the script output seems impractical. - // Why not just include it in the Task result? - // This is because we'll later report the script state as it runs, - session - .get(script_id) - .output_message_for_llm() - .expect("Script shouldn't still be running") - })?; - - Ok(message) - }) - } - }; - - cx.spawn({ - let tool_use_id = tool_use_id.clone(); - async move |thread, cx| { - let output = task.await; - thread - .update(cx, |thread, cx| { - let pending_tool_use = thread - .scripting_tool_use - .insert_tool_output(tool_use_id.clone(), output); - - cx.emit(ThreadEvent::ToolFinished { - tool_use_id, - pending_tool_use, - canceled: false, - }); - }) - .ok(); - } - }) - } - pub fn attach_tool_results( &mut self, updated_context: Vec, @@ -1654,22 +1492,12 @@ impl Thread { self.cumulative_token_usage.clone() } - pub fn deny_tool_use( - &mut self, - tool_use_id: LanguageModelToolUseId, - tool_type: ToolType, - cx: &mut Context, - ) { + pub fn deny_tool_use(&mut self, tool_use_id: LanguageModelToolUseId, cx: &mut Context) { let err = Err(anyhow::anyhow!( "Permission to run tool action denied by user" )); - if let ToolType::ScriptingTool = tool_type { - self.scripting_tool_use - .insert_tool_output(tool_use_id.clone(), err); - } else { - self.tool_use.insert_tool_output(tool_use_id.clone(), err); - } + self.tool_use.insert_tool_output(tool_use_id.clone(), err); cx.emit(ThreadEvent::ToolFinished { tool_use_id, diff --git a/crates/assistant2/src/tool_selector.rs b/crates/assistant2/src/tool_selector.rs index 1c0aae33fa..e93b727cd2 100644 --- a/crates/assistant2/src/tool_selector.rs +++ b/crates/assistant2/src/tool_selector.rs @@ -4,7 +4,6 @@ use assistant_settings::{AgentProfile, AssistantSettings}; use assistant_tool::{ToolSource, ToolWorkingSet}; use gpui::{Entity, Subscription}; use indexmap::IndexMap; -use scripting_tool::ScriptingTool; use settings::{Settings as _, SettingsStore}; use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip}; @@ -52,7 +51,6 @@ impl ToolSelector { let tools = tool_set.clone(); move |_window, cx| { tools.disable_source(ToolSource::Native, cx); - tools.disable_scripting_tool(); tools.enable( ToolSource::Native, &profile @@ -61,10 +59,6 @@ impl ToolSelector { .filter_map(|(tool, enabled)| enabled.then(|| tool.clone())) .collect::>(), ); - - if profile.tools.contains_key(ScriptingTool::NAME) { - tools.enable_scripting_tool(); - } } }); } @@ -98,11 +92,6 @@ impl ToolSelector { .collect::>(); if ToolSource::Native == source { - tools.push(( - ToolSource::Native, - ScriptingTool::NAME.into(), - tool_set.is_scripting_tool_enabled(), - )); tools.sort_by(|(_, name_a, _), (_, name_b, _)| name_a.cmp(name_b)); } @@ -136,18 +125,10 @@ impl ToolSelector { menu = menu.toggleable_entry(name.clone(), is_enabled, icon_position, None, { let tools = tool_set.clone(); move |_window, _cx| { - if name.as_ref() == ScriptingTool::NAME { - if is_enabled { - tools.disable_scripting_tool(); - } else { - tools.enable_scripting_tool(); - } + if is_enabled { + tools.disable(source.clone(), &[name.clone()]); } else { - if is_enabled { - tools.disable(source.clone(), &[name.clone()]); - } else { - tools.enable(source.clone(), &[name.clone()]); - } + tools.enable(source.clone(), &[name.clone()]); } } }); diff --git a/crates/assistant2/src/tool_use.rs b/crates/assistant2/src/tool_use.rs index 7b7399c950..9a5cfcef67 100644 --- a/crates/assistant2/src/tool_use.rs +++ b/crates/assistant2/src/tool_use.rs @@ -10,7 +10,6 @@ use language_model::{ LanguageModelRequestMessage, LanguageModelToolResult, LanguageModelToolUse, LanguageModelToolUseId, MessageContent, Role, }; -use scripting_tool::ScriptingTool; use crate::thread::MessageId; use crate::thread_store::SerializedMessage; @@ -200,8 +199,6 @@ impl ToolUseState { ) -> SharedString { if let Some(tool) = self.tools.tool(tool_name, cx) { tool.ui_text(input).into() - } else if tool_name == ScriptingTool::NAME { - "Run Lua Script".into() } else { "Unknown tool".into() } @@ -285,7 +282,7 @@ impl ToolUseState { ui_text: impl Into>, input: serde_json::Value, messages: Arc>, - tool_type: ToolType, + tool: Arc, ) { if let Some(tool_use) = self.pending_tool_uses_by_id.get_mut(&tool_use_id) { let ui_text = ui_text.into(); @@ -294,7 +291,7 @@ impl ToolUseState { tool_use_id, input, messages, - tool_type, + tool, ui_text, }; tool_use.status = PendingToolUseStatus::NeedsConfirmation(Arc::new(confirmation)); @@ -398,19 +395,13 @@ pub struct PendingToolUse { pub status: PendingToolUseStatus, } -#[derive(Debug, Clone)] -pub enum ToolType { - ScriptingTool, - NonScriptingTool(Arc), -} - #[derive(Debug, Clone)] pub struct Confirmation { pub tool_use_id: LanguageModelToolUseId, pub input: serde_json::Value, pub ui_text: Arc, pub messages: Arc>, - pub tool_type: ToolType, + pub tool: Arc, } #[derive(Debug, Clone)] diff --git a/crates/assistant_tool/src/tool_working_set.rs b/crates/assistant_tool/src/tool_working_set.rs index 74d4d4d932..2c1acad053 100644 --- a/crates/assistant_tool/src/tool_working_set.rs +++ b/crates/assistant_tool/src/tool_working_set.rs @@ -15,26 +15,14 @@ pub struct ToolWorkingSet { state: Mutex, } +#[derive(Default)] struct WorkingSetState { context_server_tools_by_id: HashMap>, context_server_tools_by_name: HashMap>, disabled_tools_by_source: HashMap>>, - is_scripting_tool_disabled: bool, next_tool_id: ToolId, } -impl Default for WorkingSetState { - fn default() -> Self { - Self { - context_server_tools_by_id: HashMap::default(), - context_server_tools_by_name: HashMap::default(), - disabled_tools_by_source: HashMap::default(), - is_scripting_tool_disabled: true, - next_tool_id: ToolId::default(), - } - } -} - impl ToolWorkingSet { pub fn tool(&self, name: &str, cx: &App) -> Option> { self.state @@ -55,7 +43,7 @@ impl ToolWorkingSet { pub fn are_all_tools_enabled(&self) -> bool { let state = self.state.lock(); - state.disabled_tools_by_source.is_empty() && !state.is_scripting_tool_disabled + state.disabled_tools_by_source.is_empty() } pub fn are_all_tools_from_source_enabled(&self, source: &ToolSource) -> bool { @@ -70,7 +58,6 @@ impl ToolWorkingSet { pub fn enable_all_tools(&self) { let mut state = self.state.lock(); state.disabled_tools_by_source.clear(); - state.enable_scripting_tool(); } pub fn disable_all_tools(&self, cx: &App) { @@ -124,21 +111,6 @@ impl ToolWorkingSet { .retain(|id, _| !tool_ids_to_remove.contains(id)); state.tools_changed(); } - - pub fn is_scripting_tool_enabled(&self) -> bool { - let state = self.state.lock(); - !state.is_scripting_tool_disabled - } - - pub fn enable_scripting_tool(&self) { - let mut state = self.state.lock(); - state.enable_scripting_tool(); - } - - pub fn disable_scripting_tool(&self) { - let mut state = self.state.lock(); - state.disable_scripting_tool(); - } } impl WorkingSetState { @@ -240,15 +212,5 @@ impl WorkingSetState { self.disable(source, &tool_names); } - - self.disable_scripting_tool(); - } - - fn enable_scripting_tool(&mut self) { - self.is_scripting_tool_disabled = false; - } - - fn disable_scripting_tool(&mut self) { - self.is_scripting_tool_disabled = true; } } diff --git a/crates/scripting_tool/Cargo.toml b/crates/scripting_tool/Cargo.toml deleted file mode 100644 index a225726b23..0000000000 --- a/crates/scripting_tool/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "scripting_tool" -version = "0.1.0" -edition.workspace = true -publish.workspace = true -license = "GPL-3.0-or-later" - -[lints] -workspace = true - -[lib] -path = "src/scripting_tool.rs" -doctest = false - -[dependencies] -anyhow.workspace = true -buffer_diff.workspace = true -clock.workspace = true -collections.workspace = true -futures.workspace = true -gpui.workspace = true -language.workspace = true -log.workspace = true -mlua.workspace = true -parking_lot.workspace = true -project.workspace = true -regex.workspace = true -schemars.workspace = true -serde.workspace = true -serde_json.workspace = true -settings.workspace = true -util.workspace = true - -[dev-dependencies] -buffer_diff = { workspace = true, features = ["test-support"] } -clock = { workspace = true, features = ["test-support"] } -collections = { workspace = true, features = ["test-support"] } -gpui = { workspace = true, features = ["test-support"] } -language = { workspace = true, features = ["test-support"] } -project = { workspace = true, features = ["test-support"] } -rand.workspace = true -settings = { workspace = true, features = ["test-support"] } diff --git a/crates/scripting_tool/LICENSE-GPL b/crates/scripting_tool/LICENSE-GPL deleted file mode 120000 index 89e542f750..0000000000 --- a/crates/scripting_tool/LICENSE-GPL +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE-GPL \ No newline at end of file diff --git a/crates/scripting_tool/src/sandbox_preamble.lua b/crates/scripting_tool/src/sandbox_preamble.lua deleted file mode 100644 index 5e31fbdd95..0000000000 --- a/crates/scripting_tool/src/sandbox_preamble.lua +++ /dev/null @@ -1,55 +0,0 @@ ----@diagnostic disable: undefined-global - --- Create a sandbox environment -local sandbox = {} - --- For now, add all globals to `sandbox` (so there effectively is no sandbox). --- We still need the logic below so that we can do things like overriding print() to write --- to our in-memory log rather than to stdout, we will delete this loop (and re-enable --- the I/O module being sandboxed below) to have things be sandboxed again. -for k, v in pairs(_G) do - if sandbox[k] == nil then - sandbox[k] = v - end -end - --- Allow access to standard libraries (safe subset) -sandbox.string = string -sandbox.table = table -sandbox.math = math -sandbox.print = sb_print -sandbox.type = type -sandbox.tostring = tostring -sandbox.tonumber = tonumber -sandbox.pairs = pairs -sandbox.ipairs = ipairs - --- Access to custom functions -sandbox.search = search -sandbox.outline = outline - --- Create a sandboxed version of LuaFileIO --- local io = {}; --- --- For now we are using unsandboxed io -local io = _G.io; - --- File functions -io.open = sb_io_open - --- Add the sandboxed io library to the sandbox environment -sandbox.io = io - --- Load the script with the sandbox environment -local user_script_fn, err = load(user_script, nil, "t", sandbox) - -if not user_script_fn then - error("Failed to load user script: " .. tostring(err)) -end - --- Execute the user script within the sandbox -local success, result = pcall(user_script_fn) - -if not success then - error("Error executing user script: " .. tostring(result)) -end diff --git a/crates/scripting_tool/src/scripting_session.rs b/crates/scripting_tool/src/scripting_session.rs deleted file mode 100644 index 65a7108f91..0000000000 --- a/crates/scripting_tool/src/scripting_session.rs +++ /dev/null @@ -1,1314 +0,0 @@ -use anyhow::anyhow; -use buffer_diff::BufferDiff; -use collections::{HashMap, HashSet}; -use futures::{ - channel::{mpsc, oneshot}, - pin_mut, SinkExt, StreamExt, -}; -use gpui::{AppContext, AsyncApp, Context, Entity, Task, WeakEntity}; -use language::Buffer; -use mlua::{ExternalResult, Lua, MultiValue, ObjectLike, Table, UserData, UserDataMethods}; -use parking_lot::Mutex; -use project::{search::SearchQuery, Fs, Project, ProjectPath, WorktreeId}; -use regex::Regex; -use std::{ - path::{Path, PathBuf}, - sync::Arc, -}; -use util::{paths::PathMatcher, ResultExt}; - -struct ForegroundFn(Box, AsyncApp) + Send>); - -struct BufferChanges { - diff: Entity, - edit_ids: Vec, -} - -pub struct ScriptingSession { - project: Entity, - scripts: Vec