From aea41b4adae8d6ae8e692a4d90df996e25101311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B9=E9=9B=AA?= <2b@yorha.xyz> Date: Thu, 11 Jun 2026 02:13:36 +0900 Subject: [PATCH] feat(ui): i18n for vector store tester and info views --- .../VectorStoreTester.tsx | 60 +++++++---- .../vector_store_management/index.tsx | 34 +++--- .../vector_store_info.tsx | 102 +++++++++++------- ui/litellm-dashboard/src/locales/en.json | 66 ++++++++++++ ui/litellm-dashboard/src/locales/zh-CN.json | 66 ++++++++++++ 5 files changed, 258 insertions(+), 70 deletions(-) diff --git a/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTester.tsx b/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTester.tsx index 5c59334fa4d..2b54741a4f7 100644 --- a/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTester.tsx +++ b/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTester.tsx @@ -4,6 +4,7 @@ import MessageManager from "@/components/molecules/message_manager"; import { SendOutlined, DatabaseOutlined, LoadingOutlined, DownOutlined, RightOutlined } from "@ant-design/icons"; import { vectorStoreSearchCall } from "../networking"; import NotificationsManager from "../molecules/notifications_manager"; +import { useTranslation } from "react-i18next"; const { TextArea } = Input; const { Text, Title } = Typography; @@ -34,6 +35,7 @@ interface VectorStoreTesterProps { } export const VectorStoreTester: React.FC = ({ vectorStoreId, accessToken, className = "" }) => { + const { t } = useTranslation(); const [query, setQuery] = useState(""); const [isLoading, setIsLoading] = useState(false); const [searchHistory, setSearchHistory] = useState< @@ -47,7 +49,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor const handleSearch = async () => { if (!query.trim()) { - MessageManager.warning("Please enter a search query"); + MessageManager.warning(t("vectorStoreManagement.vectorStoreTester.enterSearchQuery")); return; } @@ -66,7 +68,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor setQuery(""); } catch (error) { console.error("Error searching vector store:", error); - NotificationsManager.fromBackend("Failed to search vector store"); + NotificationsManager.fromBackend(t("vectorStoreManagement.vectorStoreTester.searchFailed")); } finally { setIsLoading(false); } @@ -86,7 +88,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor const clearHistory = () => { setSearchHistory([]); setExpandedResults({}); - NotificationsManager.success("Search history cleared"); + NotificationsManager.success(t("vectorStoreManagement.vectorStoreTester.historyCleared")); }; const toggleResultExpansion = (historyIndex: number, resultIndex: number) => { @@ -105,12 +107,12 @@ export const VectorStoreTester: React.FC = ({ vectorStor
- Test Vector Store + {t("vectorStoreManagement.vectorStoreTester.title")}
{searchHistory.length > 0 && ( )} @@ -120,7 +122,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor {searchHistory.length === 0 ? (
- Test your vector store by entering a search query below + {t("vectorStoreManagement.vectorStoreTester.emptyPrompt")}
) : (
@@ -130,7 +132,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor
- Query + {t("vectorStoreManagement.vectorStoreTester.queryLabel")} {formatTimestamp(entry.timestamp)}
{entry.query}
@@ -142,10 +144,12 @@ export const VectorStoreTester: React.FC = ({ vectorStor
- Vector Store Results + {t("vectorStoreManagement.vectorStoreTester.resultsLabel")} {entry.response && ( - {entry.response.data?.length || 0} results + {t("vectorStoreManagement.vectorStoreTester.resultsCount", { + count: entry.response.data?.length || 0, + })} )}
@@ -168,7 +172,9 @@ export const VectorStoreTester: React.FC = ({ vectorStor ) : ( )} - Result {resultIndex + 1} + + {t("vectorStoreManagement.vectorStoreTester.resultN", { n: resultIndex + 1 })} + {/* Show preview of content when collapsed */} {!isExpanded && result.content && result.content[0] && ( @@ -177,7 +183,9 @@ export const VectorStoreTester: React.FC = ({ vectorStor )}
- Score: {result.score.toFixed(4)} + {t("vectorStoreManagement.vectorStoreTester.scoreLabel", { + score: result.score.toFixed(4), + })}
@@ -188,7 +196,11 @@ export const VectorStoreTester: React.FC = ({ vectorStor {result.content && result.content.map((content, contentIndex) => (
-
Content ({content.type})
+
+ {t("vectorStoreManagement.vectorStoreTester.contentLabel", { + type: content.type, + })} +
{content.text}
@@ -198,21 +210,31 @@ export const VectorStoreTester: React.FC = ({ vectorStor {/* Metadata */} {(result.file_id || result.filename || result.attributes) && (
-
Metadata
+
+ {t("vectorStoreManagement.vectorStoreTester.metadataLabel")} +
{result.file_id && (
- File ID: {result.file_id} + + {t("vectorStoreManagement.vectorStoreTester.fileIdLabel")} + {" "} + {result.file_id}
)} {result.filename && (
- Filename: {result.filename} + + {t("vectorStoreManagement.vectorStoreTester.filenameLabel")} + {" "} + {result.filename}
)} {result.attributes && Object.keys(result.attributes).length > 0 && (
- Attributes: + + {t("vectorStoreManagement.vectorStoreTester.attributesLabel")} +
                                                 {JSON.stringify(result.attributes, null, 2)}
                                               
@@ -228,7 +250,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor })}
) : ( -
No results found
+
{t("common.noResults")}
)}
@@ -254,7 +276,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor value={query} onChange={(e) => setQuery(e.target.value)} onKeyDown={handleKeyDown} - placeholder="Enter your search query... (Shift+Enter for new line)" + placeholder={t("vectorStoreManagement.vectorStoreTester.searchPlaceholder")} disabled={isLoading} autoSize={{ minRows: 1, maxRows: 4 }} style={{ resize: "none" }} @@ -267,7 +289,7 @@ export const VectorStoreTester: React.FC = ({ vectorStor icon={} loading={isLoading} > - Search + {t("common.search")}
diff --git a/ui/litellm-dashboard/src/components/vector_store_management/index.tsx b/ui/litellm-dashboard/src/components/vector_store_management/index.tsx index 8695dce8704..73d5ae8a28b 100644 --- a/ui/litellm-dashboard/src/components/vector_store_management/index.tsx +++ b/ui/litellm-dashboard/src/components/vector_store_management/index.tsx @@ -22,6 +22,7 @@ import CreateVectorStore from "./CreateVectorStore"; import TestVectorStoreTab from "./TestVectorStoreTab"; import { isAdminRole } from "@/utils/roles"; import NotificationsManager from "../molecules/notifications_manager"; +import { useTranslation } from "react-i18next"; interface VectorStoreProps { accessToken: string | null; @@ -30,6 +31,7 @@ interface VectorStoreProps { } const VectorStoreManagement: React.FC = ({ accessToken, userID, userRole }) => { + const { t } = useTranslation(); const [vectorStores, setVectorStores] = useState([]); const [isCreateModalVisible, setIsCreateModalVisible] = useState(false); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); @@ -48,7 +50,7 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID setVectorStores(response.data || []); } catch (error) { console.error("Error fetching vector stores:", error); - NotificationsManager.fromBackend("Error fetching vector stores: " + error); + NotificationsManager.fromBackend(t("vectorStoreManagement.index.fetchVectorStoresFailed", { error })); } }; @@ -60,7 +62,7 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID setCredentials(response.credentials || []); } catch (error) { console.error("Error fetching credentials:", error); - NotificationsManager.fromBackend("Error fetching credentials: " + error); + NotificationsManager.fromBackend(t("vectorStoreManagement.index.fetchCredentialsFailed", { error })); } }; @@ -97,11 +99,11 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID setIsDeleting(true); try { await vectorStoreDeleteCall(accessToken, vectorStoreToDelete); - NotificationsManager.success("Vector store deleted successfully"); + NotificationsManager.success(t("vectorStoreManagement.index.deleteSuccess")); fetchVectorStores(); } catch (error) { console.error("Error deleting vector store:", error); - NotificationsManager.fromBackend("Error deleting vector store: " + error); + NotificationsManager.fromBackend(t("vectorStoreManagement.index.deleteFailed", { error })); } finally { setIsDeleting(false); setIsDeleteModalOpen(false); @@ -139,9 +141,9 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID
-

Vector Store Management

+

{t("vectorStoreManagement.index.pageTitle")}

- {lastRefreshed && Last Refreshed: {lastRefreshed}} + {lastRefreshed && {t("vectorStoreManagement.index.lastRefreshed", { time: lastRefreshed })}} = ({ accessToken, userID
-

You can use vector stores to store and retrieve LLM embeddings.

+

{t("vectorStoreManagement.index.pageDescription")}

- Create Vector Store - Manage Vector Stores - Test Vector Store + {t("vectorStoreManagement.index.tabCreate")} + {t("vectorStoreManagement.index.tabManage")} + {t("vectorStoreManagement.index.tabTest")} @@ -172,7 +174,7 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID {/* Tab 2: Manage Vector Stores */} setIsCreateModalVisible(true)}> - + Add Vector Store + {t("vectorStoreManagement.index.addVectorStore")} @@ -206,10 +208,12 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID {/* Delete Confirmation Modal */} setIsDeleteModalOpen(false)} onOk={confirmDelete} confirmLoading={isDeleting} diff --git a/ui/litellm-dashboard/src/components/vector_store_management/vector_store_info.tsx b/ui/litellm-dashboard/src/components/vector_store_management/vector_store_info.tsx index 92ed17715c6..e40783f34c7 100644 --- a/ui/litellm-dashboard/src/components/vector_store_management/vector_store_info.tsx +++ b/ui/litellm-dashboard/src/components/vector_store_management/vector_store_info.tsx @@ -8,6 +8,7 @@ import { VectorStore } from "./types"; import { Providers, providerLogoMap, provider_map } from "../provider_info_helpers"; import VectorStoreTester from "./VectorStoreTester"; import NotificationsManager from "../molecules/notifications_manager"; +import { useTranslation } from "react-i18next"; interface VectorStoreInfoViewProps { vectorStoreId: string; @@ -24,6 +25,7 @@ const VectorStoreInfoView: React.FC = ({ is_admin, editVectorStore, }) => { + const { t } = useTranslation(); const [form] = Form.useForm(); const [vectorStoreDetails, setVectorStoreDetails] = useState(null); const [isEditing, setIsEditing] = useState(editVectorStore); @@ -58,7 +60,7 @@ const VectorStoreInfoView: React.FC = ({ } } catch (error) { console.error("Error fetching vector store details:", error); - NotificationsManager.fromBackend("Error fetching vector store details: " + error); + NotificationsManager.fromBackend(t("vectorStoreManagement.vectorStoreInfo.fetchDetailsFailed", { error })); } }; @@ -86,7 +88,7 @@ const VectorStoreInfoView: React.FC = ({ try { metadata = metadataString ? JSON.parse(metadataString) : {}; } catch (e) { - NotificationsManager.fromBackend("Invalid JSON in metadata field"); + NotificationsManager.fromBackend(t("vectorStoreManagement.vectorStoreInfo.invalidMetadataJson")); return; } @@ -99,17 +101,17 @@ const VectorStoreInfoView: React.FC = ({ }; await vectorStoreUpdateCall(accessToken, updateData); - NotificationsManager.success("Vector store updated successfully"); + NotificationsManager.success(t("vectorStoreManagement.vectorStoreInfo.updateSuccess")); setIsEditing(false); fetchVectorStoreDetails(); } catch (error) { console.error("Error updating vector store:", error); - NotificationsManager.fromBackend("Error updating vector store: " + error); + NotificationsManager.fromBackend(t("vectorStoreManagement.vectorStoreInfo.updateFailed", { error })); } }; if (!vectorStoreDetails) { - return
Loading...
; + return
{t("common.loading")}
; } return ( @@ -117,18 +119,26 @@ const VectorStoreInfoView: React.FC = ({
- Vector Store ID: {vectorStoreDetails.vector_store_id} - {vectorStoreDetails.vector_store_description || "No description"} + + {t("vectorStoreManagement.vectorStoreInfo.vectorStoreIdTitle", { + id: vectorStoreDetails.vector_store_id, + })} + + + {vectorStoreDetails.vector_store_description || t("vectorStoreManagement.vectorStoreInfo.noDescription")} +
- {is_admin && !isEditing && } + {is_admin && !isEditing && ( + + )}
- Details - Test Vector Store + {t("vectorStoreManagement.vectorStoreInfo.tabDetails")} + {t("vectorStoreManagement.vectorStoreInfo.tabTest")} @@ -137,37 +147,50 @@ const VectorStoreInfoView: React.FC = ({ {isEditing ? (
- Edit Vector Store + {t("vectorStoreManagement.vectorStoreInfo.editTitle")}
- + - + - Provider{" "} - + {t("vectorStoreManagement.vectorStoreInfo.providerLabel")}{" "} + } name="custom_llm_provider" - rules={[{ required: true, message: "Please select a provider" }]} + rules={[ + { + required: true, + message: t("vectorStoreManagement.vectorStoreInfo.providerRequired"), + }, + ]} > {Object.entries(Providers).map(([providerEnum, providerDisplayName]) => { @@ -206,20 +229,23 @@ const VectorStoreInfoView: React.FC = ({ {/* Credentials */}
- Either select existing credentials OR enter provider credentials below + {t("vectorStoreManagement.vectorStoreInfo.credentialsHint")}
- + (option?.label ?? "").toLowerCase().includes(input.toLowerCase()) } options={[ - { value: null, label: "None" }, + { value: null, label: t("common.none") }, ...credentials.map((credential) => ({ value: credential.credential_name, label: credential.credential_name, @@ -238,8 +264,8 @@ const VectorStoreInfoView: React.FC = ({ - Metadata{" "} - + {t("vectorStoreManagement.vectorStoreInfo.metadataLabel")}{" "} + @@ -254,9 +280,9 @@ const VectorStoreInfoView: React.FC = ({
- setIsEditing(false)}>Cancel + setIsEditing(false)}>{t("common.cancel")} - Save Changes + {t("vectorStoreManagement.vectorStoreInfo.saveChanges")}
@@ -265,25 +291,29 @@ const VectorStoreInfoView: React.FC = ({ ) : (
- Vector Store Details - {is_admin && } + {t("vectorStoreManagement.vectorStoreInfo.detailsTitle")} + {is_admin && ( + + )}
- ID + {t("vectorStoreManagement.vectorStoreInfo.idLabel")} {vectorStoreDetails.vector_store_id}
- Name + {t("common.name")} {vectorStoreDetails.vector_store_name || "-"}
- Description + {t("common.description")} {vectorStoreDetails.vector_store_description || "-"}
- Provider + {t("vectorStoreManagement.vectorStoreInfo.providerLabel")}
{(() => { const provider = vectorStoreDetails.custom_llm_provider || "bedrock"; @@ -331,19 +361,19 @@ const VectorStoreInfoView: React.FC = ({
- Metadata + {t("vectorStoreManagement.vectorStoreInfo.metadataLabel")}
{metadataString}
- Created + {t("vectorStoreManagement.vectorStoreInfo.createdLabel")} {vectorStoreDetails.created_at ? new Date(vectorStoreDetails.created_at).toLocaleString() : "-"}
- Last Updated + {t("vectorStoreManagement.vectorStoreInfo.updatedLabel")} {vectorStoreDetails.updated_at ? new Date(vectorStoreDetails.updated_at).toLocaleString() : "-"} diff --git a/ui/litellm-dashboard/src/locales/en.json b/ui/litellm-dashboard/src/locales/en.json index 0dfdeb470b9..b413a8633a0 100644 --- a/ui/litellm-dashboard/src/locales/en.json +++ b/ui/litellm-dashboard/src/locales/en.json @@ -5875,6 +5875,72 @@ "editTooltip": "Edit vector store", "deleteTooltip": "Delete vector store", "noVectorStores": "No vector stores found" + }, + "vectorStoreTester": { + "title": "Test Vector Store", + "clearHistory": "Clear History", + "emptyPrompt": "Test your vector store by entering a search query below", + "queryLabel": "Query", + "resultsLabel": "Vector Store Results", + "resultsCount_one": "{{count}} result", + "resultsCount_other": "{{count}} results", + "resultN": "Result {{n}}", + "scoreLabel": "Score: {{score}}", + "contentLabel": "Content ({{type}})", + "metadataLabel": "Metadata", + "fileIdLabel": "File ID:", + "filenameLabel": "Filename:", + "attributesLabel": "Attributes:", + "searchPlaceholder": "Enter your search query... (Shift+Enter for new line)", + "enterSearchQuery": "Please enter a search query", + "searchFailed": "Failed to search vector store", + "historyCleared": "Search history cleared" + }, + "index": { + "pageTitle": "Vector Store Management", + "lastRefreshed": "Last Refreshed: {{time}}", + "pageDescription": "You can use vector stores to store and retrieve LLM embeddings.", + "tabCreate": "Create Vector Store", + "tabManage": "Manage Vector Stores", + "tabTest": "Test Vector Store", + "addVectorStore": "+ Add Vector Store", + "deleteModalTitle": "Delete Vector Store", + "deleteModalMessage": "Are you sure you want to delete this vector store? This action cannot be undone.", + "deleteModalInfoTitle": "Vector Store Information", + "vectorStoreIdLabel": "Vector Store ID", + "deleteSuccess": "Vector store deleted successfully", + "deleteFailed": "Error deleting vector store: {{error}}", + "fetchVectorStoresFailed": "Error fetching vector stores: {{error}}", + "fetchCredentialsFailed": "Error fetching credentials: {{error}}" + }, + "vectorStoreInfo": { + "backButton": "Back to Vector Stores", + "vectorStoreIdTitle": "Vector Store ID: {{id}}", + "noDescription": "No description", + "editButton": "Edit Vector Store", + "tabDetails": "Details", + "tabTest": "Test Vector Store", + "editTitle": "Edit Vector Store", + "vectorStoreIdLabel": "Vector Store ID", + "vectorStoreIdRequired": "Please input a vector store ID", + "vectorStoreNameLabel": "Vector Store Name", + "providerLabel": "Provider", + "providerTooltip": "Select the provider for this vector store", + "providerRequired": "Please select a provider", + "credentialsHint": "Either select existing credentials OR enter provider credentials below", + "existingCredentialsLabel": "Existing Credentials", + "existingCredentialsPlaceholder": "Select or search for existing credentials", + "metadataLabel": "Metadata", + "metadataTooltip": "JSON metadata for the vector store", + "invalidMetadataJson": "Invalid JSON in metadata field", + "saveChanges": "Save Changes", + "detailsTitle": "Vector Store Details", + "idLabel": "ID", + "createdLabel": "Created", + "updatedLabel": "Last Updated", + "updateSuccess": "Vector store updated successfully", + "updateFailed": "Error updating vector store: {{error}}", + "fetchDetailsFailed": "Error fetching vector store details: {{error}}" } } } diff --git a/ui/litellm-dashboard/src/locales/zh-CN.json b/ui/litellm-dashboard/src/locales/zh-CN.json index 04c0bb10299..52f8fd6887e 100644 --- a/ui/litellm-dashboard/src/locales/zh-CN.json +++ b/ui/litellm-dashboard/src/locales/zh-CN.json @@ -5875,6 +5875,72 @@ "editTooltip": "编辑向量存储", "deleteTooltip": "删除向量存储", "noVectorStores": "未找到向量存储" + }, + "vectorStoreTester": { + "title": "测试向量存储", + "clearHistory": "清除历史", + "emptyPrompt": "在下方输入搜索查询以测试您的向量存储", + "queryLabel": "查询", + "resultsLabel": "向量存储结果", + "resultsCount_one": "{{count}} 条结果", + "resultsCount_other": "{{count}} 条结果", + "resultN": "结果 {{n}}", + "scoreLabel": "得分:{{score}}", + "contentLabel": "内容({{type}})", + "metadataLabel": "元数据", + "fileIdLabel": "文件 ID:", + "filenameLabel": "文件名:", + "attributesLabel": "属性:", + "searchPlaceholder": "输入搜索查询...(Shift+Enter 换行)", + "enterSearchQuery": "请输入搜索查询", + "searchFailed": "搜索向量存储失败", + "historyCleared": "搜索历史已清除" + }, + "index": { + "pageTitle": "向量存储管理", + "lastRefreshed": "最后刷新:{{time}}", + "pageDescription": "您可以使用向量存储来存储和检索 LLM 嵌入。", + "tabCreate": "创建向量存储", + "tabManage": "管理向量存储", + "tabTest": "测试向量存储", + "addVectorStore": "+ 添加向量存储", + "deleteModalTitle": "删除向量存储", + "deleteModalMessage": "确定要删除此向量存储吗?此操作无法撤销。", + "deleteModalInfoTitle": "向量存储信息", + "vectorStoreIdLabel": "向量存储 ID", + "deleteSuccess": "向量存储已成功删除", + "deleteFailed": "删除向量存储失败:{{error}}", + "fetchVectorStoresFailed": "获取向量存储失败:{{error}}", + "fetchCredentialsFailed": "获取凭据失败:{{error}}" + }, + "vectorStoreInfo": { + "backButton": "返回向量存储列表", + "vectorStoreIdTitle": "向量存储 ID:{{id}}", + "noDescription": "暂无描述", + "editButton": "编辑向量存储", + "tabDetails": "详情", + "tabTest": "测试向量存储", + "editTitle": "编辑向量存储", + "vectorStoreIdLabel": "向量存储 ID", + "vectorStoreIdRequired": "请输入向量存储 ID", + "vectorStoreNameLabel": "向量存储名称", + "providerLabel": "提供商", + "providerTooltip": "为此向量存储选择提供商", + "providerRequired": "请选择提供商", + "credentialsHint": "选择现有凭据或在下方输入提供商凭据", + "existingCredentialsLabel": "现有凭据", + "existingCredentialsPlaceholder": "选择或搜索现有凭据", + "metadataLabel": "元数据", + "metadataTooltip": "向量存储的 JSON 元数据", + "invalidMetadataJson": "元数据字段中的 JSON 无效", + "saveChanges": "保存更改", + "detailsTitle": "向量存储详情", + "idLabel": "ID", + "createdLabel": "创建时间", + "updatedLabel": "最后更新时间", + "updateSuccess": "向量存储更新成功", + "updateFailed": "更新向量存储失败:{{error}}", + "fetchDetailsFailed": "获取向量存储详情失败:{{error}}" } } }