use serde::{Deserialize, Serialize};
pub const NON_STRING_TOOL_RESULT_ERROR: &str = "Tool results must be returned as plain strings. Structured JSON or table results are not supported.";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ToolOverflowMode {
Truncate,
Page,
}
impl ToolOverflowMode {
pub fn parse(value: &str) -> Option<Self> {
match value.trim() {
"truncate" => Some(Self::Truncate),
"page" => Some(Self::Page),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeInvocationResult {
pub content: String,
pub overflow_mode: Option<ToolOverflowMode>,
pub template_hint: Option<String>,
pub content_bytes: usize,
pub content_lines: usize,
}
impl RuntimeInvocationResult {
pub fn from_content_parts(
content: String,
overflow_mode: Option<ToolOverflowMode>,
template_hint: Option<String>,
) -> Self {
let normalized = normalize_text(&content);
let content_bytes = normalized.len();
let content_lines = split_lines(&normalized).len();
Self {
content,
overflow_mode,
template_hint,
content_bytes,
content_lines,
}
}
pub fn plain(content: String) -> Self {
Self::from_content_parts(content, None, None)
}
}
fn normalize_text(text: &str) -> String {
text.replace("\r\n", "\n").replace('\r', "\n")
}
fn split_lines(text: &str) -> Vec<&str> {
if text.is_empty() {
Vec::new()
} else {
text.split('\n').collect()
}
}