mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 14:22:09 +03:00
Expand the provider catalog with GitLab Duo PAT and OAuth support, NLP Cloud, and new OpenAI-compatible gateways including Azure AI Foundry, Bedrock, DataRobot, watsonx, OCI, SAP, Modal, Reka, Clarifai, and Chutes. Add specialized GitLab and NLP Cloud executors, provider-specific URL normalization and validation flows, managed catalog/model discovery updates, and dashboard metadata for the new providers. Extend search support with You.com, including request building, response normalization, validation coverage, and route/schema registration.
104 lines
3.1 KiB
TypeScript
104 lines
3.1 KiB
TypeScript
type JsonRecord = Record<string, unknown>;
|
|
|
|
export type GitLabDirectAccessDetails = {
|
|
token: string;
|
|
baseUrl: string;
|
|
expiresAt: string | null;
|
|
headers: Record<string, string>;
|
|
};
|
|
|
|
export const GITLAB_DUO_DEFAULT_BASE_URL =
|
|
process.env.GITLAB_DUO_BASE_URL || process.env.GITLAB_BASE_URL || "https://gitlab.com";
|
|
|
|
function asRecord(value: unknown): JsonRecord {
|
|
return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {};
|
|
}
|
|
|
|
export function normalizeGitLabBaseUrl(baseUrl?: unknown): string {
|
|
const raw = typeof baseUrl === "string" ? baseUrl.trim() : "";
|
|
return (raw || GITLAB_DUO_DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
}
|
|
|
|
export function resolveGitLabOAuthBaseUrl(providerSpecificData?: unknown): string {
|
|
const data = asRecord(providerSpecificData);
|
|
return normalizeGitLabBaseUrl(data.baseUrl);
|
|
}
|
|
|
|
export function buildGitLabOAuthEndpoints(baseUrl?: unknown) {
|
|
const root = normalizeGitLabBaseUrl(baseUrl);
|
|
return {
|
|
root,
|
|
authorizeUrl: `${root}/oauth/authorize`,
|
|
tokenUrl: `${root}/oauth/token`,
|
|
userUrl: `${root}/api/v4/user`,
|
|
directAccessUrl: `${root}/api/v4/code_suggestions/direct_access`,
|
|
publicCompletionsUrl: `${root}/api/v4/code_suggestions/completions`,
|
|
};
|
|
}
|
|
|
|
export function buildGitLabDirectGatewayUrl(baseUrl: string): string {
|
|
const normalized = normalizeGitLabBaseUrl(baseUrl);
|
|
if (normalized.endsWith("/ai/v2/completions")) {
|
|
return normalized;
|
|
}
|
|
if (normalized.endsWith("/ai/v2")) {
|
|
return `${normalized}/completions`;
|
|
}
|
|
return `${normalized}/ai/v2/completions`;
|
|
}
|
|
|
|
export function parseGitLabDirectAccessDetails(payload: unknown): GitLabDirectAccessDetails | null {
|
|
const data = asRecord(payload);
|
|
const token = typeof data.token === "string" ? data.token.trim() : "";
|
|
const baseUrl = typeof data.base_url === "string" ? data.base_url.trim() : "";
|
|
if (!token || !baseUrl) {
|
|
return null;
|
|
}
|
|
|
|
const rawHeaders = asRecord(data.headers);
|
|
const headers = Object.fromEntries(
|
|
Object.entries(rawHeaders).filter(
|
|
(entry): entry is [string, string] =>
|
|
typeof entry[0] === "string" && typeof entry[1] === "string"
|
|
)
|
|
);
|
|
|
|
const expiresAt =
|
|
typeof data.expires_at === "number" && Number.isFinite(data.expires_at)
|
|
? new Date(data.expires_at * 1000).toISOString()
|
|
: null;
|
|
|
|
return {
|
|
token,
|
|
baseUrl: normalizeGitLabBaseUrl(baseUrl),
|
|
expiresAt,
|
|
headers,
|
|
};
|
|
}
|
|
|
|
export function getCachedGitLabDirectAccess(
|
|
providerSpecificData?: unknown,
|
|
minValidityMs = 60_000
|
|
): GitLabDirectAccessDetails | null {
|
|
const data = asRecord(providerSpecificData);
|
|
const cache = data.gitlabDirectAccess ?? data.directAccessCache;
|
|
const parsed = parseGitLabDirectAccessDetails(cache);
|
|
if (!parsed) {
|
|
return null;
|
|
}
|
|
if (!parsed.expiresAt) {
|
|
return parsed;
|
|
}
|
|
|
|
const expiresAtMs = new Date(parsed.expiresAt).getTime();
|
|
if (!Number.isFinite(expiresAtMs) || expiresAtMs <= Date.now() + minValidityMs) {
|
|
return null;
|
|
}
|
|
|
|
return parsed;
|
|
}
|
|
|
|
export function isGitLabDirectAccessDisabled(status: number, bodyText: string): boolean {
|
|
return status === 403 && bodyText.toLowerCase().includes("direct connections are disabled");
|
|
}
|