Skip to main content

walrus_core/model/
tool.rs

1//! Tool abstractions for the unified LLM Interfaces
2
3use compact_str::CompactString;
4use schemars::Schema;
5use serde::{Deserialize, Serialize};
6
7/// A tool for the LLM
8#[derive(Debug, Clone, Deserialize, Serialize)]
9pub struct Tool {
10    /// The name of the tool
11    pub name: CompactString,
12
13    /// The description of the tool
14    pub description: CompactString,
15
16    /// The parameters of the tool
17    pub parameters: Schema,
18
19    /// Whether to strictly validate the parameters
20    pub strict: bool,
21}
22
23/// A tool call made by the model
24#[derive(Debug, Clone, Default, Deserialize, Serialize)]
25pub struct ToolCall {
26    /// The ID of the tool call
27    #[serde(default, skip_serializing_if = "CompactString::is_empty")]
28    pub id: CompactString,
29
30    /// The index of the tool call (used in streaming)
31    #[serde(default, skip_serializing)]
32    pub index: u32,
33
34    /// The type of tool (currently only "function")
35    #[serde(default, rename = "type")]
36    pub call_type: CompactString,
37
38    /// The function to call
39    pub function: FunctionCall,
40}
41
42impl ToolCall {
43    /// Merge two tool calls into one
44    pub fn merge(&mut self, call: &Self) {
45        if !call.id.is_empty() {
46            self.id = call.id.clone();
47        }
48        if !call.call_type.is_empty() {
49            self.call_type = call.call_type.clone();
50        }
51        if !call.function.name.is_empty() {
52            self.function.name = call.function.name.clone();
53        }
54        self.function.arguments.push_str(&call.function.arguments);
55    }
56}
57
58/// A function call within a tool call
59#[derive(Debug, Clone, Default, Deserialize, Serialize)]
60pub struct FunctionCall {
61    /// The name of the function to call
62    #[serde(default, skip_serializing_if = "CompactString::is_empty")]
63    pub name: CompactString,
64
65    /// The arguments to pass to the function (JSON string)
66    #[serde(skip_serializing_if = "String::is_empty")]
67    pub arguments: String,
68}
69
70/// Controls which tool is called by the model
71#[derive(Debug, Clone, Deserialize, Serialize, Default)]
72pub enum ToolChoice {
73    /// Model will not call any tool
74    #[serde(rename = "none")]
75    None,
76
77    /// Model can pick between generating a message or calling tools
78    #[serde(rename = "auto")]
79    #[default]
80    Auto,
81
82    /// Model must call one or more tools
83    #[serde(rename = "required")]
84    Required,
85
86    /// Model must call the specified function
87    Function(CompactString),
88}
89
90impl From<&str> for ToolChoice {
91    fn from(value: &str) -> Self {
92        ToolChoice::Function(value.into())
93    }
94}