@@ -73,6 +73,7 @@ use hooks::{
7373 HookTrigger ,
7474} ;
7575use summarization_state:: {
76+ CONTEXT_WINDOW_SIZE ,
7677 SummarizationState ,
7778 TokenWarningLevel ,
7879} ;
@@ -205,6 +206,7 @@ const HELP_TEXT: &str = color_print::cstr! {"
205206 <em>rm</em> <black!>Remove file(s) from context [--global]</black!>
206207 <em>clear</em> <black!>Clear all files from current context [--global]</black!>
207208 <em>hooks</em> <black!>View and manage context hooks</black!>
209+ <em>/usage</em> <black!>Show current session's context window usage</black!>
208210
209211<cyan,em>Tips:</cyan,em>
210212<em>!{command}</em> <black!>Quickly execute a command in your current session</black!>
@@ -1899,6 +1901,157 @@ where
18991901 // during PromptUser.
19001902 execute ! ( self . output, style:: Print ( "\n \n " ) , ) ?;
19011903
1904+ ChatState :: PromptUser {
1905+ tool_uses : Some ( tool_uses) ,
1906+ pending_tool_index,
1907+ skip_printing_tools : true ,
1908+ }
1909+ } ,
1910+ Command :: Usage => {
1911+ let context_messages = self . conversation_state . context_messages ( None ) . await ;
1912+ let chat_history = self . conversation_state . get_chat_history ( ) ;
1913+ let assistant_messages = chat_history
1914+ . iter ( )
1915+ . filter_map ( |message| {
1916+ if let fig_api_client:: model:: ChatMessage :: AssistantResponseMessage ( msg) = message {
1917+ Some ( msg)
1918+ } else {
1919+ None
1920+ }
1921+ } )
1922+ . collect :: < Vec < _ > > ( ) ;
1923+
1924+ let user_messages = chat_history
1925+ . iter ( )
1926+ . filter_map ( |message| {
1927+ if let fig_api_client:: model:: ChatMessage :: UserInputMessage ( msg) = message {
1928+ Some ( msg)
1929+ } else {
1930+ None
1931+ }
1932+ } )
1933+ . collect :: < Vec < _ > > ( ) ;
1934+
1935+ let context_token_count = context_messages
1936+ . iter ( )
1937+ . map ( |msg| TokenCounter :: count_tokens ( & msg. 0 . content ) )
1938+ . sum :: < usize > ( ) ;
1939+
1940+ let assistant_token_count = assistant_messages
1941+ . iter ( )
1942+ . map ( |msg| TokenCounter :: count_tokens ( & msg. content ) )
1943+ . sum :: < usize > ( ) ;
1944+
1945+ let user_token_count = user_messages
1946+ . iter ( )
1947+ . map ( |msg| TokenCounter :: count_tokens ( & msg. content ) )
1948+ . sum :: < usize > ( ) ;
1949+
1950+ let total_token_used: usize = context_token_count + assistant_token_count + user_token_count;
1951+
1952+ let window_width = self . terminal_width ( ) ;
1953+ let progress_bar_width = std:: cmp:: min ( window_width, 80 ) ; // set a max width for the progress bar for better aesthetic
1954+
1955+ let context_width =
1956+ ( ( context_token_count as f64 / CONTEXT_WINDOW_SIZE as f64 ) * progress_bar_width as f64 ) as usize ;
1957+ let assistant_width =
1958+ ( ( assistant_token_count as f64 / CONTEXT_WINDOW_SIZE as f64 ) * progress_bar_width as f64 ) as usize ;
1959+ let user_width =
1960+ ( ( user_token_count as f64 / CONTEXT_WINDOW_SIZE as f64 ) * progress_bar_width as f64 ) as usize ;
1961+
1962+ let left_over_width = progress_bar_width
1963+ - std:: cmp:: min ( context_width + assistant_width + user_width, progress_bar_width) ;
1964+
1965+ queue ! (
1966+ self . output,
1967+ style:: Print ( format!(
1968+ "\n Current context window ({} of {}k tokens used)\n " ,
1969+ total_token_used,
1970+ CONTEXT_WINDOW_SIZE / 1000
1971+ ) ) ,
1972+ style:: SetForegroundColor ( Color :: DarkCyan ) ,
1973+ // add a nice visual to mimic "tiny" progress, so the overral progress bar doesn't look too empty
1974+ style:: Print ( "|" . repeat( if context_width == 0 && context_token_count > 0 {
1975+ 1
1976+ } else {
1977+ 0
1978+ } ) ) ,
1979+ style:: Print ( "█" . repeat( context_width) ) ,
1980+ style:: SetForegroundColor ( Color :: Blue ) ,
1981+ style:: Print ( "|" . repeat( if assistant_width == 0 && assistant_token_count > 0 {
1982+ 1
1983+ } else {
1984+ 0
1985+ } ) ) ,
1986+ style:: Print ( "█" . repeat( assistant_width) ) ,
1987+ style:: SetForegroundColor ( Color :: Magenta ) ,
1988+ style:: Print ( "|" . repeat( if user_width == 0 && user_token_count > 0 { 1 } else { 0 } ) ) ,
1989+ style:: Print ( "█" . repeat( user_width) ) ,
1990+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
1991+ style:: Print ( "█" . repeat( left_over_width) ) ,
1992+ style:: Print ( " " ) ,
1993+ style:: SetForegroundColor ( Color :: Reset ) ,
1994+ style:: Print ( format!(
1995+ "{:.2}%" ,
1996+ ( total_token_used as f32 / CONTEXT_WINDOW_SIZE as f32 ) * 100.0
1997+ ) ) ,
1998+ ) ?;
1999+
2000+ queue ! ( self . output, style:: Print ( "\n \n " ) ) ?;
2001+ self . output . flush ( ) ?;
2002+
2003+ queue ! (
2004+ self . output,
2005+ style:: SetForegroundColor ( Color :: DarkCyan ) ,
2006+ style:: Print ( "█ Context files: " ) ,
2007+ style:: SetForegroundColor ( Color :: Reset ) ,
2008+ style:: Print ( format!(
2009+ "~{} tokens ({:.2}%)\n " ,
2010+ context_token_count,
2011+ ( context_token_count as f32 / CONTEXT_WINDOW_SIZE as f32 ) * 100.0
2012+ ) ) ,
2013+ style:: SetForegroundColor ( Color :: Blue ) ,
2014+ style:: Print ( "█ Q responses: " ) ,
2015+ style:: SetForegroundColor ( Color :: Reset ) ,
2016+ style:: Print ( format!(
2017+ " ~{} tokens ({:.2}%)\n " ,
2018+ assistant_token_count,
2019+ ( assistant_token_count as f32 / CONTEXT_WINDOW_SIZE as f32 ) * 100.0
2020+ ) ) ,
2021+ style:: SetForegroundColor ( Color :: Magenta ) ,
2022+ style:: Print ( "█ Your prompts: " ) ,
2023+ style:: SetForegroundColor ( Color :: Reset ) ,
2024+ style:: Print ( format!(
2025+ " ~{} tokens ({:.2}%)\n \n " ,
2026+ user_token_count,
2027+ ( user_token_count as f32 / CONTEXT_WINDOW_SIZE as f32 ) * 100.0
2028+ ) ) ,
2029+ ) ?;
2030+
2031+ queue ! (
2032+ self . output,
2033+ style:: SetAttribute ( Attribute :: Bold ) ,
2034+ style:: Print ( "\n 💡 Pro Tips:\n " ) ,
2035+ style:: SetAttribute ( Attribute :: Reset ) ,
2036+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
2037+ style:: Print ( "Run " ) ,
2038+ style:: SetForegroundColor ( Color :: DarkGreen ) ,
2039+ style:: Print ( "/compact" ) ,
2040+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
2041+ style:: Print ( " to replace the conversation history with its summary\n " ) ,
2042+ style:: Print ( "Run " ) ,
2043+ style:: SetForegroundColor ( Color :: DarkGreen ) ,
2044+ style:: Print ( "/clear" ) ,
2045+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
2046+ style:: Print ( " to erase the entire chat history\n " ) ,
2047+ style:: Print ( "Run " ) ,
2048+ style:: SetForegroundColor ( Color :: DarkGreen ) ,
2049+ style:: Print ( "/context show" ) ,
2050+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
2051+ style:: Print ( " to see tokens per context file\n \n " ) ,
2052+ style:: SetForegroundColor ( Color :: Reset ) ,
2053+ ) ?;
2054+
19022055 ChatState :: PromptUser {
19032056 tool_uses : Some ( tool_uses) ,
19042057 pending_tool_index,
0 commit comments