Add openai/ prefix for OpenAI-Compatible provider in Add Model UI

Refactor Azure-specific model name prefixing into a generic prefixWithProvider
helper that uses provider_map for lookups. This fixes OpenAI-Compatible models
not getting the required openai/ routing prefix (e.g. BAAI/bge-m3-gaudi ->
openai/BAAI/bge-m3-gaudi), and also fixes the free-text input for
OpenAI-Compatible and Ollama providers not creating model mappings at all.
This commit is contained in:
Ryan Crabbe 2026-03-02 10:52:45 -08:00
parent 92407ec0d4
commit 95521038f2
4 changed files with 25 additions and 70 deletions

View file

@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { Form, Table } from "antd";
import { TextInput } from "@tremor/react";
import { Tooltip } from "../atoms/index";
import { Providers } from "../provider_info_helpers";
import { Providers, prefixWithProvider } from "../provider_info_helpers";
const ConditionalPublicModelName: React.FC = () => {
const form = Form.useFormInstance();
@ -20,15 +20,9 @@ const ConditionalPublicModelName: React.FC = () => {
const currentMappings = form.getFieldValue("model_mappings") || [];
const updatedMappings = currentMappings.map((mapping: any) => {
if (mapping.public_name === "custom" || mapping.litellm_model === "custom") {
if (selectedProvider === Providers.Azure) {
return {
public_name: customModelName,
litellm_model: `azure/${customModelName}`,
};
}
return {
public_name: customModelName,
litellm_model: customModelName,
litellm_model: prefixWithProvider(selectedProvider, customModelName),
};
}
return mapping;
@ -52,36 +46,21 @@ const ConditionalPublicModelName: React.FC = () => {
if (model === "custom") {
return mapping.litellm_model === "custom" || mapping.litellm_model === customModelName;
}
if (selectedProvider === Providers.Azure) {
return mapping.litellm_model === `azure/${model}`;
}
return mapping.litellm_model === model;
return mapping.litellm_model === prefixWithProvider(selectedProvider, model);
}),
);
if (shouldUpdateMappings) {
const mappings = selectedModels.map((model: string) => {
if (model === "custom" && customModelName) {
if (selectedProvider === Providers.Azure) {
return {
public_name: customModelName,
litellm_model: `azure/${customModelName}`,
};
}
return {
public_name: customModelName,
litellm_model: customModelName,
};
}
if (selectedProvider === Providers.Azure) {
return {
public_name: model,
litellm_model: `azure/${model}`,
litellm_model: prefixWithProvider(selectedProvider, customModelName),
};
}
return {
public_name: model,
litellm_model: model,
litellm_model: prefixWithProvider(selectedProvider, model),
};
});

View file

@ -2,7 +2,7 @@ import React from "react";
import { Form, Select as AntSelect } from "antd";
import { TextInput, Text } from "@tremor/react";
import { Row, Col } from "antd";
import { Providers } from "../provider_info_helpers";
import { Providers, prefixWithProvider } from "../provider_info_helpers";
interface LiteLLMModelNameFieldProps {
selectedProvider: Providers;
@ -31,18 +31,10 @@ const LiteLLMModelNameField: React.FC<LiteLLMModelNameFieldProps> = ({
// Only update if the value has actually changed
if (JSON.stringify(currentModel) !== JSON.stringify(values)) {
// Create mappings first
const mappings = values.map((model) => {
if (selectedProvider === Providers.Azure) {
return {
public_name: model,
litellm_model: `azure/${model}`,
};
}
return {
public_name: model,
litellm_model: model,
};
});
const mappings = values.map((model) => ({
public_name: model,
litellm_model: prefixWithProvider(selectedProvider, model),
}));
// Update both fields in one call to reduce re-renders
form.setFieldsValue({
@ -53,43 +45,28 @@ const LiteLLMModelNameField: React.FC<LiteLLMModelNameFieldProps> = ({
}
};
const handleAzureDeploymentNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const deploymentName = e.target.value;
const handleFreeTextModelChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const modelName = e.target.value;
// Create mapping with Azure-specific format
const mappings = deploymentName
? [
{
public_name: deploymentName,
litellm_model: `azure/${deploymentName}`,
},
]
const mappings = modelName
? [{ public_name: modelName, litellm_model: prefixWithProvider(selectedProvider, modelName) }]
: [];
// Update both fields
form.setFieldsValue({
model: deploymentName,
model: modelName,
model_mappings: mappings,
});
};
// Handle custom model name changes
const handleCustomModelNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const customName = e.target.value;
// Immediately update the model mappings
const currentMappings = form.getFieldValue("model_mappings") || [];
const updatedMappings = currentMappings.map((mapping: any) => {
if (mapping.public_name === "custom" || mapping.litellm_model === "custom") {
if (selectedProvider === Providers.Azure) {
return {
public_name: customName,
litellm_model: `azure/${customName}`,
};
}
return {
public_name: customName,
litellm_model: customName,
litellm_model: prefixWithProvider(selectedProvider, customName),
};
}
return mapping;
@ -121,7 +98,7 @@ const LiteLLMModelNameField: React.FC<LiteLLMModelNameFieldProps> = ({
<>
<TextInput
placeholder={getPlaceholder(selectedProvider)}
onChange={selectedProvider === Providers.Azure ? handleAzureDeploymentNameChange : undefined}
onChange={handleFreeTextModelChange}
/>
</>
) : providerModels.length > 0 ? (

View file

@ -267,13 +267,6 @@ describe("provider_info_helpers", () => {
expect(result).toEqual(["valid-model"]);
});
it("should log provider key and mapped provider when called", () => {
const modelMap = { "gpt-3.5-turbo": { litellm_provider: "openai" } };
getProviderModels(Providers.OpenAI, modelMap);
expect(consoleSpy).toHaveBeenCalledWith(`Provider key: ${Providers.OpenAI}`);
expect(consoleSpy).toHaveBeenCalledWith(`Provider mapped to: ${provider_map[Providers.OpenAI]}`);
});
it("should return empty array for provider with no matching models", () => {
const modelMap = {
"gpt-3.5-turbo": { litellm_provider: "openai" },

View file

@ -368,11 +368,17 @@ export const getPlaceholder = (selectedProvider: string): string => {
}
};
const providersRequiringPrefix = new Set<string>(["Azure", "OpenAI_Compatible"]);
export const prefixWithProvider = (provider: string, modelName: string): string => {
if (!providersRequiringPrefix.has(provider)) return modelName;
const prefix = provider_map[provider];
return prefix ? `${prefix}/${modelName}` : modelName;
};
export const getProviderModels = (provider: Providers, modelMap: any): Array<string> => {
let providerKey = provider;
console.log(`Provider key: ${providerKey}`);
let custom_llm_provider = provider_map[providerKey];
console.log(`Provider mapped to: ${custom_llm_provider}`);
let providerModels: Array<string> = [];