use super::{BlockKind, Transcript};
use saya_agent::AgentEvent;
pub(crate) fn is_group_member(event: &AgentEvent) -> bool {
matches!(
event,
AgentEvent::ToolRequested { .. } | AgentEvent::ToolCompleted { .. }
)
}
pub(crate) fn buffer_tool_event(
transcript: &mut Transcript,
event: AgentEvent,
) -> Option<AgentEvent> {
match event {
AgentEvent::ToolRequested {
name,
arguments,
effect,
} => {
transcript.buffer_tool_request(name, arguments, effect);
None
}
AgentEvent::ToolCompleted { name, summary } => {
if transcript.buffer_tool_completion(&name, &summary) {
None
} else {
transcript.push(
BlockKind::Tool,
crate::render::tool_groups::live_completion_line(&name, &summary),
);
None
}
}
other => Some(other),
}
}
pub(crate) fn flush_tool_buffer(transcript: &mut Transcript) {
transcript.flush_tool_buffer(
request_lines,
crate::render::tool_groups::live_completion_line,
);
}
fn request_lines(name: &str, arguments: &serde_json::Value) -> Vec<String> {
if let Some(call) = crate::agent::tools::sql_tool_call(name, arguments) {
let header = match &call.target {
Some(t) => format!("SQL · {t}"),
None => "SQL".to_string(),
};
let body = call
.sql
.lines()
.map(|l| format!(" {l}"))
.collect::<Vec<_>>()
.join("\n");
return vec![format!("{header}\n{body}")];
}
vec![request_line(name, arguments)]
}
pub(crate) fn request_line(name: &str, arguments: &serde_json::Value) -> String {
if let Some(call) = crate::agent::tools::sql_tool_call(name, arguments) {
let header = match &call.target {
Some(t) => format!("SQL · {t}"),
None => "SQL".to_string(),
};
let body = call
.sql
.lines()
.map(|l| format!(" {l}"))
.collect::<Vec<_>>()
.join("\n");
return format!("{header}\n{body}");
}
match tool_call_detail(name, arguments) {
Some(detail) => format!("→ {name}: {detail}"),
None => format!("→ {name}"),
}
}
pub(crate) fn tool_call_detail(name: &str, arguments: &serde_json::Value) -> Option<String> {
crate::agent::tools::tool_call_detail(name, arguments)
}
pub(crate) fn apply_tool_edge(transcript: &mut Transcript, event: AgentEvent) -> bool {
match event {
AgentEvent::ToolRequested {
name, arguments, ..
} => {
transcript.push(BlockKind::Tool, request_line(&name, &arguments));
true
}
AgentEvent::ToolCompleted { name, summary } => {
transcript.push(
BlockKind::Tool,
crate::render::tool_groups::live_completion_line(&name, &summary),
);
true
}
AgentEvent::ToolDenied { name, reason } => {
transcript.push(BlockKind::System, format!("✗ {name} denied: {reason}"));
true
}
_ => false,
}
}