mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-15 11:22:15 +03:00
Validado em lote numa worktree combinada com os 9 PRs desta leva sobre o tip de `release/v3.8.51`: `typecheck:core` limpo, `check:provider-consistency` OK (273 entradas REGISTRY, **356** providers canônicos), `check-docs-counts-sync` exit 0 e **300/300** nos testes que a leva toca. O crescimento de arquivo que os PRs empilham uns sobre os outros foi rebaselinado num único registro datado (`_rebaseline_2026_09_03_houminxi_batch`), com a decomposição por arquivo: `providers/page.tsx` +18 (import CSV do #12504 + busca do #12495 no mesmo painel), `accountFallback.ts` +6 (o #12566 sobre o rebaseline que o #12590 já registrou — os dois tocam `checkFallbackError`) e `chatCore.ts` +3 (invalidez de cache de quota no 429 do #12325). As violações restantes (`codex.ts`, `stream.ts`) foram medidas também no tip puro e são drift da base, não desta leva.
77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
/**
|
|
* Moonshot Open Platform host recognition.
|
|
*
|
|
* Distinguishes prepaid Open Platform keys (api.moonshot.cn / api.moonshot.ai)
|
|
* from Kimi Coding Plan (api.kimi.com/coding). Custom compatible nodes are
|
|
* identified by baseUrl host, not by provider id (those ids are uuids).
|
|
*/
|
|
|
|
import { moonshotProvider } from "../../config/providers/registry/moonshot/index.ts";
|
|
import { kimiProvider } from "../../config/providers/registry/kimi/index.ts";
|
|
|
|
export const MOONSHOT_OPEN_PLATFORM_HOSTS: ReadonlySet<string> = new Set([
|
|
"api.moonshot.cn",
|
|
"api.moonshot.ai",
|
|
]);
|
|
|
|
export type MoonshotOriginConnection = {
|
|
provider?: string;
|
|
providerSpecificData?: unknown;
|
|
};
|
|
|
|
function asRecord(value: unknown): Record<string, unknown> {
|
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
? (value as Record<string, unknown>)
|
|
: {};
|
|
}
|
|
|
|
export function parseMoonshotOrigin(baseUrl: string | null | undefined): string | null {
|
|
if (typeof baseUrl !== "string" || baseUrl.trim() === "") return null;
|
|
let url: URL;
|
|
try {
|
|
url = new URL(baseUrl.trim());
|
|
} catch {
|
|
return null;
|
|
}
|
|
if (url.protocol !== "https:" && url.protocol !== "http:") return null;
|
|
const host = url.hostname.toLowerCase();
|
|
if (!MOONSHOT_OPEN_PLATFORM_HOSTS.has(host)) return null;
|
|
const port = url.port ? `:${url.port}` : "";
|
|
return `${url.protocol}//${host}${port}`;
|
|
}
|
|
|
|
export function moonshotBalanceUrl(origin: string): string {
|
|
return `${origin}/v1/users/me/balance`;
|
|
}
|
|
|
|
function registryDefaultOrigin(provider: string | undefined): string | null {
|
|
if (provider === "moonshot") return parseMoonshotOrigin(moonshotProvider.baseUrl);
|
|
if (provider === "kimi") return parseMoonshotOrigin(kimiProvider.baseUrl);
|
|
return null;
|
|
}
|
|
|
|
export function resolveMoonshotOrigin(
|
|
connection: MoonshotOriginConnection,
|
|
nodeBaseUrl?: string | null,
|
|
): string | null {
|
|
const psd = asRecord(connection.providerSpecificData);
|
|
const fromPsd = typeof psd.baseUrl === "string" ? parseMoonshotOrigin(psd.baseUrl) : null;
|
|
if (fromPsd) return fromPsd;
|
|
const fromNode = parseMoonshotOrigin(nodeBaseUrl);
|
|
if (fromNode) return fromNode;
|
|
return registryDefaultOrigin(connection.provider);
|
|
}
|
|
|
|
export function isMoonshotOpenPlatformConnection(
|
|
connection: MoonshotOriginConnection,
|
|
nodeBaseUrl?: string | null,
|
|
): boolean {
|
|
return resolveMoonshotOrigin(connection, nodeBaseUrl) !== null;
|
|
}
|
|
|
|
/** Account-level empty wallet on Open Platform. Narrower than any compatible 429. */
|
|
export function isMoonshotAccountBalanceExhausted(errorText: string | null | undefined): boolean {
|
|
const lower = String(errorText || "").toLowerCase();
|
|
return lower.includes("insufficient balance") || lower.includes("exceeded_current_quota");
|
|
}
|