use typesafe::{Client, Noul, Questions};
const CHECKS: [(&str, &str, &str, f64); 4] = [
(
"harassment",
"The text attacks, insults or demeans a person",
"Directed at someone, not just angry in general",
0.7,
),
(
"self_promotion",
"The text exists mainly to advertise something",
"A link, a discount code, or a pitch with no other content",
0.8,
),
(
"off_topic",
"The text is unrelated to the product being reviewed",
"About shipping, the seller, or something else entirely",
0.6,
),
(
"needs_human",
"The text describes a situation a moderator should look at",
"Threats, self-harm, or anything legally sensitive",
0.3, ),
];
const REVIEW: &str = "Shipping took two weeks and the box was crushed. The lamp itself is fine, \
but whoever packed it clearly did not care. Use CODE20 at checkout on my \
site for a better one.";
#[tokio::main]
async fn main() -> typesafe::Result<()> {
let client = Client::from_env()?;
let mut questions = Questions::new();
for (name, instructions, yes_means, _) in CHECKS {
questions.insert(name, Noul::new(instructions).when_true(yes_means));
}
let res = client.system_one(REVIEW, questions).await?;
let mut flagged = Vec::new();
for (name, _, _, threshold) in CHECKS {
let answer = res.noul(name).expect("asked, so answered");
let verdict = if answer.is_yes(threshold) {
flagged.push(name);
"FLAG"
} else {
"ok"
};
println!("{name:<15} {:.3} (>= {threshold}) {verdict}", answer.noul);
}
if let Some((name, answer)) = res.nouls().max_by(|a, b| a.1.noul.total_cmp(&b.1.noul)) {
println!("strongest signal: {name} at {:.3}", answer.noul);
}
println!(
"{}",
match flagged.as_slice() {
[] => "publish".to_owned(),
flags => format!("hold for review: {}", flags.join(", ")),
}
);
Ok(())
}