mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
feat(ui): add MongoDB Atlas to the vector store provider dropdown
The create form now offers MongoDB Atlas with its connection string, database, collection, embedding model, vector field, text field and candidate count. The connection string renders as a password input because it carries the database user's password, and the embedding model is picked from the proxy's own models, matching how Milvus and Valkey do it. The vector store id doubles as the Atlas Vector Search index name, so the placeholder says so.
This commit is contained in:
parent
85431297b9
commit
1f8cbee8aa
5 changed files with 185 additions and 2 deletions
6
ui/litellm-dashboard/public/assets/logos/mongodb.svg
Normal file
6
ui/litellm-dashboard/public/assets/logos/mongodb.svg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="MongoDB">
|
||||
<path fill="#00684A" fill-rule="evenodd" d="M 33.1 2.4 C 33.1 2.4 36.6 8.9 44.4 15.1 C 52.2 21.3 55.1 28.5 54.2 37.1 C 53.3 45.7 47.6 52.7 40.1 55.6 C 38.5 56.2 37.3 57.4 36.7 59 L 34.7 64 L 31.4 64 L 30.3 59.4 C 29.9 57.6 28.7 56.1 27 55.3 C 19.4 51.8 14 44.6 13.4 36 C 12.7 25.8 18.1 19.6 24.6 14 C 30.2 9.2 33.1 2.4 33.1 2.4 Z"/>
|
||||
<path fill="#00ED64" d="M 33.1 2.4 C 33.1 2.4 30.2 9.2 24.6 14 C 18.1 19.6 12.7 25.8 13.4 36 C 14 44.6 19.4 51.8 27 55.3 C 28.7 56.1 29.9 57.6 30.3 59.4 L 31.4 64 L 32.9 64 Z"/>
|
||||
<path fill="#B8C4C2" d="M 32.4 46.9 L 31.9 46.1 C 31.5 40.4 31.4 34.6 31.6 28.9 C 31.7 26.1 31.8 20.1 32.9 17.1 C 32.6 20.6 32.7 43.1 32.8 45.4 C 32.7 45.9 32.6 46.4 32.4 46.9 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 866 B |
|
|
@ -110,6 +110,57 @@ describe("buildVectorStoreLitellmParams", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("renames embedding_model to litellm_embedding_model for mongodb", () => {
|
||||
const params = buildVectorStoreLitellmParams("mongodb", {
|
||||
mongodb_connection_string: "mongodb+srv://user:pass@cluster0.mongodb.net",
|
||||
mongodb_database: "sample_mflix",
|
||||
mongodb_collection: "embedded_movies",
|
||||
mongodb_embedding_field: "plot_embedding",
|
||||
mongodb_text_field: "plot",
|
||||
mongodb_num_candidates: "200",
|
||||
embedding_model: "text-embedding-ada-002",
|
||||
});
|
||||
|
||||
expect(params).toEqual({
|
||||
mongodb_connection_string: "mongodb+srv://user:pass@cluster0.mongodb.net",
|
||||
mongodb_database: "sample_mflix",
|
||||
mongodb_collection: "embedded_movies",
|
||||
mongodb_embedding_field: "plot_embedding",
|
||||
mongodb_text_field: "plot",
|
||||
mongodb_num_candidates: "200",
|
||||
litellm_embedding_model: "text-embedding-ada-002",
|
||||
});
|
||||
});
|
||||
|
||||
it("sends only mongodb fields when an earlier provider left values in the form", () => {
|
||||
const params = buildVectorStoreLitellmParams("mongodb", {
|
||||
mongodb_connection_string: "mongodb+srv://user:pass@cluster0.mongodb.net",
|
||||
mongodb_database: "sample_mflix",
|
||||
mongodb_collection: "embedded_movies",
|
||||
embedding_model: "text-embedding-ada-002",
|
||||
valkey_host: "left-over-from-valkey.example.com",
|
||||
valkey_port: "6379",
|
||||
aws_region_name: "us-west-2",
|
||||
});
|
||||
|
||||
expect(params).not.toHaveProperty("valkey_host");
|
||||
expect(params).not.toHaveProperty("valkey_port");
|
||||
expect(params).not.toHaveProperty("aws_region_name");
|
||||
expect(params.mongodb_connection_string).toBe("mongodb+srv://user:pass@cluster0.mongodb.net");
|
||||
});
|
||||
|
||||
it("omits a blank mongodb_num_candidates so litellm picks its own candidate count", () => {
|
||||
const params = buildVectorStoreLitellmParams("mongodb", {
|
||||
mongodb_connection_string: "mongodb+srv://user:pass@cluster0.mongodb.net",
|
||||
mongodb_database: "sample_mflix",
|
||||
mongodb_collection: "embedded_movies",
|
||||
embedding_model: "text-embedding-ada-002",
|
||||
});
|
||||
|
||||
expect(params.mongodb_num_candidates).toBeUndefined();
|
||||
expect(JSON.parse(JSON.stringify(params))).not.toHaveProperty("mongodb_num_candidates");
|
||||
});
|
||||
|
||||
it("keeps embedding_model as-is for providers outside the rename set", () => {
|
||||
const params = buildVectorStoreLitellmParams("s3_vectors", {
|
||||
vector_bucket_name: "my-vector-bucket",
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import { Textarea } from "@/components/ui/textarea";
|
|||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { useZodForm } from "@/lib/forms/useZodForm";
|
||||
|
||||
const EMBEDDING_MODEL_RENAME_PROVIDERS = new Set(["milvus", "valkey"]);
|
||||
const EMBEDDING_MODEL_RENAME_PROVIDERS = new Set(["milvus", "valkey", "mongodb"]);
|
||||
|
||||
export const buildVectorStoreLitellmParams = (
|
||||
provider: string,
|
||||
|
|
@ -70,6 +70,12 @@ const PROVIDER_FIELD_NAMES = [
|
|||
"vector_bucket_name",
|
||||
"index_name",
|
||||
"aws_region_name",
|
||||
"mongodb_connection_string",
|
||||
"mongodb_database",
|
||||
"mongodb_collection",
|
||||
"mongodb_embedding_field",
|
||||
"mongodb_text_field",
|
||||
"mongodb_num_candidates",
|
||||
"valkey_host",
|
||||
"valkey_port",
|
||||
"valkey_password",
|
||||
|
|
@ -101,6 +107,12 @@ const vectorStoreShape = {
|
|||
vector_bucket_name: optionalText,
|
||||
index_name: optionalText,
|
||||
aws_region_name: optionalText,
|
||||
mongodb_connection_string: optionalText,
|
||||
mongodb_database: optionalText,
|
||||
mongodb_collection: optionalText,
|
||||
mongodb_embedding_field: optionalText,
|
||||
mongodb_text_field: optionalText,
|
||||
mongodb_num_candidates: optionalText,
|
||||
valkey_host: optionalText,
|
||||
valkey_port: optionalText,
|
||||
valkey_password: optionalText,
|
||||
|
|
@ -130,6 +142,8 @@ const EMPTY_VALUES: VectorStoreFormValues = {
|
|||
custom_llm_provider: "bedrock",
|
||||
vector_store_id: "",
|
||||
vertex_location: "global",
|
||||
mongodb_embedding_field: "embedding",
|
||||
mongodb_text_field: "text",
|
||||
valkey_port: "6379",
|
||||
valkey_ssl: "false",
|
||||
valkey_text_field: "text",
|
||||
|
|
@ -262,7 +276,9 @@ const VectorStoreForm: React.FC<VectorStoreFormProps> = ({
|
|||
: 'my-datastore_1234567890 (data store ID from Vertex AI / "Agent Search" console)'
|
||||
: selectedProvider === "valkey"
|
||||
? "my-search-index (FT index name in Valkey)"
|
||||
: "Enter vector store ID from your provider";
|
||||
: selectedProvider === "mongodb"
|
||||
? "my-vector-index (Atlas Vector Search index name)"
|
||||
: "Enter vector store ID from your provider";
|
||||
|
||||
return (
|
||||
<Dialog open={isVisible} onOpenChange={(open) => !open && handleCancel()}>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,47 @@ describe("getVectorStoreProviderLogoAndName", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("registers mongodb in the provider, logo, and field maps", () => {
|
||||
expect(getVectorStoreProviderLogoAndName("mongodb")).toEqual({
|
||||
logo: expect.stringContaining("mongodb"),
|
||||
displayName: VectorStoreProviders.MongoDB,
|
||||
});
|
||||
expect(vectorStoreProviderMap.MongoDB).toBe("mongodb");
|
||||
expect(getProviderSpecificFields("mongodb").map((field) => field.name)).toEqual([
|
||||
"mongodb_connection_string",
|
||||
"mongodb_database",
|
||||
"mongodb_collection",
|
||||
"embedding_model",
|
||||
"mongodb_embedding_field",
|
||||
"mongodb_text_field",
|
||||
"mongodb_num_candidates",
|
||||
]);
|
||||
});
|
||||
|
||||
it("hides the mongodb connection string, which carries the database password", () => {
|
||||
const connectionString = getProviderSpecificFields("mongodb").find(
|
||||
(field) => field.name === "mongodb_connection_string",
|
||||
);
|
||||
|
||||
expect(connectionString).toMatchObject({ type: "password", required: true });
|
||||
});
|
||||
|
||||
it("picks the mongodb embedding model from the proxy's models rather than a fixed list", () => {
|
||||
const embeddingField = getProviderSpecificFields("mongodb").find((field) => field.name === "embedding_model");
|
||||
|
||||
expect(embeddingField).toMatchObject({ type: "select", required: true });
|
||||
expect(embeddingField).not.toHaveProperty("options");
|
||||
});
|
||||
|
||||
it("defaults the mongodb field names so a standard collection needs no extra input", () => {
|
||||
const fields = getProviderSpecificFields("mongodb");
|
||||
const byName = (name: string) => fields.find((field) => field.name === name);
|
||||
|
||||
expect(byName("mongodb_embedding_field")).toMatchObject({ required: false, initialValue: "embedding" });
|
||||
expect(byName("mongodb_text_field")).toMatchObject({ required: false, initialValue: "text" });
|
||||
expect(byName("mongodb_num_candidates")).toMatchObject({ required: false });
|
||||
});
|
||||
|
||||
it("registers valkey in the provider, logo, and field maps", () => {
|
||||
expect(vectorStoreProviderMap.Valkey).toBe("valkey");
|
||||
expect(vectorStoreProviderLogoMap[VectorStoreProviders.Valkey]).toContain("valkey");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { getProviderLogoAndName, Providers, providerLogoMap } from "@/components/provider_info_helpers";
|
||||
import milvusLogo from "../../public/assets/logos/milvus.svg";
|
||||
import mongodbLogo from "../../public/assets/logos/mongodb.svg";
|
||||
import postgresqlLogo from "../../public/assets/logos/postgresql.svg";
|
||||
import s3VectorLogo from "../../public/assets/logos/s3_vector.png";
|
||||
import valkeyLogo from "../../public/assets/logos/valkey.svg";
|
||||
|
|
@ -13,6 +14,7 @@ export enum VectorStoreProviders {
|
|||
OpenAI = "OpenAI",
|
||||
Azure = "Azure OpenAI",
|
||||
Milvus = "Milvus",
|
||||
MongoDB = "MongoDB Atlas",
|
||||
Valkey = "Valkey",
|
||||
}
|
||||
|
||||
|
|
@ -24,6 +26,7 @@ export const vectorStoreProviderMap: Record<string, string> = {
|
|||
OpenAI: "openai",
|
||||
Azure: "azure",
|
||||
Milvus: "milvus",
|
||||
MongoDB: "mongodb",
|
||||
S3Vectors: "s3_vectors",
|
||||
Valkey: "valkey",
|
||||
};
|
||||
|
|
@ -36,6 +39,7 @@ export const vectorStoreProviderLogoMap: Record<string, string> = {
|
|||
[VectorStoreProviders.OpenAI]: providerLogoMap[Providers.OpenAI] ?? "",
|
||||
[VectorStoreProviders.Azure]: providerLogoMap[Providers.Azure] ?? "",
|
||||
[VectorStoreProviders.Milvus]: milvusLogo.src,
|
||||
[VectorStoreProviders.MongoDB]: mongodbLogo.src,
|
||||
[VectorStoreProviders.S3Vectors]: s3VectorLogo.src,
|
||||
[VectorStoreProviders.Valkey]: valkeyLogo.src,
|
||||
};
|
||||
|
|
@ -169,6 +173,71 @@ export const vectorStoreProviderFields: Record<string, VectorStoreFieldConfig[]>
|
|||
type: "select",
|
||||
},
|
||||
],
|
||||
mongodb: [
|
||||
{
|
||||
name: "mongodb_connection_string",
|
||||
label: "Connection String",
|
||||
tooltip:
|
||||
"The full MongoDB connection string for your Atlas cluster, including the database user and password. Copy it from Atlas under Connect, Drivers (e.g. mongodb+srv://user:password@cluster.mongodb.net)",
|
||||
placeholder: "mongodb+srv://user:password@cluster.mongodb.net",
|
||||
required: true,
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
name: "mongodb_database",
|
||||
label: "Database",
|
||||
tooltip: "The Atlas database holding the collection you want to search",
|
||||
placeholder: "sample_mflix",
|
||||
required: true,
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
name: "mongodb_collection",
|
||||
label: "Collection",
|
||||
tooltip: "The collection your Atlas Vector Search index was built on",
|
||||
placeholder: "embedded_movies",
|
||||
required: true,
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
name: "embedding_model",
|
||||
label: "Embedding Model",
|
||||
tooltip:
|
||||
"The embedding model on this proxy that created the vectors already stored in your collection. LiteLLM embeds every search query with it, so it must be the same model. A different model of the same size will not error, it will just return wrong results. Add it under Models first if it is not listed",
|
||||
placeholder: "text-embedding-3-small",
|
||||
required: true,
|
||||
type: "select",
|
||||
},
|
||||
{
|
||||
name: "mongodb_embedding_field",
|
||||
label: "Vector Field Name",
|
||||
tooltip:
|
||||
"The field in each document that holds its embedding. It must match the path your Atlas Vector Search index was created on (default: embedding)",
|
||||
placeholder: "embedding",
|
||||
required: false,
|
||||
type: "text",
|
||||
initialValue: "embedding",
|
||||
},
|
||||
{
|
||||
name: "mongodb_text_field",
|
||||
label: "Text Field",
|
||||
tooltip:
|
||||
"The field in each document that holds its readable text. LiteLLM returns this text in search results, and it accepts a dotted path such as metadata.body (default: text)",
|
||||
placeholder: "text",
|
||||
required: false,
|
||||
type: "text",
|
||||
initialValue: "text",
|
||||
},
|
||||
{
|
||||
name: "mongodb_num_candidates",
|
||||
label: "Candidates Considered",
|
||||
tooltip:
|
||||
"How many nearest neighbours Atlas examines before returning the top results. Higher is more accurate and slower. Leave blank to let LiteLLM scale it with the requested result count",
|
||||
placeholder: "100",
|
||||
required: false,
|
||||
type: "text",
|
||||
},
|
||||
],
|
||||
valkey: [
|
||||
{
|
||||
name: "valkey_host",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue