mod io;
mod io_agent_spawn;
#[cfg(test)]
mod io_agent_spawn_test;
mod environment;
mod io_clipboard;
mod io_process_wait;
mod io_stderr_collector;
mod io_streaming;
mod run;
mod runtime;
mod save;
mod time;
mod types;
pub use io_streaming::extract_error_identifier_from_logfile;
pub use io_streaming::extract_error_message_from_logfile;
pub use run::run_with_prompt;
pub use types::{PipelineRuntime, PromptCommand};
pub const SIGTERM_EXIT_CODE: i32 = 143;
#[cfg(test)]
pub use io_agent_spawn_test::run_with_agent_spawn_with_monitor_config;
#[cfg(test)]
use io_agent_spawn::run_with_agent_spawn;
#[cfg(test)]
use crate::agents::JsonParserType;
#[cfg(test)]
use save::build_prompt_archive_filename;
#[cfg(test)]
use crate::config::Config;
#[cfg(test)]
use crate::logger::{Colors, Logger};
#[cfg(test)]
use crate::pipeline::Timer;
#[cfg(test)]
const MAX_PROMPT_SIZE: usize = 200 * 1024;
#[cfg(test)]
fn truncate_prompt_if_needed(prompt: &str, logger: &Logger) -> String {
if prompt.len() <= MAX_PROMPT_SIZE {
return prompt.to_string();
}
let excess = prompt.len() - MAX_PROMPT_SIZE;
logger.warn(&format!(
"Prompt exceeds safe limit ({} bytes > {} bytes), truncating {} bytes",
prompt.len(),
MAX_PROMPT_SIZE,
excess
));
let truncation_markers = [
"\n---\n",
"\n```\n",
"\n<last-output>",
"\nPrevious output:",
];
if let Some(early_result) = truncation_markers.iter().find_map(|marker| {
let marker_pos = prompt.find(marker)?;
let content_start = marker_pos + marker.len();
if content_start >= prompt.len() {
return None;
}
let before_marker = &prompt[..content_start];
let after_marker = &prompt[content_start..];
if after_marker.len() > excess + 100 {
let keep_from = excess + 100;
let truncated_content = &after_marker[keep_from..];
let clean_start = truncated_content.find('\n').map_or(0, |i| i + 1);
Some(format!(
"{}\n[... {} bytes truncated to fit CLI argument limit ...]\n{}",
before_marker,
keep_from + clean_start,
&truncated_content[clean_start..]
))
} else {
None
}
}) {
return early_result;
}
let keep_start = MAX_PROMPT_SIZE / 3;
let keep_end = MAX_PROMPT_SIZE / 3;
let start_part = &prompt[..keep_start];
let end_part = &prompt[prompt.len() - keep_end..];
let start_end = start_part.rfind('\n').map_or(keep_start, |i| i + 1);
let end_start = end_part.find('\n').map_or(0, |i| i + 1);
format!(
"{}\n\n[... {} bytes truncated to fit CLI argument limit ...]\n\n{}",
&prompt[..start_end],
prompt.len() - start_end - (keep_end - end_start),
&end_part[end_start..]
)
}
#[cfg(test)]
mod tests;
#[cfg(test)]
mod sanitize_env_tests;