1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//! # tool-output-truncate
//!
//! Truncate tool output before adding it to LLM message history.
//!
//! When an agent runs `cat large_file.log`, `ripgrep`, or a database query,
//! the result can be megabytes. Naively appending it to the conversation
//! blows the context window. The standard fix is to keep the head and the
//! tail and replace the middle with an elision marker. This crate gives
//! you that, char-aware (UTF-8 safe) and line-aware, with zero deps.
//!
//! ## Quick example
//!
//! ```
//! use tool_output_truncate::truncate_middle;
//!
//! let big = (0..1000).map(|i| format!("row {i}\n")).collect::<String>();
//! let trimmed = truncate_middle(&big, 200);
//! assert!(trimmed.len() <= 200 + 64); // text + elision marker overhead
//! assert!(trimmed.starts_with("row 0"));
//! assert!(trimmed.contains("truncated"));
//! ```
//!
//! ## Strategies
//!
//! - [`truncate_middle`] - keep half at the start, half at the end.
//! Best default for arbitrary text where head and tail both carry signal
//! (logs, stack traces, file contents).
//! - [`truncate_head`] - keep the first N chars only.
//! Use when the tail is noise (e.g. very long lists where order matters).
//! - [`truncate_tail`] - keep the last N chars only.
//! Use when the head is preamble (e.g. command output with banner lines).
//! - [`truncate_middle_lines`] - line-aware version of `truncate_middle`.
//! Splits at line boundaries so you don't show half a line of JSON.
//!
//! All functions are no-op when the input already fits.
//!
//! ## What it does NOT do
//!
//! - No tokenization. Pass a char cap; if you need token caps use
//! `chars * 4` as a rough Anthropic/OpenAI proxy.
//! - No structured truncation (JSON, YAML, XML). For JSON specifically,
//! parse first and decide which fields to keep.
//! - No summarization. This is byte/char arithmetic only.
pub use ;
pub use truncate_middle_lines;