matrixcode_core/workflow/executors/
proxy.rs1use anyhow::{Context, Result};
6use async_trait::async_trait;
7use std::sync::Arc;
8
9use super::node_executor::NodeExecutor;
10use crate::tools::toolproxy::{ProxyToolDef, ProxyToolExecutor};
11use crate::workflow::context::WorkflowContext;
12use crate::workflow::def::NodeDef;
13use crate::workflow::template::TemplateRenderer;
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
61 .task
62 .as_ref()
63 .ok_or_else(|| anyhow::anyhow!("Proxy executor requires a task name"))?;
64
65 if !self.has_tool(tool_name) {
67 return Err(anyhow::anyhow!("Proxy tool '{}' not found", tool_name));
68 }
69
70 let params = self
72 .template_renderer
73 .render_params(&node.params, &context.variables)?;
74
75 let result = self
77 .executor
78 .exec(tool_name, params.clone())
79 .await
80 .with_context(|| format!("Proxy tool '{}' execution failed", tool_name))?;
81
82 let output = if let Ok(json) = serde_json::from_str::<serde_json::Value>(&result) {
84 json
85 } else {
86 serde_json::json!({
87 "result": result,
88 "tool": tool_name,
89 })
90 };
91
92 if let serde_json::Value::Object(map) = &output {
94 for (key, value) in map {
95 context.set_variable(key.clone(), value.clone());
96 }
97 }
98
99 Ok(output)
100 }
101
102 fn name(&self) -> &str {
103 "proxy_executor"
104 }
105}