Skip to main content

ask/
ask.rs

1//! Asks Jev two questions about a snippet of code, then prints the answers and what they cost.
2//!
3//! ```sh
4//! TYPESAFE_API_KEY=... cargo run --example ask
5//! ```
6//!
7//! This sends the snippet below to TypeSafe's API and is billed to the key.
8
9use serde_json::{json, Map};
10use typesafe_jev::{Client, Config, Error};
11
12fn main() -> Result<(), Error> {
13    let client = Client::from_env(Config::default())?;
14
15    let state = json!({
16        "code": "1| import os\n2| def cwd():\n3|     return os.getcwd()",
17        "query": "where is the working directory read",
18    });
19    let mut questions = Map::new();
20    questions.insert(
21        "line3".into(),
22        json!({
23            "type": "noul",
24            "instructions": "Does line 3 of the code directly answer the query?",
25        }),
26    );
27    questions.insert(
28        "relevance".into(),
29        json!({
30            "type": "score",
31            "instructions": "How relevant is the code to the query?",
32            "criteria": ["unrelated", "tangential", "relevant", "exactly what was asked"],
33        }),
34    );
35
36    match client.ask(&state, &questions) {
37        Ok(answers) => {
38            for (id, answer) in &answers {
39                println!("{id}: {answer}");
40            }
41        }
42        // Too much state for one request: a real caller would split it and ask again.
43        Err(Error::TokenLimit(message)) => eprintln!("request too large: {message}"),
44        Err(other) => return Err(other),
45    }
46
47    let usage = client.usage();
48    println!(
49        "{} request(s), {} retries, {} input tokens, ~${:.6}",
50        usage.requests(),
51        usage.retries(),
52        usage.input_tokens(),
53        usage.cost_usd()
54    );
55    Ok(())
56}