use replysieve::{Checker, Comment, Level, Verdict};
use rmcp::handler::server::wrapper::{Json, Parameters};
use rmcp::{ErrorData, ServiceExt, tool, tool_router};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, JsonSchema)]
pub(crate) struct CheckComment {
pub text: String,
pub title: Option<String>,
pub description: Option<String>,
pub parent: Option<String>,
pub level: Option<Level>,
#[serde(default)]
pub recent: Vec<String>,
}
impl CheckComment {
pub fn comment(&self) -> Comment {
Comment {
text: self.text.clone(),
title: self.title.clone(),
description: self.description.clone(),
parent: self.parent.clone(),
}
}
}
#[derive(Deserialize, JsonSchema)]
pub(crate) struct CheckBatch {
pub comments: Vec<Comment>,
pub level: Option<Level>,
#[serde(default)]
pub recent: Vec<String>,
}
#[derive(Serialize, JsonSchema)]
pub(crate) struct Verdicts {
pub verdicts: Vec<Verdict>,
}
pub(crate) fn at(checker: &Checker, level: Option<Level>) -> Checker {
match level {
Some(l) => checker.clone().at_level(l),
None => checker.clone(),
}
}
struct Server {
checker: Checker,
}
fn failed(e: replysieve::Error) -> ErrorData {
ErrorData::invalid_request(e.to_string(), None)
}
#[tool_router(server_handler)]
impl Server {
#[tool(
name = "check_comment",
description = "Judge one comment: approve, reject or needs_review, with a reason, confidence, level and model."
)]
async fn check_comment(
&self,
Parameters(p): Parameters<CheckComment>,
) -> Result<Json<Verdict>, ErrorData> {
let v = at(&self.checker, p.level)
.check(&p.comment(), &p.recent)
.await
.map_err(failed)?;
Ok(Json(v))
}
#[tool(
name = "check_batch",
description = "Judge many comments at once. Returns one verdict per comment, in input order."
)]
async fn check_batch(
&self,
Parameters(p): Parameters<CheckBatch>,
) -> Result<Json<Verdicts>, ErrorData> {
let verdicts = at(&self.checker, p.level)
.check_batch(&p.comments, &p.recent)
.await
.map_err(failed)?;
Ok(Json(Verdicts { verdicts }))
}
}
pub async fn serve(checker: Checker) -> anyhow::Result<()> {
let running = Server { checker }.serve(rmcp::transport::stdio()).await?;
running.waiting().await?;
Ok(())
}