actflow_agent_sdk/
types.rs

1//! Type definitions and utilities for the Agent SDK.
2
3use crate::proto;
4
5/// Agent inputs as JSON value.
6pub type Inputs = serde_json::Value;
7
8/// Agent execution status.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum ExecutionStatus {
11    Pending,
12    Succeeded,
13    Failed,
14    Exception,
15    Stopped,
16    Paused,
17}
18
19impl From<ExecutionStatus> for proto::NodeExecutionStatus {
20    fn from(status: ExecutionStatus) -> Self {
21        match status {
22            ExecutionStatus::Pending => proto::NodeExecutionStatus::Pending,
23            ExecutionStatus::Succeeded => proto::NodeExecutionStatus::Succeeded,
24            ExecutionStatus::Failed => proto::NodeExecutionStatus::Failed,
25            ExecutionStatus::Exception => proto::NodeExecutionStatus::Exception,
26            ExecutionStatus::Stopped => proto::NodeExecutionStatus::Stopped,
27            ExecutionStatus::Paused => proto::NodeExecutionStatus::Paused,
28        }
29    }
30}
31
32/// Agent output result.
33#[derive(Debug, Clone)]
34pub struct AgentOutput {
35    /// Execution status.
36    pub status: ExecutionStatus,
37    /// Output data.
38    pub outputs: serde_json::Value,
39    /// Error message (if status is Failed).
40    pub error: String,
41    /// Exception message (if status is Exception).
42    pub exception: String,
43}
44
45impl AgentOutput {
46    /// Create a successful output.
47    pub fn success(outputs: serde_json::Value) -> Self {
48        Self {
49            status: ExecutionStatus::Succeeded,
50            outputs,
51            error: String::new(),
52            exception: String::new(),
53        }
54    }
55
56    /// Create a failed output with error message.
57    pub fn failed(error: impl Into<String>) -> Self {
58        Self {
59            status: ExecutionStatus::Failed,
60            outputs: serde_json::Value::Null,
61            error: error.into(),
62            exception: String::new(),
63        }
64    }
65
66    /// Create an exception output.
67    pub fn exception(exception: impl Into<String>) -> Self {
68        Self {
69            status: ExecutionStatus::Exception,
70            outputs: serde_json::Value::Null,
71            error: String::new(),
72            exception: exception.into(),
73        }
74    }
75}
76
77impl From<AgentOutput> for proto::AgentOutput {
78    fn from(output: AgentOutput) -> Self {
79        Self {
80            status: proto::NodeExecutionStatus::from(output.status) as i32,
81            outputs: Some(json_to_prost_value(output.outputs)),
82            error: output.error,
83            exception: output.exception,
84        }
85    }
86}
87
88/// Convert prost_types::Value to serde_json::Value.
89pub(crate) fn prost_value_to_json(value: prost_types::Value) -> serde_json::Value {
90    use prost_types::value::Kind;
91
92    match value.kind {
93        Some(Kind::NullValue(_)) => serde_json::Value::Null,
94        Some(Kind::NumberValue(n)) => serde_json::json!(n),
95        Some(Kind::StringValue(s)) => serde_json::Value::String(s),
96        Some(Kind::BoolValue(b)) => serde_json::Value::Bool(b),
97        Some(Kind::StructValue(s)) => {
98            let map: serde_json::Map<String, serde_json::Value> = s
99                .fields
100                .into_iter()
101                .map(|(k, v)| (k, prost_value_to_json(v)))
102                .collect();
103            serde_json::Value::Object(map)
104        }
105        Some(Kind::ListValue(l)) => {
106            let arr: Vec<serde_json::Value> =
107                l.values.into_iter().map(prost_value_to_json).collect();
108            serde_json::Value::Array(arr)
109        }
110        None => serde_json::Value::Null,
111    }
112}
113
114/// Convert serde_json::Value to prost_types::Value.
115pub(crate) fn json_to_prost_value(value: serde_json::Value) -> prost_types::Value {
116    use prost_types::value::Kind;
117
118    let kind = match value {
119        serde_json::Value::Null => Kind::NullValue(0),
120        serde_json::Value::Bool(b) => Kind::BoolValue(b),
121        serde_json::Value::Number(n) => Kind::NumberValue(n.as_f64().unwrap_or(0.0)),
122        serde_json::Value::String(s) => Kind::StringValue(s),
123        serde_json::Value::Array(arr) => Kind::ListValue(prost_types::ListValue {
124            values: arr.into_iter().map(json_to_prost_value).collect(),
125        }),
126        serde_json::Value::Object(map) => Kind::StructValue(prost_types::Struct {
127            fields: map
128                .into_iter()
129                .map(|(k, v)| (k, json_to_prost_value(v)))
130                .collect(),
131        }),
132    };
133
134    prost_types::Value { kind: Some(kind) }
135}