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 (
-

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 = ({
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 && ( )} - +
- 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": "取消",