@@ -13,6 +13,7 @@ import { findExpandedThinkingId } from "../core/thinking-state";
1313import { WelcomeScreen } from "./WelcomeScreen" ;
1414import { AskUserQuestionPrompt } from "./AskUserQuestionPrompt" ;
1515import { McpStatusList } from "./McpStatusList" ;
16+ import { UsageView , type UsageData } from "./UsageView" ;
1617import { ProcessStdoutView } from "./ProcessStdoutView" ;
1718import {
1819 type AskUserQuestionAnswers ,
@@ -51,7 +52,7 @@ import { SessionManager } from "@vegamo/deepcode-core";
5152import { getCompactPromptTokenThreshold } from "@vegamo/deepcode-core" ;
5253import { writeStdout , writeStdoutLine } from "../../utils/stdio-helpers" ;
5354
54- type View = "chat" | "session-list" | "undo" | "mcp-status" ;
55+ type View = "chat" | "session-list" | "undo" | "usage" | " mcp-status";
5556
5657const STATUS_SPINNER_FRAMES = [ "⠋" , "⠙" , "⠹" , "⠸" , "⠼" , "⠴" , "⠦" , "⠧" , "⠇" , "⠏" ] ;
5758
@@ -133,6 +134,7 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
133134 const [ resolvedSettings , setResolvedSettings ] = useState ( ( ) => resolveCurrentSettings ( projectRoot ) ) ;
134135 const [ nowTick , setNowTick ] = useState ( 0 ) ;
135136 const [ mcpStatuses , setMcpStatuses ] = useState < ReturnType < typeof sessionManager . getMcpStatus > > ( [ ] ) ;
137+ const [ usageData , setUsageData ] = useState < UsageData | null > ( null ) ;
136138 const [ showProcessStdout , setShowProcessStdout ] = useState ( false ) ;
137139
138140 rawModeRef . current = mode ;
@@ -344,55 +346,15 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
344346 setErrorLine ( `Failed to fetch balance: HTTP ${ response . status } ${ response . statusText || "" } ` . trim ( ) ) ;
345347 return ;
346348 }
347- const data = ( await response . json ( ) ) as {
348- is_available : boolean ;
349- balance_infos ?: Array < {
350- currency : string ;
351- total_balance : string ;
352- granted_balance : string ;
353- topped_up_balance : string ;
354- } > ;
355- } ;
356-
357- const statusIcon = data . is_available ? "🟢" : "🔴" ;
358- const statusText = data . is_available ? "Available" : "Not available" ;
359- let content = `/usage\n└ API status: ${ statusIcon } ${ statusText } ` ;
360-
361- if ( data . balance_infos && data . balance_infos . length > 0 ) {
362- for ( const info of data . balance_infos ) {
363- content += `\n ${ info . currency } : total ${ info . total_balance } (granted ${ info . granted_balance } , topped up ${ info . topped_up_balance } )` ;
364- }
365- } else {
366- content += `\n No balance info returned.` ;
367- }
368-
369- const now = new Date ( ) . toISOString ( ) ;
370- const activeSessionId = sessionManager . getActiveSessionId ( ) ;
371- if ( activeSessionId ) {
372- sessionManager . addSessionSystemMessage ( activeSessionId , content , true ) ;
373- } else {
374- setMessages ( ( prev ) => [
375- ...prev ,
376- {
377- id : crypto . randomUUID ( ) ,
378- sessionId : "local" ,
379- role : "system" as const ,
380- content,
381- contentParams : null ,
382- messageParams : null ,
383- compacted : false ,
384- visible : true ,
385- createTime : now ,
386- updateTime : now ,
387- } ,
388- ] ) ;
389- }
349+ const data : UsageData = await response . json ( ) ;
350+ setUsageData ( data ) ;
351+ navigateToSubView ( "usage" ) ;
390352 } catch ( error ) {
391353 setErrorLine ( `Failed to fetch balance: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
392354 } finally {
393355 setBusy ( false ) ;
394356 }
395- } , [ projectRoot , sessionManager ] ) ;
357+ } , [ projectRoot , navigateToSubView ] ) ;
396358
397359 const handlePrompt = useCallback (
398360 async ( submission : PromptSubmission ) => {
@@ -1032,6 +994,8 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
1032994 void sessionManager . reconnectMcpServer ( name , latest . mcpServers ?. [ name ] ) ;
1033995 } }
1034996 />
997+ ) : view === "usage" ? (
998+ < UsageView data = { usageData ?? { is_available : false , balance_infos : [ ] } } onCancel = { ( ) => setView ( "chat" ) } />
1035999 ) : shouldShowQuestionPrompt && pendingQuestion && ! busy ? (
10361000 < AskUserQuestionPrompt
10371001 questions = { pendingQuestion . questions }
0 commit comments