Skip to content

feat(i18n): show costs in yuan for Simplified Chinese - #1398

Closed
dingxiaobo wants to merge 1 commit into
agegr:mainfrom
dingxiaobo:i18n-cny-costs
Closed

dingxiaobo wants to merge 1 commit into
agegr:mainfrom
dingxiaobo:i18n-cny-costs

Conversation

@dingxiaobo

Copy link
Copy Markdown
Contributor

Costs stay stored in dollars — pi's usage.cost, the models.dev catalog and models.json's unit prices — and only the display converts. lib/money.ts is the one place that converts: zh-CN multiplies by a hardcoded rate (1 USD = 6.69 CNY, taken 2026-10-23), zh-TW and en pass amounts through.

formatCostShort, formatNoticeCost, formatCacheWarmCost and formatCodemodeCost take the locale as their last argument rather than reading context, so they stay pure; components hand in useI18n().locale, and transcriptNoticeText, cacheMissSummaryText and ProcessDetailsGroup pass it down. The one-cent threshold is read in the displayed currency, so $0.002 shows as <$0.01 in English and as ¥0.01 in Simplified Chinese.

Settings › Models keeps its USD unit prices, because those inputs write that value back to models.json, and ProviderUsageSummary keeps each provider's own currency: real balances, not a converted figure.

(cherry picked from commit 8acd89eae96f58665ba88eb792cca3d1bbb92c97)

Costs stay stored in dollars — pi's usage.cost, the models.dev catalog and
models.json's unit prices — and only the display converts. lib/money.ts is
the one place that converts: zh-CN multiplies by a hardcoded rate (1 USD =
6.69 CNY, taken 2026-10-23), zh-TW and en pass amounts through.

formatCostShort, formatNoticeCost, formatCacheWarmCost and
formatCodemodeCost take the locale as their last argument rather than
reading context, so they stay pure; components hand in useI18n().locale,
and transcriptNoticeText, cacheMissSummaryText and ProcessDetailsGroup
pass it down. The one-cent threshold is read in the displayed currency, so
$0.002 shows as <$0.01 in English and as ¥0.01 in Simplified Chinese.

Settings › Models keeps its USD unit prices, because those inputs write
that value back to models.json, and ProviderUsageSummary keeps each
provider's own currency: real balances, not a converted figure.

(cherry picked from commit 8acd89eae96f58665ba88eb792cca3d1bbb92c97)
@agegr

agegr commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Thanks for the careful split between stored and displayed amounts. I'm closing this one, though.

pi records usage.cost in dollars, and the prices behind it (models.dev, models.json) are dollar prices too. Showing yuan means a hard-coded rate that starts going stale the day it is merged, and nothing tells the reader the number is a conversion: ¥ looks like what the provider charged, and it would differ from the provider's bill and from pi's own TUI, which shows $. A UI language picks the words, not the currency. So dollars stay in every language.

@agegr agegr closed this Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants