Skip to content

Commit 3c3107e

Browse files
committed
feat(tui): display cached token count inline with total tokens
Shows cache tokens inline when non-zero: - Sidebar context: "68,356 tokens (12.5K cached)" - Subagent footer: same format with percentage - Prompt footer: same format with percentage Implementation: - Extract cached tokens separately before summing - Show only when cached > 0 to reduce noise - Use existing Locale.number() for consistent formatting - Applied to all 3 TUI locations that display token usage
1 parent 75ffbfb commit 3c3107e

3 files changed

Lines changed: 19 additions & 6 deletions

File tree

packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,17 @@ export function Prompt(props: PromptProps) {
162162
const last = msg.findLast((item): item is AssistantMessage => item.role === "assistant" && item.tokens.output > 0)
163163
if (!last) return
164164

165+
const cached = last.tokens.cache.read + last.tokens.cache.write
165166
const tokens =
166-
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
167+
last.tokens.input + last.tokens.output + last.tokens.reasoning + cached
167168
if (tokens <= 0) return
168169

169170
const model = sync.data.provider.find((item) => item.id === last.providerID)?.models[last.modelID]
170171
const pct = model?.limit.context ? `${Math.round((tokens / model.limit.context) * 100)}%` : undefined
171172
const cost = msg.reduce((sum, item) => sum + (item.role === "assistant" ? item.cost : 0), 0)
173+
const tokenText = cached > 0 ? `${Locale.number(tokens)} (${Locale.number(cached)} cached)` : Locale.number(tokens)
172174
return {
173-
context: pct ? `${Locale.number(tokens)} (${pct})` : Locale.number(tokens),
175+
context: pct ? `${tokenText} (${pct})` : tokenText,
174176
cost: cost > 0 ? money.format(cost) : undefined,
175177
}
176178
})

packages/opencode/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,34 @@ function View(props: { api: TuiPluginApi; session_id: string }) {
1919
if (!last) {
2020
return {
2121
tokens: 0,
22+
cached: 0,
2223
percent: null,
2324
}
2425
}
2526

27+
const cached = last.tokens.cache.read + last.tokens.cache.write
2628
const tokens =
27-
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
29+
last.tokens.input + last.tokens.output + last.tokens.reasoning + cached
2830
const model = props.api.state.provider.find((item) => item.id === last.providerID)?.models[last.modelID]
2931
return {
3032
tokens,
33+
cached,
3134
percent: model?.limit.context ? Math.round((tokens / model.limit.context) * 100) : null,
3235
}
3336
})
3437

38+
const tokenText = createMemo(() => {
39+
const cached = state().cached
40+
if (cached === 0) return `${state().tokens.toLocaleString()} tokens`
41+
return `${state().tokens.toLocaleString()} tokens (${cached.toLocaleString()} cached)`
42+
})
43+
3544
return (
3645
<box>
3746
<text fg={theme().text}>
3847
<b>Context</b>
3948
</text>
40-
<text fg={theme().textMuted}>{state().tokens.toLocaleString()} tokens</text>
49+
<text fg={theme().textMuted}>{tokenText()}</text>
4150
<text fg={theme().textMuted}>{state().percent ?? 0}% used</text>
4251
<text fg={theme().textMuted}>{money.format(cost())} spent</text>
4352
</box>

packages/opencode/src/cli/cmd/tui/routes/session/subagent-footer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ export function SubagentFooter() {
3636
const last = msg.findLast((item): item is AssistantMessage => item.role === "assistant" && item.tokens.output > 0)
3737
if (!last) return
3838

39+
const cached = last.tokens.cache.read + last.tokens.cache.write
3940
const tokens =
40-
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
41+
last.tokens.input + last.tokens.output + last.tokens.reasoning + cached
4142
if (tokens <= 0) return
4243

4344
const model = sync.data.provider.find((item) => item.id === last.providerID)?.models[last.modelID]
@@ -49,8 +50,9 @@ export function SubagentFooter() {
4950
currency: "USD",
5051
})
5152

53+
const tokenText = cached > 0 ? `${Locale.number(tokens)} (${Locale.number(cached)} cached)` : Locale.number(tokens)
5254
return {
53-
context: pct ? `${Locale.number(tokens)} (${pct})` : Locale.number(tokens),
55+
context: pct ? `${tokenText} (${pct})` : tokenText,
5456
cost: cost > 0 ? money.format(cost) : undefined,
5557
}
5658
})

0 commit comments

Comments
 (0)