repositories / smith
smith
There are many coding harnesses - but this one is fast
owned by admin
smith/src/tool.rs
Raw//! Provider-neutral tool contracts and cancellation (`SMH-SPEC-SPEC0001`).
use crate::id::ToolCallId;
use crate::structured::{ToolArguments, ToolSchema};
use serde::{Deserialize, Serialize};
/// Tool specification (provider-neutral definition).
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct ToolMetadata {
/// Tool name.
pub name: String,
/// Human-readable description.
pub description: String,
/// Input schema for validation.
pub input_schema: ToolSchema,
}
impl ToolMetadata {
/// Metadata with an empty object schema.
#[must_use]
pub fn new<N: Into<String>, D: Into<String>>(name: N, description: D) -> Self {
Self {
name: name.into(),
description: description.into(),
input_schema: ToolSchema::empty_object(),
}
}
/// Replace the input schema.
/// Argument data cannot stand in for a schema.
///
/// ```compile_fail
/// use smith::{ToolArguments, ToolMetadata};
/// ToolMetadata::new("read", "Read a file").with_schema(ToolArguments::empty_object());
/// ```
#[must_use]
pub fn with_schema(mut self, schema: ToolSchema) -> Self {
self.input_schema = schema;
self
}
}
/// Tool call issued by the agent.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct ToolCall {
/// Call identifier.
pub call_id: ToolCallId,
/// Tool name.
pub name: String,
/// Arguments passed to the tool.
pub input: ToolArguments,
}
/// Tool execution result.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct ToolResult {
/// Matching call identifier.
pub call_id: ToolCallId,
/// Whether the tool succeeded.
pub ok: bool,
/// Output text or serialized result.
pub output: String,
}
/// Shared, thread-safe cancellation handle for active effects.
/// Clone into a running effect; `cancel` from the owner thread.
#[derive(Clone, Debug, Default)]
pub struct CancelHandle {
flag: std::sync::Arc<std::sync::atomic::AtomicBool>,
}
impl CancelHandle {
/// A handle that starts uncancelled.
#[must_use]
pub fn new() -> Self {
Self::default()
}
/// Request cancellation; observed by the owning effect.
pub fn cancel(&self) {
self.flag.store(true, std::sync::atomic::Ordering::Release);
}
/// Whether cancellation was requested.
#[must_use]
pub fn is_cancelled(&self) -> bool {
self.flag.load(std::sync::atomic::Ordering::Acquire)
}
}