Skip to main content

agent_runtime/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[cfg(test)]
5#[path = "types_test.rs"]
6mod types_test;
7
8/// Unique identifier for workflows
9pub type WorkflowId = String;
10
11/// Unique identifier for events
12pub type EventId = String;
13
14/// Sequential offset for event ordering
15pub type EventOffset = u64;
16
17/// Generic JSON value for flexible data passing
18pub type JsonValue = serde_json::Value;
19
20/// Input data passed to an agent
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct AgentInput {
23    pub data: JsonValue,
24    pub metadata: AgentInputMetadata,
25}
26
27impl AgentInput {
28    /// Create a new AgentInput from a text string
29    pub fn from_text(text: impl Into<String>) -> Self {
30        Self {
31            data: serde_json::json!(text.into()),
32            metadata: AgentInputMetadata {
33                step_index: 0,
34                previous_agent: None,
35            },
36        }
37    }
38
39    /// Create a new AgentInput from any JSON-serializable value
40    pub fn from_value(value: JsonValue) -> Self {
41        Self {
42            data: value,
43            metadata: AgentInputMetadata {
44                step_index: 0,
45                previous_agent: None,
46            },
47        }
48    }
49
50    /// Create a new AgentInput with metadata
51    pub fn with_metadata(data: JsonValue, metadata: AgentInputMetadata) -> Self {
52        Self { data, metadata }
53    }
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct AgentInputMetadata {
58    pub step_index: usize,
59    pub previous_agent: Option<String>,
60}
61
62/// Output data produced by an agent
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct AgentOutput {
65    pub data: JsonValue,
66    pub metadata: AgentOutputMetadata,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct AgentOutputMetadata {
71    pub agent_name: String,
72    pub execution_time_ms: u64,
73    pub tool_calls_count: usize,
74}
75
76/// Result type for agent execution
77pub type AgentResult = Result<AgentOutput, AgentError>;
78
79/// Errors that can occur during agent execution
80#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
81pub enum AgentError {
82    #[error("Tool execution failed: {0}")]
83    ToolError(String),
84
85    #[error("Invalid input: {0}")]
86    InvalidInput(String),
87
88    #[error("Execution failed: {0}")]
89    ExecutionError(String),
90}
91
92/// Tool invocation parameters
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct ToolCall {
95    pub tool_name: String,
96    pub parameters: HashMap<String, JsonValue>,
97}
98
99/// Status of a tool execution
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
101#[serde(rename_all = "snake_case")]
102pub enum ToolStatus {
103    /// Tool executed successfully and returned data
104    #[default]
105    Success,
106
107    /// Tool executed successfully but found no data/results
108    /// This signals to the LLM: "Don't retry, this is a valid empty result"
109    SuccessNoData,
110
111    /// Tool execution failed
112    Error,
113}
114
115/// Tool execution result
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct ToolResult {
118    pub output: JsonValue,
119    /// Duration in milliseconds with microsecond precision (e.g., 0.123 ms)
120    pub duration_ms: f64,
121    /// Status of the execution
122    #[serde(default)]
123    pub status: ToolStatus,
124    /// Optional message explaining the result
125    pub message: Option<String>,
126}
127
128impl ToolResult {
129    /// Create a successful result with data
130    pub fn success(output: JsonValue, duration_ms: f64) -> Self {
131        Self {
132            output,
133            duration_ms,
134            status: ToolStatus::Success,
135            message: None,
136        }
137    }
138
139    /// Create a successful result with no data
140    pub fn success_no_data(message: impl Into<String>, duration_ms: f64) -> Self {
141        Self {
142            output: JsonValue::Null,
143            duration_ms,
144            status: ToolStatus::SuccessNoData,
145            message: Some(message.into()),
146        }
147    }
148
149    /// Create an error result
150    pub fn error(message: impl Into<String>, duration_ms: f64) -> Self {
151        Self {
152            output: JsonValue::Null,
153            duration_ms,
154            status: ToolStatus::Error,
155            message: Some(message.into()),
156        }
157    }
158
159    /// Add a message to this result
160    pub fn with_message(mut self, message: impl Into<String>) -> Self {
161        self.message = Some(message.into());
162        self
163    }
164}
165
166/// Result type for tool execution
167pub type ToolExecutionResult = Result<ToolResult, ToolError>;
168
169/// Errors that can occur during tool execution
170#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
171pub enum ToolError {
172    #[error("Invalid parameters: {0}")]
173    InvalidParameters(String),
174
175    #[error("Execution failed: {0}")]
176    ExecutionFailed(String),
177}