Skip to content

Commit 2afba39

Browse files
committed
split out billin info
1 parent 9de1ad5 commit 2afba39

File tree

4 files changed

+50
-82
lines changed

4 files changed

+50
-82
lines changed

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
use std::collections::HashSet;
22

3-
use clap::Subcommand;
3+
use clap::{
4+
Args,
5+
Subcommand,
6+
};
47
use crossterm::style::Attribute;
58
use crossterm::{
69
execute,
710
style,
811
};
912

13+
use crate::cli::chat::cli::usage::{
14+
usage_data_provider,
15+
usage_renderer,
16+
};
1017
use crate::cli::chat::consts::AGENT_FORMAT_HOOKS_DOC_URL;
1118
use crate::cli::chat::context::{
1219
ContextFilePath,
@@ -27,12 +34,43 @@ use crate::constants::help_text::{
2734
use crate::os::Os;
2835
use crate::theme::StyledText;
2936

30-
#[deny(missing_docs)]
31-
#[derive(Debug, PartialEq, Subcommand)]
37+
/// Context command for viewing token usage and managing context files.
38+
/// Without subcommands: displays context window token usage breakdown by component
39+
/// (context files, tools, assistant responses, user prompts).
40+
/// With subcommands: manages context file rules (show, add, remove, clear).
41+
#[derive(Debug, PartialEq, Args)]
3242
#[command(
3343
about = context_description(),
3444
before_long_help = context_long_help()
3545
)]
46+
pub struct ContextArgs {
47+
#[command(subcommand)]
48+
pub subcommand: Option<ContextSubcommand>,
49+
}
50+
51+
impl ContextArgs {
52+
pub async fn execute(self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
53+
match self.subcommand {
54+
Some(subcommand) => subcommand.execute(os, session).await,
55+
None => {
56+
// No subcommand - show context window usage (replaces /usage --context)
57+
let usage_data = usage_data_provider::get_detailed_usage_data(session, os).await?;
58+
usage_renderer::render_context_window(&usage_data, session).await?;
59+
60+
Ok(ChatState::PromptUser {
61+
skip_printing_tools: true,
62+
})
63+
},
64+
}
65+
}
66+
67+
pub fn subcommand_name(&self) -> Option<&'static str> {
68+
self.subcommand.as_ref().map(|s| s.name())
69+
}
70+
}
71+
72+
#[deny(missing_docs)]
73+
#[derive(Debug, PartialEq, Subcommand)]
3674
/// Context subcommands
3775
pub enum ContextSubcommand {
3876
/// Display the context rule configuration and matched files

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ pub mod tangent;
2121
pub mod todos;
2222
pub mod tools;
2323
pub mod usage;
24-
2524
use changelog::ChangelogArgs;
2625
use clap::Parser;
2726
use clear::ClearArgs;
2827
use compact::CompactArgs;
29-
use context::ContextSubcommand;
3028
use editor::EditorArgs;
3129
use experiment::ExperimentArgs;
3230
use hooks::HooksArgs;
@@ -44,6 +42,7 @@ use todos::TodoSubcommand;
4442
use tools::ToolsArgs;
4543

4644
use crate::cli::chat::cli::checkpoint::CheckpointSubcommand;
45+
use crate::cli::chat::cli::context::ContextArgs;
4746
use crate::cli::chat::cli::subscribe::SubscribeArgs;
4847
use crate::cli::chat::cli::usage::UsageArgs;
4948
use crate::cli::chat::consts::AGENT_MIGRATION_DOC_URL;
@@ -72,9 +71,8 @@ pub enum SlashCommand {
7271
Agent(AgentSubcommand),
7372
#[command(hide = true)]
7473
Profile,
75-
/// Manage context files for the chat session
76-
#[command(subcommand)]
77-
Context(ContextSubcommand),
74+
/// Manage context files and view context window usage
75+
Context(ContextArgs),
7876
/// (Beta) Manage knowledge base for persistent context storage. Requires "q settings
7977
/// chat.enableKnowledge true"
8078
#[command(subcommand, hide = true)]
@@ -99,7 +97,7 @@ pub enum SlashCommand {
9997
Prompts(PromptsArgs),
10098
/// View context hooks
10199
Hooks(HooksArgs),
102-
/// Show current session's context window usage
100+
/// Show billing and credits information
103101
Usage(UsageArgs),
104102
/// See mcp server loaded
105103
Mcp(McpArgs),
@@ -237,7 +235,7 @@ impl SlashCommand {
237235
pub fn subcommand_name(&self) -> Option<&'static str> {
238236
match self {
239237
SlashCommand::Agent(sub) => Some(sub.name()),
240-
SlashCommand::Context(sub) => Some(sub.name()),
238+
SlashCommand::Context(args) => args.subcommand_name(),
241239
SlashCommand::Knowledge(sub) => Some(sub.name()),
242240
SlashCommand::Tools(arg) => arg.subcommand_name(),
243241
SlashCommand::Prompts(arg) => arg.subcommand_name(),
Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
use clap::Args;
2-
use crossterm::style::Color;
3-
use crossterm::{
4-
execute,
5-
style,
6-
};
72

83
use crate::cli::chat::token_counter::TokenCount;
94
use crate::cli::chat::{
@@ -66,81 +61,18 @@ pub struct BonusCredit {
6661
pub days_until_expiry: i64,
6762
}
6863

69-
/// Arguments for the usage command that displays token usage statistics and context window
70-
/// information.
71-
///
72-
/// This command shows how many tokens are being used by different components (context files, tools,
73-
/// assistant responses, and user prompts) within the current chat session's context window.
64+
/// Arguments for the usage command that displays credits and billing information.
7465
#[deny(missing_docs)]
7566
#[derive(Debug, PartialEq, Args)]
76-
pub struct UsageArgs {
77-
/// Show only context window usage
78-
#[arg(long)]
79-
context: bool,
80-
/// Show only credits and billing information
81-
#[arg(long)]
82-
credits: bool,
83-
}
67+
pub struct UsageArgs {}
8468

8569
impl UsageArgs {
8670
pub async fn execute(self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
87-
match (self.context, self.credits) {
88-
(true, false) => {
89-
// Show only context window usage
90-
self.show_context_usage(os, session).await
91-
},
92-
(false, true) => {
93-
// Show only credits/billing information
94-
self.show_credits_info(os, session).await
95-
},
96-
(false, false) => {
97-
// Show both (default behavior)
98-
self.show_full_usage(os, session).await
99-
},
100-
(true, true) => {
101-
// Both flags specified - show error
102-
execute!(
103-
session.stderr,
104-
style::SetForegroundColor(Color::Red),
105-
style::Print("Error: Cannot specify both --context and --credits flags\n"),
106-
style::SetForegroundColor(Color::Reset),
107-
)?;
108-
Ok(ChatState::PromptUser {
109-
skip_printing_tools: true,
110-
})
111-
},
112-
}
113-
}
114-
115-
async fn show_context_usage(&self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
116-
let usage_data = usage_data_provider::get_detailed_usage_data(session, os).await?;
117-
usage_renderer::render_context_window(&usage_data, session).await?;
118-
Ok(ChatState::PromptUser {
119-
skip_printing_tools: true,
120-
})
121-
}
122-
123-
async fn show_credits_info(&self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
71+
// Only show credits/billing information
12472
let billing_data = usage_data_provider::get_billing_usage_data(os).await?;
12573
usage_renderer::render_billing_info(&billing_data, session, true).await?;
12674
Ok(ChatState::PromptUser {
12775
skip_printing_tools: true,
12876
})
12977
}
130-
131-
async fn show_full_usage(&self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
132-
// Get both billing and context data
133-
let billing_data = usage_data_provider::get_billing_usage_data(os).await?;
134-
let usage_data = usage_data_provider::get_detailed_usage_data(session, os).await?;
135-
136-
// Render billing information
137-
usage_renderer::render_billing_info(&billing_data, session, false).await?;
138-
139-
// Render context window information
140-
usage_renderer::render_context_window(&usage_data, session).await?;
141-
142-
Ok(ChatState::PromptUser {
143-
skip_printing_tools: true,
144-
})
145-
}
14678
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::cli::chat::{
1919
use crate::os::Os;
2020

2121
/// Get detailed usage data for context window analysis
22-
pub(super) async fn get_detailed_usage_data(
22+
pub async fn get_detailed_usage_data(
2323
session: &mut ChatSession,
2424
os: &Os,
2525
) -> Result<super::DetailedUsageData, ChatError> {

0 commit comments

Comments
 (0)