From b2abda084f3151e23c8370b7e05776f27b97af41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=B9=E9=9B=AA?= <2b@yorha.xyz>
Date: Wed, 10 Jun 2026 13:00:51 +0900
Subject: [PATCH] feat(ui): i18n for activity metrics, pass-through endpoints,
and agents panel
---
.../src/components/activity_metrics.tsx | 82 +++++++++----
.../src/components/add_pass_through.tsx | 112 +++++++++---------
.../src/components/agents.tsx | 59 +++++----
ui/litellm-dashboard/src/locales/en.json | 87 ++++++++++++++
ui/litellm-dashboard/src/locales/zh-CN.json | 87 ++++++++++++++
5 files changed, 314 insertions(+), 113 deletions(-)
diff --git a/ui/litellm-dashboard/src/components/activity_metrics.tsx b/ui/litellm-dashboard/src/components/activity_metrics.tsx
index bd16c2f7219..609056815dc 100644
--- a/ui/litellm-dashboard/src/components/activity_metrics.tsx
+++ b/ui/litellm-dashboard/src/components/activity_metrics.tsx
@@ -3,6 +3,7 @@ import { resolveTeamAliasFromTeamID } from "@/utils/teamUtils";
import { AreaChart, BarChart, Card, Grid, Text, Title } from "@tremor/react";
import { Collapse } from "antd";
import React from "react";
+import { useTranslation } from "react-i18next";
import { CustomLegend, CustomTooltip } from "./common_components/chartUtils";
import { Team } from "./key_team_helpers/key_list";
import KeyModelUsageView from "./UsagePage/components/KeyModelUsageView";
@@ -23,47 +24,61 @@ const ModelSection = ({
metrics: ModelActivityData;
hidePromptCachingMetrics?: boolean;
}) => {
+ const { t } = useTranslation();
return (
{/* Summary Cards */}
- Total Requests
+ {t("activityMetrics.totalRequests")}
{metrics.total_requests.toLocaleString()}
- Total Successful Requests
+ {t("activityMetrics.totalSuccessfulRequests")}
{metrics.total_successful_requests.toLocaleString()}
- Total Tokens
+
+ {t("common.total")} {t("activityMetrics.tokens")}
+
{metrics.total_tokens.toLocaleString()}
- {Math.round(metrics.total_tokens / metrics.total_successful_requests)} avg per successful request
+
+ {Math.round(metrics.total_tokens / metrics.total_successful_requests)}{" "}
+ {t("activityMetrics.avgPerSuccessfulRequest")}
+
- Total Spend
+ {t("activityMetrics.totalSpend")}
${formatNumberWithCommas(metrics.total_spend, 2)}
- ${formatNumberWithCommas(metrics.total_spend / metrics.total_successful_requests, 3)} per successful request
+ ${formatNumberWithCommas(metrics.total_spend / metrics.total_successful_requests, 3)}{" "}
+ {t("activityMetrics.perSuccessfulRequest")}
{metrics.top_api_keys && metrics.top_api_keys.length > 0 && (
- Top Virtual Keys by Spend
+ {t("activityMetrics.topVirtualKeysBySpend")}
{metrics.top_api_keys.map((keyData, index) => (
{keyData.key_alias || `${keyData.api_key.substring(0, 10)}...`}
- {keyData.team_id && Team: {keyData.team_id} }
+ {keyData.team_id && (
+
+ {t("activityMetrics.teamLabel", { teamId: keyData.team_id })}
+
+ )}
${formatNumberWithCommas(keyData.spend, 2)}
- {keyData.requests.toLocaleString()} requests | {keyData.tokens.toLocaleString()} tokens
+ {t("activityMetrics.requestsAndTokens", {
+ requests: keyData.requests.toLocaleString(),
+ tokens: keyData.tokens.toLocaleString(),
+ })}
@@ -78,7 +93,7 @@ const ModelSection = ({
{/* Spend per day - Full width card */}
-
Spend per day
+ {t("activityMetrics.spendPerDay")}
-
Total Tokens
+
+ {t("common.total")} {t("activityMetrics.tokens")}
+
-
Requests per day
+ {t("activityMetrics.requestsPerDay")}
-
Success vs Failed Requests
+
{t("activityMetrics.successVsFailedRequests")}
-
Prompt Caching Metrics
+ {t("activityMetrics.promptCachingMetrics")}
- Cache Read: {metrics.total_cache_read_input_tokens?.toLocaleString() || 0} tokens
- Cache Creation: {metrics.total_cache_creation_input_tokens?.toLocaleString() || 0} tokens
+
+ {t("activityMetrics.cacheRead", {
+ count: metrics.total_cache_read_input_tokens?.toLocaleString() || 0,
+ })}
+
+
+ {t("activityMetrics.cacheCreation", {
+ count: metrics.total_cache_creation_input_tokens?.toLocaleString() || 0,
+ })}
+
= ({ modelMetrics, hidePromptCachingMetrics = false }) => {
+ const { t } = useTranslation();
const modelNames = Object.keys(modelMetrics).sort((a, b) => {
if (a === "") return 1;
if (b === "") return -1;
@@ -257,22 +283,24 @@ export const ActivityMetrics: React.FC = ({ modelMetrics,
{/* Global Summary */}
-
Overall Usage
+
{t("activityMetrics.overallUsage")}
- Total Requests
+ {t("activityMetrics.totalRequests")}
{totalMetrics.total_requests.toLocaleString()}
- Total Successful Requests
+ {t("activityMetrics.totalSuccessfulRequests")}
{totalMetrics.total_successful_requests.toLocaleString()}
- Total Tokens
+
+ {t("common.total")} {t("activityMetrics.tokens")}
+
{totalMetrics.total_tokens.toLocaleString()}
- Total Spend
+ {t("activityMetrics.totalSpend")}
${formatNumberWithCommas(totalMetrics.total_spend, 2)}
@@ -280,7 +308,7 @@ export const ActivityMetrics: React.FC
= ({ modelMetrics,
-
Total Tokens Over Time
+
{t("activityMetrics.totalTokensOverTime")}
= ({ modelMetrics,
-
Total Requests Over Time
+
{t("activityMetrics.totalRequestsOverTime")}
= ({ modelMetrics,
key={modelName}
header={
-
{modelMetrics[modelName].label || "Unknown Item"}
+
{modelMetrics[modelName].label || t("activityMetrics.unknownItem")}
${formatNumberWithCommas(modelMetrics[modelName].total_spend, 2)}
- {modelMetrics[modelName].total_requests.toLocaleString()} requests
+
+ {modelMetrics[modelName].total_requests.toLocaleString()} {t("activityMetrics.requests")}
+
}
>
diff --git a/ui/litellm-dashboard/src/components/add_pass_through.tsx b/ui/litellm-dashboard/src/components/add_pass_through.tsx
index 18621b99c54..63098b49fcf 100644
--- a/ui/litellm-dashboard/src/components/add_pass_through.tsx
+++ b/ui/litellm-dashboard/src/components/add_pass_through.tsx
@@ -16,6 +16,7 @@ import RoutePreview from "./route_preview";
import NotificationsManager from "./molecules/notifications_manager";
import PassThroughSecuritySection from "./common_components/PassThroughSecuritySection";
import PassThroughGuardrailsSection from "./common_components/PassThroughGuardrailsSection";
+import { useTranslation } from "react-i18next";
const { Option } = Select2;
const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH"];
@@ -34,6 +35,7 @@ const AddPassThroughEndpoint: React.FC = ({
passThroughItems,
premiumUser = false,
}) => {
+ const { t } = useTranslation();
const [form] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState(false);
const [isLoading, setIsLoading] = useState(false);
@@ -95,7 +97,7 @@ const AddPassThroughEndpoint: React.FC = ({
const updatedPassThroughSettings = [...passThroughItems, createdEndpoint];
setPassThroughItems(updatedPassThroughSettings);
- NotificationsManager.success("Pass-through endpoint created successfully");
+ NotificationsManager.success(t("addPassThrough.createSuccess"));
form.resetFields();
setPathValue("");
setTargetValue("");
@@ -104,7 +106,7 @@ const AddPassThroughEndpoint: React.FC = ({
setGuardrails({});
setIsModalVisible(false);
} catch (error) {
- NotificationsManager.fromBackend("Error creating pass-through endpoint: " + error);
+ NotificationsManager.fromBackend(t("addPassThrough.createFailed", { error }));
} finally {
setIsLoading(false);
}
@@ -112,19 +114,19 @@ const AddPassThroughEndpoint: React.FC = ({
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
- NotificationsManager.success("Copied to clipboard!");
+ NotificationsManager.success(t("common.copied"));
};
return (
setIsModalVisible(true)}>
- + Add Pass-Through Endpoint
+ {t("addPassThrough.addButton")}
- Add Pass-Through Endpoint
+ {t("addPassThrough.modalTitle")}
}
open={isModalVisible}
@@ -139,8 +141,8 @@ const AddPassThroughEndpoint: React.FC = ({
>
= ({
>
{/* Route Configuration Section */}
- Route Configuration
-
- Configure how requests to your domain will be forwarded to the target API
-
+ {t("addPassThrough.routeConfigTitle")}
+ {t("addPassThrough.routeConfigSubtitle")}
Path Prefix}
- name="path"
- rules={[{ required: true, message: "Path is required", pattern: /^\// }]}
- extra={
- Example: /bria, /adobe-photoshop, /elasticsearch
+ label={
+ {t("addPassThrough.pathPrefixLabel")}
}
+ name="path"
+ rules={[{ required: true, message: t("addPassThrough.pathRequired"), pattern: /^\// }]}
+ extra={{t("addPassThrough.pathExample")}
}
className="mb-4"
>
@@ -185,13 +185,15 @@ const AddPassThroughEndpoint: React.FC
= ({
Target URL}
+ label={
+ {t("addPassThrough.targetUrlLabel")}
+ }
name="target"
rules={[
- { required: true, message: "Target URL is required" },
- { type: "url", message: "Please enter a valid URL" },
+ { required: true, message: t("addPassThrough.targetUrlRequired") },
+ { type: "url", message: t("addPassThrough.targetUrlInvalid") },
]}
- extra={Example:https://engine.prod.bria-api.com
}
+ extra={{t("addPassThrough.targetUrlExample")}
}
className="mb-4"
>
= ({
- HTTP Methods (Optional)
-
+ {t("addPassThrough.httpMethodsLabel")}
+
@@ -217,15 +219,15 @@ const AddPassThroughEndpoint: React.FC = ({
extra={
{selectedMethods.length === 0
- ? "All HTTP methods supported (default)"
- : `Only ${selectedMethods.join(", ")} requests will be routed to this endpoint`}
+ ? t("addPassThrough.allMethodsDefault")
+ : t("addPassThrough.selectedMethodsDesc", { methods: selectedMethods.join(", ") })}
}
className="mb-4"
>
= ({
-
Include Subpaths
-
- Forward all subpaths to the target API (recommended for REST APIs)
-
+
{t("addPassThrough.includeSubpathsLabel")}
+
{t("addPassThrough.includeSubpathsDesc")}
@@ -258,26 +258,26 @@ const AddPassThroughEndpoint: React.FC = ({
{/* Headers Section */}
- Headers
-
- Add headers that will be sent with every request to the target API
-
+
+ {t("addPassThrough.headersSectionTitle")}
+
+ {t("addPassThrough.headersSectionSubtitle")}
- Authentication Headers
-
+ {t("addPassThrough.authHeadersLabel")}
+
}
name="headers"
- rules={[{ required: true, message: "Please configure the headers" }]}
+ rules={[{ required: true, message: t("addPassThrough.headersRequired") }]}
extra={
-
Add authentication tokens and other required headers
-
Common examples: auth_token, Authorization, x-api-key
+
{t("addPassThrough.headersExtraTitle")}
+
{t("addPassThrough.headersExtraExamples")}
}
>
@@ -287,16 +287,16 @@ const AddPassThroughEndpoint: React.FC = ({
{/* Default Query Parameters Section */}
- Default Query Parameters
-
- Add query parameters that will be automatically sent with every request to the target API
-
+
+ {t("addPassThrough.queryParamsSectionTitle")}
+
+ {t("addPassThrough.queryParamsSectionSubtitle")}
- Default Query Parameters (Optional)
-
+ {t("addPassThrough.queryParamsLabel")}
+
@@ -304,8 +304,8 @@ const AddPassThroughEndpoint: React.FC = ({
name="default_query_params"
extra={
-
Parameters are sent with all GET, POST, PUT, PATCH requests
-
Client parameters override defaults. Examples: version=v1, format=json, key=default
+
{t("addPassThrough.queryParamsExtraTitle")}
+
{t("addPassThrough.queryParamsExtraExamples")}
}
>
@@ -328,24 +328,22 @@ const AddPassThroughEndpoint: React.FC = ({
{/* Billing Section */}
- Billing
- Optional cost tracking for this endpoint
+
+ {t("addPassThrough.billingSectionTitle")}
+
+ {t("addPassThrough.billingSectionSubtitle")}
- Cost Per Request (USD)
-
+ {t("addPassThrough.costPerRequestLabel")}
+
}
name="cost_per_request"
- extra={
-
- The cost charged for each request through this endpoint
-
- }
+ extra={{t("addPassThrough.costPerRequestExtra")}
}
>
@@ -353,7 +351,7 @@ const AddPassThroughEndpoint: React.FC = ({
- Cancel
+ {t("common.cancel")}
= ({
form.submit();
}}
>
- {isLoading ? "Creating..." : "Add Pass-Through Endpoint"}
+ {isLoading ? t("addPassThrough.creating") : t("addPassThrough.addButton")}
diff --git a/ui/litellm-dashboard/src/components/agents.tsx b/ui/litellm-dashboard/src/components/agents.tsx
index bcba328c461..90ea09b2506 100644
--- a/ui/litellm-dashboard/src/components/agents.tsx
+++ b/ui/litellm-dashboard/src/components/agents.tsx
@@ -22,6 +22,7 @@ import { Agent, AgentKeyInfo } from "./agents/types";
import { Team } from "./key_team_helpers/key_list";
import { formatNumberWithCommas } from "@/utils/dataUtils";
import TableIconActionButton from "./common_components/IconActionButton/TableIconActionButtons/TableIconActionButton";
+import { useTranslation } from "react-i18next";
interface AgentsPanelProps {
accessToken: string | null;
@@ -34,6 +35,7 @@ interface AgentsResponse {
}
const AgentsPanel: React.FC = ({ accessToken, userRole, teams }) => {
+ const { t } = useTranslation();
const [agentsList, setAgentsList] = useState([]);
const [keyInfoMap, setKeyInfoMap] = useState>({});
const [isAddModalVisible, setIsAddModalVisible] = useState(false);
@@ -126,11 +128,11 @@ const AgentsPanel: React.FC = ({ accessToken, userRole, teams
setIsDeleting(true);
try {
await deleteAgentCall(accessToken, agentToDelete.id);
- NotificationsManager.success(`Agent "${agentToDelete.name}" deleted successfully`);
+ NotificationsManager.success(t("agents.deleteSuccess", { name: agentToDelete.name }));
fetchAgents();
} catch (error) {
console.error("Error deleting agent:", error);
- NotificationsManager.fromBackend("Failed to delete agent");
+ NotificationsManager.fromBackend(t("agents.deleteFailed"));
} finally {
setIsDeleting(false);
setAgentToDelete(null);
@@ -152,14 +154,11 @@ const AgentsPanel: React.FC = ({ accessToken, userRole, teams
return (
-
Agents
-
- List of A2A-spec agents that are available to be used in your organization. Go to AI Hub, to make agents
- public.
-
+
{t("agents.title")}
+
{t("agents.subtitle")}
= ({ accessToken, userRole, teams
{isAdmin && (
- + Add New Agent
+ {t("agents.addNewAgent")}
)}
-
+
-
Health Check
+
{t("agents.healthCheck")}
= ({ accessToken, userRole, teams
- Agent Name
- Agent ID
- Spend (USD)
- Model
- Created
- Status
- {isAdmin && Actions }
+ {t("agents.colAgentName")}
+ {t("agents.colAgentId")}
+ {t("agents.colSpend")}
+ {t("agents.colModel")}
+ {t("agents.colCreated")}
+ {t("common.status")}
+ {isAdmin && {t("common.actions")} }
{sortedAgents.length === 0 ? (
-
- No agents found. Click "+ Add New Agent" to create one.
-
+ {t("agents.noAgentsFound")}
) : (
@@ -241,17 +238,19 @@ const AgentsPanel: React.FC = ({ accessToken, userRole, teams
- {agent.litellm_params?.model || "N/A"}
+ {agent.litellm_params?.model || t("common.unknown")}
- {agent.created_at ? new Date(agent.created_at).toLocaleDateString() : "N/A"}
+
+ {agent.created_at ? new Date(agent.created_at).toLocaleDateString() : t("common.unknown")}
+
{keyInfoMap[agent.agent_id]?.has_key ? (
- Active
+ {t("common.active")}
) : (
- Needs Setup
+ {t("agents.needsSetup")}
)}
{isAdmin && (
@@ -281,16 +280,16 @@ const AgentsPanel: React.FC = ({ accessToken, userRole, teams
{agentToDelete && (
- Are you sure you want to delete agent: {agentToDelete.name}?
- This action cannot be undone.
+ {t("agents.deleteConfirm", { name: agentToDelete.name })}
+ {t("agents.deleteCannotUndo")}
)}
diff --git a/ui/litellm-dashboard/src/locales/en.json b/ui/litellm-dashboard/src/locales/en.json
index 8ab54995202..c1fab9b3bf5 100644
--- a/ui/litellm-dashboard/src/locales/en.json
+++ b/ui/litellm-dashboard/src/locales/en.json
@@ -922,6 +922,93 @@
"monthsRemaining_other": "{{count}} months remaining",
"expiringSoon": "Expiring soon"
},
+ "activityMetrics": {
+ "totalRequests": "Total Requests",
+ "totalSuccessfulRequests": "Total Successful Requests",
+ "tokens": "Tokens",
+ "avgPerSuccessfulRequest": "avg per successful request",
+ "totalSpend": "Total Spend",
+ "perSuccessfulRequest": "per successful request",
+ "topVirtualKeysBySpend": "Top Virtual Keys by Spend",
+ "teamLabel": "Team: {{teamId}}",
+ "requestsAndTokens": "{{requests}} requests | {{tokens}} tokens",
+ "spendPerDay": "Spend per day",
+ "requestsPerDay": "Requests per day",
+ "successVsFailedRequests": "Success vs Failed Requests",
+ "promptCachingMetrics": "Prompt Caching Metrics",
+ "cacheRead": "Cache Read: {{count}} tokens",
+ "cacheCreation": "Cache Creation: {{count}} tokens",
+ "overallUsage": "Overall Usage",
+ "totalTokensOverTime": "Total Tokens Over Time",
+ "totalRequestsOverTime": "Total Requests Over Time",
+ "unknownItem": "Unknown Item",
+ "unknownModel": "Unknown Model",
+ "requests": "requests"
+ },
+ "addPassThrough": {
+ "addButton": "+ Add Pass-Through Endpoint",
+ "modalTitle": "Add Pass-Through Endpoint",
+ "alertMessage": "What is a Pass-Through Endpoint?",
+ "alertDescription": "Route requests from your LiteLLM proxy to any external API. Perfect for custom models, image generation APIs, or any service you want to proxy through LiteLLM.",
+ "routeConfigTitle": "Route Configuration",
+ "routeConfigSubtitle": "Configure how requests to your domain will be forwarded to the target API",
+ "pathPrefixLabel": "Path Prefix",
+ "pathRequired": "Path is required",
+ "pathExample": "Example: /bria, /adobe-photoshop, /elasticsearch",
+ "targetUrlLabel": "Target URL",
+ "targetUrlRequired": "Target URL is required",
+ "targetUrlInvalid": "Please enter a valid URL",
+ "targetUrlExample": "Example:https://engine.prod.bria-api.com",
+ "httpMethodsLabel": "HTTP Methods (Optional)",
+ "httpMethodsTooltip": "Select specific HTTP methods. Leave empty to support all methods (GET, POST, PUT, DELETE, PATCH). Useful when the same path needs different targets for different methods.",
+ "allMethodsDefault": "All HTTP methods supported (default)",
+ "selectedMethodsDesc": "Only {{methods}} requests will be routed to this endpoint",
+ "selectMethodsPlaceholder": "Select methods (leave empty for all)",
+ "includeSubpathsLabel": "Include Subpaths",
+ "includeSubpathsDesc": "Forward all subpaths to the target API (recommended for REST APIs)",
+ "headersSectionTitle": "Headers",
+ "headersSectionSubtitle": "Add headers that will be sent with every request to the target API",
+ "authHeadersLabel": "Authentication Headers",
+ "authHeadersTooltip": "Authentication and other headers to forward with requests",
+ "headersRequired": "Please configure the headers",
+ "headersExtraTitle": "Add authentication tokens and other required headers",
+ "headersExtraExamples": "Common examples: auth_token, Authorization, x-api-key",
+ "queryParamsSectionTitle": "Default Query Parameters",
+ "queryParamsSectionSubtitle": "Add query parameters that will be automatically sent with every request to the target API",
+ "queryParamsLabel": "Default Query Parameters (Optional)",
+ "queryParamsTooltip": "Query parameters that will be added to all requests. Clients can override these by providing their own values.",
+ "queryParamsExtraTitle": "Parameters are sent with all GET, POST, PUT, PATCH requests",
+ "queryParamsExtraExamples": "Client parameters override defaults. Examples: version=v1, format=json, key=default",
+ "billingSectionTitle": "Billing",
+ "billingSectionSubtitle": "Optional cost tracking for this endpoint",
+ "costPerRequestLabel": "Cost Per Request (USD)",
+ "costPerRequestTooltip": "Optional: Track costs for requests to this endpoint",
+ "costPerRequestExtra": "The cost charged for each request through this endpoint",
+ "creating": "Creating...",
+ "createSuccess": "Pass-through endpoint created successfully",
+ "createFailed": "Error creating pass-through endpoint: {{error}}"
+ },
+ "agents": {
+ "title": "Agents",
+ "subtitle": "List of A2A-spec agents that are available to be used in your organization. Go to AI Hub, to make agents public.",
+ "alertMessage": "Why do agents need keys?",
+ "alertDescription": "Keys scope access to an agent and allow it to call MCP tools. Assign a key when creating an agent or from the Virtual Keys page.",
+ "addNewAgent": "+ Add New Agent",
+ "healthCheck": "Health Check",
+ "healthCheckTooltip": "When enabled, only agents with reachable URLs are shown",
+ "colAgentName": "Agent Name",
+ "colAgentId": "Agent ID",
+ "colSpend": "Spend (USD)",
+ "colModel": "Model",
+ "colCreated": "Created",
+ "noAgentsFound": "No agents found. Click \"+ Add New Agent\" to create one.",
+ "needsSetup": "Needs Setup",
+ "deleteModalTitle": "Delete Agent",
+ "deleteConfirm": "Are you sure you want to delete agent: {{name}}?",
+ "deleteCannotUndo": "This action cannot be undone.",
+ "deleteSuccess": "Agent \"{{name}}\" deleted successfully",
+ "deleteFailed": "Failed to delete agent"
+ },
"common": {
"save": "Save",
"cancel": "Cancel",
diff --git a/ui/litellm-dashboard/src/locales/zh-CN.json b/ui/litellm-dashboard/src/locales/zh-CN.json
index a2d5c9f30a0..d52a82f4bfc 100644
--- a/ui/litellm-dashboard/src/locales/zh-CN.json
+++ b/ui/litellm-dashboard/src/locales/zh-CN.json
@@ -922,6 +922,93 @@
"monthsRemaining_other": "剩余 {{count}} 个月",
"expiringSoon": "即将过期"
},
+ "activityMetrics": {
+ "totalRequests": "总请求数",
+ "totalSuccessfulRequests": "总成功请求数",
+ "tokens": "Token",
+ "avgPerSuccessfulRequest": "每次成功请求平均值",
+ "totalSpend": "总花费",
+ "perSuccessfulRequest": "每次成功请求",
+ "topVirtualKeysBySpend": "花费最多的虚拟密钥",
+ "teamLabel": "团队:{{teamId}}",
+ "requestsAndTokens": "{{requests}} 次请求 | {{tokens}} Token",
+ "spendPerDay": "每日花费",
+ "requestsPerDay": "每日请求数",
+ "successVsFailedRequests": "成功 vs 失败请求",
+ "promptCachingMetrics": "提示词缓存指标",
+ "cacheRead": "缓存读取:{{count}} Token",
+ "cacheCreation": "缓存创建:{{count}} Token",
+ "overallUsage": "整体用量",
+ "totalTokensOverTime": "Token 总量随时间变化",
+ "totalRequestsOverTime": "请求总量随时间变化",
+ "unknownItem": "未知项目",
+ "unknownModel": "未知模型",
+ "requests": "次请求"
+ },
+ "addPassThrough": {
+ "addButton": "+ 添加透传端点",
+ "modalTitle": "添加透传端点",
+ "alertMessage": "什么是透传端点?",
+ "alertDescription": "将来自 LiteLLM 代理的请求路由到任意外部 API。适用于自定义模型、图像生成 API 或任何您希望通过 LiteLLM 代理的服务。",
+ "routeConfigTitle": "路由配置",
+ "routeConfigSubtitle": "配置如何将您域名上的请求转发到目标 API",
+ "pathPrefixLabel": "路径前缀",
+ "pathRequired": "路径为必填项",
+ "pathExample": "示例:/bria、/adobe-photoshop、/elasticsearch",
+ "targetUrlLabel": "目标 URL",
+ "targetUrlRequired": "目标 URL 为必填项",
+ "targetUrlInvalid": "请输入有效的 URL",
+ "targetUrlExample": "示例:https://engine.prod.bria-api.com",
+ "httpMethodsLabel": "HTTP 方法(可选)",
+ "httpMethodsTooltip": "选择特定的 HTTP 方法。留空则支持所有方法(GET、POST、PUT、DELETE、PATCH)。当同一路径对不同方法需要不同目标时很有用。",
+ "allMethodsDefault": "支持所有 HTTP 方法(默认)",
+ "selectedMethodsDesc": "仅 {{methods}} 请求将路由到此端点",
+ "selectMethodsPlaceholder": "选择方法(留空表示全部)",
+ "includeSubpathsLabel": "包含子路径",
+ "includeSubpathsDesc": "将所有子路径转发到目标 API(推荐用于 REST API)",
+ "headersSectionTitle": "请求头",
+ "headersSectionSubtitle": "添加每次请求到目标 API 时都会发送的请求头",
+ "authHeadersLabel": "认证请求头",
+ "authHeadersTooltip": "随请求转发的认证及其他请求头",
+ "headersRequired": "请配置请求头",
+ "headersExtraTitle": "添加认证 Token 和其他必需的请求头",
+ "headersExtraExamples": "常见示例:auth_token、Authorization、x-api-key",
+ "queryParamsSectionTitle": "默认查询参数",
+ "queryParamsSectionSubtitle": "添加每次请求到目标 API 时自动发送的查询参数",
+ "queryParamsLabel": "默认查询参数(可选)",
+ "queryParamsTooltip": "将添加到所有请求的查询参数。客户端可通过提供自己的值来覆盖这些默认值。",
+ "queryParamsExtraTitle": "参数将随所有 GET、POST、PUT、PATCH 请求发送",
+ "queryParamsExtraExamples": "客户端参数可覆盖默认值。示例:version=v1、format=json、key=default",
+ "billingSectionTitle": "计费",
+ "billingSectionSubtitle": "此端点的可选成本追踪",
+ "costPerRequestLabel": "每次请求费用(USD)",
+ "costPerRequestTooltip": "可选:追踪此端点的请求费用",
+ "costPerRequestExtra": "通过此端点每次请求收取的费用",
+ "creating": "创建中...",
+ "createSuccess": "透传端点创建成功",
+ "createFailed": "创建透传端点时出错:{{error}}"
+ },
+ "agents": {
+ "title": "Agents",
+ "subtitle": "可在您的组织中使用的 A2A 规范 Agent 列表。前往 AI Hub 将 Agent 设为公开。",
+ "alertMessage": "为什么 Agent 需要密钥?",
+ "alertDescription": "密钥用于限定对 Agent 的访问范围,并允许其调用 MCP 工具。可在创建 Agent 时或从虚拟密钥页面分配密钥。",
+ "addNewAgent": "+ 添加新 Agent",
+ "healthCheck": "健康检查",
+ "healthCheckTooltip": "启用后,仅显示 URL 可访问的 Agent",
+ "colAgentName": "Agent 名称",
+ "colAgentId": "Agent ID",
+ "colSpend": "花费(USD)",
+ "colModel": "模型",
+ "colCreated": "创建时间",
+ "noAgentsFound": "未找到 Agent。点击「+ 添加新 Agent」以创建一个。",
+ "needsSetup": "待配置",
+ "deleteModalTitle": "删除 Agent",
+ "deleteConfirm": "确定要删除 Agent:{{name}}?",
+ "deleteCannotUndo": "此操作无法撤销。",
+ "deleteSuccess": "Agent「{{name}}」已成功删除",
+ "deleteFailed": "删除 Agent 失败"
+ },
"common": {
"save": "保存",
"cancel": "取消",