distri_types/configuration/
package.rs1use crate::ToolDefinition;
2use crate::agent::StandardDefinition;
3use crate::configuration::manifest::DistriServerConfig;
4use crate::configuration::workflow::{
5 CustomAgentDefinition, DagWorkflowDefinition, SequentialWorkflowDefinition,
6};
7use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct PluginToolDefinition {
13 pub name: String,
14 pub package_name: String,
15 pub description: String,
16 #[serde(default)]
17 pub parameters: serde_json::Value,
18 #[serde(default, skip_serializing_if = "Option::is_none")]
19 pub auth: Option<crate::auth::AuthRequirement>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct PluginWorkflowDefinition {
25 pub name: String,
26 pub package_name: String,
27 pub description: String,
28 #[serde(default)]
29 pub parameters: serde_json::Value,
30 #[serde(default, skip_serializing_if = "Vec::is_empty")]
31 pub examples: Vec<serde_json::Value>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, Default)]
36pub struct AgentCloudMetadata {
37 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub id: Option<uuid::Uuid>,
39 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub published: Option<bool>,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub published_at: Option<chrono::DateTime<chrono::Utc>>,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub is_owner: Option<bool>,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct AgentConfigWithTools {
49 #[serde(flatten)]
50 pub agent: AgentConfig,
51 #[serde(default, skip_serializing_if = "Vec::is_empty")]
52 pub resolved_tools: Vec<ToolDefinition>,
53 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub markdown: Option<String>,
55 #[serde(flatten, default)]
57 pub cloud: AgentCloudMetadata,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(tag = "agent_type", rename_all = "snake_case")]
63pub enum AgentConfig {
64 StandardAgent(StandardDefinition),
66 SequentialWorkflowAgent(SequentialWorkflowDefinition),
68 DagWorkflowAgent(DagWorkflowDefinition),
70 CustomAgent(CustomAgentDefinition),
72}
73
74impl AgentConfig {
75 pub fn get_name(&self) -> &str {
77 match self {
78 AgentConfig::StandardAgent(def) => &def.name,
79 AgentConfig::SequentialWorkflowAgent(def) => &def.name,
80 AgentConfig::DagWorkflowAgent(def) => &def.name,
81 AgentConfig::CustomAgent(def) => &def.name,
82 }
83 }
84
85 pub fn get_description(&self) -> &str {
87 match self {
88 AgentConfig::StandardAgent(def) => &def.description,
89 AgentConfig::SequentialWorkflowAgent(def) => &def.description,
90 AgentConfig::DagWorkflowAgent(def) => &def.description,
91 AgentConfig::CustomAgent(def) => &def.description,
92 }
93 }
94
95 pub fn validate(&self) -> anyhow::Result<()> {
97 match self {
98 AgentConfig::StandardAgent(def) => def.validate(),
99 AgentConfig::SequentialWorkflowAgent(def) => {
100 if def.name.is_empty() {
101 return Err(anyhow::anyhow!("Workflow name cannot be empty"));
102 }
103 if def.steps.is_empty() {
104 return Err(anyhow::anyhow!("Workflow must have at least one step"));
105 }
106 Ok(())
107 }
108 AgentConfig::DagWorkflowAgent(def) => {
109 if def.name.is_empty() {
110 return Err(anyhow::anyhow!("Workflow name cannot be empty"));
111 }
112 if def.nodes.is_empty() {
113 return Err(anyhow::anyhow!("DAG workflow must have at least one node"));
114 }
115 Ok(())
116 }
117 AgentConfig::CustomAgent(def) => {
118 if def.name.is_empty() {
119 return Err(anyhow::anyhow!("Custom agent name cannot be empty"));
120 }
121 if def.script_path.is_empty() {
122 return Err(anyhow::anyhow!("Custom agent script_path cannot be empty"));
123 }
124 Ok(())
125 }
126 }
127 }
128
129 pub fn get_working_directory(
131 &self,
132 package_config: Option<&DistriServerConfig>,
133 ) -> anyhow::Result<std::path::PathBuf> {
134 if let Some(config) = package_config {
136 return config.get_working_directory();
137 }
138
139 if let Ok(distri_home) = std::env::var("DISTRI_HOME") {
141 return Ok(std::path::PathBuf::from(distri_home));
142 }
143
144 std::env::current_dir()
146 .map_err(|e| anyhow::anyhow!("Failed to get current directory: {}", e))
147 }
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct PluginAgentDefinition {
153 pub name: String,
154 pub package_name: String,
155 pub description: String,
156 pub file_path: PathBuf,
157 pub agent_config: AgentConfig,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct PluginArtifact {
164 pub name: String,
165 pub path: PathBuf,
166 pub configuration: crate::configuration::manifest::DistriServerConfig,
167 pub tools: Vec<PluginToolDefinition>,
168 pub workflows: Vec<PluginWorkflowDefinition>,
169 pub agents: Vec<PluginAgentDefinition>,
170}