tandem_workflows/
plan_package.rs1use 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)]
92pub struct WorkflowPlanDraftRecord<Plan = Value> {
93 pub initial_plan: Plan,
94 pub current_plan: Plan,
95 #[serde(default = "default_workflow_plan_draft_revision")]
96 pub plan_revision: u32,
97 pub conversation: WorkflowPlanConversation,
98 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub planner_diagnostics: Option<Value>,
100 #[serde(default, skip_serializing_if = "Option::is_none")]
101 pub last_success_materialization: Option<Value>,
102}