use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum NodeType {
Workflow,
Action,
Transition,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum NodeStatus {
Pending,
Running,
Success,
Failed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum TreeEventType {
WorkflowStarted,
WorkflowCompleted,
WorkflowFailed,
ActionStarted,
ActionCompleted,
ActionFailed,
TransitionStarted,
TransitionCompleted,
TransitionFailed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub enum ActionType {
#[serde(rename = "FIND")]
Find,
#[serde(rename = "FIND_STATE_IMAGE")]
FindStateImage,
#[serde(rename = "EXISTS")]
Exists,
#[serde(rename = "VANISH")]
Vanish,
#[serde(rename = "CLICK")]
Click,
#[serde(rename = "DOUBLE_CLICK")]
DoubleClick,
#[serde(rename = "RIGHT_CLICK")]
RightClick,
#[serde(rename = "DRAG")]
Drag,
#[serde(rename = "SCROLL")]
Scroll,
#[serde(rename = "MOUSE_MOVE")]
MouseMove,
#[serde(rename = "TYPE")]
Type,
#[serde(rename = "KEY_PRESS")]
KeyPress,
#[serde(rename = "HOTKEY")]
Hotkey,
#[serde(rename = "IF")]
If,
#[serde(rename = "LOOP")]
Loop,
#[serde(rename = "SWITCH")]
Switch,
#[serde(rename = "TRY_CATCH")]
TryCatch,
#[serde(rename = "BREAK")]
Break,
#[serde(rename = "CONTINUE")]
Continue,
#[serde(rename = "GO_TO_STATE")]
GoToState,
#[serde(rename = "WAIT")]
Wait,
#[serde(rename = "RUN_WORKFLOW")]
RunWorkflow,
#[serde(rename = "SCREENSHOT")]
Screenshot,
#[serde(rename = "CODE_BLOCK")]
CodeBlock,
#[serde(rename = "SHELL")]
Shell,
#[serde(rename = "CUSTOM")]
Custom,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct MatchLocation {
#[serde(alias = "x")]
pub x: i64,
#[serde(alias = "y")]
pub y: i64,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "w")]
pub w: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "h")]
pub h: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TopMatch {
#[serde(alias = "confidence")]
pub confidence: f64,
#[serde(alias = "location")]
pub location: MatchLocation,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "dimensions")]
pub dimensions: Option<MatchLocation>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct RuntimeData {
#[serde(default, skip_serializing_if = "Option::is_none", alias = "typed_text")]
pub typed_text: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "character_count"
)]
pub character_count: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "image_id")]
pub image_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "found")]
pub found: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "confidence")]
pub confidence: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "location")]
pub location: Option<MatchLocation>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "dimensions")]
pub dimensions: Option<MatchLocation>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "match_method"
)]
pub match_method: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "top_matches"
)]
pub top_matches: Option<Vec<TopMatch>>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "clicked_at")]
pub clicked_at: Option<MatchLocation>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "button")]
pub button: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "target_type"
)]
pub target_type: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "source_states"
)]
pub source_states: Option<Vec<String>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "target_states"
)]
pub target_states: Option<Vec<String>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "targets_reached"
)]
pub targets_reached: Option<Vec<String>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "transitions_executed"
)]
pub transitions_executed: Option<Vec<String>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "already_at_target"
)]
pub already_at_target: Option<bool>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "condition_passed"
)]
pub condition_passed: Option<bool>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "branch_taken"
)]
pub branch_taken: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "workflow_name"
)]
pub workflow_name: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "workflow_status"
)]
pub workflow_status: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct StateContext {
#[serde(default, alias = "active_before")]
pub active_before: Vec<String>,
#[serde(default, alias = "active_after")]
pub active_after: Vec<String>,
#[serde(default, alias = "changed")]
pub changed: bool,
#[serde(default, alias = "activated")]
pub activated: Vec<String>,
#[serde(default, alias = "deactivated")]
pub deactivated: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TimingInfo {
#[serde(alias = "start_time")]
pub start_time: String,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "end_time")]
pub end_time: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "duration_ms"
)]
pub duration_ms: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct Outcome {
#[serde(alias = "success")]
pub success: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "error")]
pub error: Option<String>,
#[serde(default, alias = "retry_count")]
pub retry_count: i64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct NodeMetadata {
#[serde(default, skip_serializing_if = "Option::is_none", alias = "config")]
pub config: Option<HashMap<String, serde_json::Value>>,
#[serde(default, alias = "is_expandable")]
pub is_expandable: bool,
#[serde(default, alias = "is_inline")]
pub is_inline: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "runtime")]
pub runtime: Option<RuntimeData>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "state_context"
)]
pub state_context: Option<StateContext>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "timing")]
pub timing: Option<TimingInfo>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "outcome")]
pub outcome: Option<Outcome>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "screenshot_reference"
)]
pub screenshot_reference: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "visual_debug_reference"
)]
pub visual_debug_reference: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TreeNode {
#[serde(alias = "id")]
pub id: String,
#[serde(alias = "node_type")]
pub node_type: NodeType,
#[serde(alias = "name")]
pub name: String,
#[serde(alias = "timestamp")]
pub timestamp: f64,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "end_timestamp"
)]
pub end_timestamp: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "duration")]
pub duration: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "parent_id")]
pub parent_id: Option<String>,
#[serde(alias = "status")]
pub status: NodeStatus,
#[serde(default, alias = "metadata")]
pub metadata: NodeMetadata,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "error")]
pub error: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct PathElement {
#[serde(alias = "id")]
pub id: String,
#[serde(alias = "name")]
pub name: String,
#[serde(alias = "node_type")]
pub node_type: NodeType,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TreeEvent {
#[serde(default = "default_tree_event_type", alias = "type")]
pub r#type: String,
#[serde(alias = "event_type")]
pub event_type: TreeEventType,
#[serde(alias = "node")]
pub node: TreeNode,
#[serde(default, alias = "path")]
pub path: Vec<PathElement>,
#[serde(alias = "timestamp")]
pub timestamp: f64,
#[serde(default, alias = "sequence")]
pub sequence: i64,
}
fn default_tree_event_type() -> String {
"tree_event".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct DisplayNode {
#[serde(alias = "id")]
pub id: String,
#[serde(alias = "node_type")]
pub node_type: NodeType,
#[serde(alias = "name")]
pub name: String,
#[serde(alias = "timestamp")]
pub timestamp: f64,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "end_timestamp"
)]
pub end_timestamp: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "duration")]
pub duration: Option<f64>,
#[serde(alias = "status")]
pub status: NodeStatus,
#[serde(default, alias = "metadata")]
pub metadata: NodeMetadata,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "error")]
pub error: Option<String>,
#[serde(default, alias = "children")]
pub children: Vec<DisplayNode>,
#[serde(default = "default_true", alias = "is_expanded")]
pub is_expanded: bool,
#[serde(default, alias = "level")]
pub level: i64,
}
fn default_true() -> bool {
true
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TreeEventCreate {
#[serde(alias = "event_type")]
pub event_type: TreeEventType,
#[serde(alias = "node")]
pub node: TreeNode,
#[serde(default, alias = "path")]
pub path: Vec<PathElement>,
#[serde(alias = "timestamp")]
pub timestamp: f64,
#[serde(default, alias = "sequence")]
pub sequence: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TreeEventResponse {
#[serde(alias = "id")]
pub id: String,
#[serde(alias = "run_id")]
pub run_id: String,
#[serde(alias = "event_type")]
pub event_type: TreeEventType,
#[serde(alias = "node_id")]
pub node_id: String,
#[serde(alias = "node_type")]
pub node_type: NodeType,
#[serde(alias = "node_name")]
pub node_name: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "parent_node_id"
)]
pub parent_node_id: Option<String>,
#[serde(alias = "path")]
pub path: Vec<PathElement>,
#[serde(alias = "sequence")]
pub sequence: i64,
#[serde(alias = "event_timestamp")]
pub event_timestamp: f64,
#[serde(alias = "status")]
pub status: NodeStatus,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "error_message"
)]
pub error_message: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "metadata")]
pub metadata: Option<NodeMetadata>,
#[serde(alias = "created_at")]
pub created_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct TreeEventListResponse {
#[serde(alias = "events")]
pub events: Vec<TreeEventResponse>,
#[serde(alias = "total")]
pub total: i64,
#[serde(alias = "limit")]
pub limit: i64,
#[serde(alias = "offset")]
pub offset: i64,
#[serde(alias = "has_more")]
pub has_more: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ExecutionTreeResponse {
#[serde(alias = "run_id")]
pub run_id: String,
#[serde(alias = "root_nodes")]
pub root_nodes: Vec<DisplayNode>,
#[serde(alias = "total_events")]
pub total_events: i64,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "workflow_name"
)]
pub workflow_name: Option<String>,
#[serde(alias = "status")]
pub status: NodeStatus,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "duration_ms"
)]
pub duration_ms: Option<f64>,
#[serde(default, alias = "initial_state_ids")]
pub initial_state_ids: Vec<String>,
#[serde(default, alias = "state_name_map")]
pub state_name_map: HashMap<String, String>,
}