Repository navigation
Conversation
1283cb5 to
da70da6
Compare
|
@jundot — a short note on scope, in case it helps the review. The change is simple in kind but wide in reach: the remaining hardcoded UI strings in the admin dashboard and the macOS app now go through the existing i18n layer, with
Two properties that should keep the review cheap: all nine locales have identical key sets (via Happy to rework the key naming, the structure, or the Chinese wording — please point at whatever you'd rather see done differently, and if it's easier to review in pieces I'm glad to split it. Either way I plan to keep contributing to the oMLX UI and to the zh-Hans localization, so I'd rather get the conventions right here than repeat a pattern you'd have to correct later. |
The web admin and the macOS app still had user-visible copy baked into markup, Alpine expressions and script literals, so those screens could not follow the language setting. This routes them through i18n. 704 new keys: the cluster v2 dashboard (~390 strings across _cluster_v2.html and cluster_v2.js), the dashboard shell and settings (dashboard.js, _settings.html, _logs.html), the model-settings modal and Models screen (~115), Status / Bench / Accuracy / chat (~75), and 15 strings plus 13 catalog entries in the macOS app. Key extraction only - every locale renders the English source for the new keys, exactly as those screens did before this change, so no locale regresses. Translations can land per-locale on top. cluster_v2.js used its display label as a lookup key: requestPhaseLabel() returned 'Failed' | 'Complete' | ... and requestPhaseTone() compared that same string to choose a colour. The function now returns stable ids, the tone switch uses those ids, and the display site translates, so a translation can no longer break the colour lookup. Tests that pinned English copy now assert the i18n keys instead, and the cluster-v2 wizard harness feeds the component the real catalog as window.t so its runtime assertions still read the shipped strings.
669 of the 704 keys are translated; the remaining 35 are product names, acronyms and units (oMLX, Codex, oQ/oQe, GitHub, HuggingFace, bit-widths, ...) whose zh value is intentionally identical to the English. Only zh.json carries values - the other seven catalogs keep the English fallback, so nothing outside Chinese shows Simplified Chinese. Terminology is one translation per English term across every screen, and space-constrained labels use shorter forms than body copy. Typography follows the conventions already established in this catalog: full-width punctuation in Chinese sentences (including parentheses wrapping a placeholder), half-width only for numbers, paths and identifiers, capitalised Token as a common noun, and no ASCII ellipsis.
bcb85a6 to
cec6c9c
Compare
The keys this PR introduced were translated without looking at the macOS
app's catalog, so a number of them shipped a second Chinese rendering for
text the app already translates. 31 values change -- 30 in the web catalog,
1 in the app's -- and every one of them is a key this PR added; no
pre-existing value is touched, because that half lives in the
catalog-audit PR.
Cluster / Bench / Tools 无头节点, 最小, 批次, 预处理 TPS/请求, 已复制
DFlash / SpecPrefill 权重位宽 / 激活位宽 / 分组大小, L2 溢出…驱逐,
约 3 倍…, 较保守
Qwen ANE tuner 调优覆盖, 允许 ANE 运行 GDN, 允许 CPU 性能感知调度
oQ / oQe documentation the app already had this text in Chinese, and the
two copies had drifted apart; the web copy now
matches the app's
Five oQ values keep this PR's own wording instead, because the catalog's
conventions decide them: 位宽分配 for Bit allocation, 相同的 oQ 方案 for Same
oQ plan, 标准 oQ 的作用 for What standard oQ does, 对量化误差加权 for Weight the
quantization error, and scale/bias is kept Latin in the affine-weight step.
Also capitalises Token in the one new value that still had a lower-case
`token`, and replaces straight quotes with the catalog's “” in the one value
that had them.
cec6c9c to
e0b92d3
Compare
|
Superseded, and re-published as two focused PRs against the current This PR bundled two separate concerns: the string migration (routing hardcoded copy through the catalog) and the Simplified Chinese wording for the keys it introduced. They are being re-opened on their own so each can be reviewed for what it is:
Nothing is lost here; the work is the same, just not mixed. |
Three commits, in case you want them separately
feat(i18n): migrate the remaining hardcoded UI strings to i18n— key extraction only. Every locale renders the English source for the new keys, exactly as those screens did before, so no locale regresses at this point.feat(i18n): add Simplified Chinese for the 704 new keys— thezh-Hansvalues, inzh.jsonalone.fix(i18n): align the new values with the app's existing wording— 58 values: 32 that had been translated without looking at the macOS app's catalog, plus the 26 pre-existing values that sit inside the blocks this PR inserts keys into (details at the end).Reviewing them independently is the intent; squash them if you'd rather have one.
I kept this as a single PR rather than splitting migration and translation, because that is the shape this repo already merges: #2540 (localize the Runtime Cache panel) and #2376 (Russian admin localization) both bundle string extraction with the author's translations and regenerate the remaining catalogs as English fallback, which is exactly what happens here. Translation-only PRs also exist (#2415 for zh/zh-TW), but those complete keys that already exist — they don't introduce them.
What this does
704 new keys, 30 files, +7531/−845.
_cluster_v2.html,cluster_v2.jsdashboard.js,_settings.html,_logs.html_modal_model_settings.html,_models.html_status.html,_bench.html,_bench_accuracy.html,chat.html,base.htmlModelSettingsScreen,oMLXApp,WelcomeWindow,AboutScreen,CodeChip,Localizable.xcstringsLocale policy
Only
en.jsonandzh.jsoncarry values. The other seven catalogs were regenerated with the repo's ownscripts/normalize_i18n.py, so the new keys arrive there as the English fallback — no locale outside Chinese shows Simplified Chinese. The macOS catalog is the same: the newLocalizable.xcstringsentries declareen+zh-Hansonly, so every other language falls back to English there too.Of the 704 keys, 669 are translated; the remaining 35 are product names, acronyms and units (
oMLX,Codex,OpenCode,oQ/oQe,GitHub,HuggingFace,DDGS,SSD,ANE, bit-widths, …) whosezhvalue is deliberately identical to the English. Acronyms and mechanism names are left in Latin throughout — MTP, PLE, Engram, GDN, MoE, DFlash, SpecPrefill, TurboQuant, imatrix, rank,sidecar.Translation conventions
Terminology is one translation per English term across every screen — cluster→集群, pool→资源池, split→拆分, slice→分片, prefill→预填充, decode→解码, quantisation→量化, sensitivity→敏感度, draft model→草稿模型, keep rate→保留率, snapshot→快照. Space-constrained labels (tabs, buttons, table headers, badges) take shorter forms than body copy.
The new values were also checked against the values that already shipped, so the same meaning reads the same way on both sides of the migration:
rankstays Latin and lower-case,Tokenis capitalised as the common noun while令牌is the auth token, “this Mac” is 这台 Mac, ModelScope is 魔搭社区, and 缓存 / 热缓存, 提示词, 批大小, 队列 and the留空…sentence pattern all reuse the renderings the existing catalog established. Register matches too — the reader is addressed as 你, full sentences end with 。 and labels do not.Typography follows what this catalog already establishes:
,。:;()) in Chinese sentences; half-width only inside numbers, version strings, paths, model ids and formulas (2.5 位,192.168.1.50:8000,Qwen3.5-0.8B).显示信息({count})in the existing catalog.Tokenis capitalised as a common noun....; the Chinese ellipsis is…, which is also what the newer English strings use.“”rather than corner brackets for Simplified Chinese.(.One behaviour-preserving refactor
cluster_v2.jsused its display label as a lookup key:requestPhaseLabel()returned'Failed' | 'Complete' | 'Prefill' | 'Decode' | 'Queued'andrequestPhaseTone()compared that same string to choose a colour. Translating the return value in place would have broken the tone lookup, so the function now returns stable ids (failed,complete,prefill,decode,queued), the tone switch uses those ids, and the display site translates:window.t('cluster.v2.phase.' + requestPhaseLabel(request)). All five id/tone pairs produce the same classes as before.cluster_v2.jsalso keeps aCLUSTER_V2_STRINGSmap of the English source, used only whenwindow.tis unavailable (offline component tests). It is kept in sync withen.json; all 27 entries match it exactly.Test updates
test_admin_model_settings_template.py,test_admin_audio_upload_ui.py— asserted English copy that is now localised; they assert the keys instead.tests/ui/test_cluster_v2_wizard.py— its harness now feeds the component the real English catalog aswindow.t, so runtime assertions still read the shipped strings; source-level assertions check the keys, and the phase expectations follow the new lowercase ids. (Skipped unlessnodeis on PATH, as before.)Alignment with the macOS app's catalog
The third commit exists because the new strings were translated without comparing them with
apps/omlx-mac/Resources/Localizable.xcstrings, where the macOS app already ships Chinese for text this PR also translates — the oQ / oQe documentation in particular, whose two copies had drifted apart. 58 values change. Thirty-two are keys this PR added. The other twenty-six are pre-existing values that sit inside the blocks this PR inserts keys into — the Cluster v2 strategy and staging chips, plus two bench and usage hints — and they are corrected here rather than in the catalog-audit PR so that the two apply in either order without a conflict inzh.json.Where the two disagreed, the app's wording wins, except where this PR's reads better or the catalog's conventions decide it — 位宽分配 for Bit allocation, 相同的 oQ 方案 for Same oQ plan, 标准 oQ 的作用 for What standard oQ does, 对量化误差加权 for Weight the quantization error, and
scale/biaskept Latin in the affine-weight step.Verification
pytest -m "not slow" -k "admin or i18n or locale or template or ui or cluster or bench or settings"— 3238 passed, 16 skipped, 0 failed on this branch, and the same on a tree with the catalog-audit PR merged on top. (A full-suite run is not reliable in my environment — it dies in an unrelated native module — so the number above is a selection covering everything these changes touch.)t('…')key referenced by a template or script resolves inen.json: 1819 static references, and the only unresolved names are four intentionally dynamic prefixes concatenated with a runtime suffix —cluster.v2.phase.,settings.resource.guard_tier.,settings.resource.guard_tier.reclaim_method.andusage.— all four of which resolve to existing keys.CLUSTER_V2_STRINGSmatchesen.jsonexactly, all 27 entries.Localizable.xcstringsdiff is additive (13 entries) plus the one aligned value.