codetether_agent/tool/tetherscript/
execute.rs1use 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}