1use serde::{Deserialize, Serialize};
19use serde_json::Value;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(rename_all = "snake_case")]
25pub enum ToolPhase {
26 Streaming,
27 WaitingConfirmation,
28 Executing,
29 Completed,
30 Cancelled,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
38#[serde(tag = "phase", rename_all = "snake_case")]
39pub enum ToolState {
40 #[serde(rename_all = "camelCase")]
41 Streaming {
42 #[serde(default, skip_serializing_if = "Option::is_none")]
43 partial_input: Option<Value>,
44 },
45 #[serde(rename_all = "camelCase")]
46 WaitingConfirmation {
47 input: Value,
48 description: String,
49 approval_id: String,
50 },
51 #[serde(rename_all = "camelCase")]
52 Executing {
53 #[serde(default, skip_serializing_if = "Option::is_none")]
54 progress: Option<String>,
55 #[serde(default, skip_serializing_if = "Option::is_none")]
56 elapsed_ms: Option<u64>,
57 },
58 #[serde(rename_all = "camelCase")]
59 Completed {
60 success: bool,
61 #[serde(default, skip_serializing_if = "Option::is_none")]
62 output: Option<String>,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 elapsed_ms: Option<u64>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
66 confirmed_by: Option<ConfirmedBy>,
67 },
68 #[serde(rename_all = "camelCase")]
69 Cancelled {
70 reason: CancelReason,
71 #[serde(default, skip_serializing_if = "Option::is_none")]
72 message: Option<String>,
73 },
74}
75
76impl ToolState {
77 #[must_use]
78 pub fn phase(&self) -> ToolPhase {
79 match self {
80 Self::Streaming { .. } => ToolPhase::Streaming,
81 Self::WaitingConfirmation { .. } => ToolPhase::WaitingConfirmation,
82 Self::Executing { .. } => ToolPhase::Executing,
83 Self::Completed { .. } => ToolPhase::Completed,
84 Self::Cancelled { .. } => ToolPhase::Cancelled,
85 }
86 }
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
90#[serde(rename_all = "snake_case")]
91pub enum ConfirmedBy {
92 User,
93 Auto,
94 Setting,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
98#[serde(rename_all = "snake_case")]
99pub enum CancelReason {
100 Denied,
101 Interrupted,
102 Timeout,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
108#[serde(rename_all = "camelCase")]
109pub struct ToolInfo {
110 pub tool_id: String,
111 pub name: String,
112 pub state: ToolState,
113}