scripting_tool.rs

 1mod session;
 2
 3use project::Project;
 4use session::*;
 5
 6use assistant_tool::{Tool, ToolRegistry};
 7use gpui::{App, AppContext as _, Entity, Task};
 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: Entity<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
49        // TODO: Store a session per thread
50        let session = cx.new(|cx| ScriptSession::new(project, cx));
51        let lua_script = input.lua_script;
52
53        let (script_id, script_task) =
54            session.update(cx, |session, cx| session.run_script(lua_script, cx));
55
56        cx.spawn(|cx| async move {
57            script_task.await;
58
59            let message = session.read_with(&cx, |session, _cx| {
60                // Using a id to get the script output seems impractical.
61                // Why not just include it in the Task result?
62                // This is because we'll later report the script state as it runs,
63                // currently not supported by the `Tool` interface.
64                session
65                    .get(script_id)
66                    .output_message_for_llm()
67                    .expect("Script shouldn't still be running")
68            })?;
69
70            drop(session);
71            Ok(message)
72        })
73    }
74}