Skip to content

Commit f4fe86e

Browse files
akhileshbbontalaa
andauthored
Refactor /Usage into smaller modules (#3324)
Co-authored-by: Akhilesh Bontala <[email protected]>
1 parent 3a9214b commit f4fe86e

File tree

5 files changed

+261
-260
lines changed

5 files changed

+261
-260
lines changed

crates/chat-cli/src/cli/chat/cli/usage.rs

Lines changed: 0 additions & 259 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use clap::Args;
2+
3+
use crate::cli::chat::token_counter::TokenCount;
4+
use crate::cli::chat::{ChatError, ChatSession, ChatState};
5+
use crate::os::Os;
6+
7+
pub mod usage_data_provider;
8+
pub mod usage_renderer;
9+
10+
/// Detailed usage data for context window analysis
11+
#[derive(Debug)]
12+
pub struct DetailedUsageData {
13+
pub total_tokens: TokenCount,
14+
pub context_tokens: TokenCount,
15+
pub assistant_tokens: TokenCount,
16+
pub user_tokens: TokenCount,
17+
pub tools_tokens: TokenCount,
18+
pub context_window_size: usize,
19+
pub dropped_context_files: Vec<(String, String)>,
20+
}
21+
22+
/// Arguments for the usage command that displays token usage statistics and context window
23+
/// information.
24+
///
25+
/// This command shows how many tokens are being used by different components (context files, tools,
26+
/// assistant responses, and user prompts) within the current chat session's context window.
27+
#[deny(missing_docs)]
28+
#[derive(Debug, PartialEq, Args)]
29+
pub struct UsageArgs;
30+
31+
impl UsageArgs {
32+
pub async fn execute(self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
33+
let usage_data = usage_data_provider::get_detailed_usage_data(session, os).await?;
34+
usage_renderer::render_context_window(&usage_data, session).await?;
35+
Ok(ChatState::PromptUser { skip_printing_tools: true })
36+
}
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::cli::chat::cli::model::context_window_tokens;
2+
use crate::cli::chat::token_counter::{CharCount, TokenCount};
3+
use crate::cli::chat::{ChatError, ChatSession};
4+
use crate::os::Os;
5+
6+
/// Get detailed usage data for context window analysis
7+
pub(super) async fn get_detailed_usage_data(session: &mut ChatSession, os: &Os) -> Result<super::DetailedUsageData, ChatError> {
8+
let context_window_size = context_window_tokens(session.conversation.model_info.as_ref());
9+
10+
let state = session
11+
.conversation
12+
.backend_conversation_state(os, true, &mut std::io::stderr())
13+
.await?;
14+
15+
let data = state.calculate_conversation_size();
16+
let tool_specs_json: String = state
17+
.tools
18+
.values()
19+
.filter_map(|s| serde_json::to_string(s).ok())
20+
.collect::<Vec<String>>()
21+
.join("");
22+
let tools_char_count: CharCount = tool_specs_json.len().into();
23+
let total_tokens: TokenCount =
24+
(data.context_messages + data.user_messages + data.assistant_messages + tools_char_count).into();
25+
26+
Ok(super::DetailedUsageData {
27+
total_tokens,
28+
context_tokens: data.context_messages.into(),
29+
assistant_tokens: data.assistant_messages.into(),
30+
user_tokens: data.user_messages.into(),
31+
tools_tokens: tools_char_count.into(),
32+
context_window_size,
33+
dropped_context_files: state.dropped_context_files,
34+
})
35+
}
36+
37+
/// Get total usage percentage (external API)
38+
pub async fn get_total_usage_percentage(session: &mut ChatSession, os: &Os) -> Result<f32, ChatError> {
39+
let data = get_detailed_usage_data(session, os).await?;
40+
Ok((data.total_tokens.value() as f32 / data.context_window_size as f32) * 100.0)
41+
}

0 commit comments

Comments
 (0)