1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
10#[serde(rename_all = "snake_case")]
11pub enum AutomationV2ScheduleType {
12 Cron,
13 Interval,
14 Manual,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
18pub struct AutomationV2Schedule<MisfirePolicy = Value> {
19 #[serde(rename = "type")]
20 pub schedule_type: AutomationV2ScheduleType,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
22 pub cron_expression: Option<String>,
23 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub interval_seconds: Option<u64>,
25 pub timezone: String,
26 pub misfire_policy: MisfirePolicy,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, Default)]
30pub struct WorkflowPlanStep<InputRef = Value, OutputContract = Value> {
31 pub step_id: String,
32 pub kind: String,
33 pub objective: String,
34 #[serde(default)]
35 pub depends_on: Vec<String>,
36 pub agent_role: String,
37 #[serde(default)]
38 pub input_refs: Vec<InputRef>,
39 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub output_contract: Option<OutputContract>,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub metadata: Option<Value>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct WorkflowPlan<Schedule = Value, Step = Value> {
47 pub plan_id: String,
48 pub planner_version: String,
49 pub plan_source: String,
50 pub original_prompt: String,
51 pub normalized_prompt: String,
52 pub confidence: String,
53 pub title: String,
54 #[serde(default, skip_serializing_if = "Option::is_none")]
55 pub description: Option<String>,
56 pub schedule: Schedule,
57 pub execution_target: String,
58 pub workspace_root: String,
59 #[serde(default)]
60 pub steps: Vec<Step>,
61 #[serde(default)]
62 pub requires_integrations: Vec<String>,
63 #[serde(default)]
64 pub allowed_mcp_servers: Vec<String>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
66 pub operator_preferences: Option<Value>,
67 pub save_options: Value,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct WorkflowPlanChatMessage {
72 pub role: String,
73 pub text: String,
74 pub created_at_ms: u64,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct WorkflowPlanConversation {
79 pub conversation_id: String,
80 pub plan_id: String,
81 pub created_at_ms: u64,
82 pub updated_at_ms: u64,
83 #[serde(default)]
84 pub messages: Vec<WorkflowPlanChatMessage>,
85}
86
87fn default_workflow_plan_draft_revision() -> u32 {
88 1
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, Default)]
92pub struct WorkflowPlanDraftReviewRecord {
93 #[serde(default)]
94 pub required_capabilities: Vec<String>,
95 #[serde(default)]
96 pub requested_capabilities: Vec<String>,
97 #[serde(default)]
98 pub blocked_capabilities: Vec<String>,
99 #[serde(default)]
100 pub docs_mcp_used: bool,
101 #[serde(default, skip_serializing_if = "Option::is_none")]
102 pub preview_payload: Option<Value>,
103 #[serde(default, skip_serializing_if = "Option::is_none")]
104 pub created_at_ms: Option<u64>,
105 #[serde(default, skip_serializing_if = "Option::is_none")]
106 pub updated_at_ms: Option<u64>,
107 #[serde(default)]
108 pub validation_state: String,
109 #[serde(default)]
110 pub validation_status: String,
111 #[serde(default)]
112 pub approval_status: String,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct WorkflowPlanDraftRecord<Plan = Value> {
117 pub initial_plan: Plan,
118 pub current_plan: Plan,
119 #[serde(default = "default_workflow_plan_draft_revision")]
120 pub plan_revision: u32,
121 pub conversation: WorkflowPlanConversation,
122 #[serde(default, skip_serializing_if = "Option::is_none")]
123 pub planner_diagnostics: Option<Value>,
124 #[serde(default, skip_serializing_if = "Option::is_none")]
125 pub last_success_materialization: Option<Value>,
126 #[serde(default, skip_serializing_if = "Option::is_none")]
127 pub review: Option<WorkflowPlanDraftReviewRecord>,
128}