Make the Rust client the sole app
This commit is contained in:
1 parent
a8602c1626
commit
d8bb1699a8
230 files changed
+762
-27300
No files matched your search
@@ -0,0 +1,93 @@
|
||||
/// The default bound on a verbatim block -- a tool call's input or its
|
||||
/// output. Short, because this text is a machine's and the reader is
|
||||
/// looking for one line of it.
|
||||
pub const VERBATIM_LINES: usize = 80;
|
||||
pub const VERBATIM_BYTES: usize = 4096;
|
||||
|
||||
pub const MESSAGE_LINES: usize = 200;
|
||||
pub const MESSAGE_BYTES: usize = 16 * 1024;
|
||||
|
||||
const _: () = assert!(VERBATIM_LINES > 0 && VERBATIM_BYTES > 0);
|
||||
const _: () = assert!(MESSAGE_LINES > 0 && MESSAGE_BYTES > 0);
|
||||
|
||||
/// `text` cut to `max_lines` lines and `max_bytes` bytes, with the line
|
||||
/// count it was cut *from*; `None` when the whole of it fits.
|
||||
pub fn cut(text: &str, max_lines: usize, max_bytes: usize) -> Option<(&str, usize)> {
|
||||
debug_assert!(
|
||||
max_lines > 0 && max_bytes > 0,
|
||||
"a cap of nothing shows an empty block and a 'Show all' for every value there is",
|
||||
);
|
||||
let by_lines = text
|
||||
.char_indices()
|
||||
.filter(|(_, c)| *c == '\n')
|
||||
.nth(max_lines - 1)
|
||||
.map(|(i, _)| i);
|
||||
let by_bytes = (text.len() > max_bytes).then(|| {
|
||||
let mut end = max_bytes;
|
||||
// Back up to a character boundary: a cut inside a multi-byte
|
||||
// character panics on the slice below, and a transcript is full of
|
||||
// them.
|
||||
while !text.is_char_boundary(end) {
|
||||
end -= 1;
|
||||
}
|
||||
end
|
||||
});
|
||||
let cut = match (by_lines, by_bytes) {
|
||||
(Some(a), Some(b)) => a.min(b),
|
||||
(a, b) => a.or(b)?,
|
||||
};
|
||||
Some((&text[..cut], text.lines().count()))
|
||||
}
|
||||
|
||||
pub fn show_all_label(lines: usize) -> String {
|
||||
format!("Show all {lines} lines")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn text_under_both_bounds_is_not_cut() {
|
||||
assert_eq!(cut("one\ntwo\nthree", 80, 4096), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_line_bound_cuts_at_a_line_boundary() {
|
||||
let text = "a\nb\nc\nd\n";
|
||||
let (shown, lines) = cut(text, 2, 4096).expect("four lines is over a bound of two");
|
||||
assert_eq!(shown, "a\nb");
|
||||
assert_eq!(
|
||||
lines, 4,
|
||||
"the count is the whole text's, not the shown part's"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_byte_bound_cuts_one_long_line() {
|
||||
let text = "x".repeat(5000);
|
||||
let (shown, lines) = cut(&text, 80, 4096).expect("5000 bytes is over a bound of 4096");
|
||||
assert_eq!(shown.len(), 4096);
|
||||
assert_eq!(lines, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_tighter_of_the_two_bounds_wins() {
|
||||
let text = "aaaa\n".repeat(100);
|
||||
let (shown, _) = cut(&text, 80, 100).expect("over both");
|
||||
assert_eq!(shown.len(), 100, "the byte bound is the tighter one here");
|
||||
let (shown, _) = cut(&text, 4, 4096).expect("over the line bound");
|
||||
assert_eq!(shown, "aaaa\naaaa\naaaa\naaaa");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_cut_inside_a_multibyte_character_backs_up_to_the_boundary() {
|
||||
let text = "é".repeat(100);
|
||||
let (shown, _) = cut(&text, 80, 11).expect("200 bytes is over a bound of 11");
|
||||
assert_eq!(
|
||||
shown,
|
||||
"é".repeat(5),
|
||||
"11 bytes lands mid-character; 10 is the cut"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user