|
|
@@ -0,0 +1,516 @@
|
|
|
+{
|
|
|
+ "zh-CN": {
|
|
|
+ "providers": {
|
|
|
+ "section": {
|
|
|
+ "title": "服务商管理",
|
|
|
+ "description": "配置上游服务商的金额限流和并发限制,留空表示无限制。"
|
|
|
+ },
|
|
|
+ "addProvider": "新增服务商",
|
|
|
+ "editProvider": "编辑服务商",
|
|
|
+ "createProvider": "新增服务商",
|
|
|
+ "updateFailed": "更新服务商失败",
|
|
|
+ "deleteSuccess": "删除成功",
|
|
|
+ "confirmDeleteDesc": "确定要删除供应商 \"{name}\" 吗?此操作无法撤销。",
|
|
|
+ "confirmDeleteProvider": "确认删除供应商?",
|
|
|
+ "confirmDeleteProviderDesc": "确定要删除服务商\"{name}\"吗?此操作不可恢复。",
|
|
|
+ "noProviders": "暂无服务商配置",
|
|
|
+ "noProvidersDesc": "添加你的第一个 API 服务商",
|
|
|
+ "toggleSuccess": "供应商已{status}",
|
|
|
+ "toggleSuccessDesc": "供应商 \"{name}\" 状态已更新",
|
|
|
+ "toggleFailed": "状态切换失败",
|
|
|
+ "enabledStatus": "启用",
|
|
|
+ "disabledStatus": "禁用",
|
|
|
+ "searchResults": "找到 {count} 个匹配的供应商",
|
|
|
+ "searchNoResults": "未找到匹配的供应商",
|
|
|
+ "displayCount": "显示 {filtered} / {total} 个供应商",
|
|
|
+ "todayUsage": "今日用量",
|
|
|
+ "todayUsageCount": "{count} 次",
|
|
|
+ "circuitBroken": "熔断中",
|
|
|
+ "official": "官网",
|
|
|
+ "viewKey": "查看完整 API Key",
|
|
|
+ "viewKeyDesc": "请妥善保管,不要泄露给他人",
|
|
|
+ "keyLoading": "加载中...",
|
|
|
+ "resetCircuit": "熔断器已重置",
|
|
|
+ "resetCircuitDesc": "供应商 \"{name}\" 的熔断状态已解除",
|
|
|
+ "resetCircuitFailed": "重置熔断器失败",
|
|
|
+ "form": {
|
|
|
+ "providerName": "服务商名称",
|
|
|
+ "providerNameRequired": "服务商名称 *",
|
|
|
+ "providerNamePlaceholder": "例如: 智谱",
|
|
|
+ "apiAddress": "API 地址",
|
|
|
+ "apiAddressRequired": "API 地址 *",
|
|
|
+ "apiAddressPlaceholder": "例如: https://open.bigmodel.cn/api/anthropic",
|
|
|
+ "apiKeyRequired": "API 密钥 *",
|
|
|
+ "apiKeyLeaveEmpty": "(留空不更改)",
|
|
|
+ "apiKeyLeaveEmptyDesc": "留空则不更改密钥",
|
|
|
+ "apiKeyCurrent": "当前密钥:",
|
|
|
+ "websiteUrl": "供应商官网地址",
|
|
|
+ "websiteUrlPlaceholder": "https://example.com",
|
|
|
+ "websiteUrlDesc": "供应商官网地址,用于快速跳转管理",
|
|
|
+ "websiteUrlInvalid": "请输入有效的供应商官网地址",
|
|
|
+ "expandAll": "展开全部高级配置",
|
|
|
+ "collapseAll": "折叠全部高级配置",
|
|
|
+ "routingConfig": "路由配置",
|
|
|
+ "routingConfigSummary": "{models} 个模型白名单, {redirects} 个重定向",
|
|
|
+ "routingConfigNone": "未配置",
|
|
|
+ "providerTypeDesc": "选择供应商的 API 格式类型。",
|
|
|
+ "providerTypeDisabledNote": "注:Gemini CLI 和 OpenAI Compatible 类型功能正在开发中,暂不可用",
|
|
|
+ "modelRedirectsLabel": "模型重定向配置",
|
|
|
+ "modelRedirectsOptional": "(可选)",
|
|
|
+ "modelRedirectsDesc": "将 Claude Code 客户端请求的模型(如 claude-sonnet-4.5)重定向到上游供应商实际支持的模型(如 glm-4.6、gemini-pro)。用于成本优化或接入第三方 AI 服务。",
|
|
|
+ "modelRedirectsEmpty": "暂无重定向规则。添加规则后,系统将自动重写请求中的模型名称。",
|
|
|
+ "modelRedirectsCurrentRules": "当前规则 ({count})",
|
|
|
+ "modelRedirectsAddNew": "添加新规则",
|
|
|
+ "modelRedirectsSourceModel": "用户请求的模型",
|
|
|
+ "modelRedirectsSourcePlaceholder": "例如: claude-sonnet-4-5-20250929",
|
|
|
+ "modelRedirectsTargetModel": "实际转发的模型",
|
|
|
+ "modelRedirectsTargetPlaceholder": "例如: glm-4.6",
|
|
|
+ "modelRedirectsSourceRequired": "源模型名称不能为空",
|
|
|
+ "modelRedirectsTargetRequired": "目标模型名称不能为空",
|
|
|
+ "modelRedirectsExists": "模型 \"{model}\" 已存在重定向规则",
|
|
|
+ "joinClaudePool": "加入 Claude 调度池",
|
|
|
+ "joinClaudePoolDesc": "启用后,此供应商将与 Claude 类型供应商一起参与负载均衡调度",
|
|
|
+ "joinClaudePoolHelp": "仅当模型重定向配置中存在映射到 claude-* 模型时可用。启用后,当用户请求 claude-* 模型时,此供应商也会参与调度选择。",
|
|
|
+ "modelWhitelist": "模型白名单",
|
|
|
+ "modelWhitelistDesc": "限制此供应商可以处理的模型。默认情况下,供应商可以处理该类型下的所有模型。",
|
|
|
+ "modelWhitelistLabel": "允许的模型",
|
|
|
+ "modelWhitelistSelected": "已选择 {count} 个模型",
|
|
|
+ "modelWhitelistLoading": "加载中...",
|
|
|
+ "modelWhitelistNotFound": "未找到模型",
|
|
|
+ "modelWhitelistSearchPlaceholder": "搜索模型名称...",
|
|
|
+ "modelWhitelistSelectAll": "全选 ({count})",
|
|
|
+ "modelWhitelistClear": "清空",
|
|
|
+ "modelWhitelistManualAdd": "手动添加模型",
|
|
|
+ "modelWhitelistManualPlaceholder": "输入模型名称(如 gpt-5-turbo)",
|
|
|
+ "modelWhitelistManualDesc": "支持添加任意模型名称(不限于价格表中的模型)",
|
|
|
+ "modelWhitelistAllowAll": "允许所有 {type} 模型",
|
|
|
+ "modelWhitelistAllowAllClause": "允许所有 Claude 模型",
|
|
|
+ "modelWhitelistAllowAllOpenAI": "允许所有 OpenAI 模型",
|
|
|
+ "modelWhitelistSelectedOnly": "仅允许选中的 {count} 个模型。其他模型的请求不会调度到此供应商。",
|
|
|
+ "scheduleParams": "调度参数",
|
|
|
+ "priorityLabel": "优先级",
|
|
|
+ "priorityDesc": "数值越小优先级越高(0 最高)。系统只从最高优先级的供应商中选择。建议:主力=0,备用=1,紧急备份=2",
|
|
|
+ "priorityPlaceholder": "0",
|
|
|
+ "weightLabel": "权重",
|
|
|
+ "weightDesc": "加权随机概率。同优先级内,权重越高被选中概率越大。例如权重 1:2:3 的概率为 16%:33%:50%",
|
|
|
+ "weightPlaceholder": "1",
|
|
|
+ "costMultiplierLabel": "成本倍率",
|
|
|
+ "costMultiplierDesc": "成本计算倍数。官方供应商=1.0,便宜 20%=0.8,贵 20%=1.2(支持最多 4 位小数)",
|
|
|
+ "costMultiplierPlaceholder": "1.0",
|
|
|
+ "providerGroupLabel": "供应商分组",
|
|
|
+ "providerGroupPlaceholder": "例如: premium, economy",
|
|
|
+ "providerGroupDesc": "供应商分组标签。只有用户的 providerGroup 与此值匹配时,该用户才能使用此供应商。示例:设置为 \"premium\" 表示只供 providerGroup=\"premium\" 的用户使用",
|
|
|
+ "rateLimitConfig": "限流配置",
|
|
|
+ "rateLimitConfigSummary": "5h: ${fiveHour}, 周: ${weekly}, 月: ${monthly}, 并发: {concurrent}",
|
|
|
+ "rateLimitConfigNone": "无限制",
|
|
|
+ "limit5hLabel": "5小时消费上限 (USD)",
|
|
|
+ "limitWeeklyLabel": "周消费上限 (USD)",
|
|
|
+ "limitMonthlyLabel": "月消费上限 (USD)",
|
|
|
+ "limitConcurrentLabel": "并发 Session 上限",
|
|
|
+ "limitPlaceholderUnlimited": "留空表示无限制",
|
|
|
+ "limitPlaceholder0": "0 表示无限制",
|
|
|
+ "circuitBreakerConfig": "熔断器配置",
|
|
|
+ "circuitBreakerConfigSummary": "{failureThreshold} 次失败 / {openDuration} 分钟熔断 / {successThreshold} 次成功恢复",
|
|
|
+ "circuitBreakerDesc": "供应商连续失败时自动熔断,避免影响整体服务质量",
|
|
|
+ "failureThreshold": "失败阈值(次)",
|
|
|
+ "failureThresholdPlaceholder": "5",
|
|
|
+ "failureThresholdDesc": "连续失败多少次后触发熔断",
|
|
|
+ "openDuration": "熔断时长(分钟)",
|
|
|
+ "openDurationPlaceholder": "30",
|
|
|
+ "openDurationDesc": "熔断后多久自动进入半开状态",
|
|
|
+ "successThreshold": "恢复阈值(次)",
|
|
|
+ "successThresholdPlaceholder": "2",
|
|
|
+ "successThresholdDesc": "半开状态下成功多少次后完全恢复",
|
|
|
+ "proxyConfig": "代理配置",
|
|
|
+ "proxyConfigSummary": "已配置代理",
|
|
|
+ "proxyConfigSummaryFallback": " (启用降级)",
|
|
|
+ "proxyConfigNone": "未配置",
|
|
|
+ "proxyConfigDesc": "配置代理服务器以改善供应商连接性(支持 HTTP、HTTPS、SOCKS4、SOCKS5)",
|
|
|
+ "proxyAddressLabel": "代理地址",
|
|
|
+ "proxyAddressOptional": "(可选)",
|
|
|
+ "proxyAddressPlaceholder": "例如: http://proxy.example.com:8080 或 socks5://127.0.0.1:1080",
|
|
|
+ "proxyAddressFormats": "支持格式:",
|
|
|
+ "proxyFallbackLabel": "代理失败时降级到直连",
|
|
|
+ "proxyFallbackDesc": "启用后,代理连接失败时自动尝试直接连接供应商",
|
|
|
+ "proxyTestLabel": "连接测试",
|
|
|
+ "proxyTestButton": "测试连接",
|
|
|
+ "proxyTestTesting": "测试中...",
|
|
|
+ "proxyTestSuccess": "连接成功",
|
|
|
+ "proxyTestFailed": "连接失败",
|
|
|
+ "proxyTestDesc": "测试通过配置的代理访问供应商 URL(使用 HEAD 请求,不消耗额度)",
|
|
|
+ "proxyTestFillUrl": "请先填写供应商 URL",
|
|
|
+ "proxyTestResultSuccess": "连接成功 {via}",
|
|
|
+ "proxyTestViaProxy": "(通过代理)",
|
|
|
+ "proxyTestViaDirect": "(直连)",
|
|
|
+ "proxyTestResponseTime": "响应时间: {time}",
|
|
|
+ "proxyTestStatusCode": "| 状态码: {code}",
|
|
|
+ "proxyTestResultFailed": "连接失败",
|
|
|
+ "proxyTestTimeout": "连接超时(5秒)。请检查:\n1. 代理服务器是否可访问\n2. 代理地址和端口是否正确\n3. 代理认证信息是否正确",
|
|
|
+ "proxyTestProxyError": "代理错误: {error}",
|
|
|
+ "proxyTestNetworkError": "网络错误: {error}",
|
|
|
+ "proxyTestResultMessage": "{message}",
|
|
|
+ "proxyTestResultStatusCode": "状态码: {code}",
|
|
|
+ "proxyTestResultResponseTime": "响应时间: {time}ms",
|
|
|
+ "proxyTestResultConnectionMethod": "连接方式: {via}",
|
|
|
+ "proxyTestResultConnectionMethodProxy": "代理",
|
|
|
+ "proxyTestResultConnectionMethodDirect": "直连",
|
|
|
+ "proxyTestResultErrorType": "错误类型: {type}",
|
|
|
+ "codexStrategyConfig": "Codex Instructions 策略",
|
|
|
+ "codexStrategyConfigAuto": "自动 (推荐)",
|
|
|
+ "codexStrategyConfigForce": "强制官方",
|
|
|
+ "codexStrategyConfigKeep": "透传原样",
|
|
|
+ "codexStrategyDesc": "控制如何处理 Codex 请求的 instructions 字段,影响与上游中转站的兼容性",
|
|
|
+ "codexStrategySelect": "策略选择",
|
|
|
+ "codexStrategyAutoLabel": "自动 (推荐)",
|
|
|
+ "codexStrategyAutoDesc": "透传客户端 instructions,400 错误时自动重试官方 prompt",
|
|
|
+ "codexStrategyForceLabel": "强制官方",
|
|
|
+ "codexStrategyForceDesc": "始终使用官方 Codex CLI instructions(约 4000+ 字)",
|
|
|
+ "codexStrategyKeepLabel": "透传原样",
|
|
|
+ "codexStrategyKeepDesc": "始终透传客户端 instructions,不自动重试(适用于宽松中转站)",
|
|
|
+ "codexStrategyHint": "提示: 部分严格的 Codex 中转站(如 88code、foxcode)需要官方 instructions,选择\"自动\"或\"强制官方\"策略",
|
|
|
+ "confirmAdd": "确认添加",
|
|
|
+ "confirmUpdate": "确认更新",
|
|
|
+ "confirmAddPending": "添加中...",
|
|
|
+ "confirmUpdatePending": "更新中...",
|
|
|
+ "deleteButton": "删除",
|
|
|
+ "validUrlRequired": "请输入有效的 API 地址",
|
|
|
+ "filterProvider": "筛选供应商类型",
|
|
|
+ "filterAllProviders": "全部供应商",
|
|
|
+ "searchClear": "清除搜索"
|
|
|
+ },
|
|
|
+ "guide": {
|
|
|
+ "title": "核心原则",
|
|
|
+ "priorityFirst": "1️⃣ 优先级优先:只从最高优先级(数值最小)的供应商中选择",
|
|
|
+ "costOptimize": "2️⃣ 成本优化:同优先级内,成本倍率低的供应商有更高概率",
|
|
|
+ "healthFilter": "3️⃣ 健康过滤:自动跳过熔断或超限的供应商",
|
|
|
+ "sessionReuse": "4️⃣ 会话复用:连续对话复用同一供应商,节省上下文成本",
|
|
|
+ "scenariosTitle": "交互式场景演示",
|
|
|
+ "bestPracticesTitle": "最佳实践建议",
|
|
|
+ "bestPracticesPriority": "• 优先级设置:核心供应商设为 0,备用供应商设为 1-3",
|
|
|
+ "bestPracticesWeight": "• 权重配置:根据供应商容量设置权重(容量大 = 权重高)",
|
|
|
+ "bestPracticesCost": "• 成本倍率:官方倍率为 1.0,自建服务可设置为 0.8-1.2",
|
|
|
+ "bestPracticesLimit": "• 限额设置:根据预算设置 5 小时、7 天、30 天限额",
|
|
|
+ "bestPracticesConcurrent": "• 并发控制:根据供应商 API 限制设置 Session 并发数",
|
|
|
+ "scenario1Title": "优先级分层选择",
|
|
|
+ "scenario1Desc": "系统首先按优先级过滤,只从最高优先级的供应商中选择",
|
|
|
+ "scenario1Step1": "初始状态",
|
|
|
+ "scenario1Step1Desc": "有 4 个已启用的供应商,优先级各不相同",
|
|
|
+ "scenario1Step1Before": "供应商 A (优先级 0), B (优先级 1), C (优先级 0), D (优先级 2)",
|
|
|
+ "scenario1Step1After": "筛选出最高优先级(0)的供应商:A, C",
|
|
|
+ "scenario1Step1Decision": "只从 A 和 C 中选择,B 和 D 被过滤",
|
|
|
+ "scenario1Step2": "成本排序",
|
|
|
+ "scenario1Step2Desc": "在同优先级内,按成本倍率从低到高排序",
|
|
|
+ "scenario1Step2Before": "A (成本 1.0x), C (成本 0.8x)",
|
|
|
+ "scenario1Step2After": "排序后:C (0.8x), A (1.0x)",
|
|
|
+ "scenario1Step2Decision": "成本更低的 C 有更高的被选中概率",
|
|
|
+ "scenario1Step3": "加权随机",
|
|
|
+ "scenario1Step3Desc": "使用权重进行随机选择,权重越高被选中概率越大",
|
|
|
+ "scenario1Step3Before": "C (权重 3), A (权重 1)",
|
|
|
+ "scenario1Step3After": "C 被选中概率 75%, A 被选中概率 25%",
|
|
|
+ "scenario1Step3Decision": "最终随机选择了 C",
|
|
|
+ "scenario2Title": "用户分组过滤",
|
|
|
+ "scenario2Desc": "如果用户指定了供应商组,系统会优先从该组中选择",
|
|
|
+ "scenario2Step1": "检查用户分组",
|
|
|
+ "scenario2Step1Desc": "用户配置了 providerGroup = 'premium'",
|
|
|
+ "scenario2Step1Before": "所有供应商:A (default), B (premium), C (premium), D (economy)",
|
|
|
+ "scenario2Step1After": "过滤出 'premium' 组:B, C",
|
|
|
+ "scenario2Step1Decision": "只从 B 和 C 中选择",
|
|
|
+ "scenario2Step2": "分组降级",
|
|
|
+ "scenario2Step2Desc": "如果用户组内没有可用供应商,降级到所有供应商",
|
|
|
+ "scenario2Step2Before": "用户组 'vip' 内的供应商全部禁用或超限",
|
|
|
+ "scenario2Step2After": "降级到所有启用的供应商:A, B, C, D",
|
|
|
+ "scenario2Step2Decision": "记录警告并从全局供应商池中选择",
|
|
|
+ "scenario3Title": "健康度过滤(熔断器 + 限流)",
|
|
|
+ "scenario3Desc": "系统自动过滤掉熔断或超限的供应商",
|
|
|
+ "scenario3Step1": "熔断器检查",
|
|
|
+ "scenario3Step1Desc": "连续失败 5 次后熔断器打开,60 秒内不可用",
|
|
|
+ "scenario3Step1Before": "供应商 A 连续失败 5 次,熔断器状态:open",
|
|
|
+ "scenario3Step1After": "A 被过滤,剩余:B, C, D",
|
|
|
+ "scenario3Step1Decision": "A 在 60 秒后自动恢复到半开状态",
|
|
|
+ "scenario3Step2": "金额限流",
|
|
|
+ "scenario3Step2Desc": "检查 5 小时、7 天、30 天的消费额度是否超限",
|
|
|
+ "scenario3Step2Before": "供应商 B 的 5 小时限额 $10,已消耗 $9.8",
|
|
|
+ "scenario3Step2After": "B 被过滤(接近限额),剩余:C, D",
|
|
|
+ "scenario3Step2Decision": "5 小时窗口滑动后自动恢复",
|
|
|
+ "scenario3Step3": "并发 Session 限制",
|
|
|
+ "scenario3Step3Desc": "检查当前活跃 Session 数是否超过配置的并发限制",
|
|
|
+ "scenario3Step3Before": "供应商 C 并发限制 2,当前活跃 Session 数:2",
|
|
|
+ "scenario3Step3After": "C 被过滤(已满),剩余:D",
|
|
|
+ "scenario3Step3Decision": "Session 过期(5 分钟)后自动释放",
|
|
|
+ "scenario4Title": "会话复用机制",
|
|
|
+ "scenario4Desc": "连续对话优先使用同一供应商,利用 Claude 的上下文缓存",
|
|
|
+ "scenario4Step1": "检查历史请求",
|
|
|
+ "scenario4Step1Desc": "查询该 API Key 最近 10 秒内使用的供应商",
|
|
|
+ "scenario4Step1Before": "最近一次请求使用了供应商 B",
|
|
|
+ "scenario4Step1After": "检查 B 是否启用且健康",
|
|
|
+ "scenario4Step1Decision": "B 可用,直接复用,跳过随机选择",
|
|
|
+ "scenario4Step2": "复用失效",
|
|
|
+ "scenario4Step2Desc": "如果上次使用的供应商不可用,则重新选择",
|
|
|
+ "scenario4Step2Before": "上次使用的供应商 B 已被禁用或熔断",
|
|
|
+ "scenario4Step2After": "进入正常选择流程",
|
|
|
+ "scenario4Step2Decision": "从其他可用供应商中选择",
|
|
|
+ "step": "步骤",
|
|
|
+ "before": "过滤前:",
|
|
|
+ "after": "过滤后:",
|
|
|
+ "decision": "决策:"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "en": {
|
|
|
+ "providers": {
|
|
|
+ "section": {
|
|
|
+ "title": "Provider Management",
|
|
|
+ "description": "Configure upstream provider rate limiting and concurrent session limits. Leave empty for unlimited."
|
|
|
+ },
|
|
|
+ "addProvider": "Add Provider",
|
|
|
+ "editProvider": "Edit Provider",
|
|
|
+ "createProvider": "Add Provider",
|
|
|
+ "updateFailed": "Failed to update provider",
|
|
|
+ "deleteSuccess": "Deleted successfully",
|
|
|
+ "confirmDeleteDesc": "Are you sure you want to delete provider \"{name}\"? This action cannot be undone.",
|
|
|
+ "confirmDeleteProvider": "Confirm Delete Provider?",
|
|
|
+ "confirmDeleteProviderDesc": "Are you sure you want to delete provider \"{name}\"? This action is irreversible.",
|
|
|
+ "noProviders": "No providers configured",
|
|
|
+ "noProvidersDesc": "Add your first API provider",
|
|
|
+ "toggleSuccess": "Provider {status}",
|
|
|
+ "toggleSuccessDesc": "Provider \"{name}\" status updated",
|
|
|
+ "toggleFailed": "Toggle failed",
|
|
|
+ "enabledStatus": "enabled",
|
|
|
+ "disabledStatus": "disabled",
|
|
|
+ "searchResults": "Found {count} matching providers",
|
|
|
+ "searchNoResults": "No matching providers found",
|
|
|
+ "displayCount": "Showing {filtered} / {total} providers",
|
|
|
+ "todayUsage": "Today's Usage",
|
|
|
+ "todayUsageCount": "{count} times",
|
|
|
+ "circuitBroken": "Circuit Broken",
|
|
|
+ "official": "Official",
|
|
|
+ "viewKey": "View Complete API Key",
|
|
|
+ "viewKeyDesc": "Please keep it safe and don't share it with others",
|
|
|
+ "keyLoading": "Loading...",
|
|
|
+ "resetCircuit": "Circuit breaker reset",
|
|
|
+ "resetCircuitDesc": "Provider \"{name}\" circuit breaker status cleared",
|
|
|
+ "resetCircuitFailed": "Failed to reset circuit breaker",
|
|
|
+ "form": {
|
|
|
+ "providerName": "Provider Name",
|
|
|
+ "providerNameRequired": "Provider Name *",
|
|
|
+ "providerNamePlaceholder": "e.g. Zhipu",
|
|
|
+ "apiAddress": "API Address",
|
|
|
+ "apiAddressRequired": "API Address *",
|
|
|
+ "apiAddressPlaceholder": "e.g. https://open.bigmodel.cn/api/anthropic",
|
|
|
+ "apiKeyRequired": "API Key *",
|
|
|
+ "apiKeyLeaveEmpty": "(Leave empty to keep unchanged)",
|
|
|
+ "apiKeyLeaveEmptyDesc": "Leave empty to keep existing key",
|
|
|
+ "apiKeyCurrent": "Current key:",
|
|
|
+ "websiteUrl": "Provider Website URL",
|
|
|
+ "websiteUrlPlaceholder": "https://example.com",
|
|
|
+ "websiteUrlDesc": "Provider website URL for quick access",
|
|
|
+ "websiteUrlInvalid": "Please enter a valid provider website URL",
|
|
|
+ "expandAll": "Expand All Advanced Configuration",
|
|
|
+ "collapseAll": "Collapse All Advanced Configuration",
|
|
|
+ "routingConfig": "Routing Configuration",
|
|
|
+ "routingConfigSummary": "{models} model whitelist, {redirects} redirects",
|
|
|
+ "routingConfigNone": "Not configured",
|
|
|
+ "providerTypeDesc": "Select the API format type for the provider.",
|
|
|
+ "providerTypeDisabledNote": "Note: Gemini CLI and OpenAI Compatible types are under development",
|
|
|
+ "modelRedirectsLabel": "Model Redirects Configuration",
|
|
|
+ "modelRedirectsOptional": "(Optional)",
|
|
|
+ "modelRedirectsDesc": "Redirect Claude Code client model requests (e.g. claude-sonnet-4.5) to upstream provider supported models (e.g. glm-4.6, gemini-pro). For cost optimization or third-party AI integration.",
|
|
|
+ "modelRedirectsEmpty": "No redirect rules yet. System will auto-rewrite model names after adding rules.",
|
|
|
+ "modelRedirectsCurrentRules": "Current Rules ({count})",
|
|
|
+ "modelRedirectsAddNew": "Add New Rule",
|
|
|
+ "modelRedirectsSourceModel": "User Requested Model",
|
|
|
+ "modelRedirectsSourcePlaceholder": "e.g. claude-sonnet-4-5-20250929",
|
|
|
+ "modelRedirectsTargetModel": "Actual Forwarded Model",
|
|
|
+ "modelRedirectsTargetPlaceholder": "e.g. glm-4.6",
|
|
|
+ "modelRedirectsSourceRequired": "Source model name cannot be empty",
|
|
|
+ "modelRedirectsTargetRequired": "Target model name cannot be empty",
|
|
|
+ "modelRedirectsExists": "Model \"{model}\" already has a redirect rule",
|
|
|
+ "joinClaudePool": "Join Claude Scheduling Pool",
|
|
|
+ "joinClaudePoolDesc": "When enabled, this provider will participate in load balancing with Claude type providers",
|
|
|
+ "joinClaudePoolHelp": "Only available when model redirect config contains mappings to claude-* models. When enabled, this provider will also participate in scheduling when users request claude-* models.",
|
|
|
+ "modelWhitelist": "Model Whitelist",
|
|
|
+ "modelWhitelistDesc": "Limit models this provider can handle. By default, provider can handle all models of its type.",
|
|
|
+ "modelWhitelistLabel": "Allowed Models",
|
|
|
+ "modelWhitelistSelected": "Selected {count} models",
|
|
|
+ "modelWhitelistLoading": "Loading...",
|
|
|
+ "modelWhitelistNotFound": "Model not found",
|
|
|
+ "modelWhitelistSearchPlaceholder": "Search model name...",
|
|
|
+ "modelWhitelistSelectAll": "Select All ({count})",
|
|
|
+ "modelWhitelistClear": "Clear",
|
|
|
+ "modelWhitelistManualAdd": "Manually Add Model",
|
|
|
+ "modelWhitelistManualPlaceholder": "Enter model name (e.g. gpt-5-turbo)",
|
|
|
+ "modelWhitelistManualDesc": "Support adding any model name (not limited to price table)",
|
|
|
+ "modelWhitelistAllowAll": "Allow all {type} models",
|
|
|
+ "modelWhitelistAllowAllClause": "Allow all Claude models",
|
|
|
+ "modelWhitelistAllowAllOpenAI": "Allow all OpenAI models",
|
|
|
+ "modelWhitelistSelectedOnly": "Only allow selected {count} models. Requests for other models won't be routed to this provider.",
|
|
|
+ "scheduleParams": "Scheduling Parameters",
|
|
|
+ "priorityLabel": "Priority",
|
|
|
+ "priorityDesc": "Lower number = higher priority (0 is highest). System only selects from highest priority providers. Recommendation: Main=0, Backup=1, Emergency=2",
|
|
|
+ "priorityPlaceholder": "0",
|
|
|
+ "weightLabel": "Weight",
|
|
|
+ "weightDesc": "Weighted random probability. Within same priority, higher weight = higher selection probability. E.g. weights 1:2:3 = probabilities 16%:33%:50%",
|
|
|
+ "weightPlaceholder": "1",
|
|
|
+ "costMultiplierLabel": "Cost Multiplier",
|
|
|
+ "costMultiplierDesc": "Cost calculation multiplier. Official=1.0, 20% cheaper=0.8, 20% more expensive=1.2 (up to 4 decimal places)",
|
|
|
+ "costMultiplierPlaceholder": "1.0",
|
|
|
+ "providerGroupLabel": "Provider Group",
|
|
|
+ "providerGroupPlaceholder": "e.g. premium, economy",
|
|
|
+ "providerGroupDesc": "Provider group tag. Only users with matching providerGroup can use this provider. Example: Set to \"premium\" to allow only providerGroup=\"premium\" users",
|
|
|
+ "rateLimitConfig": "Rate Limit Configuration",
|
|
|
+ "rateLimitConfigSummary": "5h: ${fiveHour}, Weekly: ${weekly}, Monthly: ${monthly}, Concurrent: {concurrent}",
|
|
|
+ "rateLimitConfigNone": "Unlimited",
|
|
|
+ "limit5hLabel": "5-Hour Spending Limit (USD)",
|
|
|
+ "limitWeeklyLabel": "Weekly Spending Limit (USD)",
|
|
|
+ "limitMonthlyLabel": "Monthly Spending Limit (USD)",
|
|
|
+ "limitConcurrentLabel": "Concurrent Session Limit",
|
|
|
+ "limitPlaceholderUnlimited": "Leave empty for unlimited",
|
|
|
+ "limitPlaceholder0": "0 means unlimited",
|
|
|
+ "circuitBreakerConfig": "Circuit Breaker Configuration",
|
|
|
+ "circuitBreakerConfigSummary": "{failureThreshold} failures / {openDuration} min circuit break / {successThreshold} successes to recover",
|
|
|
+ "circuitBreakerDesc": "Auto circuit break on consecutive failures to avoid overall service quality impact",
|
|
|
+ "failureThreshold": "Failure Threshold (times)",
|
|
|
+ "failureThresholdPlaceholder": "5",
|
|
|
+ "failureThresholdDesc": "How many consecutive failures trigger circuit break",
|
|
|
+ "openDuration": "Circuit Break Duration (minutes)",
|
|
|
+ "openDurationPlaceholder": "30",
|
|
|
+ "openDurationDesc": "How long before auto entering half-open state",
|
|
|
+ "successThreshold": "Recovery Threshold (times)",
|
|
|
+ "successThresholdPlaceholder": "2",
|
|
|
+ "successThresholdDesc": "How many successes in half-open state to fully recover",
|
|
|
+ "proxyConfig": "Proxy Configuration",
|
|
|
+ "proxyConfigSummary": "Proxy configured",
|
|
|
+ "proxyConfigSummaryFallback": " (fallback enabled)",
|
|
|
+ "proxyConfigNone": "Not configured",
|
|
|
+ "proxyConfigDesc": "Configure proxy server to improve provider connectivity (supports HTTP, HTTPS, SOCKS4, SOCKS5)",
|
|
|
+ "proxyAddressLabel": "Proxy Address",
|
|
|
+ "proxyAddressOptional": "(Optional)",
|
|
|
+ "proxyAddressPlaceholder": "e.g. http://proxy.example.com:8080 or socks5://127.0.0.1:1080",
|
|
|
+ "proxyAddressFormats": "Supported formats:",
|
|
|
+ "proxyFallbackLabel": "Fallback to direct on proxy failure",
|
|
|
+ "proxyFallbackDesc": "When enabled, auto try direct connection on proxy failure",
|
|
|
+ "proxyTestLabel": "Connection Test",
|
|
|
+ "proxyTestButton": "Test Connection",
|
|
|
+ "proxyTestTesting": "Testing...",
|
|
|
+ "proxyTestSuccess": "Connection Successful",
|
|
|
+ "proxyTestFailed": "Connection Failed",
|
|
|
+ "proxyTestDesc": "Test provider URL access via configured proxy (uses HEAD request, no quota consumption)",
|
|
|
+ "proxyTestFillUrl": "Please fill in provider URL first",
|
|
|
+ "proxyTestResultSuccess": "Connection successful {via}",
|
|
|
+ "proxyTestViaProxy": "(via proxy)",
|
|
|
+ "proxyTestViaDirect": "(direct)",
|
|
|
+ "proxyTestResponseTime": "Response time: {time}",
|
|
|
+ "proxyTestStatusCode": "| Status code: {code}",
|
|
|
+ "proxyTestResultFailed": "Connection failed",
|
|
|
+ "proxyTestTimeout": "Connection timeout (5s). Please check:\n1. Is proxy server accessible\n2. Are proxy address and port correct\n3. Are proxy credentials correct",
|
|
|
+ "proxyTestProxyError": "Proxy error: {error}",
|
|
|
+ "proxyTestNetworkError": "Network error: {error}",
|
|
|
+ "proxyTestResultMessage": "{message}",
|
|
|
+ "proxyTestResultStatusCode": "Status code: {code}",
|
|
|
+ "proxyTestResultResponseTime": "Response time: {time}ms",
|
|
|
+ "proxyTestResultConnectionMethod": "Connection method: {via}",
|
|
|
+ "proxyTestResultConnectionMethodProxy": "Proxy",
|
|
|
+ "proxyTestResultConnectionMethodDirect": "Direct",
|
|
|
+ "proxyTestResultErrorType": "Error type: {type}",
|
|
|
+ "codexStrategyConfig": "Codex Instructions Strategy",
|
|
|
+ "codexStrategyConfigAuto": "Auto (Recommended)",
|
|
|
+ "codexStrategyConfigForce": "Force Official",
|
|
|
+ "codexStrategyConfigKeep": "Keep Original",
|
|
|
+ "codexStrategyDesc": "Control how to handle Codex request instructions field, affects upstream gateway compatibility",
|
|
|
+ "codexStrategySelect": "Strategy Selection",
|
|
|
+ "codexStrategyAutoLabel": "Auto (Recommended)",
|
|
|
+ "codexStrategyAutoDesc": "Pass through client instructions, auto retry with official prompt on 400 error",
|
|
|
+ "codexStrategyForceLabel": "Force Official",
|
|
|
+ "codexStrategyForceDesc": "Always use official Codex CLI instructions (~4000+ chars)",
|
|
|
+ "codexStrategyKeepLabel": "Keep Original",
|
|
|
+ "codexStrategyKeepDesc": "Always pass through client instructions, no auto retry (for lenient gateways)",
|
|
|
+ "codexStrategyHint": "Hint: Some strict Codex gateways (e.g. 88code, foxcode) require official instructions. Choose \"Auto\" or \"Force Official\" strategy",
|
|
|
+ "confirmAdd": "Confirm Add",
|
|
|
+ "confirmUpdate": "Confirm Update",
|
|
|
+ "confirmAddPending": "Adding...",
|
|
|
+ "confirmUpdatePending": "Updating...",
|
|
|
+ "deleteButton": "Delete",
|
|
|
+ "validUrlRequired": "Please enter a valid API address",
|
|
|
+ "filterProvider": "Filter by Provider Type",
|
|
|
+ "filterAllProviders": "All Providers",
|
|
|
+ "searchClear": "Clear search"
|
|
|
+ },
|
|
|
+ "guide": {
|
|
|
+ "title": "Core Principles",
|
|
|
+ "priorityFirst": "1️⃣ Priority First: Select only from highest priority (lowest number) providers",
|
|
|
+ "costOptimize": "2️⃣ Cost Optimization: Within same priority, lower cost multiplier has higher probability",
|
|
|
+ "healthFilter": "3️⃣ Health Filtering: Auto skip circuit-broken or over-limit providers",
|
|
|
+ "sessionReuse": "4️⃣ Session Reuse: Consecutive chats reuse same provider, saving context costs",
|
|
|
+ "scenariosTitle": "Interactive Scenario Demos",
|
|
|
+ "bestPracticesTitle": "Best Practices",
|
|
|
+ "bestPracticesPriority": "• Priority Settings: Core providers=0, Backup=1-3",
|
|
|
+ "bestPracticesWeight": "• Weight Config: Set weight by capacity (higher capacity = higher weight)",
|
|
|
+ "bestPracticesCost": "• Cost Multiplier: Official=1.0, Self-hosted can be 0.8-1.2",
|
|
|
+ "bestPracticesLimit": "• Limit Settings: Set 5h, 7d, 30d limits based on budget",
|
|
|
+ "bestPracticesConcurrent": "• Concurrent Control: Set session concurrency by provider API limits",
|
|
|
+ "scenario1Title": "Priority Layering",
|
|
|
+ "scenario1Desc": "System first filters by priority, selecting only from highest priority providers",
|
|
|
+ "scenario1Step1": "Initial State",
|
|
|
+ "scenario1Step1Desc": "4 enabled providers with different priorities",
|
|
|
+ "scenario1Step1Before": "Provider A (priority 0), B (priority 1), C (priority 0), D (priority 2)",
|
|
|
+ "scenario1Step1After": "Filtered to highest priority (0) providers: A, C",
|
|
|
+ "scenario1Step1Decision": "Select only from A and C, B and D filtered out",
|
|
|
+ "scenario1Step2": "Cost Sorting",
|
|
|
+ "scenario1Step2Desc": "Within same priority, sort by cost multiplier low to high",
|
|
|
+ "scenario1Step2Before": "A (cost 1.0x), C (cost 0.8x)",
|
|
|
+ "scenario1Step2After": "After sorting: C (0.8x), A (1.0x)",
|
|
|
+ "scenario1Step2Decision": "Lower cost C has higher selection probability",
|
|
|
+ "scenario1Step3": "Weighted Random",
|
|
|
+ "scenario1Step3Desc": "Use weight for random selection, higher weight = higher probability",
|
|
|
+ "scenario1Step3Before": "C (weight 3), A (weight 1)",
|
|
|
+ "scenario1Step3After": "C has 75% probability, A has 25%",
|
|
|
+ "scenario1Step3Decision": "Finally randomly selected C",
|
|
|
+ "scenario2Title": "User Group Filtering",
|
|
|
+ "scenario2Desc": "If user has provider group specified, system prioritizes selection from that group",
|
|
|
+ "scenario2Step1": "Check User Group",
|
|
|
+ "scenario2Step1Desc": "User configured providerGroup = 'premium'",
|
|
|
+ "scenario2Step1Before": "All providers: A (default), B (premium), C (premium), D (economy)",
|
|
|
+ "scenario2Step1After": "Filtered to 'premium' group: B, C",
|
|
|
+ "scenario2Step1Decision": "Select only from B and C",
|
|
|
+ "scenario2Step2": "Group Fallback",
|
|
|
+ "scenario2Step2Desc": "If no available providers in user group, fallback to all providers",
|
|
|
+ "scenario2Step2Before": "All providers in user group 'vip' disabled or over limit",
|
|
|
+ "scenario2Step2After": "Fallback to all enabled providers: A, B, C, D",
|
|
|
+ "scenario2Step2Decision": "Log warning and select from global provider pool",
|
|
|
+ "scenario3Title": "Health Filtering (Circuit Breaker + Rate Limit)",
|
|
|
+ "scenario3Desc": "System auto filters circuit-broken or over-limit providers",
|
|
|
+ "scenario3Step1": "Circuit Breaker Check",
|
|
|
+ "scenario3Step1Desc": "Circuit breaker opens after 5 consecutive failures, unavailable for 60s",
|
|
|
+ "scenario3Step1Before": "Provider A failed 5 times, circuit breaker: open",
|
|
|
+ "scenario3Step1After": "A filtered, remaining: B, C, D",
|
|
|
+ "scenario3Step1Decision": "A auto recovers to half-open after 60s",
|
|
|
+ "scenario3Step2": "Amount Rate Limit",
|
|
|
+ "scenario3Step2Desc": "Check if spending exceeds limits (5h, 7d, 30d)",
|
|
|
+ "scenario3Step2Before": "Provider B 5h limit $10, consumed $9.8",
|
|
|
+ "scenario3Step2After": "B filtered (near limit), remaining: C, D",
|
|
|
+ "scenario3Step2Decision": "Auto recovery after 5h sliding window",
|
|
|
+ "scenario3Step3": "Concurrent Session Limit",
|
|
|
+ "scenario3Step3Desc": "Check if active session count exceeds configured concurrent limit",
|
|
|
+ "scenario3Step3Before": "Provider C concurrent limit 2, currently 2 active sessions",
|
|
|
+ "scenario3Step3After": "C filtered (full), remaining: D",
|
|
|
+ "scenario3Step3Decision": "Auto release after session expiry (5 min)",
|
|
|
+ "scenario4Title": "Session Reuse Mechanism",
|
|
|
+ "scenario4Desc": "Consecutive chats prioritize using same provider, leveraging Claude context cache",
|
|
|
+ "scenario4Step1": "Check Request History",
|
|
|
+ "scenario4Step1Desc": "Query providers used by this API Key in last 10 seconds",
|
|
|
+ "scenario4Step1Before": "Last request used provider B",
|
|
|
+ "scenario4Step1After": "Check if B is enabled and healthy",
|
|
|
+ "scenario4Step1Decision": "B available, reuse directly, skip random selection",
|
|
|
+ "scenario4Step2": "Reuse Invalidation",
|
|
|
+ "scenario4Step2Desc": "If last used provider unavailable, reselect",
|
|
|
+ "scenario4Step2Before": "Last used provider B disabled or circuit-broken",
|
|
|
+ "scenario4Step2After": "Enter normal selection flow",
|
|
|
+ "scenario4Step2Decision": "Select from other available providers",
|
|
|
+ "step": "Step",
|
|
|
+ "before": "Before:",
|
|
|
+ "after": "After:",
|
|
|
+ "decision": "Decision:"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|