Files
OmniRoute/src/shared/utils/featureFlags.ts
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -03:00

142 lines
4.3 KiB
TypeScript

import { getFeatureFlagOverride } from "@/lib/db/featureFlags";
import {
FEATURE_FLAG_DEFINITIONS,
type FeatureFlagDefinition,
} from "@/shared/constants/featureFlagDefinitions";
/**
* Resolve the effective value of a feature flag.
* Priority: DB override > process.env > definition.defaultValue
*/
export function resolveFeatureFlag(key: string): string {
const dbOverride = getFeatureFlagOverride(key);
if (dbOverride !== undefined) return dbOverride;
const envValue = process.env[key];
if (envValue !== undefined && envValue !== "") return envValue;
const definition = FEATURE_FLAG_DEFINITIONS.find((d) => d.key === key);
return definition?.defaultValue ?? "false";
}
/**
* Check if a boolean feature flag is enabled.
* Treats "true", "1", "yes" as enabled.
*/
export function isFeatureFlagEnabled(key: string): boolean {
const value = resolveFeatureFlag(key);
return value === "true" || value === "1" || value === "yes";
}
/**
* Resolve all feature flags with their effective values and sources.
*/
export function resolveAllFeatureFlags(): Array<{
key: string;
effectiveValue: string;
source: "db" | "env" | "default";
definition: FeatureFlagDefinition;
}> {
return FEATURE_FLAG_DEFINITIONS.map((definition) => {
const dbOverride = getFeatureFlagOverride(definition.key);
if (dbOverride !== undefined) {
return { key: definition.key, effectiveValue: dbOverride, source: "db", definition };
}
const envValue = process.env[definition.key];
if (envValue !== undefined && envValue !== "") {
return { key: definition.key, effectiveValue: envValue, source: "env", definition };
}
return {
key: definition.key,
effectiveValue: definition.defaultValue,
source: "default",
definition,
};
});
}
// Backward-compatible wrappers
export function isRequireApiKeyEnabled(): boolean {
try {
return isFeatureFlagEnabled("REQUIRE_API_KEY");
} catch (error) {
console.error(
"[featureFlags] Failed to resolve REQUIRE_API_KEY, defaulting to required:",
error instanceof Error ? error.message : error
);
return true;
}
}
export function isCcCompatibleProviderEnabled(): boolean {
return isFeatureFlagEnabled("ENABLE_CC_COMPATIBLE_PROVIDER");
}
/**
* Context-window checks are fail-safe: an unavailable flag store must never
* silently disable local request bounds.
*/
export function areContextWindowChecksDisabled(): boolean {
try {
return isFeatureFlagEnabled("DISABLE_CONTEXT_WINDOW_CHECKS");
} catch (error) {
console.error(
"[featureFlags] Failed to resolve DISABLE_CONTEXT_WINDOW_CHECKS, keeping checks enabled:",
error instanceof Error ? error.message : error
);
return false;
}
}
export function isApiKeyRevealEnabledFlag(): boolean {
try {
return isFeatureFlagEnabled("ALLOW_API_KEY_REVEAL");
} catch (error) {
console.error(
"[featureFlags] Failed to resolve ALLOW_API_KEY_REVEAL, defaulting to disabled:",
error instanceof Error ? error.message : error
);
return false;
}
}
export function isModelCatalogNamesEnabled(): boolean {
return isFeatureFlagEnabled("MODEL_CATALOG_INCLUDE_NAMES");
}
export type ModelsCatalogPrefixMode = "dual" | "alias" | "canonical";
export function getModelsCatalogPrefixMode(): ModelsCatalogPrefixMode {
const value = resolveFeatureFlag("MODELS_CATALOG_PREFIX_MODE");
if (value === "alias" || value === "canonical") return value;
return "dual";
}
export function isArenaEloSyncEnabled(): boolean {
return isFeatureFlagEnabled("ARENA_ELO_SYNC_ENABLED");
}
export function isControlPlaneProxyDirectFallbackEnabled(): boolean {
try {
return isFeatureFlagEnabled("OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK");
} catch (error) {
console.error(
"[featureFlags] Failed to resolve OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK, defaulting to disabled:",
error instanceof Error ? error.message : error
);
return false;
}
}
export function isNetworkRotationSharedEgressGuardEnabled(): boolean {
try {
return isFeatureFlagEnabled("NETWORK_ROTATION_SHARED_EGRESS_GUARD");
} catch (error) {
console.error(
"[featureFlags] Failed to resolve NETWORK_ROTATION_SHARED_EGRESS_GUARD, defaulting to enabled:",
error instanceof Error ? error.message : error
);
return true;
}
}