@@ -341,6 +341,7 @@ struct TokenUsage {
341341 prompt : u64 ,
342342 completion : u64 ,
343343 total : u64 ,
344+ elapsed : u64 ,
344345}
345346
346347#[ derive( Debug , Default , PartialEq , Eq , Clone ) ]
@@ -1336,15 +1337,18 @@ fn format_dictionary_tsv(entries: &[DictionaryEntry]) -> String {
13361337/// Format token usage and reasoning as comment lines for TSV
13371338fn format_token_usage_comments ( reasoning : & str , token_usage : & TokenUsage ) -> String {
13381339 format ! (
1339- "# REASONING\n # {}\n # TOKEN USAGE\n # prompt: {}\n # completion: {}\n # total: {}\n " ,
1340+ "# REASONING\n # {}\n # TOKEN USAGE\n # prompt: {}\n # completion: {}\n # total: {}\n # \
1341+ elapsed: {} ms\n ",
13401342 reasoning. replace( '\n' , "\n # " ) ,
13411343 token_usage. prompt,
13421344 token_usage. completion,
1343- token_usage. total
1345+ token_usage. total,
1346+ token_usage. elapsed
13441347 )
13451348}
13461349
13471350/// Format tags as TSV (single row with columns: tag, reasoning, token_usage fields)
1351+ #[ rustfmt:: skip]
13481352fn format_tags_tsv (
13491353 tags_json : & serde_json:: Value ,
13501354 reasoning : & str ,
@@ -1375,47 +1379,49 @@ fn format_tags_tsv(
13751379 let reasoning_escaped = reasoning. replace ( [ '\t' , '\n' , '\r' ] , " " ) ;
13761380
13771381 format ! (
1378- "tags\t reasoning\t token_usage_prompt\t token_usage_completion\t token_usage_total\n {}\t {}\\
1379- t{}\t {}\t {}\n " ,
1382+ "tags\t reasoning\t token_prompt\t token_completion\t token_total\t elapsed\n {}\t {}\t {}\t {}\t {}\t {}\n " ,
13801383 tags_escaped,
13811384 reasoning_escaped,
13821385 token_usage. prompt,
13831386 token_usage. completion,
1384- token_usage. total
1387+ token_usage. total,
1388+ token_usage. elapsed
13851389 )
13861390}
13871391
13881392/// Format description as TSV (single row with columns: response, reasoning, token_usage fields)
1393+ #[ rustfmt:: skip]
13891394fn format_description_tsv ( response : & str , reasoning : & str , token_usage : & TokenUsage ) -> String {
13901395 // Escape tabs and newlines
13911396 let response_escaped = response. replace ( [ '\t' , '\n' , '\r' ] , " " ) ;
13921397 let reasoning_escaped = reasoning. replace ( [ '\t' , '\n' , '\r' ] , " " ) ;
13931398
13941399 format ! (
1395- "response\t reasoning\t token_usage_prompt\t token_usage_completion\t token_usage_total\n {}\\
1396- t{}\t {}\t {}\t {}\n " ,
1400+ "response\t reasoning\t token_prompt\t token_completion\t token_total\t elapsed\n {}\t {}\t {}\t {}\t {}\t {}\n " ,
13971401 response_escaped,
13981402 reasoning_escaped,
13991403 token_usage. prompt,
14001404 token_usage. completion,
1401- token_usage. total
1405+ token_usage. total,
1406+ token_usage. elapsed
14021407 )
14031408}
14041409
14051410/// Format prompt as TSV (single row with columns: response, reasoning, token_usage fields)
1411+ #[ rustfmt:: skip]
14061412fn format_prompt_tsv ( response : & str , reasoning : & str , token_usage : & TokenUsage ) -> String {
14071413 // Escape tabs and newlines
14081414 let response_escaped = response. replace ( [ '\t' , '\n' , '\r' ] , " " ) ;
14091415 let reasoning_escaped = reasoning. replace ( [ '\t' , '\n' , '\r' ] , " " ) ;
14101416
14111417 format ! (
1412- "response\t reasoning\t token_usage_prompt\t token_usage_completion\t token_usage_total\n {}\\
1413- t{}\t {}\t {}\t {}\n " ,
1418+ "response\t reasoning\t token_prompt\t token_completion\t token_total\t elapsed\n {}\t {}\t {}\t {}\t {}\t {}\n " ,
14141419 response_escaped,
14151420 reasoning_escaped,
14161421 token_usage. prompt,
14171422 token_usage. completion,
1418- token_usage. total
1423+ token_usage. total,
1424+ token_usage. elapsed
14191425 )
14201426}
14211427
@@ -1702,6 +1708,7 @@ fn get_completion(
17021708
17031709 // Get response from POST request to chat completions endpoint
17041710 let completions_endpoint = "/chat/completions" ;
1711+ let start_time = Instant :: now ( ) ;
17051712 let response = send_request (
17061713 client,
17071714 Some ( api_key) ,
@@ -1740,10 +1747,12 @@ fn get_completion(
17401747 let Some ( usage) = response_json[ "usage" ] . as_object ( ) else {
17411748 return fail_clierror ! ( "Invalid response: missing or malformed usage" ) ;
17421749 } ;
1750+ let elapsed_ms = start_time. elapsed ( ) . as_millis ( ) as u64 ;
17431751 let token_usage = TokenUsage {
17441752 prompt : usage[ "prompt_tokens" ] . as_u64 ( ) . unwrap_or ( 0 ) ,
17451753 completion : usage[ "completion_tokens" ] . as_u64 ( ) . unwrap_or ( 0 ) ,
17461754 total : usage[ "total_tokens" ] . as_u64 ( ) . unwrap_or ( 0 ) ,
1755+ elapsed : elapsed_ms,
17471756 } ;
17481757
17491758 // if flag_prompt is set, add Prompt to the Attribution and
0 commit comments