#[non_exhaustive]pub struct Response {
pub model: String,
pub answers: IndexMap<String, Answer>,
pub usage: TokenUsage,
}Expand description
What one request came back with: an Answer per question, under the id the question had.
use typesafe_jev::{Answer, Response};
let response: Response = serde_json::from_str(r#"{
"model": "jev-1.13.0",
"answers": {
"is_urgent": {"type": "noul", "noul": 0.95},
"department": {"type": "choice", "choice": "billing", "confidence": 0.81,
"probabilities": {"billing": 0.88, "technical": 0.12, "sales": 0.0}}
},
"usage": {"input_tokens": 318, "output_tokens": 34}
}"#)?;
assert_eq!(response.noul("is_urgent").map(|answer| answer.noul), Some(0.95));
let department = response.choice("department").expect("asked as a choice");
assert_eq!((department.choice.as_str(), department.probabilities["technical"]), ("billing", 0.12));
assert!(response.score("department").is_none(), "it is there, but it is not a score");
assert!(matches!(response.answers["is_urgent"], Answer::Noul(_)));Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.model: StringThe model that performed the evaluation: the release that an alias like jev-latest
stood for.
answers: IndexMap<String, Answer>One answer per question, keyed and ordered as the API returned them.
usage: TokenUsageThe tokens this request used.
Implementations§
Source§impl Response
impl Response
Sourcepub fn noul(&self, id: &str) -> Option<&NoulAnswer>
pub fn noul(&self, id: &str) -> Option<&NoulAnswer>
The answer under id, if there is one and it answers a Noul.
Examples found in repository?
examples/ask.rs (line 68)
20fn main() -> Result<(), Error> {
21 let client = Client::from_env(Config::default())?;
22
23 let ticket = Ticket {
24 customer_plan: "business",
25 message: "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. \
26 I'm losing sales. Please help ASAP.",
27 };
28 let questions = Questions::new()
29 .with(
30 "department",
31 Choice::new(
32 "Which team should handle the `message`?",
33 [
34 ("billing", "Payment or subscription issues"),
35 ("technical", "Bugs or integration problems"),
36 ("sales", "Pricing or account questions"),
37 ],
38 ),
39 )
40 .with(
41 "frustration",
42 Score::new(
43 "How frustrated the customer appears",
44 ["Calm, just stating facts", "Frustrated but civil", "Very angry, strong language"],
45 ),
46 )
47 .with("is_urgent", Noul::new("The message conveys urgency or time-sensitivity"));
48
49 let response = match client.ask(&ticket, &questions) {
50 Ok(response) => response,
51 // Too much state for one request: a real caller would split it and ask again.
52 Err(Error::TokenLimit(message)) => {
53 eprintln!("request too large: {message}");
54 return Ok(());
55 }
56 Err(other) => return Err(other),
57 };
58
59 if let Some(department) = response.choice("department") {
60 println!("department: {} (confidence {:.2})", department.choice, department.confidence);
61 for (option, probability) in &department.probabilities {
62 println!(" {option}: {probability:.2}");
63 }
64 }
65 if let Some(frustration) = response.score("frustration") {
66 println!("frustration: {:.2} of {} (confidence {:.2})", frustration.score, frustration.legend.len() - 1, frustration.confidence);
67 }
68 if let Some(urgent) = response.noul("is_urgent") {
69 println!("urgent: p={:.2}", urgent.noul);
70 }
71
72 let usage = client.usage();
73 println!(
74 "{}: {} request(s), {} retries, {} input tokens, ~${:.6}",
75 response.model,
76 usage.requests(),
77 usage.retries(),
78 usage.input_tokens(),
79 usage.cost_usd()
80 );
81 Ok(())
82}Sourcepub fn choice(&self, id: &str) -> Option<&ChoiceAnswer>
pub fn choice(&self, id: &str) -> Option<&ChoiceAnswer>
The answer under id, if there is one and it answers a Choice.
Examples found in repository?
examples/ask.rs (line 59)
20fn main() -> Result<(), Error> {
21 let client = Client::from_env(Config::default())?;
22
23 let ticket = Ticket {
24 customer_plan: "business",
25 message: "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. \
26 I'm losing sales. Please help ASAP.",
27 };
28 let questions = Questions::new()
29 .with(
30 "department",
31 Choice::new(
32 "Which team should handle the `message`?",
33 [
34 ("billing", "Payment or subscription issues"),
35 ("technical", "Bugs or integration problems"),
36 ("sales", "Pricing or account questions"),
37 ],
38 ),
39 )
40 .with(
41 "frustration",
42 Score::new(
43 "How frustrated the customer appears",
44 ["Calm, just stating facts", "Frustrated but civil", "Very angry, strong language"],
45 ),
46 )
47 .with("is_urgent", Noul::new("The message conveys urgency or time-sensitivity"));
48
49 let response = match client.ask(&ticket, &questions) {
50 Ok(response) => response,
51 // Too much state for one request: a real caller would split it and ask again.
52 Err(Error::TokenLimit(message)) => {
53 eprintln!("request too large: {message}");
54 return Ok(());
55 }
56 Err(other) => return Err(other),
57 };
58
59 if let Some(department) = response.choice("department") {
60 println!("department: {} (confidence {:.2})", department.choice, department.confidence);
61 for (option, probability) in &department.probabilities {
62 println!(" {option}: {probability:.2}");
63 }
64 }
65 if let Some(frustration) = response.score("frustration") {
66 println!("frustration: {:.2} of {} (confidence {:.2})", frustration.score, frustration.legend.len() - 1, frustration.confidence);
67 }
68 if let Some(urgent) = response.noul("is_urgent") {
69 println!("urgent: p={:.2}", urgent.noul);
70 }
71
72 let usage = client.usage();
73 println!(
74 "{}: {} request(s), {} retries, {} input tokens, ~${:.6}",
75 response.model,
76 usage.requests(),
77 usage.retries(),
78 usage.input_tokens(),
79 usage.cost_usd()
80 );
81 Ok(())
82}Sourcepub fn score(&self, id: &str) -> Option<&ScoreAnswer>
pub fn score(&self, id: &str) -> Option<&ScoreAnswer>
The answer under id, if there is one and it answers a Score.
Examples found in repository?
examples/ask.rs (line 65)
20fn main() -> Result<(), Error> {
21 let client = Client::from_env(Config::default())?;
22
23 let ticket = Ticket {
24 customer_plan: "business",
25 message: "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. \
26 I'm losing sales. Please help ASAP.",
27 };
28 let questions = Questions::new()
29 .with(
30 "department",
31 Choice::new(
32 "Which team should handle the `message`?",
33 [
34 ("billing", "Payment or subscription issues"),
35 ("technical", "Bugs or integration problems"),
36 ("sales", "Pricing or account questions"),
37 ],
38 ),
39 )
40 .with(
41 "frustration",
42 Score::new(
43 "How frustrated the customer appears",
44 ["Calm, just stating facts", "Frustrated but civil", "Very angry, strong language"],
45 ),
46 )
47 .with("is_urgent", Noul::new("The message conveys urgency or time-sensitivity"));
48
49 let response = match client.ask(&ticket, &questions) {
50 Ok(response) => response,
51 // Too much state for one request: a real caller would split it and ask again.
52 Err(Error::TokenLimit(message)) => {
53 eprintln!("request too large: {message}");
54 return Ok(());
55 }
56 Err(other) => return Err(other),
57 };
58
59 if let Some(department) = response.choice("department") {
60 println!("department: {} (confidence {:.2})", department.choice, department.confidence);
61 for (option, probability) in &department.probabilities {
62 println!(" {option}: {probability:.2}");
63 }
64 }
65 if let Some(frustration) = response.score("frustration") {
66 println!("frustration: {:.2} of {} (confidence {:.2})", frustration.score, frustration.legend.len() - 1, frustration.confidence);
67 }
68 if let Some(urgent) = response.noul("is_urgent") {
69 println!("urgent: p={:.2}", urgent.noul);
70 }
71
72 let usage = client.usage();
73 println!(
74 "{}: {} request(s), {} retries, {} input tokens, ~${:.6}",
75 response.model,
76 usage.requests(),
77 usage.retries(),
78 usage.input_tokens(),
79 usage.cost_usd()
80 );
81 Ok(())
82}Trait Implementations§
Source§impl<'de> Deserialize<'de> for Response
impl<'de> Deserialize<'de> for Response
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
impl StructuralPartialEq for Response
Auto Trait Implementations§
impl Freeze for Response
impl RefUnwindSafe for Response
impl Send for Response
impl Sync for Response
impl Unpin for Response
impl UnsafeUnpin for Response
impl UnwindSafe for Response
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more