1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
//! Runtime error types.
use thiserror::Error;
/// Result type returned by fallible runtime operations.
pub type RuntimeResult<T> = Result<T, RuntimeError>;
#[derive(Error, Debug, Clone, PartialEq)]
/// Failures produced by runtime orchestration and tool execution.
pub enum RuntimeError {
/// A model provider request or response failed.
#[error("Provider error: {0}")]
Provider(
/// Provider failure details.
String,
),
/// An agent turn exhausted its configured iteration limit.
#[error("Maximum iterations ({max}) exceeded")]
MaxIterationsExceeded {
/// Configured maximum number of iterations.
max: u32,
},
/// A tool failed while executing.
#[error("Tool execution error: {message}")]
ToolExecution {
/// Tool-provided failure details.
message: String,
},
/// No registered tool has the requested name.
#[error("Tool not found: {name}")]
ToolNotFound {
/// Requested tool name.
name: String,
},
/// Runtime configuration is invalid.
#[error("Invalid configuration: {message}")]
InvalidConfig {
/// Description of the violated configuration invariant.
message: String,
},
/// A session operation failed.
#[error("Session error: {message}")]
Session {
/// Session failure details.
message: String,
},
/// A tool call cannot proceed without approval.
#[error("Approval required for tool: {tool_name}")]
ApprovalRequired {
/// Name of the tool awaiting approval.
tool_name: String,
},
/// A turn was started while another turn remained active.
#[error("Turn already active (turn_id: {turn_id})")]
TurnAlreadyActive {
/// Identifier of the currently active turn.
turn_id: u64,
},
/// An operation targeted a turn that has already completed.
#[error("Turn has already finished")]
TurnFinished,
/// Approval was supplied while the turn was in another state.
#[error("Turn is not waiting for approval")]
NotWaitingForApproval,
/// No pending approval matches the supplied call identifier.
#[error("No pending approval for call_id: {call_id}")]
ApprovalNotFound {
/// Tool call identifier that was not pending.
call_id: String,
},
/// Interaction input was supplied while the turn was in another state.
#[error("Turn is not waiting for an interaction")]
NotWaitingForInteraction,
/// No pending interaction matches the supplied identifier.
#[error("No pending interaction for interaction_id: {interaction_id}")]
InteractionNotFound {
/// Interaction identifier that was not pending.
interaction_id: String,
},
/// A resolution has a different kind than its pending interaction.
#[error("Interaction resolution kind mismatch for interaction_id: {interaction_id}")]
InteractionKindMismatch {
/// Identifier of the interaction with the mismatched resolution.
interaction_id: String,
},
/// An interaction resolution is malformed or semantically invalid.
#[error("Invalid interaction resolution: {message}")]
InvalidInteractionResolution {
/// Description of the invalid resolution.
message: String,
},
/// An operation targeted a closed session.
#[error("Session has been closed")]
SessionClosed,
/// The session's runtime executor is no longer available.
#[error("Session runtime has been shut down")]
RuntimeShutdown,
/// Communication with an external transport failed.
#[error("Transport error: {0}")]
Transport(
/// Transport failure details.
String,
),
/// A session identifier did not resolve to a known session.
#[error("Session not found: {0}")]
SessionNotFound(
/// Session identifier that was not found.
String,
),
/// Establishing or using a connection failed.
#[error("Connection error: {0}")]
Connection(
/// Connection failure details.
String,
),
/// Capability negotiation or invocation failed.
#[error("Capability error: {0}")]
Capability(
/// Capability failure details.
String,
),
/// A turn-level operation failed.
#[error("Turn error: {0}")]
Turn(
/// Turn failure details.
String,
),
/// Loading or applying configuration failed.
#[error("Configuration error: {0}")]
Config(
/// Configuration failure details.
String,
),
}
impl RuntimeError {
/// Construct a provider failure from a message.
pub fn provider<S: Into<String>>(message: S) -> Self {
Self::Provider(message.into())
}
/// Construct an iteration-limit failure for the configured maximum.
pub fn max_iterations(max: u32) -> Self {
Self::MaxIterationsExceeded { max }
}
/// Construct a tool-execution failure from a message.
pub fn tool_execution<S: Into<String>>(message: S) -> Self {
Self::ToolExecution {
message: message.into(),
}
}
/// Construct a missing-tool failure from the requested name.
pub fn tool_not_found<S: Into<String>>(name: S) -> Self {
Self::ToolNotFound { name: name.into() }
}
/// Construct an invalid-configuration failure from a message.
pub fn invalid_config<S: Into<String>>(message: S) -> Self {
Self::InvalidConfig {
message: message.into(),
}
}
/// Construct a session failure from a message.
pub fn session<S: Into<String>>(message: S) -> Self {
Self::Session {
message: message.into(),
}
}
/// Construct an approval-required failure for a tool name.
pub fn approval_required<S: Into<String>>(tool_name: S) -> Self {
Self::ApprovalRequired {
tool_name: tool_name.into(),
}
}
/// Construct a transport failure from a message.
pub fn transport<S: Into<String>>(msg: S) -> Self {
Self::Transport(msg.into())
}
/// Construct a missing-session failure from an identifier.
pub fn session_not_found<S: Into<String>>(id: S) -> Self {
Self::SessionNotFound(id.into())
}
/// Construct a connection failure from a message.
pub fn connection<S: Into<String>>(msg: S) -> Self {
Self::Connection(msg.into())
}
/// Construct a capability failure from a message.
pub fn capability<S: Into<String>>(msg: S) -> Self {
Self::Capability(msg.into())
}
/// Return whether this error represents exhaustion of the iteration limit.
pub fn is_max_iterations(&self) -> bool {
matches!(self, Self::MaxIterationsExceeded { .. })
}
}