distri_types/configuration/
package.rs1use crate::agent::StandardDefinition;
2use crate::configuration::manifest::DistriServerConfig;
3use crate::configuration::workflow::{
4 CustomAgentDefinition, DagWorkflowDefinition, SequentialWorkflowDefinition,
5};
6use serde::{Deserialize, Serialize};
7use std::path::PathBuf;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct PluginToolDefinition {
12 pub name: String,
13 pub package_name: String,
14 pub description: String,
15 #[serde(default)]
16 pub parameters: serde_json::Value,
17 #[serde(default, skip_serializing_if = "Option::is_none")]
18 pub auth: Option<crate::auth::AuthRequirement>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct PluginWorkflowDefinition {
24 pub name: String,
25 pub package_name: String,
26 pub description: String,
27 #[serde(default)]
28 pub parameters: serde_json::Value,
29 #[serde(default, skip_serializing_if = "Vec::is_empty")]
30 pub examples: Vec<serde_json::Value>,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
35#[serde(tag = "agent_type", rename_all = "snake_case")]
36pub enum AgentConfig {
37 StandardAgent(StandardDefinition),
39 SequentialWorkflowAgent(SequentialWorkflowDefinition),
41 DagWorkflowAgent(DagWorkflowDefinition),
43 CustomAgent(CustomAgentDefinition),
45}
46
47impl AgentConfig {
48 pub fn get_name(&self) -> &str {
50 match self {
51 AgentConfig::StandardAgent(def) => &def.name,
52 AgentConfig::SequentialWorkflowAgent(def) => &def.name,
53 AgentConfig::DagWorkflowAgent(def) => &def.name,
54 AgentConfig::CustomAgent(def) => &def.name,
55 }
56 }
57
58 pub fn get_description(&self) -> &str {
60 match self {
61 AgentConfig::StandardAgent(def) => &def.description,
62 AgentConfig::SequentialWorkflowAgent(def) => &def.description,
63 AgentConfig::DagWorkflowAgent(def) => &def.description,
64 AgentConfig::CustomAgent(def) => &def.description,
65 }
66 }
67
68 pub fn validate(&self) -> anyhow::Result<()> {
70 match self {
71 AgentConfig::StandardAgent(def) => def.validate(),
72 AgentConfig::SequentialWorkflowAgent(def) => {
73 if def.name.is_empty() {
74 return Err(anyhow::anyhow!("Workflow name cannot be empty"));
75 }
76 if def.steps.is_empty() {
77 return Err(anyhow::anyhow!("Workflow must have at least one step"));
78 }
79 Ok(())
80 }
81 AgentConfig::DagWorkflowAgent(def) => {
82 if def.name.is_empty() {
83 return Err(anyhow::anyhow!("Workflow name cannot be empty"));
84 }
85 if def.nodes.is_empty() {
86 return Err(anyhow::anyhow!("DAG workflow must have at least one node"));
87 }
88 Ok(())
89 }
90 AgentConfig::CustomAgent(def) => {
91 if def.name.is_empty() {
92 return Err(anyhow::anyhow!("Custom agent name cannot be empty"));
93 }
94 if def.script_path.is_empty() {
95 return Err(anyhow::anyhow!("Custom agent script_path cannot be empty"));
96 }
97 Ok(())
98 }
99 }
100 }
101
102 pub fn get_working_directory(
104 &self,
105 package_config: Option<&DistriServerConfig>,
106 ) -> anyhow::Result<std::path::PathBuf> {
107 if let Some(config) = package_config {
109 return config.get_working_directory();
110 }
111
112 if let Ok(distri_home) = std::env::var("DISTRI_HOME") {
114 return Ok(std::path::PathBuf::from(distri_home));
115 }
116
117 std::env::current_dir()
119 .map_err(|e| anyhow::anyhow!("Failed to get current directory: {}", e))
120 }
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct PluginAgentDefinition {
126 pub name: String,
127 pub package_name: String,
128 pub description: String,
129 pub file_path: PathBuf,
130 pub agent_config: AgentConfig,
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct PluginArtifact {
137 pub name: String,
138 pub path: PathBuf,
139 pub configuration: crate::configuration::manifest::DistriServerConfig,
140 pub tools: Vec<PluginToolDefinition>,
141 pub workflows: Vec<PluginWorkflowDefinition>,
142 pub agents: Vec<PluginAgentDefinition>,
143}