mofa_plugins/tools/
rhai.rs1use super::*;
2use mofa_extra::rhai::{RhaiScriptEngine, ScriptContext, ScriptEngineConfig};
3use serde_json::json;
4
5pub struct RhaiScriptTool {
7 definition: ToolDefinition,
8 engine: RhaiScriptEngine,
9}
10
11impl RhaiScriptTool {
12 pub fn new() -> PluginResult<Self> {
13 let config = ScriptEngineConfig::default();
14 let engine = RhaiScriptEngine::new(config)?;
15 Ok(Self {
16 definition: ToolDefinition {
17 name: "rhai_script".to_string(),
18 description: "Execute Rhai scripts for complex calculations or data processing. Rhai is a safe embedded scripting language.".to_string(),
19 parameters: json!({
20 "type": "object",
21 "properties": {
22 "script": {
23 "type": "string",
24 "description": "Rhai script code to execute"
25 },
26 "variables": {
27 "type": "object",
28 "description": "Variables to inject into script context",
29 "additionalProperties": true
30 }
31 },
32 "required": ["script"]
33 }),
34 requires_confirmation: true,
35 },
36 engine,
37 })
38 }
39}
40
41#[async_trait::async_trait]
42impl ToolExecutor for RhaiScriptTool {
43 fn definition(&self) -> &ToolDefinition {
44 &self.definition
45 }
46
47 async fn execute(&self, arguments: serde_json::Value) -> PluginResult<serde_json::Value> {
48 let script = arguments["script"]
49 .as_str()
50 .ok_or_else(|| anyhow::anyhow!("Script is required"))?;
51
52 let mut context = ScriptContext::new();
53
54 if let Some(vars) = arguments.get("variables").and_then(|v| v.as_object()) {
56 for (key, value) in vars {
57 match value {
59 serde_json::Value::Number(n) => {
60 if let Some(i) = n.as_i64() {
61 context = context.with_variable(key, i)?;
62 } else if let Some(f) = n.as_f64() {
63 context = context.with_variable(key, f)?;
64 }
65 }
66 serde_json::Value::String(s) => {
67 context = context.with_variable(key, s.clone())?;
68 }
69 serde_json::Value::Bool(b) => {
70 context = context.with_variable(key, *b)?;
71 }
72 _ => {
73 context = context.with_variable(key, value.to_string())?;
75 }
76 }
77 }
78 }
79
80 let result = self.engine.execute(script, &context).await?;
81
82 Ok(json!({
83 "success": true,
84 "result": result.value,
85 "execution_time_ms": result.execution_time_ms
86 }))
87 }
88}