use crate::event_renderer::TIMER_WAKEUP_CTX_PREFIX;
use crate::markdown_render::markdown_block_with_osc8;
pub(super) const COMPLETED_AGENT_RESPONSE_PREFIX: &str = "◆ ";
pub(super) const STREAMING_AGENT_RESPONSE_PREFIX: &str = "◇ ";
pub(super) const AGENT_MESSAGE_NAME_MAX_COLUMNS: usize = 48;
pub(super) const AGENT_MESSAGE_NAME_MAX_BYTES: usize = 192;
pub(super) const QUEUED_PROJECTION_WINDOW_BYTES: usize = 16 * 1024;
pub(super) fn bounded_queued_line_start(text: &str) -> &str {
let mut end = text.len().min(QUEUED_PROJECTION_WINDOW_BYTES);
while !text.is_char_boundary(end) {
end -= 1;
}
let window = &text[..end];
window
.find(['\n', '\r'])
.map_or(window, |line_end| &window[..line_end])
}
pub(super) fn bounded_queued_line_end(text: &str) -> &str {
let mut start = text.len().saturating_sub(QUEUED_PROJECTION_WINDOW_BYTES);
while !text.is_char_boundary(start) {
start += 1;
}
let window = &text[start..];
window
.rfind(['\n', '\r'])
.map_or(window, |line_end| &window[line_end + 1..])
}
pub(super) fn queued_prompt_projection(
theme: &tau_themes::Theme,
osc8_links: bool,
prefix: tau_cli_term::StyledText,
text: &str,
) -> tau_cli_term::TwoLineElision {
let styled_prompt = |value| {
markdown_block_with_osc8(
theme,
tau_themes::names::USER_PROMPT_QUEUED,
value,
osc8_links,
)
.content
};
let styled_marker = |value| {
markdown_block_with_osc8(
theme,
tau_themes::names::USER_PROMPT_QUEUED_MARKER,
value,
osc8_links,
)
.content
};
let unabridged = (text.len() <= QUEUED_PROJECTION_WINDOW_BYTES).then(|| {
let mut prompt = styled_prompt(text);
for span in styled_marker(" (queued)").spans() {
prompt.push(span.clone());
}
prompt
});
tau_cli_term::TwoLineElision {
prefix,
first: styled_prompt(bounded_queued_line_start(text)),
last: styled_prompt(bounded_queued_line_end(text)),
first_omissions: vec![styled_prompt(" ┄"), styled_prompt("┄")],
last_omissions: vec![styled_prompt("┄ "), styled_prompt("┄")],
labels: vec![
styled_marker(" (queued)"),
styled_marker(" (q)"),
styled_marker("q"),
],
unabridged,
}
}
pub(super) fn timer_wakeup_ctx(ctx_id: Option<&str>) -> Option<(&str, &str)> {
let rest = ctx_id?.strip_prefix(TIMER_WAKEUP_CTX_PREFIX)?;
rest.rsplit_once(':')
}
pub(super) fn timer_wakeup_summary(timer_id: &str, text: Option<&str>) -> String {
let Some(text) = text else {
return format!("Timer `{timer_id}` woke this agent");
};
let trimmed = text.trim();
let timer_prefix = format!("Timer `{timer_id}` fired:");
let message = trimmed
.strip_prefix(&timer_prefix)
.map(str::trim)
.unwrap_or(trimmed);
if message.is_empty() {
format!("Timer `{timer_id}` woke this agent")
} else {
format!("Timer `{timer_id}` woke this agent: {message}")
}
}