vtcode_core/tools/registry/
execution_request.rs1use serde_json::Value;
2use std::time::Duration;
3use vtcode_commons::ErrorCategory;
4
5use super::ToolExecutionError;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9pub enum ExecSettlementMode {
10 #[default]
12 Manual,
13 SettleNonInteractive,
15}
16
17impl ExecSettlementMode {
18 #[must_use]
19 pub fn settle_noninteractive(self) -> bool {
20 matches!(self, Self::SettleNonInteractive)
21 }
22}
23
24#[derive(Debug, Clone)]
26pub struct ExecutionPolicySnapshot {
27 pub max_retries: usize,
29 pub retry_base_delay: Duration,
31 pub retry_max_delay: Duration,
33 pub retry_multiplier: f64,
35 pub retry_jitter: f64,
37 pub prevalidated: bool,
39 pub invocation_id: Option<String>,
41 pub exec_settlement_mode: ExecSettlementMode,
43 pub safety_prevalidated: bool,
45}
46
47impl Default for ExecutionPolicySnapshot {
48 fn default() -> Self {
49 Self {
50 max_retries: 0,
51 retry_base_delay: Duration::from_millis(200),
52 retry_max_delay: Duration::from_secs(2),
53 retry_multiplier: 2.0,
54 retry_jitter: 0.0,
55 prevalidated: false,
56 invocation_id: None,
57 exec_settlement_mode: ExecSettlementMode::Manual,
58 safety_prevalidated: false,
59 }
60 }
61}
62
63impl ExecutionPolicySnapshot {
64 #[must_use]
65 pub fn with_max_retries(mut self, max_retries: usize) -> Self {
66 self.max_retries = max_retries;
67 self
68 }
69
70 #[must_use]
71 pub fn with_prevalidated(mut self, prevalidated: bool) -> Self {
72 self.prevalidated = prevalidated;
73 self
74 }
75
76 #[must_use]
77 pub fn with_invocation_id(mut self, invocation_id: Option<String>) -> Self {
78 self.invocation_id = invocation_id;
79 self
80 }
81
82 #[must_use]
83 pub fn with_exec_settlement_mode(mut self, mode: ExecSettlementMode) -> Self {
84 self.exec_settlement_mode = mode;
85 self
86 }
87
88 #[must_use]
89 pub fn with_safety_prevalidated(mut self, safety_prevalidated: bool) -> Self {
90 self.safety_prevalidated = safety_prevalidated;
91 self
92 }
93}
94
95#[derive(Debug, Clone)]
97pub struct ToolExecutionRequest {
98 pub tool_name: String,
99 pub args: Value,
100 pub policy: ExecutionPolicySnapshot,
101}
102
103impl ToolExecutionRequest {
104 #[must_use]
105 pub fn new(tool_name: impl Into<String>, args: Value) -> Self {
106 Self {
107 tool_name: tool_name.into(),
108 args,
109 policy: ExecutionPolicySnapshot::default(),
110 }
111 }
112
113 #[must_use]
114 pub fn with_policy(mut self, policy: ExecutionPolicySnapshot) -> Self {
115 self.policy = policy;
116 self
117 }
118}
119
120#[derive(Debug, Clone)]
122pub struct ToolExecutionOutcome {
123 pub tool_name: String,
124 pub attempts: u32,
125 pub total_duration: Duration,
126 pub last_error_category: Option<ErrorCategory>,
127 pub output: Option<Value>,
128 pub error: Option<ToolExecutionError>,
129}
130
131impl ToolExecutionOutcome {
132 #[must_use]
133 pub fn success(tool_name: impl Into<String>, attempts: u32, output: Value) -> Self {
134 Self {
135 tool_name: tool_name.into(),
136 attempts,
137 total_duration: Duration::ZERO,
138 last_error_category: None,
139 output: Some(output),
140 error: None,
141 }
142 }
143
144 #[must_use]
145 pub fn failure(tool_name: impl Into<String>, attempts: u32, error: ToolExecutionError) -> Self {
146 let last_error_category = Some(error.category);
147 Self {
148 tool_name: tool_name.into(),
149 attempts,
150 total_duration: Duration::ZERO,
151 last_error_category,
152 output: None,
153 error: Some(error),
154 }
155 }
156
157 #[must_use]
158 pub fn with_execution_metadata(
159 mut self,
160 total_duration: Duration,
161 last_error_category: Option<ErrorCategory>,
162 ) -> Self {
163 self.total_duration = total_duration;
164 if last_error_category.is_some() {
165 self.last_error_category = last_error_category;
166 }
167 self
168 }
169
170 #[must_use]
171 pub fn is_success(&self) -> bool {
172 self.error.is_none()
173 }
174}