feat(ui): show session cost in VS Code context usage readout (#2991)

Share the desktop session-card currency formatter (lib/money.ts) and surface
the current session's cost in the extension chat-header context usage tooltip.
This commit is contained in:
Yun Feng
2026-08-19 00:34:23 +03:00
committed by GitHub
parent 47525c0cf5
commit 36ce73f753
16 changed files with 58 additions and 11 deletions
+2
View File
@@ -1284,10 +1284,12 @@ export const dict = {
'contextUsage.mobile.usedTokens': 'Verwendete Tokens',
'contextUsage.mobile.contextLimit': 'Kontextlimit',
'contextUsage.mobile.outputLimit': 'Ausgabelimit',
'contextUsage.mobile.cost': 'Kosten',
'contextUsage.mobile.usage': 'Nutzung',
'contextUsage.tooltip.usedTokens': 'Verwendete Tokens: {tokens}',
'contextUsage.tooltip.contextLimit': 'Kontextlimit: {tokens}',
'contextUsage.tooltip.outputLimit': 'Ausgabelimit: {tokens}',
'contextUsage.tooltip.cost': 'Kosten: {cost}',
'contextSidebar.session.untitled': 'Unbenannte Sitzung',
'contextSidebar.empty.openSession': 'Öffnen Sie eine Sitzung, um den Kontext zu prüfen.',
'contextSidebar.section.context': 'Kontext',
+2
View File
@@ -1437,10 +1437,12 @@ export const dict = {
'contextUsage.mobile.usedTokens': 'Used tokens',
'contextUsage.mobile.contextLimit': 'Context limit',
'contextUsage.mobile.outputLimit': 'Output limit',
'contextUsage.mobile.cost': 'Cost',
'contextUsage.mobile.usage': 'Usage',
'contextUsage.tooltip.usedTokens': 'Used tokens: {tokens}',
'contextUsage.tooltip.contextLimit': 'Context limit: {tokens}',
'contextUsage.tooltip.outputLimit': 'Output limit: {tokens}',
'contextUsage.tooltip.cost': 'Cost: {cost}',
'contextSidebar.session.untitled': 'Untitled Session',
'contextSidebar.empty.openSession': 'Open a session to inspect context.',
'contextSidebar.section.context': 'Context',
+2
View File
@@ -1403,10 +1403,12 @@ export const dict: Record<I18nKey, string> = {
"contextUsage.mobile.usedTokens": "Tokens usados",
"contextUsage.mobile.contextLimit": "Límite de contexto",
"contextUsage.mobile.outputLimit": "Límite de salida",
"contextUsage.mobile.cost": "Costo",
"contextUsage.mobile.usage": "Uso",
"contextUsage.tooltip.usedTokens": "Tokens usados: {tokens}",
"contextUsage.tooltip.contextLimit": "Límite de contexto: {tokens}",
"contextUsage.tooltip.outputLimit": "Límite de salida: {tokens}",
"contextUsage.tooltip.cost": "Costo: {cost}",
"contextSidebar.session.untitled": "Sesión sin título",
"contextSidebar.empty.openSession": "Abrir una sesión para inspeccionar el contexto.",
"contextSidebar.section.context": "Contexto",
+2
View File
@@ -1202,10 +1202,12 @@ export const dict = {
'contextUsage.mobile.usedTokens': 'Jetons utilisés',
'contextUsage.mobile.contextLimit': 'Limite de contexte',
'contextUsage.mobile.outputLimit': 'Limite de sortie',
'contextUsage.mobile.cost': 'Coût',
'contextUsage.mobile.usage': 'Usage',
'contextUsage.tooltip.usedTokens': 'Jetons utilisés : {tokens}',
'contextUsage.tooltip.contextLimit': 'Limite de contexte : {tokens}',
'contextUsage.tooltip.outputLimit': 'Limite de sortie : {tokens}',
'contextUsage.tooltip.cost': 'Coût : {cost}',
'contextSidebar.session.untitled': 'Session sans titre',
'contextSidebar.empty.openSession': 'Ouvrez une session pour inspecter le contexte.',
'contextSidebar.section.context': 'Contexte',
+2
View File
@@ -1433,10 +1433,12 @@ export const dict: Record<I18nKey, string> = {
'contextUsage.mobile.usedTokens': '使用トークン',
'contextUsage.mobile.contextLimit': 'コンテキスト制限',
'contextUsage.mobile.outputLimit': '出力制限',
'contextUsage.mobile.cost': 'コスト',
'contextUsage.mobile.usage': '使用量',
'contextUsage.tooltip.usedTokens': '使用トークン: {tokens}',
'contextUsage.tooltip.contextLimit': 'コンテキスト制限: {tokens}',
'contextUsage.tooltip.outputLimit': '出力制限: {tokens}',
'contextUsage.tooltip.cost': 'コスト: {cost}',
'contextSidebar.session.untitled': '無題のセッション',
'contextSidebar.empty.openSession': 'セッションを開いてコンテキストを確認します。',
'contextSidebar.section.context': 'コンテキスト',
+2
View File
@@ -1439,10 +1439,12 @@ export const dict: Record<I18nKey, string> = {
'contextUsage.mobile.usedTokens': '사용한 토큰',
'contextUsage.mobile.contextLimit': '컨텍스트 한도',
'contextUsage.mobile.outputLimit': '출력 한도',
'contextUsage.mobile.cost': '비용',
'contextUsage.mobile.usage': '사용량',
'contextUsage.tooltip.usedTokens': '사용됨 토큰: {tokens}',
'contextUsage.tooltip.contextLimit': '컨텍스트 한도: {tokens}',
'contextUsage.tooltip.outputLimit': '출력 한도: {tokens}',
'contextUsage.tooltip.cost': '비용: {cost}',
'contextSidebar.session.untitled': '제목 없는 세션',
'contextSidebar.empty.openSession': '컨텍스트를 볼 세션을 여세요.',
'contextSidebar.section.context': '컨텍스트',
+2
View File
@@ -1639,11 +1639,13 @@ export const dict: Record<I18nKey, string> = {
'contextUsage.aria.label': 'Użycie kontekstu',
'contextUsage.mobile.contextLimit': 'Limit kontekstu',
'contextUsage.mobile.outputLimit': 'Limit wyjścia',
'contextUsage.mobile.cost': 'Koszt',
'contextUsage.mobile.title': 'Użycie kontekstu',
'contextUsage.mobile.usage': 'Zużycie',
'contextUsage.mobile.usedTokens': 'Zużyte tokeny',
'contextUsage.tooltip.contextLimit': 'Limit kontekstu: {tokens}',
'contextUsage.tooltip.outputLimit': 'Limit wyjścia: {tokens}',
'contextUsage.tooltip.cost': 'Koszt: {cost}',
'contextUsage.tooltip.usedTokens': 'Zużyte tokeny: {tokens}',
'desktopHostSwitcher.actions.add': 'Dodaj',
'desktopHostSwitcher.actions.addInstance': 'Dodaj instancję',
@@ -1403,10 +1403,12 @@ export const dict: Record<I18nKey, string> = {
"contextUsage.mobile.usedTokens": "Tokens usados",
"contextUsage.mobile.contextLimit": "Limite de contexto",
"contextUsage.mobile.outputLimit": "Limite de saída",
"contextUsage.mobile.cost": "Custo",
"contextUsage.mobile.usage": "Uso",
"contextUsage.tooltip.usedTokens": "Tokens usados: {tokens}",
"contextUsage.tooltip.contextLimit": "Limite de contexto: {tokens}",
"contextUsage.tooltip.outputLimit": "Limite de saída: {tokens}",
"contextUsage.tooltip.cost": "Custo: {cost}",
"contextSidebar.session.untitled": "Sessão sem título",
"contextSidebar.empty.openSession": "Abrir uma sessão para inspecionar o contexto.",
"contextSidebar.section.context": "Contexto",
+2
View File
@@ -1403,10 +1403,12 @@ export const dict: Record<I18nKey, string> = {
"contextUsage.mobile.usedTokens": "Використані токени",
"contextUsage.mobile.contextLimit": "Обмеження контексту",
"contextUsage.mobile.outputLimit": "Ліміт виводу",
"contextUsage.mobile.cost": "Вартість",
"contextUsage.mobile.usage": "Використання",
"contextUsage.tooltip.usedTokens": "Використані токени: {tokens}",
"contextUsage.tooltip.contextLimit": "Обмеження контексту: {tokens}",
"contextUsage.tooltip.outputLimit": "Ліміт виводу: {tokens}",
"contextUsage.tooltip.cost": "Вартість: {cost}",
"contextSidebar.session.untitled": "Сесія без назви",
"contextSidebar.empty.openSession": "Відкрийте сесію, щоб перевірити контекст.",
"contextSidebar.section.context": "Контекст",
@@ -1403,10 +1403,12 @@ export const dict: Record<I18nKey, string> = {
'contextUsage.mobile.usedTokens': '已用 Token',
'contextUsage.mobile.contextLimit': '上下文上限',
'contextUsage.mobile.outputLimit': '输出上限',
'contextUsage.mobile.cost': '成本',
'contextUsage.mobile.usage': '使用率',
'contextUsage.tooltip.usedTokens': '已用 Token{tokens}',
'contextUsage.tooltip.contextLimit': '上下文上限:{tokens}',
'contextUsage.tooltip.outputLimit': '输出上限:{tokens}',
'contextUsage.tooltip.cost': '成本:{cost}',
'contextSidebar.session.untitled': '未命名会话',
'contextSidebar.empty.openSession': '请先打开会话以查看上下文。',
'contextSidebar.section.context': '上下文',
@@ -1413,10 +1413,12 @@ export const dict: Record<I18nKey, string> = {
'contextUsage.mobile.usedTokens': '已用 Token',
'contextUsage.mobile.contextLimit': '上下文上限',
'contextUsage.mobile.outputLimit': '輸出上限',
'contextUsage.mobile.cost': '成本',
'contextUsage.mobile.usage': '使用率',
'contextUsage.tooltip.usedTokens': '已用 Token{tokens}',
'contextUsage.tooltip.contextLimit': '上下文上限:{tokens}',
'contextUsage.tooltip.outputLimit': '輸出上限:{tokens}',
'contextUsage.tooltip.cost': '成本:{cost}',
'contextSidebar.session.untitled': '未命名會話',
'contextSidebar.empty.openSession': '請先開啟會話以查看上下文。',
'contextSidebar.section.context': '上下文',
+19
View File
@@ -0,0 +1,19 @@
import { getCurrentIntlLocale } from './i18n';
export const formatMoney = (value: number): string => {
if (!Number.isFinite(value) || value <= 0) {
return new Intl.NumberFormat(getCurrentIntlLocale(), {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(0);
}
return new Intl.NumberFormat(getCurrentIntlLocale(), {
style: 'currency',
currency: 'USD',
minimumFractionDigits: value < 0.01 ? 4 : 2,
maximumFractionDigits: value < 0.01 ? 4 : 2,
}).format(value);
};