scripting_tool.rs

 1mod session;
 2
 3use project::Project;
 4pub(crate) use session::*;
 5
 6use assistant_tool::{Tool, ToolRegistry};
 7use gpui::{App, AppContext as _, Task, WeakEntity};
 8use schemars::JsonSchema;
 9use serde::Deserialize;
10use std::sync::Arc;
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        project: WeakEntity<Project>,
42        cx: &mut App,
43    ) -> Task<anyhow::Result<String>> {
44        let input = match serde_json::from_value::<ScriptingToolInput>(input) {
45            Err(err) => return Task::ready(Err(err.into())),
46            Ok(input) => input,
47        };
48        let Some(project) = project.upgrade() else {
49            return Task::ready(Err(anyhow::anyhow!("project dropped")));
50        };
51
52        let session = cx.new(|cx| Session::new(project, cx));
53        let lua_script = input.lua_script;
54        let script = session.update(cx, |session, cx| session.run_script(lua_script, cx));
55        cx.spawn(|_cx| async move {
56            let output = script.await?.stdout;
57            drop(session);
58            Ok(format!("The script output the following:\n{output}"))
59        })
60    }
61}