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
impl Usage
Sourcepub fn record(&self, input_tokens: u64, output_tokens: u64)
pub fn record(&self, input_tokens: u64, output_tokens: u64)
One completed request and the tokens it used.
Sourcepub fn record_retry(&self)
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.
Sourcepub fn requests(&self) -> u64
pub fn requests(&self) -> u64
Requests that were answered.
Examples found in repository?
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}Sourcepub fn retries(&self) -> u64
pub fn retries(&self) -> u64
Attempts that were repeated after a transient failure.
Examples found in repository?
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}Sourcepub fn input_tokens(&self) -> u64
pub fn input_tokens(&self) -> u64
Input tokens, as reported by the API.
Examples found in repository?
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}Sourcepub fn output_tokens(&self) -> u64
pub fn output_tokens(&self) -> u64
Output tokens, as reported by the API. Jev reports them, but does not charge for them.
Sourcepub fn cost_usd(&self) -> f64
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?
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}