mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 12:52:11 +03:00
refactor(gitlawb): extract shared opengateway validator factory, fix docs path in test
- Extract gitlawb/gitlawb-gmi validators into buildOpengatewayValidator factory - Fix dockerignore-docs-coverage test: update stale docs/AUTO-COMBO.md -> docs/routing/AUTO-COMBO.md
This commit is contained in:
@@ -3492,6 +3492,55 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Opengateway-style validators (xiaomi-mimo compatible).
|
||||
* These providers share a POST /chat/completions auth check pattern and differ
|
||||
* only in default baseUrl and test model name.
|
||||
*/
|
||||
function buildOpengatewayValidator(
|
||||
defaultBaseUrl: string,
|
||||
model: string
|
||||
) {
|
||||
return async ({ apiKey, providerSpecificData }: any) => {
|
||||
try {
|
||||
const baseUrl = normalizeBaseUrl(
|
||||
providerSpecificData?.baseUrl || defaultBaseUrl
|
||||
);
|
||||
const chatUrl = `${baseUrl.replace(/\/chat\/completions$/, "")}/chat/completions`;
|
||||
const res = await validationWrite(
|
||||
chatUrl,
|
||||
{
|
||||
method: "POST",
|
||||
headers: buildBearerHeaders(apiKey, providerSpecificData),
|
||||
body: JSON.stringify({
|
||||
model,
|
||||
messages: [{ role: "user", content: "test" }],
|
||||
max_tokens: 1,
|
||||
}),
|
||||
},
|
||||
isLocal
|
||||
);
|
||||
if (res.status === 401 || res.status === 403) {
|
||||
return { valid: false, error: "Invalid API key" };
|
||||
}
|
||||
// Any non-auth response (200, 400, 422, 429) means auth passed
|
||||
return { valid: true, error: null };
|
||||
} catch (error: any) {
|
||||
return toValidationErrorResult(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Same as buildOpengatewayValidator but returns an object spreadable into SPECIALTY_VALIDATORS.
|
||||
// isLocal is captured via closure from the outer function scope.
|
||||
function buildGitlawbValidators(
|
||||
configs: [string, string, string][]
|
||||
): Record<string, ReturnType<typeof buildOpengatewayValidator>> {
|
||||
return Object.fromEntries(
|
||||
configs.map(([id, baseUrl, model]) => [id, buildOpengatewayValidator(baseUrl, model)])
|
||||
);
|
||||
}
|
||||
|
||||
// ── Specialty provider validation ──
|
||||
const SPECIALTY_VALIDATORS = {
|
||||
jules: validateJulesProvider,
|
||||
@@ -3745,62 +3794,11 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi
|
||||
},
|
||||
// Gitlawb Opengateway — Xiaomi MiMo compatible, same /models endpoint limitation.
|
||||
// Bypass /models probe in favor of chat/completions, matching xiaomi-mimo's pattern.
|
||||
gitlawb: async ({ apiKey, providerSpecificData }: any) => {
|
||||
try {
|
||||
const baseUrl = normalizeBaseUrl(
|
||||
providerSpecificData?.baseUrl || "https://opengateway.gitlawb.com/v1/xiaomi-mimo"
|
||||
);
|
||||
const chatUrl = `${baseUrl.replace(/\/chat\/completions$/, "")}/chat/completions`;
|
||||
const res = await validationWrite(
|
||||
chatUrl,
|
||||
{
|
||||
method: "POST",
|
||||
headers: buildBearerHeaders(apiKey, providerSpecificData),
|
||||
body: JSON.stringify({
|
||||
model: "mimo-v2.5-pro",
|
||||
messages: [{ role: "user", content: "test" }],
|
||||
max_tokens: 1,
|
||||
}),
|
||||
},
|
||||
isLocal
|
||||
);
|
||||
if (res.status === 401 || res.status === 403) {
|
||||
return { valid: false, error: "Invalid API key" };
|
||||
}
|
||||
// Any non-auth response (200, 400, 422, 429) means auth passed
|
||||
return { valid: true, error: null };
|
||||
} catch (error: any) {
|
||||
return toValidationErrorResult(error);
|
||||
}
|
||||
},
|
||||
"gitlawb-gmi": async ({ apiKey, providerSpecificData }: any) => {
|
||||
try {
|
||||
const baseUrl = normalizeBaseUrl(
|
||||
providerSpecificData?.baseUrl || "https://opengateway.gitlawb.com/v1/gmi-cloud"
|
||||
);
|
||||
const chatUrl = `${baseUrl.replace(/\/chat\/completions$/, "")}/chat/completions`;
|
||||
const res = await validationWrite(
|
||||
chatUrl,
|
||||
{
|
||||
method: "POST",
|
||||
headers: buildBearerHeaders(apiKey, providerSpecificData),
|
||||
body: JSON.stringify({
|
||||
model: "XiaomiMiMo/MiMo-V2.5-Pro",
|
||||
messages: [{ role: "user", content: "test" }],
|
||||
max_tokens: 1,
|
||||
}),
|
||||
},
|
||||
isLocal
|
||||
);
|
||||
if (res.status === 401 || res.status === 403) {
|
||||
return { valid: false, error: "Invalid API key" };
|
||||
}
|
||||
// Any non-auth response (200, 400, 422, 429) means auth passed
|
||||
return { valid: true, error: null };
|
||||
} catch (error: any) {
|
||||
return toValidationErrorResult(error);
|
||||
}
|
||||
},
|
||||
// Uses a factory to share validation logic across Opengateway provider variants.
|
||||
...buildGitlawbValidators([
|
||||
["gitlawb", "https://opengateway.gitlawb.com/v1/xiaomi-mimo", "mimo-v2.5-pro"],
|
||||
["gitlawb-gmi", "https://opengateway.gitlawb.com/v1/gmi-cloud", "XiaomiMiMo/MiMo-V2.5-Pro"],
|
||||
]),
|
||||
// Search providers — use factored validator
|
||||
...Object.fromEntries(
|
||||
Object.entries(SEARCH_VALIDATOR_CONFIGS).map(([id, configFn]) => [
|
||||
|
||||
@@ -25,7 +25,7 @@ const DOCKERIGNORE = path.resolve(REPO_ROOT, ".dockerignore");
|
||||
const REQUIRED_DOCS = [
|
||||
"docs/README.md",
|
||||
"docs/PROVIDERS.md",
|
||||
"docs/AUTO-COMBO.md",
|
||||
"docs/routing/AUTO-COMBO.md",
|
||||
"docs/guides/SETUP_GUIDE.md",
|
||||
"docs/guides/TROUBLESHOOTING.md",
|
||||
"docs/reference/API_REFERENCE.md",
|
||||
@@ -154,7 +154,7 @@ test("#2348 .dockerignore keeps every doc the in-product viewer needs", () => {
|
||||
|
||||
test("#2348 .dockerignore still excludes the heavy i18n tree", () => {
|
||||
const parsed = parseDockerignore(fs.readFileSync(DOCKERIGNORE, "utf8"));
|
||||
const heavy = "docs/i18n/pt-BR/docs/AUTO-COMBO.md";
|
||||
const heavy = "docs/i18n/pt-BR/docs/routing/AUTO-COMBO.md";
|
||||
assert.ok(
|
||||
isIgnored(heavy, parsed),
|
||||
`${heavy} should be excluded from Docker context but is not — image size will balloon`
|
||||
|
||||
Reference in New Issue
Block a user