1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! cargo run --example forward_compat (needs TYPESAFE_API_KEY)
//! Using API features this SDK version does not model: a hand-built question, an extra body
//! field, and the raw body for answers the typed map does not recognise.
use typesafe::{Answer, Client, Noul, Questions, json};
#[tokio::main]
async fn main() -> typesafe::Result<()> {
let client = Client::from_env()?;
let res = client
.system_one(
"The payout failed again, third time this month. I am done waiting.",
Questions::new()
.with("is_urgent", Noul::new("The message conveys urgency"))
// Any JSON object with a non-empty `type` is sent as written. Use this for
// question types or fields released after this SDK version.
.with(
"tone",
json!({
"type": "choice",
"instructions": "The register of the message",
"criteria": {"formal": null, "casual": null, "hostile": null},
"some_new_field": true,
}),
),
)
// Top-level body fields, shallow-merged last. A key named `state`, `model` or
// `questions` replaces the standard field, so keep to new names.
.extra_body("trace", json!(true))
.await?;
// Answers of a type this version knows become typed values...
for (name, answer) in &res.answers {
let confidence = answer
.confidence()
.map_or_else(String::new, |c| format!(" (confidence {c:.2})"));
match answer {
Answer::Noul(a) => println!("{name} [noul] {:.3}{confidence}", a.noul),
Answer::Choice(a) => println!("{name} [choice] {}{confidence}", a.choice),
Answer::Score(a) => println!("{name} [score] {:.2}{confidence}", a.score),
// `Answer` is `#[non_exhaustive]`; later versions add variants here.
other => println!("{name} [{}]", other.kind()),
}
}
// ...and anything else is skipped with a `tracing` warning, but is still in `raw`, along
// with every field of the response, known or not.
if let Some(answers) = res.raw["answers"].as_object() {
for (name, value) in answers {
if !res.answers.contains_key(name.as_str()) {
println!("{name} [unrecognised] {value}");
}
}
}
println!("model {}, usage {:?}", res.model, res.usage);
Ok(())
}