mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
fix(validation): strip trailing /models in Gemini validator to avoid /models/models 404 (#2545)
This commit is contained in:
@@ -741,11 +741,15 @@ async function validateGeminiLikeProvider({
|
||||
return { valid: false, error: "Missing base URL" };
|
||||
}
|
||||
|
||||
// Strip a trailing /models before appending — the default Gemini registry baseUrl is
|
||||
// `.../v1beta/models` (for the chat urlBuilder), so naively appending /models produced
|
||||
// `.../v1beta/models/models` → upstream 404 on connection validation (#2545).
|
||||
const baseForModels = baseUrl.replace(/\/models\/?$/, "");
|
||||
const requestUrl =
|
||||
typeof providerSpecificData?.modelsUrl === "string" &&
|
||||
providerSpecificData.modelsUrl.trim() !== ""
|
||||
? providerSpecificData.modelsUrl.trim()
|
||||
: `${baseUrl}/models`;
|
||||
: `${baseForModels}/models`;
|
||||
|
||||
const urlWithKey =
|
||||
authType === "query" ? `${requestUrl}?key=${encodeURIComponent(apiKey)}` : requestUrl;
|
||||
|
||||
@@ -163,3 +163,28 @@ test("#2463 openai-compatible validation does not throw on non-string modelsUrl"
|
||||
});
|
||||
assert.equal(typeof result.valid, "boolean");
|
||||
});
|
||||
|
||||
// Regression for #2545: the default Gemini (AI Studio) base URL ends in /v1beta/models,
|
||||
// so the validator must not append a second /models (which produced /models/models → 404).
|
||||
test("#2545 gemini validation does not produce /models/models", async () => {
|
||||
const calls: string[] = [];
|
||||
globalThis.fetch = async (url: any) => {
|
||||
calls.push(String(url));
|
||||
return new Response(JSON.stringify({ models: [] }), { status: 200 });
|
||||
};
|
||||
const result = await validateProviderApiKey({
|
||||
provider: "gemini",
|
||||
apiKey: "AIzaTestKey",
|
||||
providerSpecificData: {},
|
||||
});
|
||||
assert.equal(typeof result.valid, "boolean");
|
||||
assert.ok(calls.length > 0, "validator must make a request");
|
||||
assert.ok(
|
||||
!calls.some((u) => u.includes("/models/models")),
|
||||
`outbound URL must not contain /models/models — got ${calls.join(", ")}`
|
||||
);
|
||||
assert.ok(
|
||||
calls.some((u) => /\/v1beta\/models(\?|$)/.test(u)),
|
||||
`outbound URL must hit a single /models segment — got ${calls.join(", ")}`
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user