tiny_loop/tool/executor/
sequential.rs1use std::collections::HashMap;
2
3use crate::{
4 tool::{Tool, executor::ToolExecutor},
5 types::ToolCall,
6};
7use async_trait::async_trait;
8
9pub struct SequentialExecutor {
34 tools: HashMap<String, Box<dyn Tool + Sync>>,
35}
36
37impl SequentialExecutor {
38 pub fn new() -> Self {
40 Self {
41 tools: HashMap::new(),
42 }
43 }
44}
45
46#[async_trait]
47impl ToolExecutor for SequentialExecutor {
48 fn add(&mut self, name: String, tool: Box<dyn Tool + Sync>) -> Option<Box<dyn Tool + Sync>> {
49 tracing::trace!("Registering tool: {}", name);
50 self.tools.insert(name, tool)
51 }
52
53 async fn execute(&self, calls: Vec<ToolCall>) -> Vec<crate::types::ToolMessage> {
54 tracing::debug!("Executing {} tool calls sequentially", calls.len());
55 let mut results = Vec::new();
56 for call in calls {
57 tracing::debug!("Executing tool '{}'", call.function.name);
58 let message = if let Some(tool) = self.tools.get(&call.function.name) {
59 crate::types::ToolMessage {
60 tool_call_id: call.id.clone(),
61 content: tool.call(call.function.arguments).await,
62 }
63 } else {
64 tracing::debug!("Tool '{}' not found", call.function.name);
65 crate::types::ToolMessage {
66 tool_call_id: call.id,
67 content: format!("Tool '{}' not found", call.function.name),
68 }
69 };
70 results.push(message);
71 }
72 tracing::debug!("Sequential execution completed");
73 results
74 }
75}