use std::convert::Infallible;
use crate::rules::{Rule, RuleOutput, a17_conventional_commit_message::ConventionalCommitMessage};
use rig::{completion::ToolDefinition, tool::Tool};
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Debug, Deserialize)]
pub struct ValidateConventionalCommitArgs {
pub message: String,
}
#[derive(Debug, Serialize)]
pub struct ValidateConventionalCommitResult {
pub valid: bool,
pub error: Option<String>,
}
#[derive(Default)]
pub struct ValidateConventionalCommit;
impl Tool for ValidateConventionalCommit {
const NAME: &'static str = "validate_conventional_commit";
type Error = Infallible;
type Args = ValidateConventionalCommitArgs;
type Output = ValidateConventionalCommitResult;
async fn definition(&self, _prompt: String) -> ToolDefinition {
serde_json::from_value(json!({
"name": Self::NAME,
"description": "Validate a Conventional Commit message header and basic style.",
"parameters": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The commit message to validate (header and optional body)."
}
},
"required": ["message"]
}
}))
.expect("valid tool definition")
}
async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
let rule = ConventionalCommitMessage::new(None).with_message(args.message);
let result = match rule.check() {
Ok(RuleOutput::Success) => ValidateConventionalCommitResult {
valid: true,
error: None,
},
Ok(RuleOutput::Exception(msg)) => ValidateConventionalCommitResult {
valid: false,
error: Some(msg),
},
Err(err) => ValidateConventionalCommitResult {
valid: false,
error: Some(format!("Internal error: {err:?}")),
},
};
Ok(result)
}
}