mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): i18n for vector store tester and info views
This commit is contained in:
parent
8a6678ca5a
commit
aea41b4ada
5 changed files with 258 additions and 70 deletions
|
|
@ -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<VectorStoreTesterProps> = ({ 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<VectorStoreTesterProps> = ({ 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<VectorStoreTesterProps> = ({ 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<VectorStoreTesterProps> = ({ 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<VectorStoreTesterProps> = ({ vectorStor
|
|||
<div className="flex items-center">
|
||||
<DatabaseOutlined className="mr-2 text-blue-500" />
|
||||
<Title level={4} className="mb-0">
|
||||
Test Vector Store
|
||||
{t("vectorStoreManagement.vectorStoreTester.title")}
|
||||
</Title>
|
||||
</div>
|
||||
{searchHistory.length > 0 && (
|
||||
<Button onClick={clearHistory} size="small">
|
||||
Clear History
|
||||
{t("vectorStoreManagement.vectorStoreTester.clearHistory")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -120,7 +122,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
{searchHistory.length === 0 ? (
|
||||
<div className="h-full flex flex-col items-center justify-center text-gray-400">
|
||||
<DatabaseOutlined style={{ fontSize: "48px", marginBottom: "16px" }} />
|
||||
<Text>Test your vector store by entering a search query below</Text>
|
||||
<Text>{t("vectorStoreManagement.vectorStoreTester.emptyPrompt")}</Text>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
|
|
@ -130,7 +132,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
<div className="text-right">
|
||||
<div className="inline-block max-w-[80%] rounded-lg shadow-sm p-3 bg-blue-50 border border-blue-200">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<strong className="text-sm">Query</strong>
|
||||
<strong className="text-sm">{t("vectorStoreManagement.vectorStoreTester.queryLabel")}</strong>
|
||||
<span className="text-xs text-gray-500">{formatTimestamp(entry.timestamp)}</span>
|
||||
</div>
|
||||
<div className="text-left">{entry.query}</div>
|
||||
|
|
@ -142,10 +144,12 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
<div className="inline-block max-w-[80%] rounded-lg shadow-sm p-3 bg-white border border-gray-200">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<DatabaseOutlined className="text-green-500" />
|
||||
<strong className="text-sm">Vector Store Results</strong>
|
||||
<strong className="text-sm">{t("vectorStoreManagement.vectorStoreTester.resultsLabel")}</strong>
|
||||
{entry.response && (
|
||||
<span className="text-xs px-2 py-0.5 rounded bg-gray-100 text-gray-600">
|
||||
{entry.response.data?.length || 0} results
|
||||
{t("vectorStoreManagement.vectorStoreTester.resultsCount", {
|
||||
count: entry.response.data?.length || 0,
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -168,7 +172,9 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
) : (
|
||||
<RightOutlined className="text-gray-500 mr-2" />
|
||||
)}
|
||||
<span className="font-medium text-sm">Result {resultIndex + 1}</span>
|
||||
<span className="font-medium text-sm">
|
||||
{t("vectorStoreManagement.vectorStoreTester.resultN", { n: resultIndex + 1 })}
|
||||
</span>
|
||||
{/* Show preview of content when collapsed */}
|
||||
{!isExpanded && result.content && result.content[0] && (
|
||||
<span className="ml-2 text-xs text-gray-500 truncate max-w-md">
|
||||
|
|
@ -177,7 +183,9 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
)}
|
||||
</div>
|
||||
<span className="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">
|
||||
Score: {result.score.toFixed(4)}
|
||||
{t("vectorStoreManagement.vectorStoreTester.scoreLabel", {
|
||||
score: result.score.toFixed(4),
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
@ -188,7 +196,11 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
{result.content &&
|
||||
result.content.map((content, contentIndex) => (
|
||||
<div key={contentIndex} className="mb-3">
|
||||
<div className="text-xs text-gray-500 mb-1">Content ({content.type})</div>
|
||||
<div className="text-xs text-gray-500 mb-1">
|
||||
{t("vectorStoreManagement.vectorStoreTester.contentLabel", {
|
||||
type: content.type,
|
||||
})}
|
||||
</div>
|
||||
<div className="text-sm bg-gray-50 p-3 rounded border text-gray-800 max-h-40 overflow-y-auto">
|
||||
{content.text}
|
||||
</div>
|
||||
|
|
@ -198,21 +210,31 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
{/* Metadata */}
|
||||
{(result.file_id || result.filename || result.attributes) && (
|
||||
<div className="mt-3 pt-3 border-t border-gray-200">
|
||||
<div className="text-xs text-gray-500 mb-2 font-medium">Metadata</div>
|
||||
<div className="text-xs text-gray-500 mb-2 font-medium">
|
||||
{t("vectorStoreManagement.vectorStoreTester.metadataLabel")}
|
||||
</div>
|
||||
<div className="space-y-2 text-xs">
|
||||
{result.file_id && (
|
||||
<div className="bg-gray-50 p-2 rounded">
|
||||
<span className="font-medium">File ID:</span> {result.file_id}
|
||||
<span className="font-medium">
|
||||
{t("vectorStoreManagement.vectorStoreTester.fileIdLabel")}
|
||||
</span>{" "}
|
||||
{result.file_id}
|
||||
</div>
|
||||
)}
|
||||
{result.filename && (
|
||||
<div className="bg-gray-50 p-2 rounded">
|
||||
<span className="font-medium">Filename:</span> {result.filename}
|
||||
<span className="font-medium">
|
||||
{t("vectorStoreManagement.vectorStoreTester.filenameLabel")}
|
||||
</span>{" "}
|
||||
{result.filename}
|
||||
</div>
|
||||
)}
|
||||
{result.attributes && Object.keys(result.attributes).length > 0 && (
|
||||
<div className="bg-gray-50 p-2 rounded">
|
||||
<span className="font-medium block mb-1">Attributes:</span>
|
||||
<span className="font-medium block mb-1">
|
||||
{t("vectorStoreManagement.vectorStoreTester.attributesLabel")}
|
||||
</span>
|
||||
<pre className="text-xs bg-white p-2 rounded border overflow-x-auto">
|
||||
{JSON.stringify(result.attributes, null, 2)}
|
||||
</pre>
|
||||
|
|
@ -228,7 +250,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
|||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-gray-500 text-sm">No results found</div>
|
||||
<div className="text-gray-500 text-sm">{t("common.noResults")}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -254,7 +276,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ 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<VectorStoreTesterProps> = ({ vectorStor
|
|||
icon={<SendOutlined />}
|
||||
loading={isLoading}
|
||||
>
|
||||
Search
|
||||
{t("common.search")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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<VectorStoreProps> = ({ accessToken, userID, userRole }) => {
|
||||
const { t } = useTranslation();
|
||||
const [vectorStores, setVectorStores] = useState<VectorStore[]>([]);
|
||||
const [isCreateModalVisible, setIsCreateModalVisible] = useState(false);
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
|
|
@ -48,7 +50,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({ 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<VectorStoreProps> = ({ 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<VectorStoreProps> = ({ 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<VectorStoreProps> = ({ accessToken, userID
|
|||
<div className="w-full mx-4 h-[75vh]">
|
||||
<div className="gap-2 p-8 h-[75vh] w-full mt-2">
|
||||
<div className="flex justify-between mt-2 w-full items-center mb-4">
|
||||
<h1>Vector Store Management</h1>
|
||||
<h1>{t("vectorStoreManagement.index.pageTitle")}</h1>
|
||||
<div className="flex items-center space-x-2">
|
||||
{lastRefreshed && <Text>Last Refreshed: {lastRefreshed}</Text>}
|
||||
{lastRefreshed && <Text>{t("vectorStoreManagement.index.lastRefreshed", { time: lastRefreshed })}</Text>}
|
||||
<Icon
|
||||
icon={RefreshIcon}
|
||||
variant="shadow"
|
||||
|
|
@ -153,14 +155,14 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({ accessToken, userID
|
|||
</div>
|
||||
|
||||
<Text className="mb-4">
|
||||
<p>You can use vector stores to store and retrieve LLM embeddings.</p>
|
||||
<p>{t("vectorStoreManagement.index.pageDescription")}</p>
|
||||
</Text>
|
||||
|
||||
<TabGroup>
|
||||
<TabList className="mb-6">
|
||||
<Tab>Create Vector Store</Tab>
|
||||
<Tab>Manage Vector Stores</Tab>
|
||||
<Tab>Test Vector Store</Tab>
|
||||
<Tab>{t("vectorStoreManagement.index.tabCreate")}</Tab>
|
||||
<Tab>{t("vectorStoreManagement.index.tabManage")}</Tab>
|
||||
<Tab>{t("vectorStoreManagement.index.tabTest")}</Tab>
|
||||
</TabList>
|
||||
|
||||
<TabPanels>
|
||||
|
|
@ -172,7 +174,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({ accessToken, userID
|
|||
{/* Tab 2: Manage Vector Stores */}
|
||||
<TabPanel>
|
||||
<TremorButton className="mb-4" onClick={() => setIsCreateModalVisible(true)}>
|
||||
+ Add Vector Store
|
||||
{t("vectorStoreManagement.index.addVectorStore")}
|
||||
</TremorButton>
|
||||
|
||||
<Grid numItems={1} className="gap-2 pt-2 pb-2 w-full mt-2">
|
||||
|
|
@ -206,10 +208,12 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({ accessToken, userID
|
|||
{/* Delete Confirmation Modal */}
|
||||
<DeleteResourceModal
|
||||
isOpen={isDeleteModalOpen}
|
||||
title="Delete Vector Store"
|
||||
message="Are you sure you want to delete this vector store? This action cannot be undone."
|
||||
resourceInformationTitle="Vector Store Information"
|
||||
resourceInformation={[{ label: "Vector Store ID", value: vectorStoreToDelete, code: true }]}
|
||||
title={t("vectorStoreManagement.index.deleteModalTitle")}
|
||||
message={t("vectorStoreManagement.index.deleteModalMessage")}
|
||||
resourceInformationTitle={t("vectorStoreManagement.index.deleteModalInfoTitle")}
|
||||
resourceInformation={[
|
||||
{ label: t("vectorStoreManagement.index.vectorStoreIdLabel"), value: vectorStoreToDelete, code: true },
|
||||
]}
|
||||
onCancel={() => setIsDeleteModalOpen(false)}
|
||||
onOk={confirmDelete}
|
||||
confirmLoading={isDeleting}
|
||||
|
|
|
|||
|
|
@ -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<VectorStoreInfoViewProps> = ({
|
|||
is_admin,
|
||||
editVectorStore,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const [vectorStoreDetails, setVectorStoreDetails] = useState<VectorStore | null>(null);
|
||||
const [isEditing, setIsEditing] = useState<boolean>(editVectorStore);
|
||||
|
|
@ -58,7 +60,7 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
}
|
||||
} 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<VectorStoreInfoViewProps> = ({
|
|||
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<VectorStoreInfoViewProps> = ({
|
|||
};
|
||||
|
||||
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 <div>Loading...</div>;
|
||||
return <div>{t("common.loading")}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -117,18 +119,26 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<Button icon={ArrowLeftIcon} variant="light" className="mb-4" onClick={onClose}>
|
||||
Back to Vector Stores
|
||||
{t("vectorStoreManagement.vectorStoreInfo.backButton")}
|
||||
</Button>
|
||||
<Title>Vector Store ID: {vectorStoreDetails.vector_store_id}</Title>
|
||||
<Text className="text-gray-500">{vectorStoreDetails.vector_store_description || "No description"}</Text>
|
||||
<Title>
|
||||
{t("vectorStoreManagement.vectorStoreInfo.vectorStoreIdTitle", {
|
||||
id: vectorStoreDetails.vector_store_id,
|
||||
})}
|
||||
</Title>
|
||||
<Text className="text-gray-500">
|
||||
{vectorStoreDetails.vector_store_description || t("vectorStoreManagement.vectorStoreInfo.noDescription")}
|
||||
</Text>
|
||||
</div>
|
||||
{is_admin && !isEditing && <Button onClick={() => setIsEditing(true)}>Edit Vector Store</Button>}
|
||||
{is_admin && !isEditing && (
|
||||
<Button onClick={() => setIsEditing(true)}>{t("vectorStoreManagement.vectorStoreInfo.editButton")}</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<TabGroup>
|
||||
<TabList className="mb-6">
|
||||
<Tab>Details</Tab>
|
||||
<Tab>Test Vector Store</Tab>
|
||||
<Tab>{t("vectorStoreManagement.vectorStoreInfo.tabDetails")}</Tab>
|
||||
<Tab>{t("vectorStoreManagement.vectorStoreInfo.tabTest")}</Tab>
|
||||
</TabList>
|
||||
|
||||
<TabPanels>
|
||||
|
|
@ -137,37 +147,50 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
{isEditing ? (
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title>Edit Vector Store</Title>
|
||||
<Title>{t("vectorStoreManagement.vectorStoreInfo.editTitle")}</Title>
|
||||
</div>
|
||||
<Card>
|
||||
<Form form={form} onFinish={handleSave} layout="vertical" initialValues={vectorStoreDetails}>
|
||||
<Form.Item
|
||||
label="Vector Store ID"
|
||||
label={t("vectorStoreManagement.vectorStoreInfo.vectorStoreIdLabel")}
|
||||
name="vector_store_id"
|
||||
rules={[{ required: true, message: "Please input a vector store ID" }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("vectorStoreManagement.vectorStoreInfo.vectorStoreIdRequired"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input disabled />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Vector Store Name" name="vector_store_name">
|
||||
<Form.Item
|
||||
label={t("vectorStoreManagement.vectorStoreInfo.vectorStoreNameLabel")}
|
||||
name="vector_store_name"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Description" name="vector_store_description">
|
||||
<Form.Item label={t("common.description")} name="vector_store_description">
|
||||
<Input.TextArea rows={4} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Provider{" "}
|
||||
<Tooltip title="Select the provider for this vector store">
|
||||
{t("vectorStoreManagement.vectorStoreInfo.providerLabel")}{" "}
|
||||
<Tooltip title={t("vectorStoreManagement.vectorStoreInfo.providerTooltip")}>
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="custom_llm_provider"
|
||||
rules={[{ required: true, message: "Please select a provider" }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("vectorStoreManagement.vectorStoreInfo.providerRequired"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select2>
|
||||
{Object.entries(Providers).map(([providerEnum, providerDisplayName]) => {
|
||||
|
|
@ -206,20 +229,23 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
{/* Credentials */}
|
||||
<div className="mb-4">
|
||||
<Text className="text-sm text-gray-500 mb-2">
|
||||
Either select existing credentials OR enter provider credentials below
|
||||
{t("vectorStoreManagement.vectorStoreInfo.credentialsHint")}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Form.Item label="Existing Credentials" name="litellm_credential_name">
|
||||
<Form.Item
|
||||
label={t("vectorStoreManagement.vectorStoreInfo.existingCredentialsLabel")}
|
||||
name="litellm_credential_name"
|
||||
>
|
||||
<Select2
|
||||
showSearch
|
||||
placeholder="Select or search for existing credentials"
|
||||
placeholder={t("vectorStoreManagement.vectorStoreInfo.existingCredentialsPlaceholder")}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input, option) =>
|
||||
(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<VectorStoreInfoViewProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Metadata{" "}
|
||||
<Tooltip title="JSON metadata for the vector store">
|
||||
{t("vectorStoreManagement.vectorStoreInfo.metadataLabel")}{" "}
|
||||
<Tooltip title={t("vectorStoreManagement.vectorStoreInfo.metadataTooltip")}>
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -254,9 +280,9 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
</Form.Item>
|
||||
|
||||
<div className="flex justify-end space-x-2">
|
||||
<AntButton onClick={() => setIsEditing(false)}>Cancel</AntButton>
|
||||
<AntButton onClick={() => setIsEditing(false)}>{t("common.cancel")}</AntButton>
|
||||
<AntButton type="primary" htmlType="submit">
|
||||
Save Changes
|
||||
{t("vectorStoreManagement.vectorStoreInfo.saveChanges")}
|
||||
</AntButton>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
@ -265,25 +291,29 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
) : (
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title>Vector Store Details</Title>
|
||||
{is_admin && <Button onClick={() => setIsEditing(true)}>Edit Vector Store</Button>}
|
||||
<Title>{t("vectorStoreManagement.vectorStoreInfo.detailsTitle")}</Title>
|
||||
{is_admin && (
|
||||
<Button onClick={() => setIsEditing(true)}>
|
||||
{t("vectorStoreManagement.vectorStoreInfo.editButton")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<Card>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text className="font-medium">ID</Text>
|
||||
<Text className="font-medium">{t("vectorStoreManagement.vectorStoreInfo.idLabel")}</Text>
|
||||
<Text>{vectorStoreDetails.vector_store_id}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Name</Text>
|
||||
<Text className="font-medium">{t("common.name")}</Text>
|
||||
<Text>{vectorStoreDetails.vector_store_name || "-"}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Description</Text>
|
||||
<Text className="font-medium">{t("common.description")}</Text>
|
||||
<Text>{vectorStoreDetails.vector_store_description || "-"}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Provider</Text>
|
||||
<Text className="font-medium">{t("vectorStoreManagement.vectorStoreInfo.providerLabel")}</Text>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
{(() => {
|
||||
const provider = vectorStoreDetails.custom_llm_provider || "bedrock";
|
||||
|
|
@ -331,19 +361,19 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Metadata</Text>
|
||||
<Text className="font-medium">{t("vectorStoreManagement.vectorStoreInfo.metadataLabel")}</Text>
|
||||
<div className="bg-gray-50 p-3 rounded mt-2 font-mono text-xs overflow-auto max-h-48">
|
||||
<pre>{metadataString}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Created</Text>
|
||||
<Text className="font-medium">{t("vectorStoreManagement.vectorStoreInfo.createdLabel")}</Text>
|
||||
<Text>
|
||||
{vectorStoreDetails.created_at ? new Date(vectorStoreDetails.created_at).toLocaleString() : "-"}
|
||||
</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Last Updated</Text>
|
||||
<Text className="font-medium">{t("vectorStoreManagement.vectorStoreInfo.updatedLabel")}</Text>
|
||||
<Text>
|
||||
{vectorStoreDetails.updated_at ? new Date(vectorStoreDetails.updated_at).toLocaleString() : "-"}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -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}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue