use typesafe::{ChoiceOf, Client, NoulAnswer, Rubric, RubricChoice, ScoreAnswer};
#[derive(Debug, Rubric)]
struct Triage {
#[noul(
"The message conveys urgency",
yes = "A deadline, a threat to leave, or \"ASAP\"",
no = "Routine, no time pressure"
)]
is_urgent: NoulAnswer,
#[choice("Which team should handle this")]
department: ChoiceOf<Department>,
#[score(
"How frustrated the customer appears",
levels = ["Calm", "Frustrated but civil", "Very angry"]
)]
frustration: ScoreAnswer,
#[noul]
#[rubric(rename = "wants_refund")]
refund: f64, }
#[derive(Debug, Clone, Copy, PartialEq, Eq, RubricChoice)]
enum Department {
#[option("Payment or subscription issues")]
Billing,
Technical,
#[option("Pricing or account questions")]
Sales,
}
#[tokio::main]
async fn main() -> typesafe::Result<()> {
println!(
"{}",
typesafe::serde_json::to_string_pretty(&Triage::questions()).expect("questions encode")
);
let client = Client::from_env()?;
let triage: Triage = client
.ask("The payout failed again, third time this month. I'm done waiting. Refund me.")
.await?;
println!(
"department {:?} (confidence {:.2})",
*triage.department,
triage.department.confidence()
);
println!("frustration {:.2}", triage.frustration.score);
println!("urgent {}", triage.is_urgent.is_yes(0.8));
println!("refund {:.2}", triage.refund);
match *triage.department {
Department::Billing if triage.frustration.score >= 1.5 => println!("→ payments on-call"),
Department::Billing => println!("→ billing queue"),
Department::Technical => println!("→ engineering triage"),
Department::Sales => println!("→ account manager"),
}
Ok(())
}