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#[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#[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#[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}