Skip to main content

litellm_rs/core/function_calling/
processing.rs

1//! Function call processing and tool call handling
2
3use super::executor::FunctionCallingHandler;
4use super::types::ToolCall;
5use crate::core::models::openai::{ChatMessage, MessageContent, MessageRole};
6use crate::utils::error::gateway_error::{GatewayError, Result};
7use serde_json::Value;
8use tracing::{error, warn};
9
10impl FunctionCallingHandler {
11    /// Process tool calls in a chat completion request
12    pub async fn process_tool_calls(&self, tool_calls: &[ToolCall]) -> Result<Vec<ChatMessage>> {
13        let mut tool_responses = Vec::new();
14
15        for tool_call in tool_calls {
16            if tool_call.tool_type != "function" {
17                warn!("Unsupported tool type: {}", tool_call.tool_type);
18                continue;
19            }
20
21            let function_name = &tool_call.function.name;
22
23            if let Some(executor) = self.executors.get(function_name) {
24                // Parse function arguments
25                let arguments: Value = match serde_json::from_str(&tool_call.function.arguments) {
26                    Ok(args) => args,
27                    Err(e) => {
28                        error!("Failed to parse function arguments: {}", e);
29                        return Err(GatewayError::Validation(format!(
30                            "Invalid function arguments: {}",
31                            e
32                        )));
33                    }
34                };
35
36                // Validate arguments
37                if let Err(e) = executor.validate_arguments(&arguments) {
38                    error!("Function argument validation failed: {}", e);
39                    return Err(e);
40                }
41
42                // Execute function
43                match executor.execute(arguments).await {
44                    Ok(result) => {
45                        let tool_message = ChatMessage {
46                            role: MessageRole::Tool,
47                            content: Some(MessageContent::Text(result.to_string())),
48                            name: Some(function_name.clone()),
49                            function_call: None,
50                            tool_calls: None,
51                            tool_call_id: None,
52                            audio: None,
53                        };
54                        tool_responses.push(tool_message);
55                    }
56                    Err(e) => {
57                        error!("Function execution failed: {}", e);
58                        let error_message = ChatMessage {
59                            role: MessageRole::Tool,
60                            content: Some(MessageContent::Text(format!("Error: {}", e))),
61                            name: Some(function_name.clone()),
62                            function_call: None,
63                            tool_calls: None,
64                            tool_call_id: None,
65                            audio: None,
66                        };
67                        tool_responses.push(error_message);
68                    }
69                }
70            } else {
71                warn!("Unknown function: {}", function_name);
72                let error_message = ChatMessage {
73                    role: MessageRole::Tool,
74                    content: Some(MessageContent::Text(format!(
75                        "Unknown function: {}",
76                        function_name
77                    ))),
78                    name: Some(function_name.clone()),
79                    function_call: None,
80                    tool_calls: None,
81                    tool_call_id: None,
82                    audio: None,
83                };
84                tool_responses.push(error_message);
85            }
86        }
87
88        Ok(tool_responses)
89    }
90}