ngx-transformers 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-transformers.mjs","sources":["../../../projects/ngx-transformers/src/lib/transformers.providers.ts","../../../projects/ngx-transformers/src/lib/device-detection.ts","../../../projects/ngx-transformers/src/lib/pipeline.ts","../../../projects/ngx-transformers/src/lib/text-classifier.ts","../../../projects/ngx-transformers/src/lib/text-embedder.ts","../../../projects/ngx-transformers/src/lib/speech-recognizer.ts","../../../projects/ngx-transformers/src/lib/zero-shot-classifier.ts","../../../projects/ngx-transformers/src/lib/translator.ts","../../../projects/ngx-transformers/src/lib/mic-recorder.ts","../../../projects/ngx-transformers/src/lib/model-progress.component.ts","../../../projects/ngx-transformers/src/public-api.ts","../../../projects/ngx-transformers/src/ngx-transformers.ts"],"sourcesContent":["import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport type { NgxTransformersConfig } from './transformers.models';\n\n/**\n * The callable returned by Transformers.js pipeline(), reduced to the\n * surface this library relies on.\n */\nexport type PipelineLike = ((input: unknown, options?: Record<string, unknown>) => Promise<unknown>) & {\n dispose?: () => Promise<void>;\n};\n\n/**\n * Creates a pipeline for a task. The default implementation lazy-imports\n * @huggingface/transformers; tests and SSR shims can provide their own.\n */\nexport type PipelineFactory = (\n task: string,\n model: string | undefined,\n options: Record<string, unknown>,\n) => Promise<PipelineLike>;\n\nconst defaultPipelineFactory: PipelineFactory = async (task, model, options) => {\n const { pipeline } = await import('@huggingface/transformers');\n const pipe = await (pipeline as (t: string, m?: string, o?: object) => Promise<unknown>)(\n task,\n model,\n options,\n );\n return pipe as PipelineLike;\n};\n\nexport const PIPELINE_FACTORY = new InjectionToken<PipelineFactory>('ngx-transformers.pipeline-factory', {\n providedIn: 'root',\n factory: () => defaultPipelineFactory,\n});\n\nexport const NGX_TRANSFORMERS_CONFIG = new InjectionToken<NgxTransformersConfig>('ngx-transformers.config', {\n providedIn: 'root',\n factory: () => ({}),\n});\n\n/**\n * Sets workspace-wide defaults (device, dtype, extra pipeline options):\n *\n * ```ts\n * bootstrapApplication(App, {\n * providers: [provideTransformers({ device: 'webgpu', dtype: 'q8' })],\n * });\n * ```\n */\nexport function provideTransformers(config: NgxTransformersConfig): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: NGX_TRANSFORMERS_CONFIG, useValue: config }]);\n}\n","/** The slice of navigator.gpu we probe; the WebGPU lib types are not in every project's tsconfig. */\ninterface GpuLike {\n requestAdapter(): Promise<unknown | null>;\n}\n\nlet webGpuProbe: Promise<boolean> | null = null;\n\n/**\n * Whether models can run on WebGPU here: `navigator.gpu` exists AND\n * `requestAdapter()` hands back an adapter - it returns null on machines\n * without a usable GPU or with WebGPU disabled, even when the API exists.\n * Resolves false on the server. The probe runs once and is cached.\n */\nexport function hasWebGpu(): Promise<boolean> {\n webGpuProbe ??= probeWebGpu();\n return webGpuProbe;\n}\n\n/** `'webgpu'` when hasWebGpu() resolves true, else `'wasm'`. */\nexport async function detectDevice(): Promise<'webgpu' | 'wasm'> {\n return (await hasWebGpu()) ? 'webgpu' : 'wasm';\n}\n\n/** Forgets the cached probe so the next hasWebGpu() asks the browser again. */\nexport function resetDeviceDetection(): void {\n webGpuProbe = null;\n}\n\nasync function probeWebGpu(): Promise<boolean> {\n const gpu = (globalThis as { navigator?: { gpu?: GpuLike } }).navigator?.gpu;\n if (!gpu) return false;\n try {\n return (await gpu.requestAdapter()) !== null;\n } catch {\n return false;\n }\n}\n","import { DestroyRef, computed, inject, signal } from '@angular/core';\nimport { detectDevice } from './device-detection';\nimport type { ModelProgress, NgxTransformersConfig, PipelineRequest, PipelineStatus, TransformersDevice } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY, type PipelineFactory, type PipelineLike } from './transformers.providers';\n\n/** Shape of Transformers.js progress_callback events (subset we consume). */\ninterface RawProgressEvent {\n status?: string;\n file?: string;\n progress?: number;\n loaded?: number;\n total?: number;\n}\n\n/**\n * A lazily-loaded Transformers.js pipeline wrapped in signals.\n *\n * The model is not downloaded until load() or the first run() call, so\n * creating handles is free. All state is exposed as signals and safe to\n * bind in zoneless apps.\n */\nexport class PipelineHandle<TIn = unknown, TOut = unknown> {\n /** idle -> loading -> ready <-> busy; error only on load failure. */\n readonly status = signal<PipelineStatus>('idle');\n /** Download progress for the file currently transferring, else null. */\n readonly progress = signal<ModelProgress | null>(null);\n readonly error = signal<unknown>(null);\n /** True once the model is usable (including while a run is in flight). */\n readonly ready = computed(() => this.status() === 'ready' || this.status() === 'busy');\n readonly busy = computed(() => this.status() === 'busy' || this.status() === 'loading');\n\n private pipe: PipelineLike | null = null;\n private loading: Promise<void> | null = null;\n\n constructor(\n private readonly request: PipelineRequest,\n private readonly factory: PipelineFactory,\n private readonly config: NgxTransformersConfig,\n ) {}\n\n /** Downloads and initializes the model. Idempotent; retries after error. */\n load(): Promise<void> {\n if (this.pipe) return Promise.resolve();\n this.loading ??= this.doLoad().finally(() => (this.loading = null));\n return this.loading;\n }\n\n /** Runs the pipeline, loading the model first if needed. */\n run(input: TIn, runOptions?: Record<string, unknown>): Promise<TOut> {\n return this.runWith(input, runOptions);\n }\n\n /**\n * Runs the pipeline with extra positional arguments after the input, for\n * tasks whose pipeline signature is not (input, options): zero-shot\n * classification takes (text, candidateLabels, options).\n */\n protected async runWith(input: TIn, ...extraArgs: unknown[]): Promise<TOut> {\n await this.load();\n this.status.set('busy');\n try {\n const pipe = this.pipe! as (...args: unknown[]) => Promise<unknown>;\n return (await pipe(input, ...extraArgs)) as TOut;\n } finally {\n // A failed run leaves the model intact - back to ready either way.\n this.status.set('ready');\n }\n }\n\n /** Frees the model. The handle can be loaded again afterwards. */\n async dispose(): Promise<void> {\n const pipe = this.pipe;\n this.pipe = null;\n this.status.set('idle');\n this.progress.set(null);\n await pipe?.dispose?.();\n }\n\n private async doLoad(): Promise<void> {\n this.status.set('loading');\n this.error.set(null);\n const options: Record<string, unknown> = {\n ...this.config.pipelineOptions,\n ...this.request.options,\n progress_callback: (event: RawProgressEvent) => this.onProgress(event),\n };\n const device = await this.resolveDevice();\n const dtype = this.request.dtype ?? this.config.dtype;\n if (device && device !== 'auto') options['device'] = device;\n if (dtype) options['dtype'] = dtype;\n\n try {\n this.pipe = await this.factory(this.request.task, this.request.model, options);\n this.progress.set(null);\n this.status.set('ready');\n } catch (err) {\n this.error.set(err);\n this.status.set('error');\n throw err;\n }\n }\n\n /**\n * An explicit request or global device wins; with `autoDevice` on, an\n * unset or 'auto' device is probed for WebGPU (once, cached) at load time.\n */\n private async resolveDevice(): Promise<TransformersDevice | undefined> {\n const configured = this.request.device ?? this.config.device;\n if (configured && configured !== 'auto') return configured;\n return this.config.autoDevice ? detectDevice() : configured;\n }\n\n private onProgress(event: RawProgressEvent): void {\n if (event.status !== 'progress' || !event.file) return;\n this.progress.set({\n file: event.file,\n progress: Math.round(event.progress ?? 0),\n loadedBytes: event.loaded ?? 0,\n totalBytes: event.total ?? 0,\n });\n }\n}\n\n/**\n * Creates a PipelineHandle in an injection context (constructor, field\n * initializer, or runInInjectionContext). The handle is disposed with the\n * surrounding component/injector.\n */\nexport function createPipeline<TIn = unknown, TOut = unknown>(request: PipelineRequest): PipelineHandle<TIn, TOut> {\n const handle = new PipelineHandle<TIn, TOut>(\n request,\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void handle.dispose());\n return handle;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { ClassificationResult, PipelineRequest } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\nexport const DEFAULT_TEXT_CLASSIFICATION_MODEL = 'Xenova/distilbert-base-uncased-finetuned-sst-2-english';\n\n/**\n * Text classification (sentiment by default). The default model is\n * DistilBERT SST-2 (~65 MB, q8) - swap `model` for any Transformers.js\n * compatible text-classification checkpoint.\n */\nexport class TextClassifier extends PipelineHandle<string, ClassificationResult[] | ClassificationResult[][]> {\n /** Classifies one text; resolves to labels sorted by score (top first). */\n async classify(text: string, topK = 1): Promise<ClassificationResult[]> {\n const out = await this.run(text, { top_k: topK });\n // Single input: transformers.js returns a flat array of {label, score}.\n const flat = (Array.isArray(out[0]) ? out[0] : out) as ClassificationResult[];\n return [...flat].sort((a, b) => b.score - a.score);\n }\n}\n\n/** Creates a TextClassifier in an injection context. */\nexport function createTextClassifier(options: Partial<Omit<PipelineRequest, 'task'>> = {}): TextClassifier {\n const classifier = new TextClassifier(\n { task: 'text-classification', model: DEFAULT_TEXT_CLASSIFICATION_MODEL, ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void classifier.dispose());\n return classifier;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { PipelineRequest, RankedResult } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\nexport const DEFAULT_EMBEDDING_MODEL = 'Xenova/all-MiniLM-L6-v2';\n\n/** Tensor-ish output of feature-extraction: enough shape to read rows. */\ninterface TensorLike {\n dims: number[];\n data: ArrayLike<number>;\n tolist?: () => number[][];\n}\n\n/** Cosine similarity of two vectors. For normalized vectors this is the dot product. */\nexport function cosineSimilarity(a: readonly number[], b: readonly number[]): number {\n if (a.length !== b.length || a.length === 0) {\n throw new Error(`cosineSimilarity: incompatible lengths ${a.length} and ${b.length}`);\n }\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n\n/**\n * Sentence embeddings via feature-extraction (all-MiniLM-L6-v2 by default,\n * ~23 MB q8). Outputs mean-pooled, L2-normalized vectors ready for cosine\n * similarity / semantic search.\n */\nexport class TextEmbedder extends PipelineHandle<string | string[], TensorLike> {\n /** Embeds one or many texts; always resolves to one vector per text. */\n async embed(texts: string | string[]): Promise<number[][]> {\n const input = Array.isArray(texts) ? texts : [texts];\n if (input.length === 0) return [];\n const out = await this.run(input, { pooling: 'mean', normalize: true });\n return toRows(out);\n }\n\n /** Cosine similarity of two texts in [-1, 1]. */\n async similarity(a: string, b: string): Promise<number> {\n const [va, vb] = await this.embed([a, b]);\n return cosineSimilarity(va, vb);\n }\n\n /** Ranks documents against a query, most similar first. */\n async rank(query: string, documents: string[]): Promise<RankedResult[]> {\n if (documents.length === 0) return [];\n const [queryVec, ...docVecs] = await this.embed([query, ...documents]);\n return docVecs\n .map((vec, index) => ({ text: documents[index], score: cosineSimilarity(queryVec, vec), index }))\n .sort((a, b) => b.score - a.score);\n }\n}\n\nfunction toRows(out: TensorLike): number[][] {\n if (typeof out.tolist === 'function') return out.tolist();\n const [rows, cols] = out.dims.length === 2 ? out.dims : [1, out.dims[out.dims.length - 1]];\n const data = out.data;\n const result: number[][] = [];\n for (let r = 0; r < rows; r++) {\n result.push(Array.from({ length: cols }, (_, c) => data[r * cols + c]));\n }\n return result;\n}\n\n/** Creates a TextEmbedder in an injection context. */\nexport function createTextEmbedder(options: Partial<Omit<PipelineRequest, 'task'>> = {}): TextEmbedder {\n const embedder = new TextEmbedder(\n { task: 'feature-extraction', model: DEFAULT_EMBEDDING_MODEL, ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void embedder.dispose());\n return embedder;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { PipelineRequest, TranscribeOptions, Transcription, TranscriptionChunk } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\n// onnx-community, not the legacy Xenova export: the old ONNX decoder lacks\n// the quantization scales transformers.js v4's runtime requires.\nexport const DEFAULT_ASR_MODEL = 'onnx-community/whisper-tiny.en';\n\n/** Whisper expects 16 kHz mono float PCM. */\nexport const WHISPER_SAMPLE_RATE = 16000;\n\n/** Raw ASR pipeline output (subset we consume). */\ninterface RawTranscription {\n text?: string;\n chunks?: { text: string; timestamp?: [number | null, number | null] }[];\n}\n\n/**\n * Decodes an encoded audio file (wav/mp3/webm/ogg - anything the browser\n * can decode) to 16 kHz mono Float32Array, ready for Whisper. Browser-only:\n * uses AudioContext with a target sample rate, which resamples on decode.\n */\nexport async function decodeAudio(\n source: Blob | ArrayBuffer,\n targetSampleRate = WHISPER_SAMPLE_RATE,\n): Promise<Float32Array> {\n const AudioContextCtor = (globalThis as { AudioContext?: typeof AudioContext }).AudioContext;\n if (!AudioContextCtor) {\n throw new Error('decodeAudio requires a browser AudioContext (not available in this environment).');\n }\n const buffer = source instanceof Blob ? await source.arrayBuffer() : source;\n const ctx = new AudioContextCtor({ sampleRate: targetSampleRate });\n try {\n const decoded = await ctx.decodeAudioData(buffer);\n if (decoded.numberOfChannels === 1) return decoded.getChannelData(0);\n // Mix down to mono by averaging channels.\n const left = decoded.getChannelData(0);\n const right = decoded.getChannelData(1);\n const mono = new Float32Array(left.length);\n for (let i = 0; i < left.length; i++) mono[i] = (left[i] + right[i]) / 2;\n return mono;\n } finally {\n await ctx.close();\n }\n}\n\n/**\n * Speech-to-text via Whisper. The default checkpoint is whisper-tiny.en\n * (~41 MB q8, English-only); swap `model` for a multilingual or larger one\n * (e.g. Xenova/whisper-small).\n */\nexport class SpeechRecognizer extends PipelineHandle<string | Float32Array, RawTranscription | RawTranscription[]> {\n /**\n * Transcribes audio: a URL, a decoded 16 kHz Float32Array, or an encoded\n * Blob/ArrayBuffer (decoded via decodeAudio first - browser-only).\n */\n async transcribe(\n audio: string | Float32Array | Blob | ArrayBuffer,\n options: TranscribeOptions = {},\n ): Promise<Transcription> {\n const input =\n audio instanceof Blob || audio instanceof ArrayBuffer ? await decodeAudio(audio) : audio;\n\n const runOptions: Record<string, unknown> = {};\n if (options.returnTimestamps !== undefined) runOptions['return_timestamps'] = options.returnTimestamps;\n if (options.chunkLengthS !== undefined) runOptions['chunk_length_s'] = options.chunkLengthS;\n if (options.strideLengthS !== undefined) runOptions['stride_length_s'] = options.strideLengthS;\n if (options.language !== undefined) runOptions['language'] = options.language;\n if (options.task !== undefined) runOptions['task'] = options.task;\n\n const raw = await this.run(input, runOptions);\n const first = (Array.isArray(raw) ? raw[0] : raw) ?? {};\n const chunks: TranscriptionChunk[] | undefined = first.chunks?.map((c) => ({\n text: c.text,\n start: c.timestamp?.[0] ?? null,\n end: c.timestamp?.[1] ?? null,\n }));\n return { text: (first.text ?? '').trim(), ...(chunks ? { chunks } : {}) };\n }\n}\n\n/**\n * Creates a SpeechRecognizer in an injection context.\n *\n * dtype defaults to 'q4' (not the library-wide default): q8 Whisper\n * decoders fail session creation on the v4 WASM runtime\n * (huggingface/transformers.js#1707), while q4 loads and runs everywhere.\n */\nexport function createSpeechRecognizer(options: Partial<Omit<PipelineRequest, 'task'>> = {}): SpeechRecognizer {\n const recognizer = new SpeechRecognizer(\n { task: 'automatic-speech-recognition', model: DEFAULT_ASR_MODEL, dtype: 'q4', ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void recognizer.dispose());\n return recognizer;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { ClassificationResult, PipelineRequest, ZeroShotOptions } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\n// The Transformers.js docs example for this task and the smallest MNLI\n// checkpoint that behaves well on the WASM runtime (~26 MB q8).\nexport const DEFAULT_ZERO_SHOT_MODEL = 'Xenova/mobilebert-uncased-mnli';\n\n/** Raw zero-shot output: labels ordered by score, scores aligned by index. */\ninterface RawZeroShotResult {\n sequence: string;\n labels: string[];\n scores: number[];\n}\n\n/**\n * Zero-shot classification: score any labels you name against a text with\n * an NLI model, no fine-tuning. The default checkpoint is MobileBERT MNLI\n * (~26 MB q8); Xenova/distilbert-base-uncased-mnli (~80 MB) is the\n * higher-accuracy alternative.\n */\nexport class ZeroShotClassifier extends PipelineHandle<string, RawZeroShotResult | RawZeroShotResult[]> {\n /**\n * Scores each candidate label for one text; resolves sorted by score (top\n * first). Single-label mode (default) normalizes across labels so scores\n * sum to 1; `multiLabel` scores each label on its own.\n */\n async classify(text: string, labels: readonly string[], options: ZeroShotOptions = {}): Promise<ClassificationResult[]> {\n if (labels.length === 0) return [];\n const runOptions: Record<string, unknown> = {};\n if (options.multiLabel !== undefined) runOptions['multi_label'] = options.multiLabel;\n if (options.hypothesisTemplate !== undefined) runOptions['hypothesis_template'] = options.hypothesisTemplate;\n\n const raw = await this.runWith(text, [...labels], runOptions);\n const first = Array.isArray(raw) ? raw[0] : raw;\n const scoredLabels = first?.labels ?? [];\n const scores = first?.scores ?? [];\n return scoredLabels\n .map((label, index) => ({ label, score: scores[index] ?? 0 }))\n .sort((left, right) => right.score - left.score);\n }\n}\n\n/** Creates a ZeroShotClassifier in an injection context. */\nexport function createZeroShotClassifier(options: Partial<Omit<PipelineRequest, 'task'>> = {}): ZeroShotClassifier {\n const classifier = new ZeroShotClassifier(\n { task: 'zero-shot-classification', model: DEFAULT_ZERO_SHOT_MODEL, ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void classifier.dispose());\n return classifier;\n}\n","import { DestroyRef, computed, inject, signal } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { NgxTransformersConfig, TranslateOptions, TranslatorOptions } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY, type PipelineFactory } from './transformers.providers';\n\n/**\n * Default checkpoint for a language pair: Helsinki-NLP's Marian opus-mt\n * models, one per direction, ~105 MB q8 each (e.g. Xenova/opus-mt-en-ru).\n */\nexport function defaultTranslationModel(from: string, to: string): string {\n return `Xenova/opus-mt-${from}-${to}`;\n}\n\n/** Checkpoint for a pair: provideTransformers({ translationModels }) first, then opus-mt. */\nexport function resolveTranslationModel(from: string, to: string, config: NgxTransformersConfig): string {\n return config.translationModels?.[`${from}-${to}`] ?? defaultTranslationModel(from, to);\n}\n\n/**\n * Multilingual families take the pair per call as src_lang / tgt_lang;\n * Marian opus-mt checkpoints translate one fixed direction and ignore them.\n */\nconst MULTILINGUAL_MODEL_PATTERN = /nllb|m2m[_-]?100|mbart|madlad/i;\n\n/** Raw translation pipeline output, one entry per input text. */\ninterface RawTranslation {\n translation_text?: string;\n}\n\nexport type TranslationHandle = PipelineHandle<string, RawTranslation | RawTranslation[]>;\n\n/**\n * Text translation. Pipelines are created lazily, one per checkpoint: with\n * the default opus-mt family every language pair is its own model, so a\n * Translator holds one handle per pair it has been asked for, while a\n * pinned multilingual `model` (NLLB, M2M100) serves every pair from one.\n *\n * The signals mirror the handle used by the most recent call, so a single\n * `<ngx-model-progress>` covers the translator.\n */\nexport class Translator {\n private readonly active = signal<TranslationHandle | null>(null);\n private readonly handles = new Map<string, TranslationHandle>();\n\n readonly status = computed(() => this.active()?.status() ?? 'idle');\n readonly progress = computed(() => this.active()?.progress() ?? null);\n readonly error = computed(() => this.active()?.error() ?? null);\n readonly ready = computed(() => this.active()?.ready() ?? false);\n readonly busy = computed(() => this.active()?.busy() ?? false);\n\n constructor(\n private readonly options: TranslatorOptions,\n private readonly factory: PipelineFactory,\n private readonly config: NgxTransformersConfig,\n ) {}\n\n /** Downloads the model for a pair ahead of the first translate() call. */\n load(pair: TranslateOptions = {}): Promise<void> {\n return this.handleFor(pair).load();\n }\n\n /** Translates one text; the pair defaults to the one given at creation. */\n async translate(text: string, pair: TranslateOptions = {}): Promise<string> {\n const handle = this.handleFor(pair);\n const raw = await handle.run(text, this.languageOptions(pair));\n const first = Array.isArray(raw) ? raw[0] : raw;\n return (first?.translation_text ?? '').trim();\n }\n\n /** Checkpoint for a pair: the pinned model, else the configured or default one. */\n modelFor(pair: TranslateOptions = {}): string {\n if (this.options.model) return this.options.model;\n const from = pair.from ?? this.options.from;\n const to = pair.to ?? this.options.to;\n if (!from || !to) {\n throw new Error(\n 'Translator: no language pair - pass { from, to } to createTranslator() or translate(), or pin a multilingual model.',\n );\n }\n return resolveTranslationModel(from, to, this.config);\n }\n\n /**\n * The handle serving a pair, created on first use. Exposed for apps that\n * keep several pairs warm and want a progress line per model.\n */\n handleFor(pair: TranslateOptions = {}): TranslationHandle {\n const model = this.modelFor(pair);\n let handle = this.handles.get(model);\n if (!handle) {\n handle = new PipelineHandle(\n { task: 'translation', model, device: this.options.device, dtype: this.options.dtype, options: this.options.options },\n this.factory,\n this.config,\n );\n this.handles.set(model, handle);\n }\n this.active.set(handle);\n return handle;\n }\n\n /** Frees every model. The translator can be used again afterwards. */\n async dispose(): Promise<void> {\n const handles = [...this.handles.values()];\n this.handles.clear();\n this.active.set(null);\n await Promise.all(handles.map((handle) => handle.dispose()));\n }\n\n /** src_lang / tgt_lang for multilingual checkpoints; opus-mt models get nothing. */\n private languageOptions(pair: TranslateOptions): Record<string, unknown> {\n const runOptions: Record<string, unknown> = {};\n if (!MULTILINGUAL_MODEL_PATTERN.test(this.modelFor(pair))) return runOptions;\n const from = pair.from ?? this.options.from;\n const to = pair.to ?? this.options.to;\n if (from !== undefined) runOptions['src_lang'] = from;\n if (to !== undefined) runOptions['tgt_lang'] = to;\n return runOptions;\n }\n}\n\n/** Creates a Translator in an injection context. */\nexport function createTranslator(options: TranslatorOptions = {}): Translator {\n const translator = new Translator(options, inject(PIPELINE_FACTORY), inject(NGX_TRANSFORMERS_CONFIG));\n inject(DestroyRef, { optional: true })?.onDestroy(() => void translator.dispose());\n return translator;\n}\n","import { DestroyRef, inject, signal } from '@angular/core';\n\n/** Minimal recorder surface - lets tests (and exotic runtimes) inject fakes. */\nexport interface RecorderLike {\n start(): void;\n stop(): void;\n ondataavailable: ((event: { data: Blob }) => void) | null;\n onstop: (() => void) | null;\n mimeType?: string;\n}\n\nexport interface MicRecorderDeps {\n /** Defaults to navigator.mediaDevices.getUserMedia({ audio: true }). */\n getUserMedia?: () => Promise<MediaStream>;\n /** Defaults to new MediaRecorder(stream). */\n createRecorder?: (stream: MediaStream) => RecorderLike;\n}\n\n/**\n * Microphone capture with a signals API. start() asks for mic permission\n * and records; stop() resolves with the encoded audio Blob - pass it to\n * SpeechRecognizer.transcribe(). Browser-only.\n *\n * ```ts\n * readonly mic = createMicRecorder();\n * readonly whisper = createSpeechRecognizer();\n *\n * async toggle() {\n * if (this.mic.recording()) {\n * const audio = await this.mic.stop();\n * const { text } = await this.whisper.transcribe(audio);\n * } else {\n * await this.mic.start();\n * }\n * }\n * ```\n */\nexport class MicRecorder {\n readonly recording = signal(false);\n /** Elapsed recording time in whole seconds. */\n readonly seconds = signal(0);\n readonly error = signal<unknown>(null);\n\n private stream: MediaStream | null = null;\n private recorder: RecorderLike | null = null;\n private chunks: Blob[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(private readonly deps: MicRecorderDeps = {}) {}\n\n /** Requests the microphone and starts recording. No-op while recording. */\n async start(): Promise<void> {\n if (this.recording()) return;\n this.error.set(null);\n try {\n this.stream = await (this.deps.getUserMedia\n ? this.deps.getUserMedia()\n : navigator.mediaDevices.getUserMedia({ audio: true }));\n this.recorder = this.deps.createRecorder\n ? this.deps.createRecorder(this.stream)\n : (new MediaRecorder(this.stream) as unknown as RecorderLike);\n this.chunks = [];\n this.recorder.ondataavailable = (event) => {\n if (event.data.size > 0) this.chunks.push(event.data);\n };\n this.recorder.start();\n this.recording.set(true);\n this.seconds.set(0);\n this.timer = setInterval(() => this.seconds.set(this.seconds() + 1), 1000);\n } catch (err) {\n this.error.set(err);\n this.cleanup();\n throw err;\n }\n }\n\n /** Stops recording and resolves with the captured audio. */\n stop(): Promise<Blob> {\n const recorder = this.recorder;\n if (!recorder || !this.recording()) {\n return Promise.reject(new Error('MicRecorder.stop() called while not recording.'));\n }\n return new Promise<Blob>((resolve) => {\n recorder.onstop = () => {\n const blob = new Blob(this.chunks, { type: recorder.mimeType || 'audio/webm' });\n this.cleanup();\n resolve(blob);\n };\n recorder.stop();\n });\n }\n\n /** Stops tracks and timers without resolving audio (e.g. on destroy). */\n dispose(): void {\n this.cleanup();\n }\n\n private cleanup(): void {\n if (this.timer !== null) clearInterval(this.timer);\n this.timer = null;\n this.stream?.getTracks().forEach((track) => track.stop());\n this.stream = null;\n this.recorder = null;\n this.recording.set(false);\n }\n}\n\n/** Creates a MicRecorder in an injection context; disposed with the component. */\nexport function createMicRecorder(deps: MicRecorderDeps = {}): MicRecorder {\n const recorder = new MicRecorder(deps);\n inject(DestroyRef, { optional: true })?.onDestroy(() => recorder.dispose());\n return recorder;\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport type { ModelProgress, PipelineStatus } from './transformers.models';\n\n/**\n * Drop-in status line for a PipelineHandle: shows model download progress\n * while loading, then the ready/busy/error state. Themeable via CSS custom\n * properties (--nt-accent, --nt-ink, --nt-muted, --nt-track).\n *\n * ```html\n * <ngx-model-progress [status]=\"classifier.status()\" [progress]=\"classifier.progress()\" />\n * ```\n */\n@Component({\n selector: 'ngx-model-progress',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"nt-row\" [class.nt-error]=\"status() === 'error'\" role=\"status\">\n <span class=\"nt-dot\" [attr.data-status]=\"status()\"></span>\n <span class=\"nt-label\">{{ label() }}</span>\n @if (status() === 'loading' && progress(); as p) {\n <span class=\"nt-file\">{{ p.file }}</span>\n <div class=\"nt-track\" role=\"progressbar\" [attr.aria-valuenow]=\"p.progress\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n <div class=\"nt-fill\" [style.width.%]=\"p.progress\"></div>\n </div>\n <span class=\"nt-pct\">{{ p.progress }}%</span>\n }\n </div>\n `,\n styles: `\n :host {\n --nt-accent: #f59e0b;\n --nt-ink: #1e293b;\n --nt-muted: #64748b;\n --nt-track: #e2e8f0;\n display: block;\n font-size: 12.5px;\n color: var(--nt-ink);\n }\n .nt-row { display: flex; align-items: center; gap: 8px; }\n .nt-dot {\n width: 8px; height: 8px; border-radius: 50%; flex: none;\n background: var(--nt-muted);\n }\n .nt-dot[data-status='loading'] { background: var(--nt-accent); animation: nt-blink 1s ease-in-out infinite; }\n .nt-dot[data-status='ready'] { background: #22c55e; }\n .nt-dot[data-status='busy'] { background: #3b82f6; animation: nt-blink 0.7s ease-in-out infinite; }\n .nt-dot[data-status='error'] { background: #dc2626; }\n .nt-label { font-weight: 600; }\n .nt-file { color: var(--nt-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }\n .nt-track {\n flex: 1; min-width: 60px; height: 6px; border-radius: 3px;\n background: var(--nt-track); overflow: hidden;\n }\n .nt-fill { height: 100%; background: var(--nt-accent); border-radius: 3px; transition: width 120ms linear; }\n .nt-pct { font-variant-numeric: tabular-nums; color: var(--nt-muted); }\n .nt-error .nt-label { color: #dc2626; }\n @keyframes nt-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }\n @media (prefers-reduced-motion: reduce) {\n .nt-dot { animation: none; }\n .nt-fill { transition: none; }\n }\n `,\n})\nexport class ModelProgressComponent {\n status = input.required<PipelineStatus>();\n progress = input<ModelProgress | null>(null);\n /** Labels per status; override to localize. */\n labels = input<Partial<Record<PipelineStatus, string>>>({});\n\n readonly label = computed(() => {\n const defaults: Record<PipelineStatus, string> = {\n idle: 'Model not loaded',\n loading: 'Downloading model',\n ready: 'Model ready',\n busy: 'Running',\n error: 'Failed to load model',\n };\n return this.labels()[this.status()] ?? defaults[this.status()];\n });\n}\n","/*\n * Public API Surface of ngx-transformers\n */\n\nexport * from './lib/transformers.models';\nexport * from './lib/transformers.providers';\nexport * from './lib/pipeline';\nexport * from './lib/device-detection';\nexport * from './lib/text-classifier';\nexport * from './lib/text-embedder';\nexport * from './lib/speech-recognizer';\nexport * from './lib/zero-shot-classifier';\nexport * from './lib/translator';\nexport * from './lib/mic-recorder';\nexport * from './lib/model-progress.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-transformers.mjs","sources":["../../../projects/ngx-transformers/src/lib/transformers.providers.ts","../../../projects/ngx-transformers/src/lib/device-detection.ts","../../../projects/ngx-transformers/src/lib/pipeline.ts","../../../projects/ngx-transformers/src/lib/text-classifier.ts","../../../projects/ngx-transformers/src/lib/text-embedder.ts","../../../projects/ngx-transformers/src/lib/speech-recognizer.ts","../../../projects/ngx-transformers/src/lib/zero-shot-classifier.ts","../../../projects/ngx-transformers/src/lib/translator.ts","../../../projects/ngx-transformers/src/lib/text-generator.ts","../../../projects/ngx-transformers/src/lib/inference-resource.ts","../../../projects/ngx-transformers/src/lib/mic-recorder.ts","../../../projects/ngx-transformers/src/lib/model-progress.component.ts","../../../projects/ngx-transformers/src/public-api.ts","../../../projects/ngx-transformers/src/ngx-transformers.ts"],"sourcesContent":["import {\n DestroyRef,\n EnvironmentProviders,\n InjectionToken,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { createWorkerPipelineFactory, takeOnToken, type WorkerLike } from 'ngx-transformers/worker';\nimport type { NgxTransformersConfig } from './transformers.models';\n\n/**\n * The callable returned by Transformers.js pipeline(), reduced to the\n * surface this library relies on.\n */\nexport type PipelineLike = ((\n input: unknown,\n options?: Record<string, unknown>,\n) => Promise<unknown>) & {\n dispose?: () => Promise<void>;\n};\n\n/**\n * Creates a pipeline for a task. The default implementation lazy-imports\n * @huggingface/transformers; tests and SSR shims can provide their own.\n */\nexport type PipelineFactory = (\n task: string,\n model: string | undefined,\n options: Record<string, unknown>,\n) => Promise<PipelineLike>;\n\n/**\n * The slice of the @huggingface/transformers module the default factory\n * uses. The real module satisfies it, so an importer can configure\n * `env` and return the module as is.\n */\nexport interface TransformersModuleLike {\n // A method signature on purpose: it keeps the overloaded, generic\n // pipeline() of the real module assignable.\n pipeline(task: string, model?: string, options?: object): Promise<unknown>;\n /** Streams generated text for the `onToken` run option; optional in test stubs. */\n TextStreamer?: new (\n // `never` keeps the real class (which wants a PreTrainedTokenizer) assignable.\n tokenizer: never,\n options: {\n skip_prompt?: boolean;\n skip_special_tokens?: boolean;\n callback_function?: (text: string) => void;\n },\n ) => unknown;\n}\n\nconst importTransformers = (): Promise<TransformersModuleLike> =>\n import('@huggingface/transformers');\n\n/**\n * Wraps a pipeline so the `onToken` run option (TextGenerator streaming)\n * becomes a Transformers.js TextStreamer on the pipeline's tokenizer.\n */\nfunction withTokenStreaming(pipe: PipelineLike, module: TransformersModuleLike): PipelineLike {\n const streaming = (async (input: unknown, ...args: unknown[]) => {\n const { args: rest, onToken } = takeOnToken(args);\n if (onToken && module.TextStreamer) {\n const options = { ...(rest[rest.length - 1] as Record<string, unknown>) };\n options['streamer'] = new module.TextStreamer(\n (pipe as unknown as { tokenizer?: unknown }).tokenizer as never,\n { skip_prompt: true, skip_special_tokens: true, callback_function: onToken },\n );\n rest[rest.length - 1] = options;\n }\n return (pipe as (...a: unknown[]) => Promise<unknown>)(input, ...rest);\n }) as PipelineLike;\n streaming.dispose = () => pipe.dispose?.() ?? Promise.resolve();\n return streaming;\n}\n\n/**\n * The factory behind PIPELINE_FACTORY. It imports @huggingface/transformers\n * lazily, on the first pipeline, so the library adds nothing to the initial\n * bundle. Wrap it to add options or logging while keeping the lazy import:\n *\n * ```ts\n * const base = createDefaultPipelineFactory();\n * const factory: PipelineFactory = (task, model, options) =>\n * base(task, model, { ...options, revision: 'v2' });\n * providers: [{ provide: PIPELINE_FACTORY, useValue: factory }]\n * ```\n *\n * `load` is the importer. Tests pass a stub module; apps that need to\n * configure Transformers.js (`env.allowRemoteModels`, `env.localModelPath`)\n * do it there, before returning the module.\n */\nexport function createDefaultPipelineFactory(\n load: () => Promise<TransformersModuleLike> = importTransformers,\n): PipelineFactory {\n return async (task, model, options) => {\n const module = await load();\n const pipe = (await module.pipeline(task, model, options)) as PipelineLike;\n return withTokenStreaming(pipe, module);\n };\n}\n\nexport const PIPELINE_FACTORY = new InjectionToken<PipelineFactory>(\n 'ngx-transformers.pipeline-factory',\n {\n providedIn: 'root',\n factory: () => createDefaultPipelineFactory(),\n },\n);\n\nexport const NGX_TRANSFORMERS_CONFIG = new InjectionToken<NgxTransformersConfig>(\n 'ngx-transformers.config',\n {\n providedIn: 'root',\n factory: () => ({}),\n },\n);\n\n/**\n * Sets workspace-wide defaults (device, dtype, extra pipeline options):\n *\n * ```ts\n * bootstrapApplication(App, {\n * providers: [provideTransformers({ device: 'webgpu', dtype: 'q8' })],\n * });\n * ```\n */\nexport function provideTransformers(config: NgxTransformersConfig): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: NGX_TRANSFORMERS_CONFIG, useValue: config }]);\n}\n\n/**\n * Runs every pipeline in a Web Worker so inference never blocks the UI.\n * The worker file imports the worker entry point:\n *\n * ```ts\n * // transformers.worker.ts\n * /// <reference lib=\"webworker\" />\n * import { runTransformersWorker } from 'ngx-transformers/worker';\n * runTransformersWorker();\n *\n * // app.config.ts\n * provideTransformersWorker(\n * () => new Worker(new URL('./transformers.worker', import.meta.url), { type: 'module' }),\n * )\n * ```\n *\n * The worker is created on the first pipeline and terminated with the\n * injector. Handles, signals and the wrappers work unchanged; results must\n * survive structured cloning (plain objects, arrays, typed arrays and\n * tensors do). A worker that fails to start rejects the calls waiting on\n * it, like a failed load in-thread.\n */\nexport function provideTransformersWorker(createWorker: () => WorkerLike): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: PIPELINE_FACTORY,\n useFactory: () => {\n const factory = createWorkerPipelineFactory(createWorker);\n inject(DestroyRef).onDestroy(() => factory.terminate());\n return factory;\n },\n },\n ]);\n}\n","/** The slice of navigator.gpu we probe; the WebGPU lib types are not in every project's tsconfig. */\ninterface GpuLike {\n requestAdapter(): Promise<unknown | null>;\n}\n\nlet webGpuProbe: Promise<boolean> | null = null;\n\n/**\n * Whether models can run on WebGPU here: `navigator.gpu` exists AND\n * `requestAdapter()` hands back an adapter - it returns null on machines\n * without a usable GPU or with WebGPU disabled, even when the API exists.\n * Resolves false on the server. The probe runs once and is cached.\n */\nexport function hasWebGpu(): Promise<boolean> {\n webGpuProbe ??= probeWebGpu();\n return webGpuProbe;\n}\n\n/** `'webgpu'` when hasWebGpu() resolves true, else `'wasm'`. */\nexport async function detectDevice(): Promise<'webgpu' | 'wasm'> {\n return (await hasWebGpu()) ? 'webgpu' : 'wasm';\n}\n\n/** Forgets the cached probe so the next hasWebGpu() asks the browser again. */\nexport function resetDeviceDetection(): void {\n webGpuProbe = null;\n}\n\nasync function probeWebGpu(): Promise<boolean> {\n const gpu = (globalThis as { navigator?: { gpu?: GpuLike } }).navigator?.gpu;\n if (!gpu) return false;\n try {\n return (await gpu.requestAdapter()) !== null;\n } catch {\n return false;\n }\n}\n","import { DestroyRef, computed, inject, signal } from '@angular/core';\nimport { detectDevice } from './device-detection';\nimport type {\n ModelProgress,\n NgxTransformersConfig,\n OverallProgress,\n PipelineRequest,\n PipelineStatus,\n TransformersDevice,\n} from './transformers.models';\nimport {\n NGX_TRANSFORMERS_CONFIG,\n PIPELINE_FACTORY,\n type PipelineFactory,\n type PipelineLike,\n} from './transformers.providers';\n\n/** Shape of Transformers.js progress_callback events (subset we consume). */\ninterface RawProgressEvent {\n status?: string;\n file?: string;\n progress?: number;\n loaded?: number;\n total?: number;\n}\n\n/** A pipeline callable with the positional extras some tasks take after the input. */\ntype Runnable = (...args: unknown[]) => Promise<unknown>;\n\ninterface FileProgress {\n loaded: number;\n total: number;\n done: boolean;\n}\n\n/**\n * One load-to-dispose span of a handle. dispose() swaps in a fresh session,\n * so async work still holding the old one knows it was cancelled and keeps\n * its bookkeeping (in-flight runs, the loading promise) to itself.\n */\ninterface Session {\n pipe: PipelineLike | null;\n loading: Promise<void> | null;\n /** Runs executing against this session's pipe. */\n inFlight: number;\n /** Per-file download state of the current load attempt, by file name. */\n files: Map<string, FileProgress>;\n}\n\nconst newSession = (): Session => ({ pipe: null, loading: null, inFlight: 0, files: new Map() });\n\n/**\n * A lazily-loaded Transformers.js pipeline wrapped in signals.\n *\n * The model is not downloaded until load() or the first run() call, so\n * creating handles is free. All state is exposed as signals and safe to\n * bind in zoneless apps.\n */\nexport class PipelineHandle<TIn = unknown, TOut = unknown> {\n /** idle -> loading -> ready <-> busy; error only on load failure. */\n readonly status = signal<PipelineStatus>('idle');\n /** Download progress: the file reported last, plus the total over all files. */\n readonly progress = signal<ModelProgress | null>(null);\n /** The last load error; cleared when a load starts. */\n readonly error = signal<unknown>(null);\n /** The error of the most recently started run, if it failed; cleared when a run starts. */\n readonly runError = signal<unknown>(null);\n /** True once the model is usable (including while a run is in flight). */\n readonly ready = computed(() => this.status() === 'ready' || this.status() === 'busy');\n readonly busy = computed(() => this.status() === 'busy' || this.status() === 'loading');\n\n private session = newSession();\n private destroyed = false;\n /** Counts runs so only the most recently started one writes runError. */\n private runSequence = 0;\n\n constructor(\n private readonly request: PipelineRequest,\n private readonly factory: PipelineFactory,\n private readonly config: NgxTransformersConfig,\n ) {}\n\n /** Downloads and initializes the model. Idempotent; retries after error. */\n load(): Promise<void> {\n if (this.destroyed) return Promise.reject(destroyedError());\n const session = this.session;\n if (session.pipe) return Promise.resolve();\n session.loading ??= this.doLoad(session).finally(() => {\n session.loading = null;\n });\n return session.loading;\n }\n\n /**\n * Runs the pipeline, loading the model first if needed. Besides the\n * pipeline's own options, `runOptions.signal` (an AbortSignal) makes the\n * run reject before it starts when the signal has already fired, which\n * spares superseded runs the inference (see inferenceResource()).\n */\n run(input: TIn, runOptions?: Record<string, unknown>): Promise<TOut> {\n return this.runWith(input, runOptions);\n }\n\n /**\n * Runs the pipeline with extra positional arguments after the input, for\n * tasks whose pipeline signature is not (input, options): zero-shot\n * classification takes (text, candidateLabels, options).\n */\n protected async runWith(input: TIn, ...extraArgs: unknown[]): Promise<TOut> {\n const { args, signal } = takeSignal(extraArgs);\n await this.load();\n // The model cannot be interrupted, but a run nobody wants any more\n // (a newer input superseded it while the model loaded) need not start.\n if (signal?.aborted) throw abortError();\n const session = this.session;\n const pipe = session.pipe;\n if (!pipe) {\n throw new Error('PipelineHandle: disposed before the model finished loading.');\n }\n const sequence = ++this.runSequence;\n session.inFlight++;\n this.status.set('busy');\n this.runError.set(null);\n try {\n return (await (pipe as Runnable)(input, ...args)) as TOut;\n } catch (err) {\n if (this.session === session && sequence === this.runSequence) this.runError.set(err);\n throw err;\n } finally {\n // Back to ready once the last overlapping run finishes - a failed run\n // leaves the model intact. A run that outlived dispose() settles its\n // own, retired session and leaves the status alone.\n session.inFlight--;\n if (session.inFlight === 0 && this.session === session) this.status.set('ready');\n }\n }\n\n /**\n * Frees the model. A download still in flight is cancelled: its model is\n * released on arrival and the handle stays idle. The handle can be loaded\n * again afterwards; destroy() is the terminal variant.\n */\n async dispose(): Promise<void> {\n const session = this.session;\n this.session = newSession();\n this.status.set('idle');\n this.progress.set(null);\n await session.pipe?.dispose?.();\n }\n\n /**\n * dispose() for good: later load() and run() calls reject instead of\n * downloading a model nobody would release. create*() registers this with\n * the DestroyRef of the injection context, so a handle declared in a\n * component ends with the component.\n */\n destroy(): Promise<void> {\n this.destroyed = true;\n return this.dispose();\n }\n\n private async doLoad(session: Session): Promise<void> {\n this.status.set('loading');\n this.error.set(null);\n // A retry after a failed attempt starts its bookkeeping from scratch.\n session.files = new Map();\n this.progress.set(null);\n const options: Record<string, unknown> = {\n ...this.config.pipelineOptions,\n ...this.request.options,\n progress_callback: (event: RawProgressEvent) => this.onProgress(event, session),\n };\n const device = await this.resolveDevice();\n // Disposed while probing the device: do not start the download at all.\n if (this.session !== session) return;\n const dtype = this.request.dtype ?? this.config.dtype;\n if (device && device !== 'auto') options['device'] = device;\n if (dtype) options['dtype'] = dtype;\n\n try {\n const pipe = await this.factory(this.request.task, this.request.model, options);\n if (this.session !== session) {\n // Disposed while downloading: nobody wants this model any more.\n await pipe.dispose?.();\n return;\n }\n session.pipe = pipe;\n this.progress.set(null);\n this.status.set('ready');\n } catch (err) {\n // A cancelled load is not an error - dispose() already reset the handle.\n if (this.session !== session) return;\n this.progress.set(null);\n this.error.set(err);\n this.status.set('error');\n throw err;\n }\n }\n\n /**\n * An explicit request or global device wins; with `autoDevice` on, an\n * unset or 'auto' device is probed for WebGPU (once, cached) at load time.\n */\n private async resolveDevice(): Promise<TransformersDevice | undefined> {\n const configured = this.request.device ?? this.config.device;\n if (configured && configured !== 'auto') return configured;\n return this.config.autoDevice ? detectDevice() : configured;\n }\n\n /**\n * Transformers.js reports each file on its own (initiate, download,\n * progress, done). The session records every file it hears about; the\n * signal is published on progress and done events only, so a file that\n * has not transferred a byte never replaces the one that is moving.\n */\n private onProgress(event: RawProgressEvent, session: Session): void {\n // Events from a load that dispose() cancelled must not resurrect the bar.\n if (this.session !== session || !event.file) return;\n const file = session.files.get(event.file) ?? { loaded: 0, total: 0, done: false };\n session.files.set(event.file, file);\n switch (event.status) {\n case 'progress':\n file.loaded = event.loaded ?? file.loaded;\n file.total = event.total ?? file.total;\n break;\n case 'done':\n file.done = true;\n if (file.total > 0) file.loaded = file.total;\n break;\n default:\n return; // initiate / download: recorded, not published\n }\n const percent = event.status === 'done' ? 100 : Math.round(event.progress ?? 0);\n const overall = overallOf(session.files);\n this.progress.set({\n file: event.file,\n progress: percent,\n loadedBytes: file.loaded,\n totalBytes: file.total,\n ...(overall ? { overall } : {}),\n });\n }\n}\n\n/**\n * The total over the files seen so far. Transformers.js fetches the small\n * files (config, tokenizer) before it starts the weights, so a total\n * computed before the weights are known would read 100% and then collapse;\n * it is therefore withheld until a weights file has been seen.\n */\nfunction overallOf(files: Map<string, FileProgress>): OverallProgress | undefined {\n let weightsSeen = false;\n let loadedBytes = 0;\n let totalBytes = 0;\n let filesDone = 0;\n for (const [name, file] of files) {\n if (name.includes('.onnx')) weightsSeen = true;\n if (file.total > 0) {\n loadedBytes += Math.min(file.loaded, file.total);\n totalBytes += file.total;\n }\n if (file.done) filesDone++;\n }\n if (!weightsSeen) return undefined;\n return {\n progress: totalBytes > 0 ? Math.round((loadedBytes / totalBytes) * 100) : 0,\n loadedBytes,\n totalBytes,\n files: files.size,\n filesDone,\n };\n}\n\n/** Pulls `signal` out of a call's trailing options object. */\nfunction takeSignal(args: unknown[]): { args: unknown[]; signal?: AbortSignal } {\n const last = args[args.length - 1];\n if (typeof last !== 'object' || last === null || Array.isArray(last)) return { args };\n const { signal, ...rest } = last as { signal?: unknown } & Record<string, unknown>;\n if (!(signal instanceof AbortSignal)) return { args };\n return { args: [...args.slice(0, -1), rest], signal };\n}\n\nfunction abortError(): Error {\n return new DOMException('PipelineHandle: the run was aborted before it started.', 'AbortError');\n}\n\nfunction destroyedError(): Error {\n return new Error('PipelineHandle: destroyed with its component; create a new handle.');\n}\n\n/**\n * Creates a PipelineHandle in an injection context (constructor, field\n * initializer, or runInInjectionContext). The handle is destroyed with the\n * surrounding component/injector.\n */\nexport function createPipeline<TIn = unknown, TOut = unknown>(\n request: PipelineRequest,\n): PipelineHandle<TIn, TOut> {\n const handle = new PipelineHandle<TIn, TOut>(\n request,\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void handle.destroy());\n return handle;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { ClassificationResult, PipelineRequest, RunOptions } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\nexport const DEFAULT_TEXT_CLASSIFICATION_MODEL =\n 'Xenova/distilbert-base-uncased-finetuned-sst-2-english';\n\n/**\n * Text classification (sentiment by default). The default model is\n * DistilBERT SST-2 (~65 MB, q8) - swap `model` for any Transformers.js\n * compatible text-classification checkpoint.\n */\nexport class TextClassifier extends PipelineHandle<\n string,\n ClassificationResult[] | ClassificationResult[][]\n> {\n /** Classifies one text; resolves to labels sorted by score (top first). */\n async classify(\n text: string,\n topK = 1,\n options: RunOptions = {},\n ): Promise<ClassificationResult[]> {\n const out = await this.run(text, { top_k: topK, signal: options.signal });\n // Single input: transformers.js returns a flat array of {label, score}.\n const flat = (Array.isArray(out[0]) ? out[0] : out) as ClassificationResult[];\n return [...flat].sort((a, b) => b.score - a.score);\n }\n}\n\n/** Creates a TextClassifier in an injection context. */\nexport function createTextClassifier(\n options: Partial<Omit<PipelineRequest, 'task'>> = {},\n): TextClassifier {\n const classifier = new TextClassifier(\n { task: 'text-classification', model: DEFAULT_TEXT_CLASSIFICATION_MODEL, ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void classifier.destroy());\n return classifier;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { PipelineRequest, RankedResult, RunOptions } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\nexport const DEFAULT_EMBEDDING_MODEL = 'Xenova/all-MiniLM-L6-v2';\n\n/** Tensor-ish output of feature-extraction: enough shape to read rows. */\ninterface TensorLike {\n dims: number[];\n data: ArrayLike<number>;\n tolist?: () => number[][];\n}\n\n/** Cosine similarity of two vectors. For normalized vectors this is the dot product. */\nexport function cosineSimilarity(a: readonly number[], b: readonly number[]): number {\n if (a.length !== b.length || a.length === 0) {\n throw new Error(`cosineSimilarity: incompatible lengths ${a.length} and ${b.length}`);\n }\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n\n/**\n * Sentence embeddings via feature-extraction (all-MiniLM-L6-v2 by default,\n * ~23 MB q8). Outputs mean-pooled, L2-normalized vectors ready for cosine\n * similarity / semantic search.\n */\nexport class TextEmbedder extends PipelineHandle<string | string[], TensorLike> {\n /** Embeds one or many texts; always resolves to one vector per text. */\n async embed(texts: string | string[], options: RunOptions = {}): Promise<number[][]> {\n const input = Array.isArray(texts) ? texts : [texts];\n if (input.length === 0) return [];\n const out = await this.run(input, { pooling: 'mean', normalize: true, signal: options.signal });\n return toRows(out);\n }\n\n /** Cosine similarity of two texts in [-1, 1]. */\n async similarity(a: string, b: string, options: RunOptions = {}): Promise<number> {\n const [va, vb] = await this.embed([a, b], options);\n return cosineSimilarity(va, vb);\n }\n\n /** Ranks documents against a query, most similar first. */\n async rank(\n query: string,\n documents: string[],\n options: RunOptions = {},\n ): Promise<RankedResult[]> {\n if (documents.length === 0) return [];\n const [queryVec, ...docVecs] = await this.embed([query, ...documents], options);\n return docVecs\n .map((vec, index) => ({\n text: documents[index],\n score: cosineSimilarity(queryVec, vec),\n index,\n }))\n .sort((a, b) => b.score - a.score);\n }\n}\n\nfunction toRows(out: TensorLike): number[][] {\n if (typeof out.tolist === 'function') return out.tolist();\n const [rows, cols] = out.dims.length === 2 ? out.dims : [1, out.dims[out.dims.length - 1]];\n const data = out.data;\n const result: number[][] = [];\n for (let r = 0; r < rows; r++) {\n result.push(Array.from({ length: cols }, (_, c) => data[r * cols + c]));\n }\n return result;\n}\n\n/** Creates a TextEmbedder in an injection context. */\nexport function createTextEmbedder(\n options: Partial<Omit<PipelineRequest, 'task'>> = {},\n): TextEmbedder {\n const embedder = new TextEmbedder(\n { task: 'feature-extraction', model: DEFAULT_EMBEDDING_MODEL, ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void embedder.destroy());\n return embedder;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type {\n PipelineRequest,\n TranscribeOptions,\n Transcription,\n TranscriptionChunk,\n} from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\n// onnx-community, not the legacy Xenova export: the old ONNX decoder lacks\n// the quantization scales transformers.js v4's runtime requires.\nexport const DEFAULT_ASR_MODEL = 'onnx-community/whisper-tiny.en';\n\n/** Whisper expects 16 kHz mono float PCM. */\nexport const WHISPER_SAMPLE_RATE = 16000;\n\n/** Raw ASR pipeline output (subset we consume). */\ninterface RawTranscription {\n text?: string;\n chunks?: { text: string; timestamp?: [number | null, number | null] }[];\n}\n\n/**\n * Decodes an encoded audio file (wav/mp3/webm/ogg - anything the browser\n * can decode) to 16 kHz mono Float32Array, ready for Whisper. Browser-only:\n * uses AudioContext with a target sample rate, which resamples on decode.\n */\nexport async function decodeAudio(\n source: Blob | ArrayBuffer,\n targetSampleRate = WHISPER_SAMPLE_RATE,\n): Promise<Float32Array> {\n const AudioContextCtor = (globalThis as { AudioContext?: typeof AudioContext }).AudioContext;\n if (!AudioContextCtor) {\n throw new Error(\n 'decodeAudio requires a browser AudioContext (not available in this environment).',\n );\n }\n const buffer = source instanceof Blob ? await source.arrayBuffer() : source;\n const ctx = new AudioContextCtor({ sampleRate: targetSampleRate });\n try {\n const decoded = await ctx.decodeAudioData(buffer);\n if (decoded.numberOfChannels === 1) return decoded.getChannelData(0);\n // Mix down to mono by averaging channels.\n const left = decoded.getChannelData(0);\n const right = decoded.getChannelData(1);\n const mono = new Float32Array(left.length);\n for (let i = 0; i < left.length; i++) mono[i] = (left[i] + right[i]) / 2;\n return mono;\n } finally {\n await ctx.close();\n }\n}\n\n/**\n * Speech-to-text via Whisper. The default checkpoint is whisper-tiny.en\n * (~41 MB q8, English-only); swap `model` for a multilingual or larger one\n * (e.g. Xenova/whisper-small).\n */\nexport class SpeechRecognizer extends PipelineHandle<\n string | Float32Array,\n RawTranscription | RawTranscription[]\n> {\n /**\n * Transcribes audio: a URL, a decoded 16 kHz Float32Array, or an encoded\n * Blob/ArrayBuffer (decoded via decodeAudio first - browser-only).\n */\n async transcribe(\n audio: string | Float32Array | Blob | ArrayBuffer,\n options: TranscribeOptions = {},\n ): Promise<Transcription> {\n const input =\n audio instanceof Blob || audio instanceof ArrayBuffer ? await decodeAudio(audio) : audio;\n\n const runOptions: Record<string, unknown> = {};\n if (options.returnTimestamps !== undefined)\n runOptions['return_timestamps'] = options.returnTimestamps;\n if (options.chunkLengthS !== undefined) runOptions['chunk_length_s'] = options.chunkLengthS;\n if (options.strideLengthS !== undefined) runOptions['stride_length_s'] = options.strideLengthS;\n if (options.language !== undefined) runOptions['language'] = options.language;\n if (options.task !== undefined) runOptions['task'] = options.task;\n if (options.signal !== undefined) runOptions['signal'] = options.signal;\n\n const raw = await this.run(input, runOptions);\n const first = (Array.isArray(raw) ? raw[0] : raw) ?? {};\n const chunks: TranscriptionChunk[] | undefined = first.chunks?.map((c) => ({\n text: c.text,\n start: c.timestamp?.[0] ?? null,\n end: c.timestamp?.[1] ?? null,\n }));\n return { text: (first.text ?? '').trim(), ...(chunks ? { chunks } : {}) };\n }\n}\n\n/**\n * Creates a SpeechRecognizer in an injection context.\n *\n * dtype defaults to 'q4' (not the library-wide default): q8 Whisper\n * decoders fail session creation on the v4 WASM runtime\n * (huggingface/transformers.js#1707), while q4 loads and runs everywhere.\n */\nexport function createSpeechRecognizer(\n options: Partial<Omit<PipelineRequest, 'task'>> = {},\n): SpeechRecognizer {\n const recognizer = new SpeechRecognizer(\n { task: 'automatic-speech-recognition', model: DEFAULT_ASR_MODEL, dtype: 'q4', ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void recognizer.destroy());\n return recognizer;\n}\n","import { DestroyRef, inject } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { ClassificationResult, PipelineRequest, ZeroShotOptions } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\n// The Transformers.js docs example for this task and the smallest MNLI\n// checkpoint that behaves well on the WASM runtime (~26 MB q8).\nexport const DEFAULT_ZERO_SHOT_MODEL = 'Xenova/mobilebert-uncased-mnli';\n\n/** Raw zero-shot output: labels ordered by score, scores aligned by index. */\ninterface RawZeroShotResult {\n sequence: string;\n labels: string[];\n scores: number[];\n}\n\n/**\n * Zero-shot classification: score any labels you name against a text with\n * an NLI model, no fine-tuning. The default checkpoint is MobileBERT MNLI\n * (~26 MB q8); Xenova/distilbert-base-uncased-mnli (~80 MB) is the\n * higher-accuracy alternative.\n */\nexport class ZeroShotClassifier extends PipelineHandle<\n string,\n RawZeroShotResult | RawZeroShotResult[]\n> {\n /**\n * Scores each candidate label for one text; resolves sorted by score (top\n * first). Single-label mode (default) normalizes across labels so scores\n * sum to 1; `multiLabel` scores each label on its own.\n */\n async classify(\n text: string,\n labels: readonly string[],\n options: ZeroShotOptions = {},\n ): Promise<ClassificationResult[]> {\n if (labels.length === 0) return [];\n const runOptions: Record<string, unknown> = {};\n if (options.multiLabel !== undefined) runOptions['multi_label'] = options.multiLabel;\n if (options.hypothesisTemplate !== undefined)\n runOptions['hypothesis_template'] = options.hypothesisTemplate;\n if (options.signal !== undefined) runOptions['signal'] = options.signal;\n\n const raw = await this.runWith(text, [...labels], runOptions);\n const first = Array.isArray(raw) ? raw[0] : raw;\n const scoredLabels = first?.labels ?? [];\n const scores = first?.scores ?? [];\n return scoredLabels\n .map((label, index) => ({ label, score: scores[index] ?? 0 }))\n .sort((left, right) => right.score - left.score);\n }\n}\n\n/** Creates a ZeroShotClassifier in an injection context. */\nexport function createZeroShotClassifier(\n options: Partial<Omit<PipelineRequest, 'task'>> = {},\n): ZeroShotClassifier {\n const classifier = new ZeroShotClassifier(\n { task: 'zero-shot-classification', model: DEFAULT_ZERO_SHOT_MODEL, ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void classifier.destroy());\n return classifier;\n}\n","import { DestroyRef, computed, inject, signal } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type {\n NgxTransformersConfig,\n TranslateOptions,\n TranslatorOptions,\n} from './transformers.models';\nimport {\n NGX_TRANSFORMERS_CONFIG,\n PIPELINE_FACTORY,\n type PipelineFactory,\n} from './transformers.providers';\n\n/**\n * Default checkpoint for a language pair: Helsinki-NLP's Marian opus-mt\n * models, one per direction, ~105 MB q8 each (e.g. Xenova/opus-mt-en-ru).\n */\nexport function defaultTranslationModel(from: string, to: string): string {\n return `Xenova/opus-mt-${from}-${to}`;\n}\n\n/** Checkpoint for a pair: provideTransformers({ translationModels }) first, then opus-mt. */\nexport function resolveTranslationModel(\n from: string,\n to: string,\n config: NgxTransformersConfig,\n): string {\n return config.translationModels?.[`${from}-${to}`] ?? defaultTranslationModel(from, to);\n}\n\n/**\n * Multilingual families take the pair per call as src_lang / tgt_lang;\n * Marian opus-mt checkpoints translate one fixed direction and ignore them.\n */\nconst MULTILINGUAL_MODEL_PATTERN = /nllb|m2m[_-]?100|mbart|madlad/i;\n\n/** Raw translation pipeline output, one entry per input text. */\ninterface RawTranslation {\n translation_text?: string;\n}\n\nexport type TranslationHandle = PipelineHandle<string, RawTranslation | RawTranslation[]>;\n\n/**\n * Text translation. Pipelines are created lazily, one per checkpoint: with\n * the default opus-mt family every language pair is its own model, so a\n * Translator holds one handle per pair it has been asked for, while a\n * pinned multilingual `model` (NLLB, M2M100) serves every pair from one.\n *\n * The signals mirror the handle used by the most recent call, so a single\n * `<ngx-model-progress>` covers the translator.\n */\nexport class Translator {\n private readonly active = signal<TranslationHandle | null>(null);\n private readonly handles = new Map<string, TranslationHandle>();\n private destroyed = false;\n\n readonly status = computed(() => this.active()?.status() ?? 'idle');\n readonly progress = computed(() => this.active()?.progress() ?? null);\n readonly error = computed(() => this.active()?.error() ?? null);\n readonly runError = computed(() => this.active()?.runError() ?? null);\n readonly ready = computed(() => this.active()?.ready() ?? false);\n readonly busy = computed(() => this.active()?.busy() ?? false);\n\n constructor(\n private readonly options: TranslatorOptions,\n private readonly factory: PipelineFactory,\n private readonly config: NgxTransformersConfig,\n ) {}\n\n /** Downloads the model for a pair ahead of the first translate() call. */\n async load(pair: TranslateOptions = {}): Promise<void> {\n return this.handleFor(pair).load();\n }\n\n /** Translates one text; the pair defaults to the one given at creation. */\n async translate(text: string, pair: TranslateOptions = {}): Promise<string> {\n const handle = this.handleFor(pair);\n const raw = await handle.run(text, { ...this.languageOptions(pair), signal: pair.signal });\n const first = Array.isArray(raw) ? raw[0] : raw;\n return (first?.translation_text ?? '').trim();\n }\n\n /** Checkpoint for a pair: the pinned model, else the configured or default one. */\n modelFor(pair: TranslateOptions = {}): string {\n if (this.options.model) return this.options.model;\n const from = pair.from ?? this.options.from;\n const to = pair.to ?? this.options.to;\n if (!from || !to) {\n throw new Error(\n 'Translator: no language pair - pass { from, to } to createTranslator() or translate(), or pin a multilingual model.',\n );\n }\n return resolveTranslationModel(from, to, this.config);\n }\n\n /**\n * The handle serving a pair, created on first use. Exposed for apps that\n * keep several pairs warm and want a progress line per model.\n */\n handleFor(pair: TranslateOptions = {}): TranslationHandle {\n if (this.destroyed) {\n throw new Error('Translator: destroyed with its component; create a new translator.');\n }\n const model = this.modelFor(pair);\n let handle = this.handles.get(model);\n if (!handle) {\n handle = new PipelineHandle(\n {\n task: 'translation',\n model,\n device: this.options.device,\n dtype: this.options.dtype,\n options: this.options.options,\n },\n this.factory,\n this.config,\n );\n this.handles.set(model, handle);\n }\n this.active.set(handle);\n return handle;\n }\n\n /**\n * dispose() for good: later calls reject instead of loading a model nobody\n * would release. createTranslator() registers this with the DestroyRef.\n */\n destroy(): Promise<void> {\n this.destroyed = true;\n return this.dispose();\n }\n\n /** Frees every model. The translator can be used again afterwards. */\n async dispose(): Promise<void> {\n const handles = [...this.handles.values()];\n this.handles.clear();\n this.active.set(null);\n await Promise.all(handles.map((handle) => handle.dispose()));\n }\n\n /** src_lang / tgt_lang for multilingual checkpoints; opus-mt models get nothing. */\n private languageOptions(pair: TranslateOptions): Record<string, unknown> {\n const runOptions: Record<string, unknown> = {};\n if (!MULTILINGUAL_MODEL_PATTERN.test(this.modelFor(pair))) return runOptions;\n const from = pair.from ?? this.options.from;\n const to = pair.to ?? this.options.to;\n if (from !== undefined) runOptions['src_lang'] = from;\n if (to !== undefined) runOptions['tgt_lang'] = to;\n return runOptions;\n }\n}\n\n/** Creates a Translator in an injection context. */\nexport function createTranslator(options: TranslatorOptions = {}): Translator {\n const translator = new Translator(\n options,\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void translator.destroy());\n return translator;\n}\n","import { DestroyRef, inject, signal } from '@angular/core';\nimport { PipelineHandle } from './pipeline';\nimport type { ChatMessage, GenerateOptions, PipelineRequest } from './transformers.models';\nimport { NGX_TRANSFORMERS_CONFIG, PIPELINE_FACTORY } from './transformers.providers';\n\n// The smallest instruct model that holds a conversation; its repository\n// ships the ONNX variants Transformers.js loads (~100 MB at q4).\nexport const DEFAULT_TEXT_GENERATION_MODEL = 'HuggingFaceTB/SmolLM2-135M-Instruct';\n\n/** Raw text-generation output: the reply as a string, or the chat with the reply appended. */\ninterface RawGeneration {\n generated_text?: string | ChatMessage[];\n}\n\n/**\n * Text generation with a small language model, streamed token by token.\n * The default checkpoint is SmolLM2-135M-Instruct; swap `model` for any\n * Transformers.js text-generation checkpoint (Qwen2.5, Llama, Phi...).\n */\nexport class TextGenerator extends PipelineHandle<\n string | ChatMessage[],\n RawGeneration | RawGeneration[]\n> {\n /** The text generated so far by the latest generate() call; reset when a call starts. */\n readonly output = signal('');\n /** Only the most recently started call may write output. */\n private generation = 0;\n private warnedNoStreaming = false;\n\n /**\n * Generates a reply to a prompt or a chat. Tokens stream into `output`\n * (and `options.onToken`) while the model runs; resolves with the full,\n * trimmed reply.\n */\n async generate(prompt: string | ChatMessage[], options: GenerateOptions = {}): Promise<string> {\n const runOptions: Record<string, unknown> = { max_new_tokens: options.maxNewTokens ?? 256 };\n if (options.doSample !== undefined) runOptions['do_sample'] = options.doSample;\n if (options.temperature !== undefined) runOptions['temperature'] = options.temperature;\n if (options.topP !== undefined) runOptions['top_p'] = options.topP;\n if (options.topK !== undefined) runOptions['top_k'] = options.topK;\n if (options.repetitionPenalty !== undefined) {\n runOptions['repetition_penalty'] = options.repetitionPenalty;\n }\n // A plain prompt would otherwise come back with the prompt in front.\n if (typeof prompt === 'string') runOptions['return_full_text'] = false;\n if (options.signal !== undefined) runOptions['signal'] = options.signal;\n\n const generation = ++this.generation;\n let streamed = 0;\n this.output.set('');\n runOptions['onToken'] = (text: string) => {\n streamed++;\n if (generation === this.generation) this.output.update((current) => current + text);\n options.onToken?.(text);\n };\n\n const raw = await this.run(prompt, runOptions);\n const first = Array.isArray(raw) ? raw[0] : raw;\n const generated = first?.generated_text;\n const text = Array.isArray(generated) ? (generated.at(-1)?.content ?? '') : (generated ?? '');\n const reply = text.trim();\n if (generation === this.generation) this.output.set(reply);\n if (streamed === 0 && reply && !this.warnedNoStreaming) {\n // Streaming relies on the pipeline factory turning the onToken run\n // option into a TextStreamer, which the built-in factories do. A\n // custom factory that returns a raw pipeline drops it silently.\n this.warnedNoStreaming = true;\n console.warn(\n 'ngx-transformers: the reply arrived without streamed tokens. A custom PIPELINE_FACTORY must wrap createDefaultPipelineFactory() (or handle the onToken run option) for TextGenerator.output to stream.',\n );\n }\n return reply;\n }\n}\n\n/**\n * Creates a TextGenerator in an injection context; destroyed with the\n * component. dtype defaults to 'q4', the size/quality sweet spot for small\n * decoders on the WebAssembly runtime.\n */\nexport function createTextGenerator(\n options: Partial<Omit<PipelineRequest, 'task'>> = {},\n): TextGenerator {\n const generator = new TextGenerator(\n { task: 'text-generation', model: DEFAULT_TEXT_GENERATION_MODEL, dtype: 'q4', ...options },\n inject(PIPELINE_FACTORY),\n inject(NGX_TRANSFORMERS_CONFIG),\n );\n inject(DestroyRef, { optional: true })?.onDestroy(() => void generator.destroy());\n return generator;\n}\n","import {\n Injector,\n effect,\n inject,\n resource,\n signal,\n untracked,\n type ResourceRef,\n type Signal,\n} from '@angular/core';\n\nexport interface InferenceResourceOptions<TIn, TOut> {\n /**\n * The input to run on, read reactively. Return `undefined` for \"nothing\n * to do\": the resource stays idle and keeps no value.\n */\n input: () => TIn | undefined;\n /**\n * Runs the model for one input, typically a handle method. The abort\n * signal fires when a newer input supersedes this run: pass it on as the\n * method's `signal` option and a superseded run that has not started yet\n * (it was waiting for the model to load) is skipped instead of queued.\n */\n run: (input: TIn, abortSignal: AbortSignal) => Promise<TOut>;\n /** Wait this long after the last input change before running (typing). */\n debounceMs?: number;\n /** Required outside an injection context. */\n injector?: Injector;\n}\n\n/**\n * Runs inference whenever an input signal changes, as an Angular resource:\n * `value()`, `isLoading()`, `error()` and `status()` are signals, and only\n * the result for the latest input is kept.\n *\n * ```ts\n * readonly text = signal('');\n * readonly classifier = createTextClassifier();\n * readonly sentiment = inferenceResource({\n * input: () => this.text().trim() || undefined,\n * run: (text, signal) => this.classifier.classify(text, 1, { signal }),\n * debounceMs: 300,\n * });\n * // template: @if (sentiment.value(); as result) { {{ result[0].label }} }\n * ```\n */\nexport function inferenceResource<TIn, TOut>(\n options: InferenceResourceOptions<TIn, TOut>,\n): ResourceRef<TOut | undefined> {\n const injector = options.injector ?? inject(Injector);\n const input = options.debounceMs\n ? debounced(options.input, options.debounceMs, injector)\n : options.input;\n return resource<TOut, TIn | undefined>({\n params: () => input(),\n loader: ({ params, abortSignal }) => options.run(params, abortSignal),\n injector,\n });\n}\n\n/** A signal that follows `source` once it has been stable for `ms`. */\nfunction debounced<T>(source: () => T, ms: number, injector: Injector): Signal<T> {\n const out = signal<T>(untracked(source));\n effect(\n (onCleanup) => {\n const value = source();\n const timer = setTimeout(() => out.set(value), ms);\n onCleanup(() => clearTimeout(timer));\n },\n { injector },\n );\n return out.asReadonly();\n}\n","import { DestroyRef, inject, signal } from '@angular/core';\n\n/** Minimal recorder surface - lets tests (and exotic runtimes) inject fakes. */\nexport interface RecorderLike {\n start(): void;\n stop(): void;\n ondataavailable: ((event: { data: Blob }) => void) | null;\n onstop: (() => void) | null;\n mimeType?: string;\n}\n\nexport interface MicRecorderDeps {\n /** Defaults to navigator.mediaDevices.getUserMedia({ audio: true }). */\n getUserMedia?: () => Promise<MediaStream>;\n /** Defaults to new MediaRecorder(stream). */\n createRecorder?: (stream: MediaStream) => RecorderLike;\n}\n\n/**\n * Microphone capture with a signals API. start() asks for mic permission\n * and records; stop() resolves with the encoded audio Blob - pass it to\n * SpeechRecognizer.transcribe(). Browser-only.\n *\n * ```ts\n * readonly mic = createMicRecorder();\n * readonly whisper = createSpeechRecognizer();\n *\n * async toggle() {\n * if (this.mic.recording()) {\n * const audio = await this.mic.stop();\n * const { text } = await this.whisper.transcribe(audio);\n * } else {\n * await this.mic.start();\n * }\n * }\n * ```\n */\nexport class MicRecorder {\n readonly recording = signal(false);\n /** Elapsed recording time in whole seconds. */\n readonly seconds = signal(0);\n readonly error = signal<unknown>(null);\n\n private stream: MediaStream | null = null;\n private recorder: RecorderLike | null = null;\n private chunks: Blob[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(private readonly deps: MicRecorderDeps = {}) {}\n\n /** Requests the microphone and starts recording. No-op while recording. */\n async start(): Promise<void> {\n if (this.recording()) return;\n this.error.set(null);\n try {\n this.stream = await (this.deps.getUserMedia\n ? this.deps.getUserMedia()\n : navigator.mediaDevices.getUserMedia({ audio: true }));\n this.recorder = this.deps.createRecorder\n ? this.deps.createRecorder(this.stream)\n : (new MediaRecorder(this.stream) as unknown as RecorderLike);\n this.chunks = [];\n this.recorder.ondataavailable = (event) => {\n if (event.data.size > 0) this.chunks.push(event.data);\n };\n this.recorder.start();\n this.recording.set(true);\n this.seconds.set(0);\n this.timer = setInterval(() => this.seconds.set(this.seconds() + 1), 1000);\n } catch (err) {\n this.error.set(err);\n this.cleanup();\n throw err;\n }\n }\n\n /** Stops recording and resolves with the captured audio. */\n stop(): Promise<Blob> {\n const recorder = this.recorder;\n if (!recorder || !this.recording()) {\n return Promise.reject(new Error('MicRecorder.stop() called while not recording.'));\n }\n return new Promise<Blob>((resolve) => {\n recorder.onstop = () => {\n const blob = new Blob(this.chunks, { type: recorder.mimeType || 'audio/webm' });\n this.cleanup();\n resolve(blob);\n };\n recorder.stop();\n });\n }\n\n /** Stops tracks and timers without resolving audio (e.g. on destroy). */\n dispose(): void {\n this.cleanup();\n }\n\n private cleanup(): void {\n if (this.timer !== null) clearInterval(this.timer);\n this.timer = null;\n this.stream?.getTracks().forEach((track) => track.stop());\n this.stream = null;\n this.recorder = null;\n this.recording.set(false);\n }\n}\n\n/** Creates a MicRecorder in an injection context; disposed with the component. */\nexport function createMicRecorder(deps: MicRecorderDeps = {}): MicRecorder {\n const recorder = new MicRecorder(deps);\n inject(DestroyRef, { optional: true })?.onDestroy(() => recorder.dispose());\n return recorder;\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport type { ModelProgress, PipelineStatus } from './transformers.models';\n\n/**\n * Drop-in status line for a PipelineHandle: shows model download progress\n * (over every file of the model) while loading, then the ready/busy/error\n * state. Themeable via CSS custom\n * properties (--nt-accent, --nt-ink, --nt-muted, --nt-track).\n *\n * ```html\n * <ngx-model-progress [status]=\"classifier.status()\" [progress]=\"classifier.progress()\" />\n * ```\n */\n@Component({\n selector: 'ngx-model-progress',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"nt-row\" [class.nt-error]=\"status() === 'error'\" role=\"status\">\n <span class=\"nt-dot\" [attr.data-status]=\"status()\"></span>\n <span class=\"nt-label\">{{ label() }}</span>\n @if (status() === 'loading' && progress(); as p) {\n <span class=\"nt-file\">{{ p.file }}</span>\n @if (p.overall && p.overall.files > 1) {\n <span class=\"nt-files\">{{ p.overall.filesDone }}/{{ p.overall.files }} files</span>\n }\n <div\n class=\"nt-track\"\n role=\"progressbar\"\n [attr.aria-valuenow]=\"percent(p)\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n >\n <div class=\"nt-fill\" [style.width.%]=\"percent(p)\"></div>\n </div>\n <span class=\"nt-pct\">{{ percent(p) }}%</span>\n }\n </div>\n `,\n styles: `\n :host {\n --nt-accent: #f59e0b;\n --nt-ink: #1e293b;\n --nt-muted: #64748b;\n --nt-track: #e2e8f0;\n display: block;\n font-size: 12.5px;\n color: var(--nt-ink);\n }\n .nt-row {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .nt-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex: none;\n background: var(--nt-muted);\n }\n .nt-dot[data-status='loading'] {\n background: var(--nt-accent);\n animation: nt-blink 1s ease-in-out infinite;\n }\n .nt-dot[data-status='ready'] {\n background: #22c55e;\n }\n .nt-dot[data-status='busy'] {\n background: #3b82f6;\n animation: nt-blink 0.7s ease-in-out infinite;\n }\n .nt-dot[data-status='error'] {\n background: #dc2626;\n }\n .nt-label {\n font-weight: 600;\n }\n .nt-file {\n color: var(--nt-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 180px;\n }\n .nt-track {\n flex: 1;\n min-width: 60px;\n height: 6px;\n border-radius: 3px;\n background: var(--nt-track);\n overflow: hidden;\n }\n .nt-fill {\n height: 100%;\n background: var(--nt-accent);\n border-radius: 3px;\n transition: width 120ms linear;\n }\n .nt-files {\n color: var(--nt-muted);\n white-space: nowrap;\n }\n .nt-pct {\n font-variant-numeric: tabular-nums;\n color: var(--nt-muted);\n }\n .nt-error .nt-label {\n color: #dc2626;\n }\n @keyframes nt-blink {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.35;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .nt-dot {\n animation: none;\n }\n .nt-fill {\n transition: none;\n }\n }\n `,\n})\nexport class ModelProgressComponent {\n status = input.required<PipelineStatus>();\n progress = input<ModelProgress | null>(null);\n /** Labels per status; override to localize. */\n labels = input<Partial<Record<PipelineStatus, string>>>({});\n\n /** The bar follows the whole download when the handle reports it, else the current file. */\n percent(progress: ModelProgress): number {\n return progress.overall?.progress ?? progress.progress;\n }\n\n readonly label = computed(() => {\n const defaults: Record<PipelineStatus, string> = {\n idle: 'Model not loaded',\n loading: 'Downloading model',\n ready: 'Model ready',\n busy: 'Running',\n error: 'Failed to load model',\n };\n return this.labels()[this.status()] ?? defaults[this.status()];\n });\n}\n","/**\n * Public API surface of ngx-transformers: handles, wrappers, configuration\n * and the progress component.\n *\n * @module ngx-transformers\n */\n\nexport * from './lib/transformers.models';\nexport * from './lib/transformers.providers';\nexport * from './lib/pipeline';\nexport * from './lib/device-detection';\nexport * from './lib/text-classifier';\nexport * from './lib/text-embedder';\nexport * from './lib/speech-recognizer';\nexport * from './lib/zero-shot-classifier';\nexport * from './lib/translator';\nexport * from './lib/text-generator';\nexport * from './lib/inference-resource';\nexport * from './lib/mic-recorder';\nexport * from './lib/model-progress.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ngx-transformers",
3
- "version": "0.3.0",
4
- "description": "Run Hugging Face Transformers.js models in Angular - on-device ML with a signals API: text classification, zero-shot classification, embeddings, semantic search, translation, Whisper speech-to-text. No server, no API key.",
3
+ "version": "0.4.0",
4
+ "description": "Run Hugging Face Transformers.js models in Angular - on-device ML with a signals API: text classification, zero-shot classification, embeddings, semantic search, translation, Whisper speech-to-text and small LLMs with streaming, in a Web Worker if you like. No server, no API key.",
5
5
  "keywords": [
6
6
  "angular",
7
7
  "transformers",
@@ -19,7 +19,11 @@
19
19
  "speech-to-text",
20
20
  "speech-recognition",
21
21
  "zero-shot-classification",
22
- "translation"
22
+ "translation",
23
+ "text-generation",
24
+ "llm",
25
+ "web-worker",
26
+ "rag"
23
27
  ],
24
28
  "license": "MIT",
25
29
  "author": "Muzaffar Qosimov",
@@ -49,6 +53,10 @@
49
53
  ".": {
50
54
  "types": "./types/ngx-transformers.d.ts",
51
55
  "default": "./fesm2022/ngx-transformers.mjs"
56
+ },
57
+ "./worker": {
58
+ "types": "./types/ngx-transformers-worker.d.ts",
59
+ "default": "./fesm2022/ngx-transformers-worker.mjs"
52
60
  }
53
61
  },
54
62
  "type": "module"
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Messages between the main thread (client.ts) and the worker (host.ts).
3
+ * Every request carries an id the response echoes; pipelines get a pipeId.
4
+ */
5
+ interface CreateRequest {
6
+ type: 'create';
7
+ id: number;
8
+ task: string;
9
+ model?: string;
10
+ /** Pipeline options without functions; progress is reported by message. */
11
+ options: Record<string, unknown>;
12
+ }
13
+ interface RunRequest {
14
+ type: 'run';
15
+ id: number;
16
+ pipeId: number;
17
+ /** The input followed by the pipeline's positional arguments (options last). */
18
+ args: unknown[];
19
+ /** Stream generated text back as `token` messages (the onToken run option). */
20
+ stream: boolean;
21
+ }
22
+ interface DisposeRequest {
23
+ type: 'dispose';
24
+ pipeId: number;
25
+ }
26
+ type WorkerRequest = CreateRequest | RunRequest | DisposeRequest;
27
+ interface CreatedResponse {
28
+ type: 'created';
29
+ id: number;
30
+ pipeId: number;
31
+ }
32
+ interface ResultResponse {
33
+ type: 'result';
34
+ id: number;
35
+ result: unknown;
36
+ }
37
+ interface ErrorResponse {
38
+ type: 'error';
39
+ id: number;
40
+ name: string;
41
+ message: string;
42
+ }
43
+ interface ProgressResponse {
44
+ type: 'progress';
45
+ id: number;
46
+ event: Record<string, unknown>;
47
+ }
48
+ interface TokenResponse {
49
+ type: 'token';
50
+ id: number;
51
+ text: string;
52
+ }
53
+ type WorkerResponse = CreatedResponse | ResultResponse | ErrorResponse | ProgressResponse | TokenResponse;
54
+ /**
55
+ * A Transformers.js Tensor after crossing the worker boundary: the class is
56
+ * lost to structured cloning, so the host sends its shape and buffer.
57
+ */
58
+ interface TensorData {
59
+ dims: number[];
60
+ data: ArrayLike<number>;
61
+ }
62
+
63
+ /**
64
+ * Helpers shared by the in-thread and worker pipeline factories for the run
65
+ * options ngx-transformers adds on top of the Transformers.js ones.
66
+ */
67
+ /** Run option: called with each piece of generated text (text-generation). */
68
+ type OnToken = (text: string) => void;
69
+ /**
70
+ * Pulls the `onToken` callback out of a pipeline call's trailing options
71
+ * object. Returns the arguments without it, plus the callback if present.
72
+ */
73
+ declare function takeOnToken(args: unknown[]): {
74
+ args: unknown[];
75
+ onToken?: OnToken;
76
+ };
77
+ /** A shallow copy of an options object without its function-valued entries. */
78
+ declare function withoutFunctions(options: Record<string, unknown>): Record<string, unknown>;
79
+ /** Same as withoutFunctions() for the trailing options object of a call, if any. */
80
+ declare function withoutFunctionsInLast(args: unknown[]): unknown[];
81
+
82
+ /** The slice of @huggingface/transformers the host uses. */
83
+ interface WorkerTransformersModule {
84
+ pipeline(task: string, model?: string, options?: object): Promise<unknown>;
85
+ TextStreamer?: new (tokenizer: never, options: {
86
+ skip_prompt?: boolean;
87
+ skip_special_tokens?: boolean;
88
+ callback_function?: (text: string) => void;
89
+ }) => unknown;
90
+ }
91
+ interface WorkerHostOptions {
92
+ /** Sends a message to the main thread (postMessage in a worker). */
93
+ post: (message: WorkerResponse, transfer?: Transferable[]) => void;
94
+ /** Imports @huggingface/transformers; tests pass a stub. */
95
+ load?: () => Promise<WorkerTransformersModule>;
96
+ }
97
+ interface WorkerHost {
98
+ /** Handles one request from the main thread. Resolves once the reply is posted. */
99
+ handle(message: WorkerRequest): Promise<void>;
100
+ }
101
+ /**
102
+ * The worker side of ngx-transformers/worker: creates pipelines on request,
103
+ * runs them, streams progress and generated tokens back, and disposes them.
104
+ * runTransformersWorker() wires it to the worker's message port; tests call
105
+ * handle() directly.
106
+ */
107
+ declare function createTransformersWorkerHost(options: WorkerHostOptions): WorkerHost;
108
+ /** The worker global scope surface the host needs. */
109
+ interface WorkerScopeLike {
110
+ postMessage(message: unknown, transfer?: Transferable[]): void;
111
+ onmessage: ((event: {
112
+ data: unknown;
113
+ }) => void) | null;
114
+ }
115
+ /**
116
+ * Entry point for the worker file of an app:
117
+ *
118
+ * ```ts
119
+ * // transformers.worker.ts
120
+ * /// <reference lib="webworker" />
121
+ * import { runTransformersWorker } from 'ngx-transformers/worker';
122
+ * runTransformersWorker();
123
+ * ```
124
+ *
125
+ * Pair it with provideTransformersWorker() on the main thread.
126
+ */
127
+ declare function runTransformersWorker(scope?: WorkerScopeLike, load?: () => Promise<WorkerTransformersModule>): WorkerHost;
128
+
129
+ /** What a worker's 'error' / 'messageerror' event carries, as far as the client reads it. */
130
+ interface WorkerErrorEventLike {
131
+ message?: string;
132
+ data?: unknown;
133
+ }
134
+ /** The Worker surface the client needs; a real Worker satisfies it. */
135
+ interface WorkerLike {
136
+ postMessage(message: unknown, transfer?: Transferable[]): void;
137
+ addEventListener(type: 'message', listener: (event: {
138
+ data: unknown;
139
+ }) => void): void;
140
+ addEventListener(type: 'error' | 'messageerror', listener: (event: WorkerErrorEventLike) => void): void;
141
+ terminate?(): void;
142
+ }
143
+ /** A pipeline proxy on the main thread: calls run in the worker. */
144
+ type WorkerPipeline = ((input: unknown, ...args: unknown[]) => Promise<unknown>) & {
145
+ dispose: () => Promise<void>;
146
+ };
147
+ /** Structurally the same as ngx-transformers' PipelineFactory, plus terminate(). */
148
+ type WorkerPipelineFactory = ((task: string, model: string | undefined, options: Record<string, unknown>) => Promise<WorkerPipeline>) & {
149
+ /** Stops the worker (if one was created); the next pipeline starts a fresh one. */
150
+ terminate(): void;
151
+ };
152
+ /**
153
+ * A pipeline factory whose pipelines live in a Web Worker, so inference
154
+ * never blocks the UI thread. The worker runs runTransformersWorker() and
155
+ * is created lazily, on the first pipeline. Provide the factory through
156
+ * PIPELINE_FACTORY, or use provideTransformersWorker() from
157
+ * ngx-transformers which does exactly that.
158
+ *
159
+ * A worker that fails to start or crashes rejects every pending call and
160
+ * is dropped; the next pipeline creates a new one.
161
+ */
162
+ declare function createWorkerPipelineFactory(worker: WorkerLike | (() => WorkerLike)): WorkerPipelineFactory;
163
+
164
+ export { createTransformersWorkerHost, createWorkerPipelineFactory, runTransformersWorker, takeOnToken, withoutFunctions, withoutFunctionsInLast };
165
+ export type { CreateRequest, CreatedResponse, DisposeRequest, ErrorResponse, OnToken, ProgressResponse, ResultResponse, RunRequest, TensorData, TokenResponse, WorkerErrorEventLike, WorkerHost, WorkerHostOptions, WorkerLike, WorkerPipeline, WorkerPipelineFactory, WorkerRequest, WorkerResponse, WorkerScopeLike, WorkerTransformersModule };