swiftide_core/chat_completion/
tools.rs1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6#[non_exhaustive]
7pub enum ToolOutput {
8    Text(String),
10
11    Fail(String),
13    Stop,
15}
16
17impl ToolOutput {
18    pub fn content(&self) -> Option<&str> {
19        match self {
20            ToolOutput::Fail(s) | ToolOutput::Text(s) => Some(s),
21            _ => None,
22        }
23    }
24}
25
26impl<T: AsRef<str>> From<T> for ToolOutput {
27    fn from(s: T) -> Self {
28        ToolOutput::Text(s.as_ref().to_string())
29    }
30}
31
32impl std::fmt::Display for ToolOutput {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match self {
35            ToolOutput::Text(value) => write!(f, "{value}"),
36            ToolOutput::Fail(value) => write!(f, "Tool call failed: {value}"),
37            ToolOutput::Stop => write!(f, "Stop"),
38        }
39    }
40}
41
42#[derive(Clone, Debug, Builder, PartialEq, Serialize, Deserialize)]
44#[builder(setter(into, strip_option))]
45pub struct ToolCall {
46    id: String,
47    name: String,
48    #[builder(default)]
49    args: Option<String>,
50}
51
52impl std::hash::Hash for &ToolCall {
54    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
55        self.name.hash(state);
56        self.args.hash(state);
57    }
58}
59
60impl std::fmt::Display for ToolCall {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        write!(
63            f,
64            "{id}#{name} {args}",
65            id = self.id,
66            name = self.name,
67            args = self.args.as_deref().unwrap_or("")
68        )
69    }
70}
71
72impl ToolCall {
73    pub fn builder() -> ToolCallBuilder {
74        ToolCallBuilder::default()
75    }
76
77    pub fn id(&self) -> &str {
78        &self.id
79    }
80
81    pub fn name(&self) -> &str {
82        &self.name
83    }
84
85    pub fn args(&self) -> Option<&str> {
86        self.args.as_deref()
87    }
88}
89
90#[derive(Clone, Debug, Hash, Eq, PartialEq, Default, Builder)]
94#[builder(setter(into))]
95pub struct ToolSpec {
96    pub name: String,
98    pub description: String,
100
101    #[builder(default)]
102    pub parameters: Vec<ParamSpec>,
104}
105
106impl ToolSpec {
107    pub fn builder() -> ToolSpecBuilder {
108        ToolSpecBuilder::default()
109    }
110}
111
112#[derive(Clone, Debug, Hash, Eq, PartialEq, Default, strum_macros::AsRefStr)]
113#[strum(serialize_all = "camelCase")]
114pub enum ParamType {
115    #[default]
116    String,
117    Number,
118    Boolean,
119    Array,
120    }
124
125#[derive(Clone, Debug, Hash, Eq, PartialEq, Builder)]
127#[builder(setter(into))]
128pub struct ParamSpec {
129    pub name: String,
131    pub description: String,
133    #[builder(default)]
135    pub ty: ParamType,
136    #[builder(default = true)]
140    pub required: bool,
141}
142
143impl ParamSpec {
144    pub fn builder() -> ParamSpecBuilder {
145        ParamSpecBuilder::default()
146    }
147}