scripting_tool.rs

 1mod session;
 2
 3pub(crate) use session::*;
 4
 5use assistant_tool::{Tool, ToolRegistry};
 6use gpui::{App, AppContext as _, Task, WeakEntity, Window};
 7use schemars::JsonSchema;
 8use serde::Deserialize;
 9use std::sync::Arc;
10use workspace::Workspace;
11
12pub fn init(cx: &App) {
13    let registry = ToolRegistry::global(cx);
14    registry.register_tool(ScriptingTool);
15}
16
17#[derive(Debug, Deserialize, JsonSchema)]
18struct ScriptingToolInput {
19    lua_script: String,
20}
21
22struct ScriptingTool;
23
24impl Tool for ScriptingTool {
25    fn name(&self) -> String {
26        "lua-interpreter".into()
27    }
28
29    fn description(&self) -> String {
30        include_str!("scripting_tool_description.txt").into()
31    }
32
33    fn input_schema(&self) -> serde_json::Value {
34        let schema = schemars::schema_for!(ScriptingToolInput);
35        serde_json::to_value(&schema).unwrap()
36    }
37
38    fn run(
39        self: Arc<Self>,
40        input: serde_json::Value,
41        workspace: WeakEntity<Workspace>,
42        _window: &mut Window,
43        cx: &mut App,
44    ) -> Task<anyhow::Result<String>> {
45        let input = match serde_json::from_value::<ScriptingToolInput>(input) {
46            Err(err) => return Task::ready(Err(err.into())),
47            Ok(input) => input,
48        };
49        let Ok(project) = workspace.read_with(cx, |workspace, _cx| workspace.project().clone())
50        else {
51            return Task::ready(Err(anyhow::anyhow!("No project found")));
52        };
53
54        let session = cx.new(|cx| Session::new(project, cx));
55        let lua_script = input.lua_script;
56        let script = session.update(cx, |session, cx| session.run_script(lua_script, cx));
57        cx.spawn(|_cx| async move {
58            let output = script.await?.stdout;
59            drop(session);
60            Ok(format!("The script output the following:\n{output}"))
61        })
62    }
63}