diff --git a/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.test.tsx b/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.test.tsx index f980aee3c2c..c9c41cd1d8e 100644 --- a/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.test.tsx +++ b/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.test.tsx @@ -2,8 +2,35 @@ import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { vi } from "vitest"; import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { TFunction } from "i18next"; import { getAgentHubTableColumns, AgentHubData } from "./AgentHubTableColumns"; +const mockT = ((key: string, opts?: Record) => { + if (key === "aiHub.agentHubTableColumns.skillCount") { + const count = opts?.count as number; + return count === 1 ? `${count} skill` : `${count} skills`; + } + const last = key.split(".").pop() ?? key; + const map: Record = { + colAgentName: "Agent Name", + copyAgentName: "Copy agent name", + colVersion: "Version", + colProtocol: "Protocol", + colSkills: "Skills", + colCapabilities: "Capabilities", + colIOModes: "I/O Modes", + ioIn: "In:", + ioOut: "Out:", + colPublic: "Public", + detailsShort: "Info", + description: "Description", + details: "Details", + yes: "Yes", + no: "No", + }; + return map[last] ?? key; +}) as unknown as TFunction; + const mockAgent: AgentHubData = { agent_id: "agent-1", protocolVersion: "1.0", @@ -33,7 +60,7 @@ function TestTable({ showModal?: ReturnType; copyToClipboard?: ReturnType; }) { - const columns = getAgentHubTableColumns(showModal, copyToClipboard, publicPage); + const columns = getAgentHubTableColumns(mockT, showModal, copyToClipboard, publicPage); const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel() }); return ( diff --git a/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.tsx b/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.tsx index 09b1c147615..8e52aff72ee 100644 --- a/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.tsx +++ b/ui/litellm-dashboard/src/components/AIHub/AgentHubTableColumns.tsx @@ -2,6 +2,7 @@ import { ColumnDef } from "@tanstack/react-table"; import { Button, Badge, Text } from "@tremor/react"; import { Tooltip, Tag } from "antd"; import { CopyOutlined, InfoCircleOutlined } from "@ant-design/icons"; +import { TFunction } from "i18next"; export interface AgentHubData { agent_id?: string; @@ -29,13 +30,14 @@ export interface AgentHubData { } export const getAgentHubTableColumns = ( + t: TFunction, showModal: (agent: AgentHubData) => void, copyToClipboard: (text: string) => void, publicPage: boolean = false, ): ColumnDef[] => { const allColumns: ColumnDef[] = [ { - header: "Agent Name", + header: t("aiHub.agentHubTableColumns.colAgentName"), accessorKey: "name", enableSorting: true, sortingFn: "alphanumeric", @@ -46,7 +48,7 @@ export const getAgentHubTableColumns = (
{agent.name} - + copyToClipboard(agent.name)} className="cursor-pointer text-gray-500 hover:text-blue-500 text-xs" @@ -62,7 +64,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Description", + header: t("common.description"), accessorKey: "description", enableSorting: true, sortingFn: "alphanumeric", @@ -76,7 +78,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Version", + header: t("aiHub.agentHubTableColumns.colVersion"), accessorKey: "version", enableSorting: true, sortingFn: "alphanumeric", @@ -94,7 +96,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Protocol", + header: t("aiHub.agentHubTableColumns.colProtocol"), accessorKey: "protocolVersion", enableSorting: true, sortingFn: "alphanumeric", @@ -108,7 +110,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Skills", + header: t("aiHub.agentHubTableColumns.colSkills"), accessorKey: "skills", enableSorting: false, cell: ({ row }) => { @@ -118,7 +120,7 @@ export const getAgentHubTableColumns = ( return (
- {skills.length} skill{skills.length !== 1 ? "s" : ""} + {t("aiHub.agentHubTableColumns.skillCount", { count: skills.length })} {skills.length > 0 && (
@@ -135,7 +137,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Capabilities", + header: t("aiHub.agentHubTableColumns.colCapabilities"), accessorKey: "capabilities", enableSorting: false, cell: ({ row }) => { @@ -161,7 +163,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "I/O Modes", + header: t("aiHub.agentHubTableColumns.colIOModes"), accessorKey: "defaultInputModes", enableSorting: false, cell: ({ row }) => { @@ -172,10 +174,11 @@ export const getAgentHubTableColumns = ( return (
- In: {inputModes.join(", ") || "-"} + {t("aiHub.agentHubTableColumns.ioIn")} {inputModes.join(", ") || "-"} - Out: {outputModes.join(", ") || "-"} + {t("aiHub.agentHubTableColumns.ioOut")}{" "} + {outputModes.join(", ") || "-"}
); @@ -185,7 +188,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Public", + header: t("aiHub.agentHubTableColumns.colPublic"), accessorKey: "is_public", enableSorting: true, sortingFn: (rowA, rowB) => { @@ -198,11 +201,11 @@ export const getAgentHubTableColumns = ( return agent.is_public === true ? ( - Yes + {t("common.yes")} ) : ( - No + {t("common.no")} ); }, @@ -211,7 +214,7 @@ export const getAgentHubTableColumns = ( }, }, { - header: "Details", + header: t("common.details"), id: "details", enableSorting: false, cell: ({ row }) => { @@ -219,8 +222,8 @@ export const getAgentHubTableColumns = ( return ( ); }, diff --git a/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx b/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx index 5d171139ab5..830ee5fc9b0 100644 --- a/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx +++ b/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx @@ -31,6 +31,7 @@ import { useRouter } from "next/navigation"; import React, { useCallback, useEffect, useState } from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings"; +import { useTranslation } from "react-i18next"; import { checkTokenValidity } from "@/utils/jwtUtils"; import { getCookie } from "@/utils/cookieUtils"; @@ -64,6 +65,7 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, // Admin Viewer follows the read-parity rule: see the AI Hub catalog, but // cannot toggle public visibility (write). const canModify = isProxyAdminRole(userRole || ""); + const { t } = useTranslation(); const [publicPageAllowed, setPublicPageAllowed] = useState(false); const [modelHubData, setModelHubData] = useState(null); @@ -306,7 +308,7 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text); - NotificationsManager.success("Copied to clipboard!"); + NotificationsManager.success(t("aiHub.modelHubTable.copiedToClipboard")); }; const formatCapabilityName = (key: string) => { @@ -399,23 +401,21 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Header with Title, Description and URL */}
- AI Hub + {t("aiHub.modelHubTable.title")} {isAdminRole(userRole || "") ? ( -

- Make models, agents, and MCP servers public for developers to know what's available. -

+

{t("aiHub.modelHubTable.adminDescription")}

) : ( -

A list of all public model names personally available to you.

+

{t("aiHub.modelHubTable.userDescription")}

)}
- Model Hub URL: + {t("aiHub.modelHubTable.modelHubUrl")}
{`${getProxyBaseUrl()}/ui/model_hub_table`} @@ -433,10 +433,10 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Tab System for Model Hub, Agent Hub, MCP Hub, and Plugin Marketplace */} - Model Hub - Agent Hub - MCP Hub - Skill Hub + {t("aiHub.modelHubTable.tabModelHub")} + {t("aiHub.modelHubTable.tabAgentHub")} + {t("aiHub.modelHubTable.tabMcpHub")} + {t("aiHub.modelHubTable.tabSkillHub")} @@ -447,7 +447,9 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Header with Make Public Button */} {publicPage == false && canModify && (
- +
)} @@ -465,7 +467,10 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
- Showing {filteredData.length} of {modelHubData?.length || 0} models + {t("aiHub.modelHubTable.showingModels", { + filtered: filteredData.length, + total: modelHubData?.length || 0, + })}
@@ -476,13 +481,15 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Header with Make Public Button */} {publicPage == false && canModify && (
- +
)} {/* Agent Table */} = ({ accessToken, publicPage,
- Showing {agentHubData?.length || 0} agent{agentHubData?.length !== 1 ? "s" : ""} + {t("aiHub.modelHubTable.showingAgents", { count: agentHubData?.length || 0 })}
@@ -502,7 +509,9 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Header with Make Public Button */} {publicPage == false && canModify && (
- +
)} @@ -517,7 +526,7 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
- Showing {mcpHubData?.length || 0} MCP server{mcpHubData?.length !== 1 ? "s" : ""} + {t("aiHub.modelHubTable.showingMcpServers", { count: mcpHubData?.length || 0 })}
@@ -526,7 +535,9 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {publicPage == false && canModify && (
- +
)} = ({ accessToken, publicPage,
) : ( - Public Model Hub not enabled. -

Ask your proxy admin to enable this on their Admin UI.

+ {t("aiHub.modelHubTable.publicHubNotEnabled")} +

{t("aiHub.modelHubTable.askAdminToEnable")}

)} {/* Public Page Modal */} = ({ accessToken, publicPage, >
- Shareable Link: + {t("aiHub.modelHubTable.shareableLink")} {`${getProxyBaseUrl()}/ui/model_hub_table`}
- +
{/* Model Details Modal */} = ({ accessToken, publicPage,
{/* Model Overview */}
- Model Overview + {t("aiHub.modelHubTable.modelOverview")}
- Model Group: + {t("aiHub.modelHubTable.fieldModelGroup")} {selectedModel.model_group}
- Mode: - {selectedModel.mode || "Not specified"} + {t("aiHub.modelHubTable.fieldMode")} + {selectedModel.mode || t("aiHub.modelHubTable.notSpecified")}
- Providers: + {t("aiHub.modelHubTable.fieldProviders")}
{selectedModel.providers.map((provider) => ( @@ -611,30 +622,34 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Token and Cost Information */}
- Token & Cost Information + {t("aiHub.modelHubTable.tokenCostInfo")}
- Max Input Tokens: - {selectedModel.max_input_tokens?.toLocaleString() || "Not specified"} -
-
- Max Output Tokens: - {selectedModel.max_output_tokens?.toLocaleString() || "Not specified"} -
-
- Input Cost per 1M Tokens: + {t("aiHub.modelHubTable.fieldMaxInputTokens")} - {selectedModel.input_cost_per_token - ? formatCost(selectedModel.input_cost_per_token) - : "Not specified"} + {selectedModel.max_input_tokens?.toLocaleString() || t("aiHub.modelHubTable.notSpecified")}
- Output Cost per 1M Tokens: + {t("aiHub.modelHubTable.fieldMaxOutputTokens")} + + {selectedModel.max_output_tokens?.toLocaleString() || t("aiHub.modelHubTable.notSpecified")} + +
+
+ {t("aiHub.modelHubTable.fieldInputCost")} + + {selectedModel.input_cost_per_token + ? formatCost(selectedModel.input_cost_per_token) + : t("aiHub.modelHubTable.notSpecified")} + +
+
+ {t("aiHub.modelHubTable.fieldOutputCost")} {selectedModel.output_cost_per_token ? formatCost(selectedModel.output_cost_per_token) - : "Not specified"} + : t("aiHub.modelHubTable.notSpecified")}
@@ -642,14 +657,14 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Capabilities */}
- Capabilities + {t("aiHub.modelHubTable.sectionCapabilities")}
{(() => { const capabilities = getModelCapabilities(selectedModel); const colors = ["green", "blue", "purple", "orange", "red", "yellow"]; if (capabilities.length === 0) { - return No special capabilities listed; + return {t("aiHub.modelHubTable.noCapabilities")}; } return capabilities.map((capability, index) => ( @@ -664,17 +679,17 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Rate Limits */} {(selectedModel.tpm || selectedModel.rpm) && (
- Rate Limits + {t("aiHub.modelHubTable.sectionRateLimits")}
{selectedModel.tpm && (
- Tokens per Minute: + {t("aiHub.modelHubTable.fieldTokensPerMinute")} {selectedModel.tpm.toLocaleString()}
)} {selectedModel.rpm && (
- Requests per Minute: + {t("aiHub.modelHubTable.fieldRequestsPerMinute")} {selectedModel.rpm.toLocaleString()}
)} @@ -685,7 +700,7 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Supported OpenAI Parameters */} {selectedModel.supported_openai_params && (
- Supported OpenAI Parameters + {t("aiHub.modelHubTable.sectionSupportedParams")}
{selectedModel.supported_openai_params.map((param) => ( @@ -698,7 +713,7 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage, {/* Usage Example */}
- Usage Example + {t("aiHub.modelHubTable.sectionUsageExample")} {`import openai @@ -726,7 +741,7 @@ print(response.choices[0].message.content)`} {/* Agent Details Modal */} {/* Agent Overview */}
- Agent Overview + {t("aiHub.modelHubTable.agentOverview")}
- Name: + {t("aiHub.modelHubTable.fieldName")} {selectedAgent.name}
- Version: + {t("aiHub.modelHubTable.fieldVersion")} v{selectedAgent.version}
- Protocol Version: + {t("aiHub.modelHubTable.fieldProtocolVersion")} {selectedAgent.protocolVersion}
- URL: + {t("aiHub.modelHubTable.fieldUrl")}
{selectedAgent.url}
- Description: + {t("common.description")}: {selectedAgent.description}
@@ -771,7 +786,7 @@ print(response.choices[0].message.content)`} {/* Capabilities */} {selectedAgent.capabilities && Object.keys(selectedAgent.capabilities).length > 0 && (
- Capabilities + {t("aiHub.modelHubTable.sectionCapabilities")}
{Object.entries(selectedAgent.capabilities) .filter(([_, value]) => value === true) @@ -786,26 +801,26 @@ print(response.choices[0].message.content)`} {/* Input/Output Modes */}
- Input/Output Modes + {t("aiHub.modelHubTable.sectionInputOutputModes")}
- Input Modes: + {t("aiHub.modelHubTable.fieldInputModes")}
{selectedAgent.defaultInputModes?.map((mode) => ( {mode} - )) || Not specified} + )) || {t("aiHub.modelHubTable.notSpecified")}}
- Output Modes: + {t("aiHub.modelHubTable.fieldOutputModes")}
{selectedAgent.defaultOutputModes?.map((mode) => ( {mode} - )) || Not specified} + )) || {t("aiHub.modelHubTable.notSpecified")}}
@@ -814,14 +829,16 @@ print(response.choices[0].message.content)`} {/* Skills */} {selectedAgent.skills && selectedAgent.skills.length > 0 && (
- Skills + {t("aiHub.modelHubTable.sectionSkills")}
{selectedAgent.skills.map((skill) => (
{skill.name} - ID: {skill.id} + + {t("aiHub.modelHubTable.skillId", { id: skill.id })} +
{skill.tags && skill.tags.length > 0 && (
@@ -836,7 +853,9 @@ print(response.choices[0].message.content)`} {skill.description} {skill.examples && skill.examples.length > 0 && (
- Examples: + + {t("aiHub.modelHubTable.skillExamples")} +
{skill.examples.map((example, idx) => ( @@ -855,8 +874,8 @@ print(response.choices[0].message.content)`} {/* Additional Properties */} {selectedAgent.supportsAuthenticatedExtendedCard && (
- Additional Features - Supports Authenticated Extended Card + {t("aiHub.modelHubTable.sectionAdditionalFeatures")} + {t("aiHub.modelHubTable.supportsAuthCard")}
)}
@@ -865,7 +884,7 @@ print(response.choices[0].message.content)`} {/* MCP Server Details Modal */} {/* Server Overview */}
- Server Overview + {t("aiHub.modelHubTable.mcpServerOverview")}
- Server Name: + {t("aiHub.modelHubTable.fieldServerName")} {selectedMcpServer.server_name}
- Server ID: + {t("aiHub.modelHubTable.fieldServerId")}
{selectedMcpServer.server_id} {selectedMcpServer.alias && (
- Alias: + {t("aiHub.modelHubTable.fieldAlias")} {selectedMcpServer.alias}
)}
- Transport: + {t("aiHub.modelHubTable.fieldTransport")} {selectedMcpServer.transport}
- Auth Type: + {t("aiHub.modelHubTable.fieldAuthType")} {selectedMcpServer.auth_type}
- Status: + {t("common.status")}: - {selectedMcpServer.status || "unknown"} + {selectedMcpServer.status || t("common.unknown")}
{selectedMcpServer.description && (
- Description: + {t("common.description")}: {selectedMcpServer.description}
)} @@ -933,10 +952,10 @@ print(response.choices[0].message.content)`} {/* Connection Details */}
- Connection Details + {t("aiHub.modelHubTable.sectionConnectionDetails")}
- URL: + {t("aiHub.modelHubTable.fieldUrl")}
{selectedMcpServer.url} {selectedMcpServer.command && (
- Command: + {t("aiHub.modelHubTable.fieldCommand")} {selectedMcpServer.command}
)} @@ -957,7 +976,7 @@ print(response.choices[0].message.content)`} {/* Tools */} {selectedMcpServer.allowed_tools && selectedMcpServer.allowed_tools.length > 0 && (
- Allowed Tools + {t("aiHub.modelHubTable.sectionAllowedTools")}
{selectedMcpServer.allowed_tools.map((tool, idx) => ( @@ -971,7 +990,7 @@ print(response.choices[0].message.content)`} {/* Teams */} {selectedMcpServer.teams && selectedMcpServer.teams.length > 0 && (
- Teams + {t("aiHub.modelHubTable.sectionTeams")}
{selectedMcpServer.teams.map((team, idx) => ( @@ -985,7 +1004,7 @@ print(response.choices[0].message.content)`} {/* Access Groups */} {selectedMcpServer.mcp_access_groups && selectedMcpServer.mcp_access_groups.length > 0 && (
- Access Groups + {t("aiHub.modelHubTable.sectionAccessGroups")}
{selectedMcpServer.mcp_access_groups.map((group, idx) => ( @@ -998,34 +1017,34 @@ print(response.choices[0].message.content)`} {/* Metadata */}
- Metadata + {t("aiHub.modelHubTable.sectionMetadata")}
- Created By: + {t("aiHub.modelHubTable.fieldCreatedBy")} {selectedMcpServer.created_by}
- Updated By: + {t("aiHub.modelHubTable.fieldUpdatedBy")} {selectedMcpServer.updated_by}
- Created At: + {t("common.createdAt")}: {new Date(selectedMcpServer.created_at).toLocaleString()}
- Updated At: + {t("common.updatedAt")}: {new Date(selectedMcpServer.updated_at).toLocaleString()}
{selectedMcpServer.last_health_check && (
- Last Health Check: + {t("aiHub.modelHubTable.fieldLastHealthCheck")} {new Date(selectedMcpServer.last_health_check).toLocaleString()}
)}
{selectedMcpServer.health_check_error && (
- Health Check Error: + {t("aiHub.modelHubTable.fieldHealthCheckError")} {selectedMcpServer.health_check_error}
)} @@ -1033,7 +1052,7 @@ print(response.choices[0].message.content)`} {/* Usage Example */}
- Usage Example + {t("aiHub.modelHubTable.sectionUsageExample")} {`from fastmcp import Client import asyncio diff --git a/ui/litellm-dashboard/src/components/AIHub/SkillHubDashboard.tsx b/ui/litellm-dashboard/src/components/AIHub/SkillHubDashboard.tsx index f4b50fe3e51..b157282eda5 100644 --- a/ui/litellm-dashboard/src/components/AIHub/SkillHubDashboard.tsx +++ b/ui/litellm-dashboard/src/components/AIHub/SkillHubDashboard.tsx @@ -72,7 +72,7 @@ const SkillHubDashboard: React.FC = ({ } if (isLoading) { - return
Loading skills...
; + return
{t("aiHub.skillHubDashboard.loadingSkills")}
; } return ( @@ -80,15 +80,15 @@ const SkillHubDashboard: React.FC = ({ {/* Stats row */}
-
Total Skills
+
{t("aiHub.skillHubDashboard.statTotalSkills")}
{totalSkills}
-
Namespaces
+
{t("aiHub.skillHubDashboard.statNamespaces")}
{namespaces.length}
-
Domains
+
{t("aiHub.skillHubDashboard.statDomains")}
{domains.length}
@@ -96,10 +96,12 @@ const SkillHubDashboard: React.FC = ({ {/* Search + filters + table */}
-

All {publicPage ? "Public " : ""}Skills

+

+ {publicPage ? t("aiHub.skillHubDashboard.allPublicSkills") : t("aiHub.skillHubDashboard.allSkills")} +

} - placeholder="Search by name, namespace, or tag…" + placeholder={t("aiHub.skillHubDashboard.searchPlaceholder")} value={search} onChange={(e) => setSearch(e.target.value)} style={{ width: 280 }} @@ -124,7 +126,7 @@ const SkillHubDashboard: React.FC = ({ />
- Showing {filteredSkills.length} of {totalSkills} skill{totalSkills !== 1 ? "s" : ""} + {t("aiHub.skillHubDashboard.showing", { filtered: filteredSkills.length, count: totalSkills })}
diff --git a/ui/litellm-dashboard/src/locales/en.json b/ui/litellm-dashboard/src/locales/en.json index a0013e8324d..efac8f6e345 100644 --- a/ui/litellm-dashboard/src/locales/en.json +++ b/ui/litellm-dashboard/src/locales/en.json @@ -6490,5 +6490,109 @@ "saveSuccess": "Permissions updated successfully", "saveFailed": "Failed to update permissions" } + }, + "aiHub": { + "agentHubTableColumns": { + "colAgentName": "Agent Name", + "copyAgentName": "Copy agent name", + "colVersion": "Version", + "colProtocol": "Protocol", + "colSkills": "Skills", + "skillCount_one": "{{count}} skill", + "skillCount_other": "{{count}} skills", + "colCapabilities": "Capabilities", + "colIOModes": "I/O Modes", + "ioIn": "In:", + "ioOut": "Out:", + "colPublic": "Public", + "detailsShort": "Info" + }, + "modelHubTable": { + "title": "AI Hub", + "adminDescription": "Make models, agents, and MCP servers public for developers to know what's available.", + "userDescription": "A list of all public model names personally available to you.", + "modelHubUrl": "Model Hub URL:", + "copyUrl": "Copy URL", + "copiedToClipboard": "Copied to clipboard!", + "tabModelHub": "Model Hub", + "tabAgentHub": "Agent Hub", + "tabMcpHub": "MCP Hub", + "tabSkillHub": "Skill Hub", + "selectModelsPublic": "Select Models to Make Public", + "selectAgentsPublic": "Select Agents to Make Public", + "selectMcpPublic": "Select MCP Servers to Make Public", + "selectSkillsPublic": "Select Skills to Make Public", + "showingModels": "Showing {{filtered}} of {{total}} models", + "showingAgents_one": "Showing {{count}} agent", + "showingAgents_other": "Showing {{count}} agents", + "showingMcpServers_one": "Showing {{count}} MCP server", + "showingMcpServers_other": "Showing {{count}} MCP servers", + "publicHubNotEnabled": "Public Model Hub not enabled.", + "askAdminToEnable": "Ask your proxy admin to enable this on their Admin UI.", + "publicModelHubTitle": "Public Model Hub", + "shareableLink": "Shareable Link:", + "seePage": "See Page", + "modelDetails": "Model Details", + "modelOverview": "Model Overview", + "fieldModelGroup": "Model Group:", + "fieldMode": "Mode:", + "fieldProviders": "Providers:", + "fieldMaxInputTokens": "Max Input Tokens:", + "fieldMaxOutputTokens": "Max Output Tokens:", + "fieldInputCost": "Input Cost per 1M Tokens:", + "fieldOutputCost": "Output Cost per 1M Tokens:", + "notSpecified": "Not specified", + "tokenCostInfo": "Token & Cost Information", + "sectionCapabilities": "Capabilities", + "noCapabilities": "No special capabilities listed", + "sectionRateLimits": "Rate Limits", + "fieldTokensPerMinute": "Tokens per Minute:", + "fieldRequestsPerMinute": "Requests per Minute:", + "sectionSupportedParams": "Supported OpenAI Parameters", + "sectionUsageExample": "Usage Example", + "agentDetails": "Agent Details", + "agentOverview": "Agent Overview", + "fieldName": "Name:", + "fieldVersion": "Version:", + "fieldProtocolVersion": "Protocol Version:", + "fieldUrl": "URL:", + "sectionInputOutputModes": "Input/Output Modes", + "fieldInputModes": "Input Modes:", + "fieldOutputModes": "Output Modes:", + "sectionSkills": "Skills", + "skillId": "ID: {{id}}", + "skillExamples": "Examples:", + "sectionAdditionalFeatures": "Additional Features", + "supportsAuthCard": "Supports Authenticated Extended Card", + "mcpServerDetails": "MCP Server Details", + "mcpServerOverview": "Server Overview", + "fieldServerName": "Server Name:", + "fieldServerId": "Server ID:", + "fieldAlias": "Alias:", + "fieldTransport": "Transport:", + "fieldAuthType": "Auth Type:", + "sectionConnectionDetails": "Connection Details", + "fieldCommand": "Command:", + "sectionAllowedTools": "Allowed Tools", + "sectionTeams": "Teams", + "sectionAccessGroups": "Access Groups", + "sectionMetadata": "Metadata", + "fieldCreatedBy": "Created By:", + "fieldUpdatedBy": "Updated By:", + "fieldLastHealthCheck": "Last Health Check:", + "fieldHealthCheckError": "Health Check Error:" + }, + "skillHubDashboard": { + "loadingSkills": "Loading skills...", + "statTotalSkills": "Total Skills", + "statNamespaces": "Namespaces", + "statDomains": "Domains", + "allSkills": "All Skills", + "allPublicSkills": "All Public Skills", + "allDomainsPlaceholder": "All Domains", + "searchPlaceholder": "Search by name, namespace, or tag…", + "showing_one": "Showing {{filtered}} of {{count}} skill", + "showing_other": "Showing {{filtered}} of {{count}} skills" + } } } diff --git a/ui/litellm-dashboard/src/locales/zh-CN.json b/ui/litellm-dashboard/src/locales/zh-CN.json index b5161e8fa22..14bb46fd12f 100644 --- a/ui/litellm-dashboard/src/locales/zh-CN.json +++ b/ui/litellm-dashboard/src/locales/zh-CN.json @@ -6490,5 +6490,109 @@ "saveSuccess": "权限更新成功", "saveFailed": "更新权限失败" } + }, + "aiHub": { + "agentHubTableColumns": { + "colAgentName": "Agent 名称", + "copyAgentName": "复制 Agent 名称", + "colVersion": "版本", + "colProtocol": "协议", + "colSkills": "技能", + "skillCount_one": "{{count}} 个技能", + "skillCount_other": "{{count}} 个技能", + "colCapabilities": "能力", + "colIOModes": "输入/输出模式", + "ioIn": "输入:", + "ioOut": "输出:", + "colPublic": "公开", + "detailsShort": "详情" + }, + "modelHubTable": { + "title": "AI Hub", + "adminDescription": "将模型、Agent 和 MCP 服务器设为公开,让开发者了解可用资源。", + "userDescription": "您个人可用的所有公开模型名称列表。", + "modelHubUrl": "模型 Hub URL:", + "copyUrl": "复制 URL", + "copiedToClipboard": "已复制到剪贴板!", + "tabModelHub": "模型 Hub", + "tabAgentHub": "Agent Hub", + "tabMcpHub": "MCP Hub", + "tabSkillHub": "技能 Hub", + "selectModelsPublic": "选择要公开的模型", + "selectAgentsPublic": "选择要公开的 Agent", + "selectMcpPublic": "选择要公开的 MCP 服务器", + "selectSkillsPublic": "选择要公开的技能", + "showingModels": "显示 {{filtered}} / {{total}} 个模型", + "showingAgents_one": "显示 {{count}} 个 Agent", + "showingAgents_other": "显示 {{count}} 个 Agent", + "showingMcpServers_one": "显示 {{count}} 个 MCP 服务器", + "showingMcpServers_other": "显示 {{count}} 个 MCP 服务器", + "publicHubNotEnabled": "公开模型 Hub 未启用。", + "askAdminToEnable": "请联系代理管理员在管理界面中启用此功能。", + "publicModelHubTitle": "公开模型 Hub", + "shareableLink": "可分享链接:", + "seePage": "查看页面", + "modelDetails": "模型详情", + "modelOverview": "模型概览", + "fieldModelGroup": "模型组:", + "fieldMode": "模式:", + "fieldProviders": "提供商:", + "fieldMaxInputTokens": "最大输入 Token 数:", + "fieldMaxOutputTokens": "最大输出 Token 数:", + "fieldInputCost": "每百万 Token 输入费用:", + "fieldOutputCost": "每百万 Token 输出费用:", + "notSpecified": "未指定", + "tokenCostInfo": "Token 与费用信息", + "sectionCapabilities": "能力", + "noCapabilities": "暂无特殊能力说明", + "sectionRateLimits": "速率限制", + "fieldTokensPerMinute": "每分钟 Token 数:", + "fieldRequestsPerMinute": "每分钟请求数:", + "sectionSupportedParams": "支持的 OpenAI 参数", + "sectionUsageExample": "使用示例", + "agentDetails": "Agent 详情", + "agentOverview": "Agent 概览", + "fieldName": "名称:", + "fieldVersion": "版本:", + "fieldProtocolVersion": "协议版本:", + "fieldUrl": "URL:", + "sectionInputOutputModes": "输入/输出模式", + "fieldInputModes": "输入模式:", + "fieldOutputModes": "输出模式:", + "sectionSkills": "技能", + "skillId": "ID:{{id}}", + "skillExamples": "示例:", + "sectionAdditionalFeatures": "附加功能", + "supportsAuthCard": "支持已认证扩展卡片", + "mcpServerDetails": "MCP 服务器详情", + "mcpServerOverview": "服务器概览", + "fieldServerName": "服务器名称:", + "fieldServerId": "服务器 ID:", + "fieldAlias": "别名:", + "fieldTransport": "传输方式:", + "fieldAuthType": "认证类型:", + "sectionConnectionDetails": "连接详情", + "fieldCommand": "命令:", + "sectionAllowedTools": "允许的工具", + "sectionTeams": "团队", + "sectionAccessGroups": "访问组", + "sectionMetadata": "元数据", + "fieldCreatedBy": "创建人:", + "fieldUpdatedBy": "更新人:", + "fieldLastHealthCheck": "最后健康检查:", + "fieldHealthCheckError": "健康检查错误:" + }, + "skillHubDashboard": { + "loadingSkills": "正在加载技能...", + "statTotalSkills": "技能总数", + "statNamespaces": "命名空间", + "statDomains": "域", + "allSkills": "全部技能", + "allPublicSkills": "全部公开技能", + "allDomainsPlaceholder": "所有域", + "searchPlaceholder": "按名称、命名空间或标签搜索…", + "showing_one": "显示 {{filtered}} / {{count}} 个技能", + "showing_other": "显示 {{filtered}} / {{count}} 个技能" + } } }