UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

90 lines (80 loc) 3.08 kB
/** * Provider-agnostic transformers loader. * * ADR-094: prefer the maintained `@huggingface/transformers` (which * pulls in `protobufjs >=7.5.5` and clears the critical RCE CVE * chain), fall back to the legacy `@xenova/transformers` for * backwards compatibility with consumers who haven't installed the * new package yet. * * Both packages export the same `pipeline()` function with compatible * signatures for our usage (`pipeline('feature-extraction', modelId)`), * so callers can use the returned function transparently. The `source` * field is reported through `embeddings_status.ruvectorStatus` so * users can see which package satisfied the runtime. */ export type PipelineFn = ( task: string, model?: string, options?: Record<string, unknown>, ) => Promise<unknown>; export interface TransformersHandle { pipeline: PipelineFn; source: '@huggingface/transformers' | '@xenova/transformers'; version?: string; } let cached: TransformersHandle | null = null; let cacheChecked = false; /** * Load a working transformers pipeline. Returns null if neither * package is installed. Caches the first successful resolution so * subsequent calls don't re-import. */ export async function loadTransformersPipeline(): Promise<TransformersHandle | null> { if (cacheChecked) return cached; cacheChecked = true; // Use indirect import paths through string variables so TypeScript // doesn't try to resolve module types at compile time. Both packages // are runtime-optional; types aren't needed for the typed PipelineFn // signature we expose. const tryLoad = async (specifier: string): Promise<Record<string, unknown> | null> => { try { // Webpack/tsc can't statically resolve the specifier when it's a // variable, which is intentional here — we want runtime resolution // that gracefully fails if the package isn't installed. const mod = await import(/* @vite-ignore */ specifier); return mod as Record<string, unknown>; } catch { return null; } }; // Prefer the maintained successor. const hf = await tryLoad('@huggingface/transformers'); if (hf && typeof hf.pipeline === 'function') { cached = { pipeline: hf.pipeline as PipelineFn, source: '@huggingface/transformers', version: typeof hf.version === 'string' ? hf.version : undefined, }; return cached; } // Fall back to the legacy package so existing installs keep working. const xen = await tryLoad('@xenova/transformers'); if (xen && typeof xen.pipeline === 'function') { cached = { pipeline: xen.pipeline as PipelineFn, source: '@xenova/transformers', version: typeof xen.version === 'string' ? xen.version : undefined, }; return cached; } return null; } /** * Synchronous probe — returns whether either package was loaded * during a previous call to `loadTransformersPipeline()`. For status * tools that don't want to trigger a fresh import. */ export function getCachedTransformersSource(): TransformersHandle | null { return cached; }