agentvet 0.1.0

Validate LLM-generated tool args before execution. Throws a structured ToolArgError with LLM-friendly retry hints when the model hallucinates wrong types or missing fields.
Documentation
use thiserror::Error;

/// One concrete schema violation.
#[derive(Debug, Clone)]
pub struct ToolArgIssue {
    /// JSON pointer to the offending field, e.g. `/city` or `/units`.
    pub pointer: String,
    /// Short human-readable description, e.g. `"required property missing"`.
    pub message: String,
}

/// Structured error returned when LLM-supplied tool args fail validation.
#[derive(Debug, Clone, Error)]
#[error("tool args invalid: {} issue(s)", issues.len())]
pub struct ToolArgError {
    /// All discovered issues (validation does not short-circuit).
    pub issues: Vec<ToolArgIssue>,
}

impl ToolArgError {
    /// Render a short, action-oriented hint suitable for sending back to the
    /// model so it can fix its tool call on the next turn.
    ///
    /// Format:
    /// ```text
    /// Tool call rejected. Fix and try again:
    ///   - /city: required property missing
    ///   - /units: must be one of: ["c", "f"]
    /// ```
    pub fn for_llm(&self) -> String {
        let mut s = String::from("Tool call rejected. Fix and try again:\n");
        for i in &self.issues {
            s.push_str("  - ");
            if !i.pointer.is_empty() {
                s.push_str(&i.pointer);
                s.push_str(": ");
            }
            s.push_str(&i.message);
            s.push('\n');
        }
        s.trim_end().to_string()
    }
}