|
| 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