ferrin_spec/language_model/
tool.rs1use serde::Deserialize;
4use serde::Serialize;
5
6use crate::json::JsonObject;
7use crate::json::JsonValue;
8use crate::shared::ProviderOptions;
9use crate::shared::ToolName;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13#[serde(tag = "type", rename_all = "lowercase")]
14#[non_exhaustive]
15pub enum ToolDefinition {
16 Function {
19 name: ToolName,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 description: Option<String>,
24 input_schema: JsonValue,
26 #[serde(default, skip_serializing_if = "Option::is_none")]
28 strict: Option<bool>,
29 #[serde(default, skip_serializing_if = "Vec::is_empty")]
31 input_examples: Vec<JsonObject>,
32 #[serde(default, skip_serializing_if = "Option::is_none")]
34 provider_options: Option<ProviderOptions>,
35 },
36 Provider {
39 id: String,
41 name: ToolName,
43 #[serde(default)]
45 args: JsonObject,
46 },
47}
48
49impl ToolDefinition {
50 #[must_use]
52 pub fn function(
53 name: impl Into<ToolName>,
54 description: Option<String>,
55 input_schema: JsonValue,
56 ) -> Self {
57 Self::Function {
58 name: name.into(),
59 description,
60 input_schema,
61 strict: None,
62 input_examples: Vec::new(),
63 provider_options: None,
64 }
65 }
66
67 #[must_use]
69 pub fn provider(id: impl Into<String>, name: impl Into<ToolName>, args: JsonObject) -> Self {
70 Self::Provider {
71 id: id.into(),
72 name: name.into(),
73 args,
74 }
75 }
76
77 #[must_use]
79 pub fn name(&self) -> &ToolName {
80 match self {
81 Self::Function { name, .. } | Self::Provider { name, .. } => name,
82 }
83 }
84
85 #[must_use]
87 pub fn is_provider_tool(&self) -> bool {
88 matches!(self, Self::Provider { .. })
89 }
90}