use serde::{Deserialize, Serialize};
use crate::ir::cache::CacheControl;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct ToolSpec {
pub name: String,
pub description: String,
pub kind: ToolKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cache_control: Option<CacheControl>,
}
impl ToolSpec {
#[must_use]
pub fn function(
name: impl Into<String>,
description: impl Into<String>,
input_schema: serde_json::Value,
) -> Self {
Self {
name: name.into(),
description: description.into(),
kind: ToolKind::Function { input_schema },
cache_control: None,
}
}
#[must_use]
pub fn with_cache_control(mut self, cache: CacheControl) -> Self {
self.cache_control = Some(cache);
self
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ToolKind {
Function {
input_schema: serde_json::Value,
},
WebSearch {
max_uses: Option<u32>,
allowed_domains: Vec<String>,
},
Computer {
display_width: u32,
display_height: u32,
},
TextEditor,
Bash,
CodeExecution,
FileSearch {
vector_store_ids: Vec<String>,
},
CodeInterpreter,
ImageGeneration,
McpConnector {
name: String,
server_url: String,
authorization_token: Option<String>,
},
Memory,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(tag = "mode", rename_all = "snake_case")]
#[non_exhaustive]
pub enum ToolChoice {
#[default]
Auto,
Required,
Specific {
name: String,
},
None,
}