vtcode_commons/ui_protocol/
progress.rs1use std::sync::atomic::{AtomicU64, Ordering};
2use std::time::Instant;
3
4static NEXT_OPERATION: AtomicU64 = AtomicU64::new(1);
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct ProgressOperation {
9 id: u64,
10 started_at: Instant,
11}
12
13impl ProgressOperation {
14 pub fn start() -> Self {
15 Self {
16 id: NEXT_OPERATION.fetch_add(1, Ordering::Relaxed),
17 started_at: Instant::now(),
18 }
19 }
20
21 pub fn id(self) -> u64 {
22 self.id
23 }
24
25 pub fn started_at(self) -> Instant {
26 self.started_at
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum ProgressPhase {
33 Initializing,
34 PreparingContext,
35 SavingCheckpoint,
36 WaitingForModel,
37 Processing,
38 ReceivingResponse,
39 Retrying,
40 CheckingPermissions,
41 WaitingForApproval,
42 RunningTools,
43}
44
45impl ProgressPhase {
46 pub fn label(self) -> &'static str {
47 match self {
48 Self::Initializing => "Initializing session",
49 Self::PreparingContext => "Preparing context",
50 Self::SavingCheckpoint => "Saving checkpoint",
51 Self::WaitingForModel => "Waiting for model",
52 Self::Processing => "Processing",
53 Self::ReceivingResponse => "Receiving response",
54 Self::Retrying => "Retrying request",
55 Self::CheckingPermissions => "Checking permissions",
56 Self::WaitingForApproval => "Waiting for approval",
57 Self::RunningTools => "Running tools",
58 }
59 }
60
61 pub fn is_animated(self) -> bool {
62 self != Self::WaitingForApproval
63 }
64
65 pub fn format(self, elapsed_secs: u64) -> String {
66 format!("{} ยท {elapsed_secs}s", self.label())
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub enum ProgressUpdate {
72 Begin {
73 operation: ProgressOperation,
74 phase: ProgressPhase,
75 },
76 Phase {
77 operation: ProgressOperation,
78 phase: ProgressPhase,
79 },
80 Finish {
81 operation: ProgressOperation,
82 },
83}