Files
KimiCodeSwitch/src/i18n/en.ts
T
KimiSwitch Dev 2614f80d0f v0.6.0: 预设供应商 + 供应商账单查询
## 新增

- 15 条主流供应商预设(Kimi Coding / Moonshot / Anthropic /
  DeepSeek / 智谱 GLM / z.ai / 阿里百炼 / MiniMax / StepFun /
  SiliconFlow / Novita / OpenRouter / OpenAI / Google AI Studio /
  火山方舟),通过 PresetPickerModal 一键填表
- 供应商余额/套餐查询(卡片底部 UsageFooter):余额类
  (DeepSeek / SiliconFlow / OpenRouter / StepFun / Novita) +
  套餐类(Kimi For Coding / 智谱 GLM / MiniMax),5min stale TTL +
  force_refresh + 并发 ≤3
- Rust 端 services/ 模块(balance / coding_plan / usage_types),
  参考 cc-switch(MIT,© Jason Young)实现
- query_provider_usage 命令:Rust 端从 config 加载 key,
  不经 IPC 序列化 API key
- usageKinds 持久化到 SQLite settings(JSON 数组),
  load 时合并回 config,导出 config.toml 时不写
- detect_provider 启发式:旧用户升级后自动获得账单支持
- save-time 校验:未完成供应商(缺 api_key / base_url / 模型)
  保存时弹 confirm 列出原因;新增未提交 back 时静默 drop
- docs/PROPOSAL-presets-and-usage.md(v0.4-draft 实施档)
- docs/VERIFICATION-CHECKLIST.md(70+ 项手动验证清单)

## 修复

- handleDuplicateProvider 的 alias.slice 漏洞:老数据
  非规范 alias 复制不再错位
- handleSelectPreset 不再 auto-save,半成品不会落盘
- handleSwitchProvider 校验取消时自动 refresh 回滚,
  不会出现内存改 / 盘没动的脏态

## 文档

- README / README_EN 致谢段补 cc-switch(预设 + 账单)
- README 已知限制与后续建议段(/reload 上游限制调研结论)
- i18n 补 5 条校验 key + 11 条预设 UI key + 12 条账单 key

详见 docs/PROPOSAL-presets-and-usage.md 与
docs/VERIFICATION-CHECKLIST.md
2026-07-29 20:59:53 +08:00

367 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { TranslationKey } from "./zh";
export const enTranslations: Record<TranslationKey, string> = {
// App / global
appTitle: "Kimi Switch",
loading: "Loading...",
loadTimeout: "Loading is taking a while. Try restarting the app if it stays stuck.",
loadFailed: "Failed to load:",
retry: "Retry",
saveConfig: "Save Config",
reloadConfig: "Reload Config",
openConfigDir: "Open Config Dir",
unsavedConfirm: "You have unsaved changes. Are you sure you want to reload?",
validationNoApiKey: "Missing API key",
validationNoBaseUrl: "Missing base URL",
validationNoModels: "No models configured",
validationBlankModels: "Model entries with empty model id: {aliases}",
saveValidationConfirm:
"The following providers are not fully configured. Save anyway?\n\n{details}\n\n(Click OK to save to config.toml as-is; click Cancel to keep editing.)",
providerNotFound: "Provider not found",
backToList: "Back to list",
syncToOmp: "Sync to OMP",
syncedToOmp: "Synced to OMP: ",
ompOverwriteConfirm: "OMP already has provider \"{existing}\". Replace with \"{name}\"?",
deleteProviderConfirm: "Delete provider {name}?",
// Provider list
providers: "Providers",
dashboard: "Dashboard",
sessions: "Sessions",
addProvider: "Add Provider",
noProviders: "No providers yet",
addFirstProvider: "Add first provider",
noUrl: "No URL",
modelCount: "{count} models",
ompActive: "OMP Active",
defaultModel: "Default: {name}",
edit: "Edit",
delete: "Delete",
copyProvider: "Duplicate provider",
testConnectivity: "Test connectivity",
testing: "Testing...",
connectivityOk: "{name} reachable ({latency}ms)",
connectivitySlow: "{name} reachable but slow ({latency}ms)",
connectivityFail: "{name} unreachable: {error}",
copiedProvider: "Duplicated as {name}",
// Provider edit
editProvider: "Edit Provider",
back: "Back",
basicInfo: "Basic Info",
modelMapping: "Model Mapping",
configJson: "Config JSON",
providerName: "Provider Name",
note: "Note",
notePlaceholder: "e.g. company account",
officialUrl: "Official URL",
managedProvider: "Managed provider (no credentials needed)",
apiSettings: "API Settings",
apiFormat: "API Format",
authField: "Auth Field",
apiKey: "API Key",
show: "Show",
hide: "Hide",
requestUrl: "Request URL",
fullUrl: "Full URL",
baseUrlHint: "Enter a {type} API-compatible endpoint without a trailing slash.",
envPairs: "Env pairs",
addEnv: "+ Add",
modelMappingDesc: "Display name only affects the /model menu; 1M declares context capability for Kimi Code.",
oneClickSetup: "One-click setup",
fetchModels: "Fetch models",
fetchingModels: "Fetching...",
discoveredModels: "Discovered {count} models",
addSelected: "Add selected",
displayName: "Display name",
actualModel: "Actual model",
contextSize: "Context size",
supports1M: "Supports 1M",
default: "Default",
operation: "Operation",
isDefault: "Default",
setDefault: "Set default",
deleteModelConfirm: "Delete model {alias}?",
noModelMappings: "No model mappings",
addModelMapping: "+ Add model mapping",
readOnlyPreview: "Editable JSON",
apply: "Apply",
invalidJson: "Invalid JSON: {message}",
clickToSelectIcon: "Click to select icon",
clickToChangeIcon: "Click to change icon",
selectIcon: "Select icon",
clearIcon: "Clear icon",
iconPickerSearch: "Search icons",
iconPickerSearchPlaceholder: "Type an icon name...",
iconPickerNoResults: "No matching icons found",
// Agent / target
target: "Target",
targetKimi: "Kimi Code",
targetOmp: "OMP",
targetQwen: "Qwen Code",
agent: "Agent",
agentKimiCode: "Kimi Code",
agentPi: "Pi",
activate: "Activate",
activated: "Activated",
disabled: "Disabled",
switchTo: "Switch to",
inUse: "In use",
switchReloadHint: "After switching providers, run /reload in Kimi Code to apply the change.",
reloadCopiedHint: "Provider switched. /reload copied to clipboard; paste it in Kimi Code.",
unsavedChanges: "Unsaved changes",
qwenActivateNotImplemented: "Qwen Code activation will be implemented in a follow-up.",
agentSettings: "Global Settings",
enableThinking: "Enable thinking",
thinkingLevel: "Thinking level",
thinkingKeep: "Keep thinking content",
thinkingLow: "Low",
thinkingMedium: "Medium",
thinkingHigh: "High",
thinkingMax: "Max",
thinkingContextHint: "Thinking uses more context. Ensure the model context length and reserved size are sufficient.",
loopControlSettings: "Loop Control",
maxRetriesPerStep: "Max retries per step",
reservedContextSize: "Reserved context size",
backgroundSettings: "Background Tasks",
maxRunningTasks: "Max running tasks",
keepAliveOnExit: "Keep alive on exit",
permissionRules: "Permission Rules",
permissionDecision: "Decision",
permissionPattern: "Pattern",
permissionAllow: "Allow",
permissionDeny: "Deny",
permissionAsk: "Ask",
addRule: "+ Add rule",
addCommonRules: "Add common rules",
hooks: "Lifecycle Hooks",
hookEvent: "Event",
hookMatcher: "Matcher",
hookCommand: "Command",
hookTimeout: "Timeout",
addHook: "+ Add hook",
importConfig: "Import current config",
importConfigConfirm: "Importing will overwrite unsaved changes. Continue?",
importConfigFailed: "Import failed: {message}",
capabilities: "Capabilities",
fetchEnableThinking: "Enable thinking for fetched models",
capThinking: "Thinking",
capAlwaysThinking: "Always Thinking",
capImageIn: "Image Input",
capVideoIn: "Video Input",
capToolUse: "Tool Use",
customCapabilities: "Other capabilities (comma-separated)",
// Sessions
sessionsTitle: "Sessions",
sessionsSubtitle:
"Browse, preview, archive, or delete Kimi Code sessions by workspace. Archiving keeps data on disk.",
workspaces: "Workspaces",
workspaceIsolatedHint: "Sessions are isolated per workspace",
allWorkspaces: "All workspaces",
emptyWorkspace: "Empty",
deleteWorkspace: "Delete workspace",
noSessions: "No sessions",
statusActive: "Active",
statusArchived: "Archived",
statusAll: "All",
selectAll: "Select all",
deselectAll: "Deselect all",
selectedCount: "{n} selected",
archive: "Archive",
unarchive: "Unarchive",
sessionTitle: "Session",
workspace: "Workspace",
status: "Status",
size: "Size",
updated: "Updated",
actions: "Actions",
sessionsInView: "{n} sessions",
isolatedToWorkspace: "this workspace only",
openPreview: "Open preview",
scanning: "Scanning…",
refresh: "Refresh",
refreshing: "Refreshing…",
refreshed: "Refreshed",
cancel: "Cancel",
confirmDeleteTitle: "Delete session forever?",
confirmDeleteSession:
"This cannot be undone. Prefer archive if you only want it out of the way.",
confirmBulkTitle: "Delete selected forever?",
confirmBulkDelete: "Permanently delete {n} sessions. This cannot be undone.",
confirmDeleteWorkspaceTitle: "Delete empty workspace?",
confirmDeleteWorkspace: "Only workspaces with no sessions can be removed.",
deleteForever: "Delete forever",
previewTitle: "Session preview",
previewHint:
"Roles and truncated text only — secrets and raw tool dumps are omitted.",
previewEmpty: "No previewable messages",
previewTruncated: "Preview truncated",
roleUser: "User",
roleAssistant: "Assistant",
roleSystem: "System",
// Heatmap
noData: "No data",
heatLess: "Less",
heatMore: "More",
requests: "Requests",
cacheHitRate: "Cache hit rate",
// Daily detail modal
dayDetail: "Daily usage detail",
close: "Close",
totalTokens: "Total tokens",
cost: "Cost",
modelDistribution: "Model distribution",
providerDistribution: "Provider distribution",
modalEscHint: "Press Esc or click outside to close",
doubleClickHint: "Double-click for details",
// Languages
language: "Language",
zh: "中文",
en: "English",
// Theme & Settings
themeLight: "Light",
themeDark: "Dark",
themeAuto: "Auto",
settings: "Settings",
settingsTitle: "Settings",
settingsAppearance: "Appearance",
settingsUpdates: "Updates",
settingsAbout: "About",
checkUpdate: "Check for updates",
checking: "Checking…",
upToDate: "You're up to date",
updateAvailable: "Update available",
currentVersion: "Current version",
latestVersion: "Latest version",
downloadUpdate: "Download update",
downloading: "Downloading…",
downloadComplete: "Download complete, click to install",
install: "Install",
updateCheckFailed: "Update check failed",
lastChecked: "Last checked",
appDescription: "Windows desktop LLM provider config manager",
referenceProject: "Reference project",
// Validation errors
emptyProviderName: "Provider name is empty",
duplicateProviderName: "Duplicate provider name: {0}",
missingCredentials: "Provider '{0}' is missing credentials (api_key or env key)",
ambiguousCredentials: "Provider '{0}' has both direct and env credentials; only one source is allowed",
missingVertexProject: "Vertex provider '{0}' is missing GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_LOCATION",
emptyModelAlias: "Model alias is empty",
duplicateModelAlias: "Duplicate model alias: {0}",
unknownModelProvider: "Model '{0}' references unknown provider '{1}'",
emptyModelId: "Model '{0}' has an empty model ID",
invalidMaxContextSize: "Model '{0}' has an invalid max_context_size",
// Dashboard — ranges / status
rangeToday: "Today",
range7d: "7d",
range30d: "30d",
rangeAll: "All",
dashLoadFailed: "Failed to load",
// Dashboard — KPI labels
kpiRequests: "Requests",
kpiInputOther: "Non-cached input",
kpiOutput: "Output",
kpiCacheRead: "Cache read",
kpiCacheCreation: "Cache creation",
kpiCacheHit: "Cache hit",
kpiCost: "Est. cost",
// Dashboard — cards
cardHeatmap: "Full-year heatmap",
cardHeatmapSub: "Coloured by token volume",
cardDailyTrend: "Usage trend",
cardDailyTrendSubCapped: "Last 30 days · {n} days total",
tabModelTrend: "Model usage trend",
tabProviderTrend: "Provider–model usage trend",
providerUnknown: "Unknown provider",
cardDailyTrendSub: "{n} days",
cardModelUsage: "Model usage",
cardModelUsageSub: "{n} models",
cardRecent: "Recent requests",
cardRecentCapped: "Showing first {n} / {m}",
cardRecentCount: "{n} entries",
// Dashboard — table columns / units
colModel: "Model",
colTokens: "Tokens",
colCacheHit: "Cache hit",
colTime: "Time",
colInput: "Input",
colOutput: "Output",
colCacheRead: "Cache read",
unitTimes: "requests",
estimate: "est.",
collapse: "Collapse",
expandAll: "Expand all ({n})",
// Dashboard — pagination
paginationPage: "Page {x} / {y}",
paginationRange: "{x}–{y}",
paginationPerPage: "{n} per page",
pageFirst: "First",
pagePrev: "Previous",
pageNext: "Next",
pageLast: "Last",
// Dashboard — footer / attribution
footerScanned: "Scanned {n} files · {m} records",
dashboardAttribution: "Dashboard ported from",
sessionsAttribution: "Session manager ported from",
attributionSuffix: "(MIT, © JochenYang)",
// Sessions — preview
previewCollapseChars: "Collapse · {n} chars",
previewExpandChars: "Expand · {n} chars",
// Provider presets
presetPickerTitle: "Choose a provider preset",
presetSearchPlaceholder: "Search presets...",
presetSortOriginal: "Default",
presetSortAlpha: "A-Z",
presetNoResults: "No matching presets",
presetCustomConfig: "+ Custom configuration",
presetFooterHint: "Presets only pre-fill the form; every field stays editable afterwards.",
presetCategoryOfficial: "Official",
presetCategoryCnOfficial: "China",
presetCategoryThirdParty: "Third-party",
presetCategoryAggregator: "Aggregator",
presetNameAnthropic: "Anthropic",
presetNameKimiCoding: "Kimi For Coding",
presetNameMoonshot: "Moonshot Platform",
presetNameDeepseek: "DeepSeek",
presetNameZhipu: "Zhipu GLM",
presetNameZai: "z.ai (Zhipu Global)",
presetNameBailian: "Alibaba Bailian",
presetNameMinimax: "MiniMax",
presetNameStepfun: "StepFun",
presetNameSiliconflow: "SiliconFlow",
presetNameNovita: "Novita AI",
presetNameOpenrouter: "OpenRouter",
presetNameOpenai: "OpenAI",
presetNameGoogleGenai: "Google AI Studio",
presetNameVolcengine: "Volcengine Ark",
// Provider usage
usageBalance: "Balance",
usageUsed: "used",
usageRemaining: "left",
usageRefresh: "Refresh",
usageRetry: "Retry",
usageQueryFailed: "Query failed",
usageNetworkError: "Network error",
usageInvalidKey: "Invalid API key",
usageResetIn: "resets in {time}",
usageResetDone: "reset",
usageLoading: "Querying…",
};