mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): i18n for model dashboard tables and health check
This commit is contained in:
parent
6d04f50e80
commit
b00ffa1e04
7 changed files with 177 additions and 48 deletions
|
|
@ -8,6 +8,7 @@ import { errorPatterns } from "@/utils/errorPatterns";
|
|||
import { individualModelHealthCheckCall, latestHealthChecksCall } from "../networking";
|
||||
import { Table as TableInstance } from "@tanstack/react-table";
|
||||
import { Team } from "../key_team_helpers/key_list";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface HealthStatus {
|
||||
status: string;
|
||||
|
|
@ -51,6 +52,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
pageSize = 50,
|
||||
onPageChange,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const [modelHealthStatuses, setModelHealthStatuses] = useState<{ [key: string]: HealthStatus }>({});
|
||||
const [selectedModelsForHealth, setSelectedModelsForHealth] = useState<string[]>([]);
|
||||
const [allModelsSelected, setAllModelsSelected] = useState<boolean>(false);
|
||||
|
|
@ -547,15 +549,13 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
<div className="mb-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
<Title>Model Health Status</Title>
|
||||
<Text className="text-gray-600 mt-1">
|
||||
Run health checks on individual models to verify they are working correctly
|
||||
</Text>
|
||||
<Title>{t("modelDashboard.healthCheckComponent.title")}</Title>
|
||||
<Text className="text-gray-600 mt-1">{t("modelDashboard.healthCheckComponent.subtitle")}</Text>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
{selectedModelsForHealth.length > 0 && (
|
||||
<Button size="sm" variant="light" onClick={() => handleSelectAll(false)} className="px-3 py-1 text-sm">
|
||||
Clear Selection
|
||||
{t("modelDashboard.healthCheckComponent.clearSelection")}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
|
|
@ -566,8 +566,8 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
className="px-3 py-1 text-sm"
|
||||
>
|
||||
{selectedModelsForHealth.length > 0 && selectedModelsForHealth.length < all_models_on_proxy.length
|
||||
? "Run Selected Checks"
|
||||
: "Run All Checks"}
|
||||
? t("modelDashboard.healthCheckComponent.runSelectedChecks")
|
||||
: t("modelDashboard.healthCheckComponent.runAllChecks")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -578,8 +578,12 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
<div className="flex justify-between items-center mb-3">
|
||||
<span data-testid="health-results-count" className="text-sm text-gray-700">
|
||||
{totalCount > 0
|
||||
? `Showing ${resultsStart} - ${resultsEnd} of ${totalCount} results`
|
||||
: "Showing 0 results"}
|
||||
? t("modelDashboard.healthCheckComponent.showingResults", {
|
||||
start: resultsStart,
|
||||
end: resultsEnd,
|
||||
total: totalCount,
|
||||
})
|
||||
: t("modelDashboard.healthCheckComponent.showingZeroResults")}
|
||||
</span>
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
|
|
@ -590,7 +594,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
isLoading || currentPage === 1 ? "bg-gray-100 text-gray-400 cursor-not-allowed" : "hover:bg-gray-50"
|
||||
}`}
|
||||
>
|
||||
Previous
|
||||
{t("common.previous")}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handlePageChange(currentPage + 1)}
|
||||
|
|
@ -601,13 +605,14 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
: "hover:bg-gray-50"
|
||||
}`}
|
||||
>
|
||||
Next
|
||||
{t("common.next")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<ModelDataTable
|
||||
columns={healthCheckColumns(
|
||||
t,
|
||||
modelHealthStatuses,
|
||||
selectedModelsForHealth,
|
||||
allModelsSelected,
|
||||
|
|
@ -628,12 +633,16 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
|
||||
{/* Error Modal */}
|
||||
<Modal
|
||||
title={selectedErrorDetails ? `Health Check Error - ${selectedErrorDetails.modelName}` : "Error Details"}
|
||||
title={
|
||||
selectedErrorDetails
|
||||
? t("modelDashboard.healthCheckComponent.errorModalTitle", { modelName: selectedErrorDetails.modelName })
|
||||
: t("modelDashboard.healthCheckComponent.errorModalFallbackTitle")
|
||||
}
|
||||
open={errorModalVisible}
|
||||
onCancel={closeErrorModal}
|
||||
footer={[
|
||||
<AntdButton key="close" onClick={closeErrorModal}>
|
||||
Close
|
||||
{t("common.close")}
|
||||
</AntdButton>,
|
||||
]}
|
||||
width={800}
|
||||
|
|
@ -641,14 +650,14 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
{selectedErrorDetails && (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text className="font-medium">Error:</Text>
|
||||
<Text className="font-medium">{t("modelDashboard.healthCheckComponent.errorLabel")}</Text>
|
||||
<div className="mt-2 p-3 bg-red-50 border border-red-200 rounded-md">
|
||||
<Text className="text-red-800">{selectedErrorDetails.cleanedError}</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Full Error Details:</Text>
|
||||
<Text className="font-medium">{t("modelDashboard.healthCheckComponent.fullErrorLabel")}</Text>
|
||||
<div className="mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto">
|
||||
<pre className="text-sm text-gray-800 whitespace-pre-wrap">{selectedErrorDetails.fullError}</pre>
|
||||
</div>
|
||||
|
|
@ -660,13 +669,17 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
{/* Success Modal */}
|
||||
<Modal
|
||||
title={
|
||||
selectedSuccessDetails ? `Health Check Response - ${selectedSuccessDetails.modelName}` : "Response Details"
|
||||
selectedSuccessDetails
|
||||
? t("modelDashboard.healthCheckComponent.successModalTitle", {
|
||||
modelName: selectedSuccessDetails.modelName,
|
||||
})
|
||||
: t("modelDashboard.healthCheckComponent.successModalFallbackTitle")
|
||||
}
|
||||
open={successModalVisible}
|
||||
onCancel={closeSuccessModal}
|
||||
footer={[
|
||||
<AntdButton key="close" onClick={closeSuccessModal}>
|
||||
Close
|
||||
{t("common.close")}
|
||||
</AntdButton>,
|
||||
]}
|
||||
width={800}
|
||||
|
|
@ -674,14 +687,14 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
{selectedSuccessDetails && (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text className="font-medium">Status:</Text>
|
||||
<Text className="font-medium">{t("modelDashboard.healthCheckComponent.statusLabel")}</Text>
|
||||
<div className="mt-2 p-3 bg-green-50 border border-green-200 rounded-md">
|
||||
<Text className="text-green-800">Health check passed successfully</Text>
|
||||
<Text className="text-green-800">{t("modelDashboard.healthCheckComponent.healthCheckPassed")}</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Response Details:</Text>
|
||||
<Text className="font-medium">{t("modelDashboard.healthCheckComponent.responseDetailsLabel")}</Text>
|
||||
<div className="mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto">
|
||||
<pre className="text-sm text-gray-800 whitespace-pre-wrap">
|
||||
{JSON.stringify(selectedSuccessDetails.response, null, 2)}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import NotificationsManager from "@/components/molecules/notifications_manager";
|
|||
import { parseErrorMessage } from "@/components/shared/errorUtils";
|
||||
import { Button, Form, Modal, Skeleton, Space, Switch, Typography } from "antd";
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface ModelSettingsModalProps {
|
||||
isVisible: boolean;
|
||||
|
|
@ -14,6 +15,7 @@ interface ModelSettingsModalProps {
|
|||
}
|
||||
|
||||
const ModelSettingsModal: React.FC<ModelSettingsModalProps> = ({ isVisible, onCancel, onSuccess }) => {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const { mutateAsync, isPending } = useStoreModelInDB();
|
||||
const { data: proxyConfigData, isLoading: isLoadingConfig, refetch } = useProxyConfig(ConfigType.GENERAL_SETTINGS);
|
||||
|
|
@ -44,16 +46,20 @@ const ModelSettingsModal: React.FC<ModelSettingsModalProps> = ({ isVisible, onCa
|
|||
try {
|
||||
await mutateAsync(formValues, {
|
||||
onSuccess: () => {
|
||||
NotificationsManager.success("Model storage settings updated successfully");
|
||||
NotificationsManager.success(t("modelDashboard.modelSettingsModal.updateSuccess"));
|
||||
refetch();
|
||||
onSuccess?.();
|
||||
},
|
||||
onError: (error) => {
|
||||
NotificationsManager.fromBackend("Failed to save model storage settings: " + parseErrorMessage(error));
|
||||
NotificationsManager.fromBackend(
|
||||
t("modelDashboard.modelSettingsModal.updateFailed", { error: parseErrorMessage(error) }),
|
||||
);
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
NotificationsManager.fromBackend("Failed to save model storage settings: " + parseErrorMessage(error));
|
||||
NotificationsManager.fromBackend(
|
||||
t("modelDashboard.modelSettingsModal.updateFailed", { error: parseErrorMessage(error) }),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -64,15 +70,15 @@ const ModelSettingsModal: React.FC<ModelSettingsModalProps> = ({ isVisible, onCa
|
|||
|
||||
return (
|
||||
<Modal
|
||||
title={<Typography.Title level={5}>Model Settings</Typography.Title>}
|
||||
title={<Typography.Title level={5}>{t("modelDashboard.modelSettingsModal.title")}</Typography.Title>}
|
||||
open={isVisible}
|
||||
footer={
|
||||
<Space>
|
||||
<Button onClick={handleCancel} disabled={isPending || isLoadingConfig}>
|
||||
Cancel
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
<Button type="primary" loading={isPending} disabled={isLoadingConfig} onClick={() => form.submit()}>
|
||||
{isPending ? "Saving..." : "Save Settings"}
|
||||
{isPending ? t("common.saving") : t("modelDashboard.modelSettingsModal.saveSettings")}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
|
|
@ -86,11 +92,11 @@ const ModelSettingsModal: React.FC<ModelSettingsModalProps> = ({ isVisible, onCa
|
|||
initialValues={initialValues}
|
||||
>
|
||||
<Form.Item
|
||||
label="Store Model in DB"
|
||||
label={t("modelDashboard.modelSettingsModal.storeModelInDb")}
|
||||
name="store_model_in_db"
|
||||
tooltip={
|
||||
proxyConfigData?.find((f) => f.field_name === "store_model_in_db")?.field_description ||
|
||||
"If enabled, models and config are stored in and loaded from the database."
|
||||
t("modelDashboard.modelSettingsModal.storeModelInDbTooltip")
|
||||
}
|
||||
valuePropName="checked"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import {
|
|||
TableHeaderSortDropdown,
|
||||
SortState,
|
||||
} from "../common_components/TableHeaderSortDropdown/TableHeaderSortDropdown";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// Extend the column meta type to include className
|
||||
declare module "@tanstack/react-table" {
|
||||
|
|
@ -47,6 +48,7 @@ export function AllModelsDataTable<TData, TValue>({
|
|||
enablePagination = false,
|
||||
onRowClick,
|
||||
}: AllModelsDataTableProps<TData, TValue>) {
|
||||
const { t } = useTranslation();
|
||||
const [columnResizeMode] = React.useState<ColumnResizeMode>("onChange");
|
||||
const [columnSizing, setColumnSizing] = React.useState({});
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});
|
||||
|
|
@ -173,7 +175,7 @@ export function AllModelsDataTable<TData, TValue>({
|
|||
<TableRow>
|
||||
<TableCell colSpan={columns.length} className="h-8 text-center">
|
||||
<div className="text-center text-gray-500">
|
||||
<p>🚅 Loading models...</p>
|
||||
<p>{t("modelDashboard.allModelsTable.loadingModels")}</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
@ -207,7 +209,7 @@ export function AllModelsDataTable<TData, TValue>({
|
|||
<TableRow>
|
||||
<TableCell colSpan={columns.length} className="h-8 text-center">
|
||||
<div className="text-center text-gray-500">
|
||||
<p>No models found</p>
|
||||
<p>{t("modelDashboard.allModelsTable.noModels")}</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Tooltip, Checkbox } from "antd";
|
|||
import { Text } from "@tremor/react";
|
||||
import { InformationCircleIcon, PlayIcon, RefreshIcon } from "@heroicons/react/outline";
|
||||
import { Team } from "@/components/key_team_helpers/key_list";
|
||||
import { TFunction } from "i18next";
|
||||
|
||||
interface HealthCheckData {
|
||||
model_name: string;
|
||||
|
|
@ -32,6 +33,7 @@ interface HealthStatus {
|
|||
}
|
||||
|
||||
export const healthCheckColumns = (
|
||||
t: TFunction,
|
||||
modelHealthStatuses: { [key: string]: HealthStatus },
|
||||
selectedModelsForHealth: string[],
|
||||
allModelsSelected: boolean,
|
||||
|
|
@ -54,7 +56,7 @@ export const healthCheckColumns = (
|
|||
onChange={(e) => handleSelectAll(e.target.checked)}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
<span>Model ID</span>
|
||||
<span>{t("modelDashboard.healthCheckColumns.modelId")}</span>
|
||||
</div>
|
||||
),
|
||||
accessorKey: "model_info.id",
|
||||
|
|
@ -85,7 +87,7 @@ export const healthCheckColumns = (
|
|||
},
|
||||
},
|
||||
{
|
||||
header: "Model Name",
|
||||
header: () => t("modelDashboard.healthCheckColumns.modelName"),
|
||||
accessorKey: "model_name",
|
||||
enableSorting: true,
|
||||
sortingFn: "alphanumeric",
|
||||
|
|
@ -103,7 +105,7 @@ export const healthCheckColumns = (
|
|||
},
|
||||
},
|
||||
{
|
||||
header: "Team Alias",
|
||||
header: () => t("modelDashboard.healthCheckColumns.teamAlias"),
|
||||
accessorKey: "model_info.team_id",
|
||||
enableSorting: true,
|
||||
sortingFn: "alphanumeric",
|
||||
|
|
@ -128,7 +130,7 @@ export const healthCheckColumns = (
|
|||
},
|
||||
},
|
||||
{
|
||||
header: "Health Status",
|
||||
header: () => t("modelDashboard.healthCheckColumns.healthStatus"),
|
||||
accessorKey: "health_status",
|
||||
enableSorting: true,
|
||||
sortingFn: (rowA, rowB, columnId) => {
|
||||
|
|
@ -164,7 +166,7 @@ export const healthCheckColumns = (
|
|||
style={{ animationDelay: "0.4s" }}
|
||||
></div>
|
||||
</div>
|
||||
<Text className="text-gray-600 text-sm">Checking...</Text>
|
||||
<Text className="text-gray-600 text-sm">{t("modelDashboard.healthCheckColumns.checking")}</Text>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -177,7 +179,7 @@ export const healthCheckColumns = (
|
|||
<div className="flex items-center space-x-2">
|
||||
{getStatusBadge(healthStatus.status)}
|
||||
{hasSuccessResponse && showSuccessModal && (
|
||||
<Tooltip title="View response details" placement="top">
|
||||
<Tooltip title={t("modelDashboard.healthCheckColumns.viewResponseDetails")} placement="top">
|
||||
<button
|
||||
onClick={() => showSuccessModal(displayName, modelHealthStatuses[modelId]?.successResponse)}
|
||||
className="p-1 text-green-600 hover:text-green-800 hover:bg-green-50 rounded cursor-pointer transition-colors"
|
||||
|
|
@ -191,7 +193,7 @@ export const healthCheckColumns = (
|
|||
},
|
||||
},
|
||||
{
|
||||
header: "Error Details",
|
||||
header: () => t("modelDashboard.healthCheckColumns.errorDetailsHeader"),
|
||||
accessorKey: "health_error",
|
||||
enableSorting: false,
|
||||
cell: ({ row }) => {
|
||||
|
|
@ -201,7 +203,7 @@ export const healthCheckColumns = (
|
|||
const healthStatus = modelHealthStatuses[modelId];
|
||||
|
||||
if (!healthStatus?.error) {
|
||||
return <Text className="text-gray-400 text-sm">No errors</Text>;
|
||||
return <Text className="text-gray-400 text-sm">{t("modelDashboard.healthCheckColumns.noErrors")}</Text>;
|
||||
}
|
||||
|
||||
const cleanedError = healthStatus.error;
|
||||
|
|
@ -215,7 +217,7 @@ export const healthCheckColumns = (
|
|||
</Tooltip>
|
||||
</div>
|
||||
{showErrorModal && fullError !== cleanedError && (
|
||||
<Tooltip title="View full error details" placement="top">
|
||||
<Tooltip title={t("modelDashboard.healthCheckColumns.viewFullErrorDetails")} placement="top">
|
||||
<button
|
||||
onClick={() => showErrorModal(displayName, cleanedError, fullError)}
|
||||
className="p-1 text-red-600 hover:text-red-800 hover:bg-red-50 rounded cursor-pointer transition-colors"
|
||||
|
|
@ -229,7 +231,7 @@ export const healthCheckColumns = (
|
|||
},
|
||||
},
|
||||
{
|
||||
header: "Last Check",
|
||||
header: () => t("modelDashboard.healthCheckColumns.lastCheck"),
|
||||
accessorKey: "last_check",
|
||||
enableSorting: true,
|
||||
sortingFn: (rowA, rowB, columnId) => {
|
||||
|
|
@ -261,13 +263,13 @@ export const healthCheckColumns = (
|
|||
|
||||
return (
|
||||
<Text className="text-gray-600 text-sm">
|
||||
{model.health_loading ? "Check in progress..." : model.last_check}
|
||||
{model.health_loading ? t("modelDashboard.healthCheckColumns.checkInProgress") : model.last_check}
|
||||
</Text>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: "Last Success",
|
||||
header: () => t("modelDashboard.healthCheckColumns.lastSuccess"),
|
||||
accessorKey: "last_success",
|
||||
enableSorting: true,
|
||||
sortingFn: (rowA, rowB, columnId) => {
|
||||
|
|
@ -304,7 +306,7 @@ export const healthCheckColumns = (
|
|||
},
|
||||
},
|
||||
{
|
||||
header: "Actions",
|
||||
header: () => t("common.actions"),
|
||||
id: "actions",
|
||||
cell: ({ row }) => {
|
||||
const model = row.original;
|
||||
|
|
@ -312,10 +314,10 @@ export const healthCheckColumns = (
|
|||
|
||||
const hasExistingStatus = model.health_status && model.health_status !== "none";
|
||||
const tooltipText = model.health_loading
|
||||
? "Checking..."
|
||||
? t("modelDashboard.healthCheckColumns.checking")
|
||||
: hasExistingStatus
|
||||
? "Re-run Health Check"
|
||||
: "Run Health Check";
|
||||
? t("modelDashboard.healthCheckColumns.rerunHealthCheck")
|
||||
: t("modelDashboard.healthCheckColumns.runHealthCheck");
|
||||
|
||||
return (
|
||||
<Tooltip title={tooltipText} placement="top">
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
import React from "react";
|
||||
import { Table, TableHead, TableHeaderCell, TableBody, TableRow, TableCell } from "@tremor/react";
|
||||
import { SwitchVerticalIcon, ChevronUpIcon, ChevronDownIcon } from "@heroicons/react/outline";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// Extend the column meta type to include className
|
||||
declare module "@tanstack/react-table" {
|
||||
|
|
@ -43,6 +44,7 @@ export function ModelDataTable<TData, TValue>({
|
|||
enablePagination = false,
|
||||
onRowClick,
|
||||
}: ModelDataTableProps<TData, TValue>) {
|
||||
const { t } = useTranslation();
|
||||
const [sorting, setSorting] = React.useState<SortingState>(defaultSorting);
|
||||
const [columnResizeMode] = React.useState<ColumnResizeMode>("onChange");
|
||||
const [columnSizing, setColumnSizing] = React.useState({});
|
||||
|
|
@ -160,7 +162,7 @@ export function ModelDataTable<TData, TValue>({
|
|||
<TableRow>
|
||||
<TableCell colSpan={columns.length} className="h-8 text-center">
|
||||
<div className="text-center text-gray-500">
|
||||
<p>🚅 Loading models...</p>
|
||||
<p>{t("modelDashboard.table.loadingModels")}</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
@ -194,7 +196,7 @@ export function ModelDataTable<TData, TValue>({
|
|||
<TableRow>
|
||||
<TableCell colSpan={columns.length} className="h-8 text-center">
|
||||
<div className="text-center text-gray-500">
|
||||
<p>No models found</p>
|
||||
<p>{t("modelDashboard.table.noModels")}</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
|
|||
|
|
@ -7253,5 +7253,57 @@
|
|||
"updateSuccess": "Search tool updated successfully",
|
||||
"updateFailed": "Failed to update search tool"
|
||||
}
|
||||
},
|
||||
"modelDashboard": {
|
||||
"table": {
|
||||
"loadingModels": "🚅 Loading models...",
|
||||
"noModels": "No models found"
|
||||
},
|
||||
"allModelsTable": {
|
||||
"loadingModels": "🚅 Loading models...",
|
||||
"noModels": "No models found"
|
||||
},
|
||||
"healthCheckComponent": {
|
||||
"title": "Model Health Status",
|
||||
"subtitle": "Run health checks on individual models to verify they are working correctly",
|
||||
"clearSelection": "Clear Selection",
|
||||
"runSelectedChecks": "Run Selected Checks",
|
||||
"runAllChecks": "Run All Checks",
|
||||
"showingResults": "Showing {{start}} - {{end}} of {{total}} results",
|
||||
"showingZeroResults": "Showing 0 results",
|
||||
"errorModalTitle": "Health Check Error - {{modelName}}",
|
||||
"errorModalFallbackTitle": "Error Details",
|
||||
"errorLabel": "Error:",
|
||||
"fullErrorLabel": "Full Error Details:",
|
||||
"successModalTitle": "Health Check Response - {{modelName}}",
|
||||
"successModalFallbackTitle": "Response Details",
|
||||
"statusLabel": "Status:",
|
||||
"healthCheckPassed": "Health check passed successfully",
|
||||
"responseDetailsLabel": "Response Details:"
|
||||
},
|
||||
"healthCheckColumns": {
|
||||
"modelId": "Model ID",
|
||||
"modelName": "Model Name",
|
||||
"teamAlias": "Team Alias",
|
||||
"healthStatus": "Health Status",
|
||||
"checking": "Checking...",
|
||||
"viewResponseDetails": "View response details",
|
||||
"errorDetailsHeader": "Error Details",
|
||||
"noErrors": "No errors",
|
||||
"viewFullErrorDetails": "View full error details",
|
||||
"lastCheck": "Last Check",
|
||||
"checkInProgress": "Check in progress...",
|
||||
"lastSuccess": "Last Success",
|
||||
"rerunHealthCheck": "Re-run Health Check",
|
||||
"runHealthCheck": "Run Health Check"
|
||||
},
|
||||
"modelSettingsModal": {
|
||||
"title": "Model Settings",
|
||||
"saveSettings": "Save Settings",
|
||||
"storeModelInDb": "Store Model in DB",
|
||||
"storeModelInDbTooltip": "If enabled, models and config are stored in and loaded from the database.",
|
||||
"updateSuccess": "Model storage settings updated successfully",
|
||||
"updateFailed": "Failed to save model storage settings: {{error}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7253,5 +7253,57 @@
|
|||
"updateSuccess": "搜索工具更新成功",
|
||||
"updateFailed": "更新搜索工具失败"
|
||||
}
|
||||
},
|
||||
"modelDashboard": {
|
||||
"table": {
|
||||
"loadingModels": "🚅 正在加载模型...",
|
||||
"noModels": "未找到模型"
|
||||
},
|
||||
"allModelsTable": {
|
||||
"loadingModels": "🚅 正在加载模型...",
|
||||
"noModels": "未找到模型"
|
||||
},
|
||||
"healthCheckComponent": {
|
||||
"title": "模型健康检查状态",
|
||||
"subtitle": "对各模型运行健康检查,验证其是否正常工作",
|
||||
"clearSelection": "清除选择",
|
||||
"runSelectedChecks": "运行所选检查",
|
||||
"runAllChecks": "运行所有检查",
|
||||
"showingResults": "显示第 {{start}} - {{end}} 条,共 {{total}} 条结果",
|
||||
"showingZeroResults": "显示 0 条结果",
|
||||
"errorModalTitle": "健康检查错误 - {{modelName}}",
|
||||
"errorModalFallbackTitle": "错误详情",
|
||||
"errorLabel": "错误:",
|
||||
"fullErrorLabel": "完整错误详情:",
|
||||
"successModalTitle": "健康检查响应 - {{modelName}}",
|
||||
"successModalFallbackTitle": "响应详情",
|
||||
"statusLabel": "状态:",
|
||||
"healthCheckPassed": "健康检查通过",
|
||||
"responseDetailsLabel": "响应详情:"
|
||||
},
|
||||
"healthCheckColumns": {
|
||||
"modelId": "模型 ID",
|
||||
"modelName": "模型名称",
|
||||
"teamAlias": "团队别名",
|
||||
"healthStatus": "健康状态",
|
||||
"checking": "检查中...",
|
||||
"viewResponseDetails": "查看响应详情",
|
||||
"errorDetailsHeader": "错误详情",
|
||||
"noErrors": "无错误",
|
||||
"viewFullErrorDetails": "查看完整错误详情",
|
||||
"lastCheck": "最近检查",
|
||||
"checkInProgress": "检查进行中...",
|
||||
"lastSuccess": "最近成功",
|
||||
"rerunHealthCheck": "重新运行健康检查",
|
||||
"runHealthCheck": "运行健康检查"
|
||||
},
|
||||
"modelSettingsModal": {
|
||||
"title": "模型设置",
|
||||
"saveSettings": "保存设置",
|
||||
"storeModelInDb": "将模型存储到数据库",
|
||||
"storeModelInDbTooltip": "启用后,模型和配置将存储到数据库并从数据库加载。",
|
||||
"updateSuccess": "模型存储设置已成功更新",
|
||||
"updateFailed": "保存模型存储设置失败:{{error}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue