mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-16 20:02:45 +03:00
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.
86 lines
2.9 KiB
TypeScript
86 lines
2.9 KiB
TypeScript
import { getUpstreamProxyConfig } from "@/lib/localDb";
|
|
import type { FallbackBackend } from "@/lib/db/upstreamProxy";
|
|
|
|
/**
|
|
* Module-level cache for upstream proxy config (shared across all requests).
|
|
* 10s TTL prevents per-request DB lookups while staying fresh enough for setting changes.
|
|
*/
|
|
type UpstreamProxyConfigCacheEntry = {
|
|
mode: string;
|
|
enabled: boolean;
|
|
cliproxyapiModelMapping: Record<string, unknown> | null;
|
|
// #dario: retry-leg backend when mode === "fallback".
|
|
fallbackBackend: FallbackBackend;
|
|
ts: number;
|
|
};
|
|
|
|
const _proxyConfigCache = new Map<string, UpstreamProxyConfigCacheEntry>();
|
|
const PROXY_CONFIG_CACHE_TTL = 10_000;
|
|
|
|
/**
|
|
* Module-level cache for all combos data (shared across all requests).
|
|
* Uses cached promises to prevent thundering herd — all concurrent callers
|
|
* wait for the same underlying DB query while it's in flight.
|
|
*/
|
|
let _combosPromise: Promise<unknown[]> | null = null;
|
|
let _combosCacheTs = 0;
|
|
let _combosCacheVersionSnapshot = -1;
|
|
const COMBOS_CACHE_TTL = 10_000;
|
|
|
|
export async function getCombosCached(): Promise<unknown[]> {
|
|
const now = Date.now();
|
|
const { getCombos, getCombosCacheVersion } = await import("@/lib/localDb");
|
|
const version = getCombosCacheVersion();
|
|
// A combo write (create/update/delete/reorder) bumps the shared version via
|
|
// invalidateDbCache("combos"); when it no longer matches our snapshot we drop
|
|
// the cached promise so the nested-combo expansion stops serving removed
|
|
// targets/models within the 10s TTL window (#3147).
|
|
if (version !== _combosCacheVersionSnapshot) {
|
|
clearCombosCache();
|
|
}
|
|
if (_combosPromise && now - _combosCacheTs < COMBOS_CACHE_TTL) {
|
|
return _combosPromise;
|
|
}
|
|
_combosCacheTs = now;
|
|
_combosCacheVersionSnapshot = version;
|
|
_combosPromise = getCombos();
|
|
return _combosPromise;
|
|
}
|
|
|
|
export function clearCombosCache() {
|
|
_combosPromise = null;
|
|
_combosCacheTs = 0;
|
|
_combosCacheVersionSnapshot = -1;
|
|
}
|
|
|
|
export function clearUpstreamProxyConfigCache(providerId?: string) {
|
|
if (providerId) {
|
|
_proxyConfigCache.delete(providerId);
|
|
return;
|
|
}
|
|
_proxyConfigCache.clear();
|
|
}
|
|
|
|
export async function getUpstreamProxyConfigCached(providerId: string) {
|
|
const cached = _proxyConfigCache.get(providerId);
|
|
if (cached && Date.now() - cached.ts < PROXY_CONFIG_CACHE_TTL) return cached;
|
|
const cfg = await getUpstreamProxyConfig(providerId).catch(() => null);
|
|
const result: UpstreamProxyConfigCacheEntry = cfg
|
|
? {
|
|
mode: cfg.mode,
|
|
enabled: cfg.enabled,
|
|
cliproxyapiModelMapping: cfg.cliproxyapiModelMapping ?? null,
|
|
fallbackBackend: cfg.fallbackBackend,
|
|
ts: Date.now(),
|
|
}
|
|
: {
|
|
mode: "native" as const,
|
|
enabled: false,
|
|
cliproxyapiModelMapping: null,
|
|
fallbackBackend: "cliproxyapi" as const,
|
|
ts: Date.now(),
|
|
};
|
|
_proxyConfigCache.set(providerId, result);
|
|
return result;
|
|
}
|