agent: Create TerminalToolCard
and display shell output while it's running (#29546)
Also, don't require a worktree to run the terminal tool. Release Notes: - N/A
This commit is contained in:
parent
5afb89ca93
commit
83b8530e1f
15 changed files with 560 additions and 343 deletions
48
crates/util/src/size.rs
Normal file
48
crates/util/src/size.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
pub fn format_file_size(size: u64, use_decimal: bool) -> String {
|
||||
if use_decimal {
|
||||
if size < 1000 {
|
||||
format!("{size}B")
|
||||
} else if size < 1000 * 1000 {
|
||||
format!("{:.1}KB", size as f64 / 1000.0)
|
||||
} else {
|
||||
format!("{:.1}MB", size as f64 / (1000.0 * 1000.0))
|
||||
}
|
||||
} else {
|
||||
if size < 1024 {
|
||||
format!("{size}B")
|
||||
} else if size < 1024 * 1024 {
|
||||
format!("{:.1}KiB", size as f64 / 1024.0)
|
||||
} else {
|
||||
format!("{:.1}MiB", size as f64 / (1024.0 * 1024.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_format_file_size_decimal() {
|
||||
assert_eq!(format_file_size(0, true), "0B");
|
||||
assert_eq!(format_file_size(999, true), "999B");
|
||||
assert_eq!(format_file_size(1000, true), "1.0KB");
|
||||
assert_eq!(format_file_size(1500, true), "1.5KB");
|
||||
assert_eq!(format_file_size(999999, true), "1000.0KB");
|
||||
assert_eq!(format_file_size(1000000, true), "1.0MB");
|
||||
assert_eq!(format_file_size(1500000, true), "1.5MB");
|
||||
assert_eq!(format_file_size(10000000, true), "10.0MB");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_file_size_binary() {
|
||||
assert_eq!(format_file_size(0, false), "0B");
|
||||
assert_eq!(format_file_size(1023, false), "1023B");
|
||||
assert_eq!(format_file_size(1024, false), "1.0KiB");
|
||||
assert_eq!(format_file_size(1536, false), "1.5KiB");
|
||||
assert_eq!(format_file_size(1048575, false), "1024.0KiB");
|
||||
assert_eq!(format_file_size(1048576, false), "1.0MiB");
|
||||
assert_eq!(format_file_size(1572864, false), "1.5MiB");
|
||||
assert_eq!(format_file_size(10485760, false), "10.0MiB");
|
||||
}
|
||||
}
|
41
crates/util/src/time.rs
Normal file
41
crates/util/src/time.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use std::time::Duration;
|
||||
|
||||
pub fn duration_alt_display(duration: Duration) -> String {
|
||||
if duration < Duration::from_secs(60) {
|
||||
format!("{}s", duration.as_secs())
|
||||
} else {
|
||||
duration_clock_format(duration)
|
||||
}
|
||||
}
|
||||
|
||||
fn duration_clock_format(duration: Duration) -> String {
|
||||
let hours = duration.as_secs() / 3600;
|
||||
let minutes = (duration.as_secs() % 3600) / 60;
|
||||
let seconds = duration.as_secs() % 60;
|
||||
|
||||
if hours > 0 {
|
||||
format!("{hours}:{minutes:02}:{seconds:02}")
|
||||
} else if minutes > 0 {
|
||||
format!("{minutes}:{seconds:02}")
|
||||
} else {
|
||||
format!("{seconds}")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_duration_to_clock_format() {
|
||||
use duration_clock_format as f;
|
||||
assert_eq!("0", f(Duration::from_secs(0)));
|
||||
assert_eq!("59", f(Duration::from_secs(59)));
|
||||
assert_eq!("1:00", f(Duration::from_secs(60)));
|
||||
assert_eq!("10:00", f(Duration::from_secs(600)));
|
||||
assert_eq!("1:00:00", f(Duration::from_secs(3600)));
|
||||
assert_eq!("3:02:01", f(Duration::from_secs(3600 * 3 + 60 * 2 + 1)));
|
||||
assert_eq!("23:59:59", f(Duration::from_secs(3600 * 24 - 1)));
|
||||
assert_eq!("100:00:00", f(Duration::from_secs(3600 * 100)));
|
||||
}
|
||||
}
|
|
@ -4,8 +4,10 @@ pub mod fs;
|
|||
pub mod markdown;
|
||||
pub mod paths;
|
||||
pub mod serde;
|
||||
pub mod size;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub mod test;
|
||||
pub mod time;
|
||||
|
||||
use anyhow::Result;
|
||||
use futures::Future;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue