use crate::provider::{ContentPart, Message};
use crate::session::Session;
pub(super) type PendingToolCall = (String, String, String);
pub(super) fn compose_system_prompt(base: &str, session: &Session) -> String {
let log = match crate::session::tasks::TaskLog::for_session(&session.id) {
Ok(l) => l,
Err(_) => return base.to_string(),
};
let events = log.read_all_blocking().unwrap_or_default();
let state = crate::session::tasks::TaskState::from_log(&events);
match crate::session::tasks::governance_block(&state) {
Some(block) => format!("{base}\n\n{block}"),
None => base.to_string(),
}
}
pub(super) fn collect_tool_calls(message: &Message) -> Vec<PendingToolCall> {
message
.content
.iter()
.filter_map(extract_tool_call)
.collect()
}
pub(super) fn response_text(message: &Message) -> String {
message
.content
.iter()
.filter_map(extract_text)
.collect::<Vec<_>>()
.join("\n")
}
fn extract_tool_call(part: &ContentPart) -> Option<PendingToolCall> {
match part {
ContentPart::ToolCall {
id,
name,
arguments,
..
} => Some((id.clone(), name.clone(), arguments.clone())),
_ => None,
}
}
fn extract_text(part: &ContentPart) -> Option<String> {
match part {
ContentPart::Text { text } => Some(text.clone()),
_ => None,
}
}