From 12b8d595625611f9f1d161ad50d1a9ed0caa063c Mon Sep 17 00:00:00 2001 From: kcwhite Date: Sat, 7 Jun 2025 18:21:11 -0600 Subject: [PATCH] Bug fix for trailing slash error when using LiteLLM provider (#4275) * Added changeset for my code changes * Use URL constructor for joining baseUrl and path in litellm.ts * Restoring Roo dotfiles * Moved Roo dotfiles to root directory * Revert this * Add tests for litellm URL constructor fix --------- Co-authored-by: Kevin White Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com> Co-authored-by: Daniel Riccio --- .changeset/metal-suns-lay.md | 5 +++++ .../fetchers/__tests__/litellm.test.ts | 20 +++++++++++++++++++ src/api/providers/fetchers/litellm.ts | 4 +++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset/metal-suns-lay.md diff --git a/.changeset/metal-suns-lay.md b/.changeset/metal-suns-lay.md new file mode 100644 index 0000000000..c0efff6a88 --- /dev/null +++ b/.changeset/metal-suns-lay.md @@ -0,0 +1,5 @@ +--- +"roo-code": patch +--- + +Bug fix for trailing slash error when using LiteLLM provider diff --git a/src/api/providers/fetchers/__tests__/litellm.test.ts b/src/api/providers/fetchers/__tests__/litellm.test.ts index 49e928548f..046146d7c4 100644 --- a/src/api/providers/fetchers/__tests__/litellm.test.ts +++ b/src/api/providers/fetchers/__tests__/litellm.test.ts @@ -12,6 +12,26 @@ describe("getLiteLLMModels", () => { jest.clearAllMocks() }) + it("handles base URLs with trailing slashes correctly", async () => { + const mockResponse = { + data: { + data: [], + }, + } + + mockedAxios.get.mockResolvedValue(mockResponse) + + await getLiteLLMModels("test-api-key", "http://localhost:4000/") + + expect(mockedAxios.get).toHaveBeenCalledWith("http://localhost:4000/v1/model/info", { + headers: { + Authorization: "Bearer test-api-key", + "Content-Type": "application/json", + }, + timeout: 5000, + }) + }) + it("successfully fetches and formats LiteLLM models", async () => { const mockResponse = { data: { diff --git a/src/api/providers/fetchers/litellm.ts b/src/api/providers/fetchers/litellm.ts index 1c257300ec..47617cd390 100644 --- a/src/api/providers/fetchers/litellm.ts +++ b/src/api/providers/fetchers/litellm.ts @@ -21,8 +21,10 @@ export async function getLiteLLMModels(apiKey: string, baseUrl: string): Promise if (apiKey) { headers["Authorization"] = `Bearer ${apiKey}` } + // Use URL constructor to properly join base URL and path + const url = new URL("/v1/model/info", baseUrl).href // Added timeout to prevent indefinite hanging - const response = await axios.get(`${baseUrl}/v1/model/info`, { headers, timeout: 5000 }) + const response = await axios.get(url, { headers, timeout: 5000 }) const models: ModelRecord = {} const computerModels = Array.from(LITELLM_COMPUTER_USE_MODELS)