Files
OmniRoute/src/shared/utils/providerFallbackColor.ts

42 lines
1.7 KiB
TypeScript

/**
* Deterministic fallback color for provider ids that are not present in the static
* AI_PROVIDERS registry — e.g. user-defined `openai-compatible-*` / `anthropic-compatible-*`
* providers backed by the `provider_nodes` table. Without this, every such custom provider
* rendered as the same anonymous gray node in the Topology view, indistinguishable from any
* other custom provider even though its label was already resolved correctly. See #8328.
*/
// Small palette of visually distinguishable, saturated colors — spread far enough apart in
// hue to stay distinguishable side-by-side on both light and dark topology backgrounds.
export const FALLBACK_COLOR_PALETTE: readonly string[] = [
"#0ea5e9", // sky
"#a855f7", // purple
"#f59e0b", // amber
"#10b981", // emerald
"#ec4899", // pink
"#6366f1", // indigo
"#14b8a6", // teal
"#f97316", // orange
];
/** FNV-1a hash — fast, deterministic, and well-distributed for short id strings. */
function hashProviderId(value: string): number {
let hash = 0x811c9dc5;
for (let i = 0; i < value.length; i++) {
hash ^= value.charCodeAt(i);
hash = Math.imul(hash, 0x01000193);
}
return hash >>> 0;
}
/**
* Returns a deterministic color for a provider id not present in the static AI_PROVIDERS
* registry: the same id always maps to the same palette entry, and different ids spread
* across the palette so distinct custom providers stay visually distinguishable.
*/
export function getFallbackProviderColor(providerId: string): string {
if (!providerId) return FALLBACK_COLOR_PALETTE[0];
const index = hashProviderId(providerId) % FALLBACK_COLOR_PALETTE.length;
return FALLBACK_COLOR_PALETTE[index];
}