Skip to main content

llm/
tools.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4#[doc = include_str!("docs/tools.md")]
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
6pub struct ToolDefinition {
7    pub name: String,
8    pub description: String,
9    pub parameters: serde_json::Value,
10    pub server: Option<String>,
11    #[serde(default, skip_serializing_if = "Option::is_none")]
12    pub annotations: Option<ToolAnnotations>,
13}
14
15#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
16#[serde(rename_all = "camelCase")]
17pub struct ToolAnnotations {
18    pub title: Option<String>,
19    pub read_only_hint: Option<bool>,
20    pub destructive_hint: Option<bool>,
21    pub idempotent_hint: Option<bool>,
22    pub open_world_hint: Option<bool>,
23}
24
25impl ToolDefinition {
26    pub fn new(name: impl Into<String>, description: impl Into<String>, parameters: serde_json::Value) -> Self {
27        Self { name: name.into(), description: description.into(), parameters, server: None, annotations: None }
28    }
29
30    pub fn with_server(mut self, server: impl Into<String>) -> Self {
31        self.server = Some(server.into());
32        self
33    }
34
35    pub fn with_annotations(mut self, annotations: impl Into<Option<ToolAnnotations>>) -> Self {
36        self.annotations = annotations.into();
37        self
38    }
39}
40
41impl ToolAnnotations {
42    pub fn read_only() -> Self {
43        Self { read_only_hint: Some(true), ..Self::default() }
44    }
45}
46
47/// Tool call request from the LLM
48#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
49pub struct ToolCallRequest {
50    pub id: String,
51    pub name: String,
52    pub arguments: String,
53}
54
55/// Successful result of a tool call
56#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
57pub struct ToolCallResult {
58    pub id: String,
59    pub name: String,
60    pub arguments: String,
61    pub result: String,
62}
63
64/// Error result of a tool call
65#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
66pub struct ToolCallError {
67    pub id: String,
68    pub name: String,
69    pub arguments: Option<String>,
70    pub error: String,
71}
72
73impl ToolCallError {
74    pub fn from_request(request: &ToolCallRequest, error: impl Into<String>) -> Self {
75        Self {
76            id: request.id.clone(),
77            name: request.name.clone(),
78            arguments: Some(request.arguments.clone()),
79            error: error.into(),
80        }
81    }
82}