use oxi_ai::{ContentBlock, ToolCall, TextContent, ToolResultMessage};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
pub fn extract_tool_calls(message: &oxi_ai::AssistantMessage) -> Vec<ToolCall> {
let mut tool_calls = Vec::new();
for block in &message.content {
if let ContentBlock::ToolCall(tc) = block {
tool_calls.push(tc.clone());
}
}
tool_calls
}
pub fn create_tool_result_message(finalized: &FinalizedToolCall) -> ToolResultMessage {
let content_blocks = if let Some(ref blocks) = finalized.result.content_blocks {
blocks.clone()
} else {
vec![ContentBlock::Text(TextContent::new(finalized.result.output.clone()))]
};
ToolResultMessage::new(
finalized.tool_call.id.clone(),
&finalized.tool_call.name,
content_blocks,
)
}
pub fn should_terminate_batch(finalized_calls: &[FinalizedToolCall]) -> bool {
if finalized_calls.is_empty() {
return false;
}
finalized_calls.iter().all(|f| f.result.terminate)
}
pub fn should_stop_after_turn(
_messages: &[oxi_ai::Message],
_assistant_message: &oxi_ai::AssistantMessage,
max_iterations: usize,
external_stop: &Arc<AtomicBool>,
turn_number: usize,
) -> bool {
if external_stop.load(Ordering::SeqCst) {
return true;
}
if turn_number >= max_iterations {
return true;
}
false
}
use crate::AgentToolResult;
pub struct FinalizedToolCall {
pub tool_call: oxi_ai::ToolCall,
pub result: AgentToolResult,
pub is_error: bool,
}