matrixcode_core/workflow/executors/
proxy.rs1use anyhow::{Context, Result};
6use async_trait::async_trait;
7use std::sync::Arc;
8
9use crate::tools::toolproxy::{ProxyToolExecutor, ProxyToolDef};
10use crate::workflow::context::WorkflowContext;
11use crate::workflow::def::NodeDef;
12use crate::workflow::template::TemplateRenderer;
13use super::node_executor::NodeExecutor;
14
15pub struct ProxyExecutor {
19 executor: Arc<dyn ProxyToolExecutor>,
21 tool_defs: Vec<ProxyToolDef>,
23 template_renderer: TemplateRenderer,
25}
26
27impl ProxyExecutor {
28 pub fn new(executor: Arc<dyn ProxyToolExecutor>, tool_defs: Vec<ProxyToolDef>) -> Self {
30 Self {
31 executor,
32 tool_defs,
33 template_renderer: TemplateRenderer::new(),
34 }
35 }
36
37 pub fn has_tool(&self, name: &str) -> bool {
39 self.tool_defs.iter().any(|t| t.definition.name == name)
40 }
41
42 pub fn get_timeout(&self, name: &str) -> u64 {
44 self.tool_defs
45 .iter()
46 .find(|t| t.definition.name == name)
47 .map(|t| t.timeout_ms)
48 .unwrap_or(30000)
49 }
50}
51
52#[async_trait]
53impl NodeExecutor for ProxyExecutor {
54 async fn execute(
55 &self,
56 node: &NodeDef,
57 context: &mut WorkflowContext,
58 ) -> Result<serde_json::Value> {
59 let tool_name = node.task.as_ref()
61 .ok_or_else(|| anyhow::anyhow!("Proxy executor requires a task name"))?;
62
63 if !self.has_tool(tool_name) {
65 return Err(anyhow::anyhow!("Proxy tool '{}' not found", tool_name));
66 }
67
68 let params = self.template_renderer.render_params(&node.params, &context.variables)?;
70
71 let result = self.executor.exec(tool_name, params.clone()).await
73 .with_context(|| format!("Proxy tool '{}' execution failed", tool_name))?;
74
75 let output = if let Ok(json) = serde_json::from_str::<serde_json::Value>(&result) {
77 json
78 } else {
79 serde_json::json!({
80 "result": result,
81 "tool": tool_name,
82 })
83 };
84
85 if let serde_json::Value::Object(map) = &output {
87 for (key, value) in map {
88 context.set_variable(key.clone(), value.clone());
89 }
90 }
91
92 Ok(output)
93 }
94
95 fn name(&self) -> &str {
96 "proxy_executor"
97 }
98}