From 129811bce8aa7c8d422798949a8b38f327c67f05 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 23:10:59 +0900 Subject: [PATCH] feat(ui): i18n for prompts batch 2 --- .../conversation_panel/MessageInput.tsx | 6 +- .../conversation_panel/VariableInput.tsx | 6 +- .../conversation_panel/VariableWarning.tsx | 8 +- .../conversation_panel/index.tsx | 4 +- .../conversation_panel/useConversation.ts | 23 +++-- .../prompts/prompt_editor_view/index.tsx | 24 +++-- .../src/components/prompts/prompt_info.tsx | 91 ++++++++++--------- .../src/components/prompts/prompt_table.tsx | 26 +++--- .../src/components/prompts/tool_modal.tsx | 12 ++- ui/litellm-dashboard/src/locales/en.json | 83 +++++++++++++++++ ui/litellm-dashboard/src/locales/zh-CN.json | 83 +++++++++++++++++ 11 files changed, 285 insertions(+), 81 deletions(-) diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/MessageInput.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/MessageInput.tsx index 24024e136a2..c991b618376 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/MessageInput.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/MessageInput.tsx @@ -2,6 +2,7 @@ import React from "react"; import { ArrowUpOutlined } from "@ant-design/icons"; import { Button as TremorButton } from "@tremor/react"; import { Input } from "antd"; +import { useTranslation } from "react-i18next"; const { TextArea } = Input; @@ -24,6 +25,7 @@ const MessageInput: React.FC = ({ onKeyDown, onCancel, }) => { + const { t } = useTranslation(); return (
@@ -31,7 +33,7 @@ const MessageInput: React.FC = ({ value={inputMessage} onChange={(e) => onInputChange(e.target.value)} onKeyDown={onKeyDown} - placeholder="Type your message... (Shift+Enter for new line)" + placeholder={t("promptsPage.messageInput.placeholder")} disabled={isLoading} className="flex-1" autoSize={{ minRows: 1, maxRows: 4 }} @@ -57,7 +59,7 @@ const MessageInput: React.FC = ({ {isLoading && ( - Cancel + {t("common.cancel")} )}
diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableInput.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableInput.tsx index 8d982d50afb..ee5ab97dd95 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableInput.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableInput.tsx @@ -1,5 +1,6 @@ import React from "react"; import { Input } from "antd"; +import { useTranslation } from "react-i18next"; interface VariableInputProps { extractedVariables: string[]; @@ -8,13 +9,14 @@ interface VariableInputProps { } const VariableInput: React.FC = ({ extractedVariables, variables, onVariableChange }) => { + const { t } = useTranslation(); if (extractedVariables.length === 0) { return null; } return (
-

Fill in template variables to start testing

+

{t("promptsPage.variableInput.title")}

{extractedVariables.map((varName) => (
@@ -26,7 +28,7 @@ const VariableInput: React.FC = ({ extractedVariables, varia onVariableChange(varName, e.target.value)} - placeholder={`Enter value for ${varName}`} + placeholder={t("promptsPage.variableInput.valuePlaceholder", { varName })} size="small" />
diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableWarning.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableWarning.tsx index 4f46f6aa566..3b8e55f9fc8 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableWarning.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/VariableWarning.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { useTranslation } from "react-i18next"; interface VariableWarningProps { extractedVariables: string[]; @@ -6,6 +7,7 @@ interface VariableWarningProps { } const VariableWarning: React.FC = ({ extractedVariables, variables }) => { + const { t } = useTranslation(); const missingVariables = extractedVariables.filter( (varName) => !variables[varName] || variables[varName].trim() === "", ); @@ -19,9 +21,11 @@ const VariableWarning: React.FC = ({ extractedVariables, v
⚠️
-

Please fill in all template variables above

+

{t("promptsPage.variableWarning.title")}

- Missing: {missingVariables.map((varName) => `{{${varName}}}`).join(", ")} + {t("promptsPage.variableWarning.missing", { + list: missingVariables.map((varName) => `{{${varName}}}`).join(", "), + })}

diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/index.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/index.tsx index 726a3a009bb..09cf96a6a59 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/index.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/index.tsx @@ -1,6 +1,7 @@ import React from "react"; import { ClearOutlined } from "@ant-design/icons"; import { Button as TremorButton } from "@tremor/react"; +import { useTranslation } from "react-i18next"; import { ConversationPanelProps } from "./types"; import { useConversation } from "./useConversation"; import VariableInput from "./VariableInput"; @@ -9,6 +10,7 @@ import VariableWarning from "./VariableWarning"; import MessageInput from "./MessageInput"; const ConversationPanel: React.FC = ({ prompt, accessToken }) => { + const { t } = useTranslation(); const { isLoading, messages, @@ -43,7 +45,7 @@ const ConversationPanel: React.FC = ({ prompt, accessTok className="bg-gray-100 hover:bg-gray-200 text-gray-700 border-gray-300" icon={ClearOutlined} > - Clear Chat + {t("promptsPage.conversationPanel.clearChat")}
)} diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/useConversation.ts b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/useConversation.ts index 7b595c777c1..dd3d9fa003e 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/useConversation.ts +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/conversation_panel/useConversation.ts @@ -1,4 +1,5 @@ import { useState, useRef, useEffect } from "react"; +import { useTranslation } from "react-i18next"; import NotificationsManager from "../../../molecules/notifications_manager"; import { TokenUsage } from "../../../playground/chat_ui/ResponseMetrics"; import { Message } from "./types"; @@ -6,6 +7,7 @@ import { convertToDotPrompt, extractVariables } from "../utils"; import { getProxyBaseUrl, getGlobalLitellmHeaderName } from "../../../networking"; export const useConversation = (prompt: any, accessToken: string | null) => { + const { t } = useTranslation(); const [isLoading, setIsLoading] = useState(false); const [messages, setMessages] = useState([]); const [inputMessage, setInputMessage] = useState(""); @@ -37,12 +39,12 @@ export const useConversation = (prompt: any, accessToken: string | null) => { const handleSendMessage = async () => { if (!accessToken) { - NotificationsManager.fromBackend("Access token is required"); + NotificationsManager.fromBackend(t("promptsPage.conversationPanel.accessTokenRequired")); return; } if (extractedVariables.length > 0 && !allVariablesFilled) { - NotificationsManager.fromBackend("Please fill in all template variables"); + NotificationsManager.fromBackend(t("promptsPage.conversationPanel.fillAllVariables")); return; } @@ -183,9 +185,18 @@ export const useConversation = (prompt: any, accessToken: string | null) => { setMessages((prev) => { const lastMsg = prev[prev.length - 1]; if (lastMsg && lastMsg.role === "assistant" && lastMsg.content === "") { - return [...prev.slice(0, -1), { role: "assistant", content: `Error: ${error.message}` }]; + return [ + ...prev.slice(0, -1), + { + role: "assistant", + content: t("promptsPage.conversationPanel.errorMessage", { message: error.message }), + }, + ]; } - return [...prev, { role: "assistant", content: `Error: ${error.message}` }]; + return [ + ...prev, + { role: "assistant", content: t("promptsPage.conversationPanel.errorMessage", { message: error.message }) }, + ]; }); } } finally { @@ -199,14 +210,14 @@ export const useConversation = (prompt: any, accessToken: string | null) => { abortController.abort(); setAbortController(null); setIsLoading(false); - NotificationsManager.info("Request cancelled"); + NotificationsManager.info(t("promptsPage.conversationPanel.requestCancelled")); } }; const handleClearConversation = () => { setMessages([]); setVariablesFilled(false); - NotificationsManager.success("Chat history cleared."); + NotificationsManager.success(t("promptsPage.conversationPanel.chatCleared")); }; const handleKeyDown = (event: React.KeyboardEvent) => { diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/index.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/index.tsx index c8c572468f8..7bcb85ecfa3 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/index.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/index.tsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; import ToolModal from "../tool_modal"; import NotificationsManager from "../../molecules/notifications_manager"; import { createPromptCall, updatePromptCall, getPromptInfo } from "../../networking"; @@ -15,13 +16,14 @@ import DotpromptViewTab from "./DotpromptViewTab"; import VersionHistorySidePanel from "./VersionHistorySidePanel"; const PromptEditorView: React.FC = ({ onClose, onSuccess, accessToken, initialPromptData }) => { + const { t } = useTranslation(); const getInitialPrompt = (): PromptType => { if (initialPromptData) { try { return parseExistingPrompt(initialPromptData); } catch (error) { console.error("Error parsing existing prompt:", error); - NotificationsManager.fromBackend("Failed to parse prompt data"); + NotificationsManager.fromBackend(t("promptsPage.promptEditorView.failedToParsePrompt")); } } return { @@ -142,7 +144,7 @@ const PromptEditorView: React.FC = ({ onClose, onSuccess, setShowToolModal(false); setEditingToolIndex(null); } catch (error) { - NotificationsManager.fromBackend("Invalid JSON format"); + NotificationsManager.fromBackend(t("promptsPage.promptEditorView.invalidJsonFormat")); } }; @@ -172,7 +174,7 @@ const PromptEditorView: React.FC = ({ onClose, onSuccess, // NotificationsManager.success(`Loaded version v${versionNum}`); } catch (error) { console.error("Error loading version:", error); - NotificationsManager.fromBackend("Failed to load prompt version"); + NotificationsManager.fromBackend(t("promptsPage.promptEditorView.failedToLoadVersion")); } }; @@ -186,12 +188,12 @@ const PromptEditorView: React.FC = ({ onClose, onSuccess, const handleSave = async () => { if (!accessToken) { - NotificationsManager.fromBackend("Access token is required"); + NotificationsManager.fromBackend(t("promptsPage.promptEditorView.accessTokenRequired")); return; } if (!prompt.name || prompt.name.trim() === "") { - NotificationsManager.fromBackend("Please enter a valid prompt name"); + NotificationsManager.fromBackend(t("promptsPage.promptEditorView.invalidPromptName")); return; } @@ -215,16 +217,18 @@ const PromptEditorView: React.FC = ({ onClose, onSuccess, if (editMode && initialPromptData?.prompt_spec?.prompt_id) { await updatePromptCall(accessToken, initialPromptData.prompt_spec.prompt_id, promptData); - NotificationsManager.success("Prompt updated successfully!"); + NotificationsManager.success(t("promptsPage.promptEditorView.updateSuccess")); } else { await createPromptCall(accessToken, promptData); - NotificationsManager.success("Prompt created successfully!"); + NotificationsManager.success(t("promptsPage.promptEditorView.createSuccess")); } onSuccess(); onClose(); } catch (error) { console.error("Error saving prompt:", error); - NotificationsManager.fromBackend(editMode ? "Failed to update prompt" : "Failed to save prompt"); + NotificationsManager.fromBackend( + editMode ? t("promptsPage.promptEditorView.updateFailed") : t("promptsPage.promptEditorView.saveFailed"), + ); } finally { setIsSaving(false); setShowNameModal(false); @@ -321,7 +325,7 @@ const PromptEditorView: React.FC = ({ onClose, onSuccess, }`} onClick={() => setViewMode("pretty")} > - PRETTY + {t("promptsPage.promptEditorView.viewModePretty")}
diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_info.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_info.tsx index a5e76542ebd..7914fac0c32 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_info.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_info.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; +import { useTranslation, Trans } from "react-i18next"; import { Card, Title, @@ -43,6 +44,7 @@ export interface PromptInfoProps { } const PromptInfoView: React.FC = ({ promptId, onClose, accessToken, isAdmin, onDelete, onEdit }) => { + const { t } = useTranslation(); const [promptData, setPromptData] = useState(null); const [promptTemplate, setPromptTemplate] = useState(null); const [rawApiResponse, setRawApiResponse] = useState(null); @@ -77,7 +79,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo } setSelectedVersion(response.prompt_spec.version || null); } catch (error) { - NotificationsManager.fromBackend("Failed to load prompt information"); + NotificationsManager.fromBackend(t("promptsPage.promptInfo.failedToLoadInfo")); console.error("Error fetching prompt info:", error); } finally { setLoading(false); @@ -124,11 +126,11 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo }, [selectedEnv]); if (loading && !promptData) { - return
Loading...
; + return
{t("common.loading")}
; } if (!promptData) { - return
Prompt not found
; + return
{t("promptsPage.promptInfo.promptNotFound")}
; } const formatDate = (dateString?: string) => { @@ -156,12 +158,12 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo setIsDeleting(true); try { await deletePromptCall(accessToken, basePromptId); - NotificationsManager.success(`Prompt "${basePromptId}" deleted successfully`); + NotificationsManager.success(t("promptsPage.promptInfo.deleteSuccess", { id: basePromptId })); onDelete?.(); onClose(); } catch (error) { console.error("Error deleting prompt:", error); - NotificationsManager.fromBackend("Failed to delete prompt"); + NotificationsManager.fromBackend(t("promptsPage.promptInfo.deleteFailed")); } finally { setIsDeleting(false); setShowDeleteConfirm(false); @@ -184,7 +186,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo setPromptTemplate(response.raw_prompt_template); setRawApiResponse(response); } catch { - NotificationsManager.fromBackend(`Failed to load version v${versionNum}`); + NotificationsManager.fromBackend(t("promptsPage.promptInfo.failedToLoadVersion", { version: versionNum })); } }; @@ -198,11 +200,11 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo
- Back to Prompts + {t("promptsPage.promptInfo.backToPrompts")}
- Prompt Details + {t("promptsPage.promptInfo.title")}
{basePromptId}
@@ -286,7 +288,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo {isViewingOldVersion && (
- Viewing v{selectedVersion} — not the latest version (v{latestVersion}) + {t("promptsPage.promptInfo.viewingOldVersion", { version: selectedVersion, latest: latestVersion })} = ({ promptId, onClose, accessTo if (latest) handleVersionClick(latest); }} > - Go to latest + {t("promptsPage.promptInfo.goToLatest")}
)} - Overview - {promptTemplate ? Prompt Template : <>} - Raw JSON + {t("promptsPage.promptInfo.tabOverview")} + {promptTemplate ? {t("promptsPage.promptInfo.tabPromptTemplate")} : <>} + {t("promptsPage.promptInfo.tabRawJson")} @@ -313,7 +315,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo - Version + {t("promptsPage.promptInfo.cardVersion")}
{currentVersion} @@ -323,41 +325,43 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo - Prompt Type + {t("promptsPage.promptInfo.cardPromptType")}
{promptData.prompt_info?.prompt_type || "-"}
- Created By + {t("promptsPage.promptInfo.cardCreatedBy")}
{promptData.created_by || "-"}
- Created At + {t("common.createdAt")}
{formatDate(promptData.created_at)} - Updated: {formatDate(promptData.updated_at)} + + {t("promptsPage.promptInfo.updatedAt", { date: formatDate(promptData.updated_at) })} +
{/* Version History Table */} - Version History — {selectedEnv} + {t("promptsPage.promptInfo.versionHistoryTitle", { env: selectedEnv })} {loadingVersions ? ( - Loading versions... + {t("promptsPage.promptInfo.loadingVersions")} ) : versionHistory.length > 0 ? ( - Version - Created By - Date - Actions + {t("promptsPage.promptInfo.colVersion")} + {t("promptsPage.promptInfo.cardCreatedBy")} + {t("promptsPage.promptInfo.colDate")} + {t("common.actions")} @@ -377,7 +381,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo v{vNum} {isLatest && ( - latest + {t("promptsPage.promptInfo.latestBadge")} )} @@ -394,7 +398,6 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo size="xs" onClick={(e) => { e.stopPropagation(); - // Build a response-like object for the editor const editData = { prompt_spec: { ...v, @@ -406,7 +409,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo onEdit?.(editData); }} > - Edit + {t("common.edit")} @@ -415,7 +418,9 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo
) : ( - No versions found in {selectedEnv} + + {t("promptsPage.promptInfo.noVersionsFound", { env: selectedEnv })} + )}
@@ -425,7 +430,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo
- Prompt Template + {t("promptsPage.promptInfo.tabPromptTemplate")}
- Template ID + {t("promptsPage.promptInfo.templateId")}
{promptTemplate.litellm_prompt_id}
- Content + {t("promptsPage.promptInfo.templateContent")}
{promptTemplate.content}
@@ -456,7 +461,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo {promptTemplate.metadata && Object.keys(promptTemplate.metadata).length > 0 && (
- Template Metadata + {t("promptsPage.promptInfo.templateMetadata")}
                           {JSON.stringify(promptTemplate.metadata, null, 2)}
@@ -473,7 +478,7 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo
           
             
               
- Raw API Response + {t("promptsPage.promptInfo.rawApiResponse")}
@@ -501,18 +506,22 @@ const PromptInfoView: React.FC = ({ promptId, onClose, accessTo {/* Delete Confirmation Modal */}

- Are you sure you want to delete prompt: {basePromptId}? + }} + />

-

This action cannot be undone.

+

{t("promptsPage.promptInfo.deleteCannotUndo")}

); diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_table.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_table.tsx index dbdeaff5daf..ce44032933c 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_table.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_table.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from "react"; +import { useTranslation } from "react-i18next"; import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow, Button } from "@tremor/react"; import { SwitchVerticalIcon, ChevronUpIcon, ChevronDownIcon, TrashIcon } from "@heroicons/react/outline"; import { Tooltip } from "antd"; @@ -38,6 +39,7 @@ const PromptTable: React.FC = ({ accessToken, isAdmin, }) => { + const { t } = useTranslation(); const [sorting, setSorting] = useState([{ id: "created_at", desc: true }]); const [modelHubData, setModelHubData] = useState>(new Map()); @@ -75,7 +77,7 @@ const PromptTable: React.FC = ({ const columns: ColumnDef[] = [ { - header: "Prompt ID", + header: t("promptsPage.promptTable.colPromptId"), accessorKey: "prompt_id", cell: (info: any) => { const fullId = String(info.getValue() || ""); @@ -92,7 +94,7 @@ const PromptTable: React.FC = ({ {displayId} - + { e.stopPropagation(); @@ -106,7 +108,7 @@ const PromptTable: React.FC = ({ }, }, { - header: "Model", + header: t("promptsPage.promptTable.colModel"), accessorKey: "model", cell: ({ row }) => { const prompt = row.original; @@ -160,7 +162,7 @@ const PromptTable: React.FC = ({ }, }, { - header: "Created At", + header: t("common.createdAt"), accessorKey: "created_at", cell: ({ row }) => { const prompt = row.original; @@ -172,7 +174,7 @@ const PromptTable: React.FC = ({ }, }, { - header: "Updated At", + header: t("common.updatedAt"), accessorKey: "updated_at", cell: ({ row }) => { const prompt = row.original; @@ -184,7 +186,7 @@ const PromptTable: React.FC = ({ }, }, { - header: "Environment", + header: t("promptsPage.promptTable.colEnvironment"), accessorKey: "environment", cell: ({ row }) => { const prompt = row.original; @@ -200,7 +202,7 @@ const PromptTable: React.FC = ({ }, }, { - header: "Created By", + header: t("promptsPage.promptTable.colCreatedBy"), accessorKey: "created_by", cell: ({ row }) => { const prompt = row.original; @@ -208,7 +210,7 @@ const PromptTable: React.FC = ({ }, }, { - header: "Type", + header: t("promptsPage.promptTable.colType"), accessorKey: "prompt_info.prompt_type", cell: ({ row }) => { const prompt = row.original; @@ -222,7 +224,7 @@ const PromptTable: React.FC = ({ ...(isAdmin ? [ { - header: "Actions", + header: t("common.actions"), id: "actions", enableSorting: false, cell: ({ row }: any) => { @@ -231,7 +233,7 @@ const PromptTable: React.FC = ({ return (
- +
} open={visible} @@ -61,10 +63,10 @@ const ToolModal: React.FC = ({ visible, initialJson, onSave, onC width={800} footer={[ , , ]} > @@ -74,7 +76,7 @@ const ToolModal: React.FC = ({ visible, initialJson, onSave, onC value={json} onChange={(e) => setJson(e.target.value)} className="w-full min-h-[400px] px-4 py-3 border border-gray-300 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none" - placeholder="Paste your tool JSON here..." + placeholder={t("promptsPage.toolModal.placeholder")} />
diff --git a/ui/litellm-dashboard/src/locales/en.json b/ui/litellm-dashboard/src/locales/en.json index bcdd37074a0..574362c6d96 100644 --- a/ui/litellm-dashboard/src/locales/en.json +++ b/ui/litellm-dashboard/src/locales/en.json @@ -4565,6 +4565,89 @@ "active": "Active", "savedToDatabase": "Saved to Database", "configPrompt": "Config Prompt" + }, + "messageInput": { + "placeholder": "Type your message... (Shift+Enter for new line)" + }, + "variableInput": { + "title": "Fill in template variables to start testing", + "valuePlaceholder": "Enter value for {{varName}}" + }, + "variableWarning": { + "title": "Please fill in all template variables above", + "missing": "Missing: {{list}}" + }, + "conversationPanel": { + "clearChat": "Clear Chat", + "accessTokenRequired": "Access token is required", + "fillAllVariables": "Please fill in all template variables", + "requestCancelled": "Request cancelled", + "chatCleared": "Chat history cleared.", + "errorMessage": "Error: {{message}}" + }, + "promptEditorView": { + "failedToParsePrompt": "Failed to parse prompt data", + "invalidJsonFormat": "Invalid JSON format", + "failedToLoadVersion": "Failed to load prompt version", + "accessTokenRequired": "Access token is required", + "invalidPromptName": "Please enter a valid prompt name", + "updateSuccess": "Prompt updated successfully!", + "createSuccess": "Prompt created successfully!", + "updateFailed": "Failed to update prompt", + "saveFailed": "Failed to save prompt", + "viewModePretty": "PRETTY", + "viewModeDotprompt": "DOTPROMPT" + }, + "promptInfo": { + "failedToLoadInfo": "Failed to load prompt information", + "promptNotFound": "Prompt not found", + "backToPrompts": "Back to Prompts", + "title": "Prompt Details", + "promptStudio": "Prompt Studio", + "deletePrompt": "Delete Prompt", + "viewingOldVersion": "Viewing v{{version}} — not the latest version (v{{latest}})", + "goToLatest": "Go to latest", + "tabOverview": "Overview", + "tabPromptTemplate": "Prompt Template", + "tabRawJson": "Raw JSON", + "cardVersion": "Version", + "cardPromptType": "Prompt Type", + "cardCreatedBy": "Created By", + "updatedAt": "Updated: {{date}}", + "versionHistoryTitle": "Version History — {{env}}", + "loadingVersions": "Loading versions...", + "colVersion": "Version", + "colDate": "Date", + "latestBadge": "latest", + "noVersionsFound": "No versions found in {{env}}", + "templateId": "Template ID", + "templateContent": "Content", + "templateMetadata": "Template Metadata", + "copyContent": "Copy Content", + "rawApiResponse": "Raw API Response", + "copyJson": "Copy JSON", + "deleteModalTitle": "Delete Prompt", + "deleteConfirmText": "Are you sure you want to delete prompt: {{id}}?", + "deleteCannotUndo": "This action cannot be undone.", + "deleteSuccess": "Prompt \"{{id}}\" deleted successfully", + "deleteFailed": "Failed to delete prompt", + "failedToLoadVersion": "Failed to load version v{{version}}" + }, + "promptTable": { + "colPromptId": "Prompt ID", + "colModel": "Model", + "colEnvironment": "Environment", + "colCreatedBy": "Created By", + "colType": "Type", + "copyPromptId": "Copy prompt ID", + "deletePrompt": "Delete prompt", + "noPromptsFound": "No prompts found" + }, + "toolModal": { + "title": "Add Tool", + "invalidJsonError": "Invalid JSON format. Please check your syntax.", + "placeholder": "Paste your tool JSON here...", + "addButton": "Add" } } } diff --git a/ui/litellm-dashboard/src/locales/zh-CN.json b/ui/litellm-dashboard/src/locales/zh-CN.json index b993d528f9a..a7fc7124ac7 100644 --- a/ui/litellm-dashboard/src/locales/zh-CN.json +++ b/ui/litellm-dashboard/src/locales/zh-CN.json @@ -4565,6 +4565,89 @@ "active": "当前", "savedToDatabase": "已保存到数据库", "configPrompt": "配置提示词" + }, + "messageInput": { + "placeholder": "输入消息...(Shift+Enter 换行)" + }, + "variableInput": { + "title": "填写模板变量以开始测试", + "valuePlaceholder": "输入 {{varName}} 的值" + }, + "variableWarning": { + "title": "请填写上方所有模板变量", + "missing": "缺少:{{list}}" + }, + "conversationPanel": { + "clearChat": "清空对话", + "accessTokenRequired": "访问令牌不能为空", + "fillAllVariables": "请填写所有模板变量", + "requestCancelled": "请求已取消", + "chatCleared": "对话历史已清空。", + "errorMessage": "错误:{{message}}" + }, + "promptEditorView": { + "failedToParsePrompt": "解析提示词数据失败", + "invalidJsonFormat": "JSON 格式无效", + "failedToLoadVersion": "加载提示词版本失败", + "accessTokenRequired": "访问令牌不能为空", + "invalidPromptName": "请输入有效的提示词名称", + "updateSuccess": "提示词更新成功!", + "createSuccess": "提示词创建成功!", + "updateFailed": "更新提示词失败", + "saveFailed": "保存提示词失败", + "viewModePretty": "可视化", + "viewModeDotprompt": "DOTPROMPT" + }, + "promptInfo": { + "failedToLoadInfo": "加载提示词信息失败", + "promptNotFound": "提示词不存在", + "backToPrompts": "返回提示词列表", + "title": "提示词详情", + "promptStudio": "提示词工作室", + "deletePrompt": "删除提示词", + "viewingOldVersion": "正在查看 v{{version}} — 非最新版本(v{{latest}})", + "goToLatest": "跳转到最新版本", + "tabOverview": "概览", + "tabPromptTemplate": "提示词模板", + "tabRawJson": "原始 JSON", + "cardVersion": "版本", + "cardPromptType": "提示词类型", + "cardCreatedBy": "创建者", + "updatedAt": "更新于:{{date}}", + "versionHistoryTitle": "版本历史 — {{env}}", + "loadingVersions": "加载版本中...", + "colVersion": "版本", + "colDate": "日期", + "latestBadge": "最新", + "noVersionsFound": "在 {{env}} 中未找到版本", + "templateId": "模板 ID", + "templateContent": "内容", + "templateMetadata": "模板元数据", + "copyContent": "复制内容", + "rawApiResponse": "原始 API 响应", + "copyJson": "复制 JSON", + "deleteModalTitle": "删除提示词", + "deleteConfirmText": "确定要删除提示词:{{id}}?", + "deleteCannotUndo": "此操作无法撤销。", + "deleteSuccess": "提示词「{{id}}」已成功删除", + "deleteFailed": "删除提示词失败", + "failedToLoadVersion": "加载版本 v{{version}} 失败" + }, + "promptTable": { + "colPromptId": "提示词 ID", + "colModel": "模型", + "colEnvironment": "环境", + "colCreatedBy": "创建者", + "colType": "类型", + "copyPromptId": "复制提示词 ID", + "deletePrompt": "删除提示词", + "noPromptsFound": "未找到提示词" + }, + "toolModal": { + "title": "添加工具", + "invalidJsonError": "JSON 格式无效,请检查语法。", + "placeholder": "在此粘贴工具 JSON...", + "addButton": "添加" } } }