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: String,
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: impl Into<String>) -> Self {
27 Self {
28 name: name.into(),
29 description: description.into(),
30 parameters: parameters.into(),
31 server: None,
32 annotations: None,
33 }
34 }
35
36 pub fn with_server(mut self, server: impl Into<String>) -> Self {
37 self.server = Some(server.into());
38 self
39 }
40
41 pub fn with_annotations(mut self, annotations: impl Into<Option<ToolAnnotations>>) -> Self {
42 self.annotations = annotations.into();
43 self
44 }
45}
46
47impl ToolAnnotations {
48 pub fn read_only() -> Self {
49 Self { read_only_hint: Some(true), ..Self::default() }
50 }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
55pub struct ToolCallRequest {
56 pub id: String,
57 pub name: String,
58 pub arguments: String,
59}
60
61#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
63pub struct ToolCallResult {
64 pub id: String,
65 pub name: String,
66 pub arguments: String,
67 pub result: String,
68}
69
70#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
72pub struct ToolCallError {
73 pub id: String,
74 pub name: String,
75 pub arguments: Option<String>,
76 pub error: String,
77}
78
79impl ToolCallError {
80 pub fn from_request(request: &ToolCallRequest, error: impl Into<String>) -> Self {
81 Self {
82 id: request.id.clone(),
83 name: request.name.clone(),
84 arguments: Some(request.arguments.clone()),
85 error: error.into(),
86 }
87 }
88}