Skip to main content

Usage

Struct Usage 

Source
pub struct Usage { /* private fields */ }
Expand description

Thread-safe request and token counters.

A Client fills its own Usage from the usage object of every successful reply and counts each retry. The counters are atomic, so the totals can be read while requests are in flight; they are then a snapshot, not a transaction.

Usage::record and Usage::record_retry are public so that a caller who talks to another provider through the same code path can keep the same accounting.

Implementations§

Source§

impl Usage

Source

pub fn record(&self, input_tokens: u64, output_tokens: u64)

One completed request and the tokens it used.

Source

pub fn record_retry(&self)

One attempt that had to be repeated. A request that is retried twice before it succeeds counts as one request and two retries.

Source

pub fn requests(&self) -> u64

Requests that were answered.

Examples found in repository?
examples/ask.rs (line 50)
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}
Source

pub fn retries(&self) -> u64

Attempts that were repeated after a transient failure.

Examples found in repository?
examples/ask.rs (line 51)
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}
Source

pub fn input_tokens(&self) -> u64

Input tokens, as reported by the API.

Examples found in repository?
examples/ask.rs (line 52)
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}
Source

pub fn output_tokens(&self) -> u64

Output tokens, as reported by the API. Jev reports them, but does not charge for them.

Source

pub fn cost_usd(&self) -> f64

The input tokens at Jev’s list price, USD_PER_INPUT_MTOK. An estimate: the price is a constant in this crate, not something the API reports.

Examples found in repository?
examples/ask.rs (line 53)
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}

Trait Implementations§

Source§

impl Debug for Usage

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Usage

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for Usage

§

impl RefUnwindSafe for Usage

§

impl Send for Usage

§

impl Sync for Usage

§

impl Unpin for Usage

§

impl UnsafeUnpin for Usage

§

impl UnwindSafe for Usage

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.