fix(ui): keep litellm_credential_name from LiteLLM Params JSON when no credential is selected (#39005)

* fix(ui): keep litellm_credential_name from LiteLLM Params JSON when no credential is selected

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(ui): drop null litellm_credential_name from AddModelPanel payload fixture

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
devin-ai-integration[bot] 2026-08-31 17:55:53 -07:00 • committed by GitHub
parent 97cac0b8ed
commit 33cc9c1c48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 2 deletions

View file

@ -87,7 +87,6 @@ const alwaysMounted = {
api_key: undefined,
api_base: undefined,
custom_llm_provider: "openai",
litellm_credential_name: null,
model: "gpt-4o",
};

View file

@ -73,4 +73,28 @@ describe("prepareModelAddRequest", () => {
expect(deployment.litellmParamsObj.litellm_credential_name).toBe("selected-credential");
expect(deployment.litellmParamsObj.timeout).toBe(5);
});
it("keeps litellm_credential_name from LiteLLM Params JSON when no credential is selected", async () => {
const formValues = {
model_mappings: [
{
public_name: "Public Model",
litellm_model: "litellm/public",
},
],
model_name: "custom-model-name",
litellm_extra_params: JSON.stringify({
litellm_credential_name: "from-json",
timeout: 5,
}),
litellm_credential_name: null,
};
const deployments = await prepareModelAddRequest({ ...formValues }, "token", null);
expect(deployments).toHaveLength(1);
const [deployment] = deployments!;
expect(deployment.litellmParamsObj.litellm_credential_name).toBe("from-json");
expect(deployment.litellmParamsObj.timeout).toBe(5);
});
});

View file

@ -91,6 +91,9 @@ export const prepareModelAddRequest = async (formValues: Record<string, any>, ac
if (value === "") {
continue;
}
if (key === "litellm_credential_name" && value == null) {
continue;
}
// Skip the custom_pricing and pricing_model fields as they're only used for UI control
if (key === "custom_pricing" || key === "pricing_model" || key === "cache_control") {
continue;
@ -124,7 +127,7 @@ export const prepareModelAddRequest = async (formValues: Record<string, any>, ac
if (value && value != undefined) {
try {
litellmExtraParams = JSON.parse(value);
if ("litellm_credential_name" in litellmExtraParams) {
if ("litellm_credential_name" in litellmExtraParams && formValues.litellm_credential_name) {
delete litellmExtraParams.litellm_credential_name;
}
} catch (error) {