Skip to content

Commit d686247

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 dba03a7 commit d686247

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
@@ -188,15 +188,17 @@ export function Prompt(props: PromptProps) {
188188
const last = msg.findLast((item): item is AssistantMessage => item.role === "assistant" && item.tokens.output > 0)
189189
if (!last) return
190190

191+
const cached = last.tokens.cache.read + last.tokens.cache.write
191192
const tokens =
192-
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
193+
last.tokens.input + last.tokens.output + last.tokens.reasoning + cached
193194
if (tokens <= 0) return
194195

195196
const model = sync.data.provider.find((item) => item.id === last.providerID)?.models[last.modelID]
196197
const pct = model?.limit.context ? `${Math.round((tokens / model.limit.context) * 100)}%` : undefined
197198
const cost = msg.reduce((sum, item) => sum + (item.role === "assistant" ? item.cost : 0), 0)
199+
const tokenText = cached > 0 ? `${Locale.number(tokens)} (${Locale.number(cached)} cached)` : Locale.number(tokens)
198200
return {
199-
context: pct ? `${Locale.number(tokens)} (${pct})` : Locale.number(tokens),
201+
context: pct ? `${tokenText} (${pct})` : tokenText,
200202
cost: cost > 0 ? money.format(cost) : undefined,
201203
}
202204
})

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)