Skip to main content

codetether_agent/tool/tetherscript/
execute.rs

1use anyhow::Result;
2use async_trait::async_trait;
3use serde_json::Value;
4
5use super::{errors, load, result, schema, task};
6use crate::tool::{Tool, ToolResult};
7
8use super::input::TetherScriptPluginInput;
9use super::tool::TetherScriptPluginTool;
10
11#[async_trait]
12impl Tool for TetherScriptPluginTool {
13    fn id(&self) -> &str {
14        "tetherscript_plugin"
15    }
16
17    fn name(&self) -> &str {
18        "TetherScript Plugin"
19    }
20
21    fn description(&self) -> &str {
22        "Execute a TetherScript plugin hook from inline source or a `.tether`/legacy `.kl` file path."
23    }
24
25    fn parameters(&self) -> Value {
26        schema::parameters()
27    }
28
29    async fn execute(&self, args: Value) -> Result<ToolResult> {
30        execute_tetherscript(self, args).await
31    }
32}
33
34async fn execute_tetherscript(tool: &TetherScriptPluginTool, args: Value) -> Result<ToolResult> {
35    let input: TetherScriptPluginInput = match serde_json::from_value(args) {
36        Ok(input) => input,
37        Err(error) => return Ok(errors::invalid_params(tool.id(), error)),
38    };
39    if !input.has_source() && !input.has_path() {
40        return Ok(errors::missing_source(tool.id()));
41    }
42
43    let (source_name, source) = match load::source(&input, tool.root()).await {
44        Ok(source) => source,
45        Err(error) => return Ok(ToolResult::error(error.to_string())),
46    };
47    let request = task::TetherScriptRun::new(source_name, source, input);
48    Ok(result::from_run(task::run(request).await?))
49}