@workglow/ai-provider 0.0.71 → 0.0.72

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.
@@ -3,8 +3,12 @@
3
3
  * Copyright 2025 Steven Roussey <sroussey@gmail.com>
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { AiProviderRunFn, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, TextFillMaskTaskExecuteInput, TextFillMaskTaskExecuteOutput, TextGenerationTaskExecuteInput, TextGenerationTaskExecuteOutput, TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, TextNamedEntityRecognitionTaskExecuteInput, TextNamedEntityRecognitionTaskExecuteOutput, TextQuestionAnswerTaskExecuteInput, TextQuestionAnswerTaskExecuteOutput, TextRewriterTaskExecuteInput, TextRewriterTaskExecuteOutput, TextSummaryTaskExecuteInput, TextSummaryTaskExecuteOutput, TextTranslationTaskExecuteInput, TextTranslationTaskExecuteOutput, UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput } from "@workglow/ai";
6
+ import type { AiProviderRunFn, BackgroundRemovalTaskExecuteInput, BackgroundRemovalTaskExecuteOutput, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, ImageClassificationTaskExecuteInput, ImageClassificationTaskExecuteOutput, ImageEmbeddingTaskExecuteInput, ImageEmbeddingTaskExecuteOutput, ImageSegmentationTaskExecuteInput, ImageSegmentationTaskExecuteOutput, ImageToTextTaskExecuteInput, ImageToTextTaskExecuteOutput, ObjectDetectionTaskExecuteInput, ObjectDetectionTaskExecuteOutput, TextClassificationTaskExecuteInput, TextClassificationTaskExecuteOutput, TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, TextFillMaskTaskExecuteInput, TextFillMaskTaskExecuteOutput, TextGenerationTaskExecuteInput, TextGenerationTaskExecuteOutput, TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, TextNamedEntityRecognitionTaskExecuteInput, TextNamedEntityRecognitionTaskExecuteOutput, TextQuestionAnswerTaskExecuteInput, TextQuestionAnswerTaskExecuteOutput, TextRewriterTaskExecuteInput, TextRewriterTaskExecuteOutput, TextSummaryTaskExecuteInput, TextSummaryTaskExecuteOutput, TextTranslationTaskExecuteInput, TextTranslationTaskExecuteOutput, UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput } from "@workglow/ai";
7
7
  import { HfTransformersOnnxModelRecord } from "./HFT_ModelSchema";
8
+ /**
9
+ * Clear all cached pipelines
10
+ */
11
+ export declare function clearPipelineCache(): void;
8
12
  /**
9
13
  * Core implementation for downloading and caching a Hugging Face Transformers model.
10
14
  * This is shared between inline and worker implementations.
@@ -20,7 +24,7 @@ export declare const HFT_Unload: AiProviderRunFn<UnloadModelTaskExecuteInput, Un
20
24
  * This is shared between inline and worker implementations.
21
25
  */
22
26
  export declare const HFT_TextEmbedding: AiProviderRunFn<TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, HfTransformersOnnxModelRecord>;
23
- export declare const HFT_TextClassifier: AiProviderRunFn<TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, HfTransformersOnnxModelRecord>;
27
+ export declare const HFT_TextClassification: AiProviderRunFn<TextClassificationTaskExecuteInput, TextClassificationTaskExecuteOutput, HfTransformersOnnxModelRecord>;
24
28
  export declare const HFT_TextLanguageDetection: AiProviderRunFn<TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, HfTransformersOnnxModelRecord>;
25
29
  export declare const HFT_TextNamedEntityRecognition: AiProviderRunFn<TextNamedEntityRecognitionTaskExecuteInput, TextNamedEntityRecognitionTaskExecuteOutput, HfTransformersOnnxModelRecord>;
26
30
  export declare const HFT_TextFillMask: AiProviderRunFn<TextFillMaskTaskExecuteInput, TextFillMaskTaskExecuteOutput, HfTransformersOnnxModelRecord>;
@@ -49,4 +53,30 @@ export declare const HFT_TextSummary: AiProviderRunFn<TextSummaryTaskExecuteInpu
49
53
  * This is shared between inline and worker implementations.
50
54
  */
51
55
  export declare const HFT_TextQuestionAnswer: AiProviderRunFn<TextQuestionAnswerTaskExecuteInput, TextQuestionAnswerTaskExecuteOutput, HfTransformersOnnxModelRecord>;
56
+ /**
57
+ * Core implementation for image segmentation using Hugging Face Transformers.
58
+ */
59
+ export declare const HFT_ImageSegmentation: AiProviderRunFn<ImageSegmentationTaskExecuteInput, ImageSegmentationTaskExecuteOutput, HfTransformersOnnxModelRecord>;
60
+ /**
61
+ * Core implementation for image to text using Hugging Face Transformers.
62
+ */
63
+ export declare const HFT_ImageToText: AiProviderRunFn<ImageToTextTaskExecuteInput, ImageToTextTaskExecuteOutput, HfTransformersOnnxModelRecord>;
64
+ /**
65
+ * Core implementation for background removal using Hugging Face Transformers.
66
+ */
67
+ export declare const HFT_BackgroundRemoval: AiProviderRunFn<BackgroundRemovalTaskExecuteInput, BackgroundRemovalTaskExecuteOutput, HfTransformersOnnxModelRecord>;
68
+ /**
69
+ * Core implementation for image embedding using Hugging Face Transformers.
70
+ */
71
+ export declare const HFT_ImageEmbedding: AiProviderRunFn<ImageEmbeddingTaskExecuteInput, ImageEmbeddingTaskExecuteOutput, HfTransformersOnnxModelRecord>;
72
+ /**
73
+ * Core implementation for image classification using Hugging Face Transformers.
74
+ * Auto-selects between regular and zero-shot classification.
75
+ */
76
+ export declare const HFT_ImageClassification: AiProviderRunFn<ImageClassificationTaskExecuteInput, ImageClassificationTaskExecuteOutput, HfTransformersOnnxModelRecord>;
77
+ /**
78
+ * Core implementation for object detection using Hugging Face Transformers.
79
+ * Auto-selects between regular and zero-shot detection.
80
+ */
81
+ export declare const HFT_ObjectDetection: AiProviderRunFn<ObjectDetectionTaskExecuteInput, ObjectDetectionTaskExecuteOutput, HfTransformersOnnxModelRecord>;
52
82
  //# sourceMappingURL=HFT_JobRunFns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HFT_JobRunFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/common/HFT_JobRunFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,8BAA8B,EAC9B,8BAA8B,EAC9B,+BAA+B,EAC/B,6BAA6B,EAC7B,8BAA8B,EAC9B,4BAA4B,EAC5B,6BAA6B,EAC7B,8BAA8B,EAC9B,+BAA+B,EAC/B,qCAAqC,EACrC,sCAAsC,EACtC,0CAA0C,EAC1C,2CAA2C,EAC3C,kCAAkC,EAClC,mCAAmC,EACnC,4BAA4B,EAC5B,6BAA6B,EAC7B,2BAA2B,EAC3B,4BAA4B,EAC5B,+BAA+B,EAC/B,gCAAgC,EAEhC,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAqVlE;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,eAAe,CACxC,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,CAS9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eAAe,CACtC,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,CAgB9B,CAAC;AAwCF;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,eAAe,CAC7C,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,CA0B9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,8BAA8B,EAC9B,+BAA+B,EAC/B,6BAA6B,CAyB9B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,eAAe,CACrD,qCAAqC,EACrC,sCAAsC,EACtC,6BAA6B,CAyB9B,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,eAAe,CAC1D,0CAA0C,EAC1C,2CAA2C,EAC3C,6BAA6B,CA0B9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAC5C,4BAA4B,EAC5B,6BAA6B,EAC7B,6BAA6B,CAmB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,8BAA8B,EAC9B,+BAA+B,EAC/B,6BAA6B,CAwB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAC/C,+BAA+B,EAC/B,gCAAgC,EAChC,6BAA6B,CAyB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAC5C,4BAA4B,EAC5B,6BAA6B,EAC7B,6BAA6B,CA+B9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,eAAe,CAC3C,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,CAsB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAAe,CAClD,kCAAkC,EAClC,mCAAmC,EACnC,6BAA6B,CAuB9B,CAAC"}
1
+ {"version":3,"file":"HFT_JobRunFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/common/HFT_JobRunFns.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"HFT_Client_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Client_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,UAAU,EAAyB,MAAM,cAAc,CAAC;AACxE,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAInF;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
1
+ {"version":3,"file":"HFT_Client_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Client_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,UAAU,EAAyB,MAAM,cAAc,CAAC;AACxE,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAInF;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAmDf"}
@@ -1 +1 @@
1
- {"version":3,"file":"HFT_Inline_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Inline_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAS,UAAU,EAA0C,MAAM,cAAc,CAAC;AACzF,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAiBnF;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
1
+ {"version":3,"file":"HFT_Inline_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Inline_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAS,UAAU,EAA0C,MAAM,cAAc,CAAC;AACzF,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAuBnF;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAmDf"}
@@ -1 +1 @@
1
- {"version":3,"file":"HFT_Worker_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Worker_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH,eAAO,MAAM,iBAAiB,gDAA+C,CAAC;AAE9E,eAAO,MAAM,0BAA0B,MAqBtC,CAAC"}
1
+ {"version":3,"file":"HFT_Worker_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Worker_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH,eAAO,MAAM,iBAAiB,gDAA+C,CAAC;AAE9E,eAAO,MAAM,0BAA0B,MA2BtC,CAAC"}
package/dist/index.js CHANGED
@@ -56,11 +56,14 @@ import {
56
56
  pipeline,
57
57
  TextStreamer
58
58
  } from "@sroussey/transformers";
59
- import { PermanentJobError } from "@workglow/job-queue";
60
59
  var pipelines = new Map;
60
+ function clearPipelineCache() {
61
+ pipelines.clear();
62
+ }
61
63
  var getPipeline = async (model, onProgress, options = {}, progressScaleMax = 10) => {
62
- if (pipelines.has(model.model_id)) {
63
- return pipelines.get(model.model_id);
64
+ const cacheKey = `${model.model_id}:${model.providerConfig.pipeline}`;
65
+ if (pipelines.has(cacheKey)) {
66
+ return pipelines.get(cacheKey);
64
67
  }
65
68
  const fileSizes = new Map;
66
69
  const fileProgress = new Map;
@@ -260,7 +263,7 @@ var getPipeline = async (model, onProgress, options = {}, progressScaleMax = 10)
260
263
  if (abortSignal?.aborted) {
261
264
  throw new Error("Operation aborted after pipeline creation");
262
265
  }
263
- pipelines.set(model.model_id, result);
266
+ pipelines.set(cacheKey, result);
264
267
  return result;
265
268
  } catch (error) {
266
269
  if (abortSignal?.aborted) {
@@ -326,15 +329,30 @@ var HFT_TextEmbedding = async (input, model, onProgress, signal) => {
326
329
  });
327
330
  if (hfVector.size !== model?.providerConfig.nativeDimensions) {
328
331
  console.warn(`HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`, input, hfVector);
329
- throw new PermanentJobError(`HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`);
332
+ throw new Error(`HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`);
330
333
  }
331
334
  return { vector: hfVector.data };
332
335
  };
333
- var HFT_TextClassifier = async (input, model, onProgress, signal) => {
334
- const textClassifier = await getPipeline(model, onProgress, {
336
+ var HFT_TextClassification = async (input, model, onProgress, signal) => {
337
+ if (model?.providerConfig?.pipeline === "zero-shot-classification") {
338
+ if (!input.candidateLabels || !Array.isArray(input.candidateLabels) || input.candidateLabels.length === 0) {
339
+ throw new Error("Zero-shot text classification requires candidate labels");
340
+ }
341
+ const zeroShotClassifier = await getPipeline(model, onProgress, {
342
+ abort_signal: signal
343
+ });
344
+ const result2 = await zeroShotClassifier(input.text, input.candidateLabels, {});
345
+ return {
346
+ categories: result2.labels.map((label, idx) => ({
347
+ label,
348
+ score: result2.scores[idx]
349
+ }))
350
+ };
351
+ }
352
+ const TextClassification = await getPipeline(model, onProgress, {
335
353
  abort_signal: signal
336
354
  });
337
- const result = await textClassifier(input.text, {
355
+ const result = await TextClassification(input.text, {
338
356
  top_k: input.maxCategories || undefined,
339
357
  ...signal ? { abort_signal: signal } : {}
340
358
  });
@@ -354,10 +372,10 @@ var HFT_TextClassifier = async (input, model, onProgress, signal) => {
354
372
  };
355
373
  };
356
374
  var HFT_TextLanguageDetection = async (input, model, onProgress, signal) => {
357
- const textClassifier = await getPipeline(model, onProgress, {
375
+ const TextClassification = await getPipeline(model, onProgress, {
358
376
  abort_signal: signal
359
377
  });
360
- const result = await textClassifier(input.text, {
378
+ const result = await TextClassification(input.text, {
361
379
  top_k: input.maxLanguages || undefined,
362
380
  ...signal ? { abort_signal: signal } : {}
363
381
  });
@@ -478,7 +496,7 @@ var HFT_TextRewriter = async (input, model, onProgress, signal) => {
478
496
  text = text[text.length - 1]?.content;
479
497
  }
480
498
  if (text === promptedText) {
481
- throw new PermanentJobError("Rewriter failed to generate new text");
499
+ throw new Error("Rewriter failed to generate new text");
482
500
  }
483
501
  return {
484
502
  text
@@ -522,6 +540,131 @@ var HFT_TextQuestionAnswer = async (input, model, onProgress, signal) => {
522
540
  text: answerText
523
541
  };
524
542
  };
543
+ var HFT_ImageSegmentation = async (input, model, onProgress, signal) => {
544
+ const segmenter = await getPipeline(model, onProgress, {
545
+ abort_signal: signal
546
+ });
547
+ const result = await segmenter(input.image, {
548
+ threshold: input.threshold,
549
+ mask_threshold: input.maskThreshold,
550
+ ...signal ? { abort_signal: signal } : {}
551
+ });
552
+ const masks = Array.isArray(result) ? result : [result];
553
+ const processedMasks = await Promise.all(masks.map(async (mask) => ({
554
+ label: mask.label || "",
555
+ score: mask.score || 0,
556
+ mask: {}
557
+ })));
558
+ return {
559
+ masks: processedMasks
560
+ };
561
+ };
562
+ var HFT_ImageToText = async (input, model, onProgress, signal) => {
563
+ const captioner = await getPipeline(model, onProgress, {
564
+ abort_signal: signal
565
+ });
566
+ const result = await captioner(input.image, {
567
+ max_new_tokens: input.maxTokens,
568
+ ...signal ? { abort_signal: signal } : {}
569
+ });
570
+ const text = Array.isArray(result) ? result[0]?.generated_text : result?.generated_text;
571
+ return {
572
+ text: text || ""
573
+ };
574
+ };
575
+ var HFT_BackgroundRemoval = async (input, model, onProgress, signal) => {
576
+ const remover = await getPipeline(model, onProgress, {
577
+ abort_signal: signal
578
+ });
579
+ const result = await remover(input.image, {
580
+ ...signal ? { abort_signal: signal } : {}
581
+ });
582
+ const resultImage = Array.isArray(result) ? result[0] : result;
583
+ return {
584
+ image: imageToBase64(resultImage)
585
+ };
586
+ };
587
+ var HFT_ImageEmbedding = async (input, model, onProgress, signal) => {
588
+ const embedder = await getPipeline(model, onProgress, {
589
+ abort_signal: signal
590
+ });
591
+ const result = await embedder(input.image);
592
+ return {
593
+ vector: result.data
594
+ };
595
+ };
596
+ var HFT_ImageClassification = async (input, model, onProgress, signal) => {
597
+ if (model?.providerConfig?.pipeline === "zero-shot-image-classification") {
598
+ if (!input.categories || !Array.isArray(input.categories) || input.categories.length === 0) {
599
+ console.warn("Zero-shot image classification requires categories", input);
600
+ throw new Error("Zero-shot image classification requires categories");
601
+ }
602
+ const zeroShotClassifier = await getPipeline(model, onProgress, {
603
+ abort_signal: signal
604
+ });
605
+ const result2 = await zeroShotClassifier(input.image, input.categories, {});
606
+ const results2 = Array.isArray(result2) ? result2 : [result2];
607
+ return {
608
+ categories: results2.map((r) => ({
609
+ label: r.label,
610
+ score: r.score
611
+ }))
612
+ };
613
+ }
614
+ const classifier = await getPipeline(model, onProgress, {
615
+ abort_signal: signal
616
+ });
617
+ const result = await classifier(input.image, {
618
+ top_k: input.maxCategories,
619
+ ...signal ? { abort_signal: signal } : {}
620
+ });
621
+ const results = Array.isArray(result) ? result : [result];
622
+ return {
623
+ categories: results.map((r) => ({
624
+ label: r.label,
625
+ score: r.score
626
+ }))
627
+ };
628
+ };
629
+ var HFT_ObjectDetection = async (input, model, onProgress, signal) => {
630
+ if (model?.providerConfig?.pipeline === "zero-shot-object-detection") {
631
+ if (!input.labels || !Array.isArray(input.labels) || input.labels.length === 0) {
632
+ throw new Error("Zero-shot object detection requires labels");
633
+ }
634
+ const zeroShotDetector = await getPipeline(model, onProgress, {
635
+ abort_signal: signal
636
+ });
637
+ const result2 = await zeroShotDetector(input.image, Array.from(input.labels), {
638
+ threshold: input.threshold
639
+ });
640
+ const detections2 = Array.isArray(result2) ? result2 : [result2];
641
+ return {
642
+ detections: detections2.map((d) => ({
643
+ label: d.label,
644
+ score: d.score,
645
+ box: d.box
646
+ }))
647
+ };
648
+ }
649
+ const detector = await getPipeline(model, onProgress, {
650
+ abort_signal: signal
651
+ });
652
+ const result = await detector(input.image, {
653
+ threshold: input.threshold,
654
+ ...signal ? { abort_signal: signal } : {}
655
+ });
656
+ const detections = Array.isArray(result) ? result : [result];
657
+ return {
658
+ detections: detections.map((d) => ({
659
+ label: d.label,
660
+ score: d.score,
661
+ box: d.box
662
+ }))
663
+ };
664
+ };
665
+ function imageToBase64(image) {
666
+ return image.toBase64?.() || "";
667
+ }
525
668
  function createTextStreamer(tokenizer, updateProgress, signal) {
526
669
  let count = 0;
527
670
  return new TextStreamer(tokenizer, {
@@ -642,14 +785,20 @@ async function register_HFT_ClientJobFns(worker, client) {
642
785
  "UnloadModelTask",
643
786
  "TextEmbeddingTask",
644
787
  "TextLanguageDetectionTask",
645
- "TextClassifierTask",
788
+ "TextClassificationTask",
646
789
  "TextFillMaskTask",
647
790
  "TextNamedEntityRecognitionTask",
648
791
  "TextGenerationTask",
649
792
  "TextTranslationTask",
650
793
  "TextRewriterTask",
651
794
  "TextSummaryTask",
652
- "TextQuestionAnswerTask"
795
+ "TextQuestionAnswerTask",
796
+ "ImageSegmentationTask",
797
+ "ImageToTextTask",
798
+ "BackgroundRemovalTask",
799
+ "ImageEmbeddingTask",
800
+ "ImageClassificationTask",
801
+ "ObjectDetectionTask"
653
802
  ];
654
803
  for (const name of names) {
655
804
  ProviderRegistry.registerAsWorkerRunFn(HF_TRANSFORMERS_ONNX, name);
@@ -685,12 +834,18 @@ async function register_HFT_InlineJobFns(client) {
685
834
  ["TextGenerationTask"]: HFT_TextGeneration,
686
835
  ["TextQuestionAnswerTask"]: HFT_TextQuestionAnswer,
687
836
  ["TextLanguageDetectionTask"]: HFT_TextLanguageDetection,
688
- ["TextClassifierTask"]: HFT_TextClassifier,
837
+ ["TextClassificationTask"]: HFT_TextClassification,
689
838
  ["TextFillMaskTask"]: HFT_TextFillMask,
690
839
  ["TextNamedEntityRecognitionTask"]: HFT_TextNamedEntityRecognition,
691
840
  ["TextRewriterTask"]: HFT_TextRewriter,
692
841
  ["TextSummaryTask"]: HFT_TextSummary,
693
- ["TextTranslationTask"]: HFT_TextTranslation
842
+ ["TextTranslationTask"]: HFT_TextTranslation,
843
+ ["ImageSegmentationTask"]: HFT_ImageSegmentation,
844
+ ["ImageToTextTask"]: HFT_ImageToText,
845
+ ["BackgroundRemovalTask"]: HFT_BackgroundRemoval,
846
+ ["ImageEmbeddingTask"]: HFT_ImageEmbedding,
847
+ ["ImageClassificationTask"]: HFT_ImageClassification,
848
+ ["ObjectDetectionTask"]: HFT_ObjectDetection
694
849
  };
695
850
  for (const [jobName, fn] of Object.entries(fns)) {
696
851
  ProviderRegistry.registerRunFn(HF_TRANSFORMERS_ONNX, jobName, fn);
@@ -727,13 +882,19 @@ var HFT_WORKER_JOBRUN_REGISTER = globalServiceRegistry2.register(HFT_WORKER_JOBR
727
882
  workerServer.registerFunction("TextEmbeddingTask", HFT_TextEmbedding);
728
883
  workerServer.registerFunction("TextGenerationTask", HFT_TextGeneration);
729
884
  workerServer.registerFunction("TextLanguageDetectionTask", HFT_TextLanguageDetection);
730
- workerServer.registerFunction("TextClassifierTask", HFT_TextClassifier);
885
+ workerServer.registerFunction("TextClassificationTask", HFT_TextClassification);
731
886
  workerServer.registerFunction("TextFillMaskTask", HFT_TextFillMask);
732
887
  workerServer.registerFunction("TextNamedEntityRecognitionTask", HFT_TextNamedEntityRecognition);
733
888
  workerServer.registerFunction("TextTranslationTask", HFT_TextTranslation);
734
889
  workerServer.registerFunction("TextRewriterTask", HFT_TextRewriter);
735
890
  workerServer.registerFunction("TextSummaryTask", HFT_TextSummary);
736
891
  workerServer.registerFunction("TextQuestionAnswerTask", HFT_TextQuestionAnswer);
892
+ workerServer.registerFunction("ImageSegmentationTask", HFT_ImageSegmentation);
893
+ workerServer.registerFunction("ImageToTextTask", HFT_ImageToText);
894
+ workerServer.registerFunction("BackgroundRemovalTask", HFT_BackgroundRemoval);
895
+ workerServer.registerFunction("ImageEmbeddingTask", HFT_ImageEmbedding);
896
+ workerServer.registerFunction("ImageClassificationTask", HFT_ImageClassification);
897
+ workerServer.registerFunction("ObjectDetectionTask", HFT_ObjectDetection);
737
898
  parentPort.postMessage({ type: "ready" });
738
899
  console.log("HFT_WORKER_JOBRUN registered");
739
900
  return workerServer;
@@ -767,17 +928,22 @@ import {
767
928
  TextClassifier,
768
929
  TextEmbedder
769
930
  } from "@mediapipe/tasks-text";
770
- import { PermanentJobError as PermanentJobError2 } from "@workglow/job-queue";
931
+ import {
932
+ ImageClassifier,
933
+ ImageEmbedder,
934
+ ImageSegmenter,
935
+ ObjectDetector
936
+ } from "@mediapipe/tasks-vision";
937
+ import { PermanentJobError } from "@workglow/job-queue";
771
938
  var wasm_tasks = new Map;
772
939
  var wasm_reference_counts = new Map;
773
- var model_to_wasm_mapping = new Map;
774
940
  var getWasmTask = async (model, onProgress, signal) => {
775
941
  const taskEngine = model.providerConfig.taskEngine;
776
942
  if (wasm_tasks.has(taskEngine)) {
777
943
  return wasm_tasks.get(taskEngine);
778
944
  }
779
945
  if (signal.aborted) {
780
- throw new PermanentJobError2("Aborted job");
946
+ throw new PermanentJobError("Aborted job");
781
947
  }
782
948
  onProgress(0.1, "Loading WASM task");
783
949
  let wasmFileset;
@@ -795,7 +961,7 @@ var getWasmTask = async (model, onProgress, signal) => {
795
961
  wasmFileset = await FilesetResolver.forGenAiTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm");
796
962
  break;
797
963
  default:
798
- throw new PermanentJobError2("Invalid task engine");
964
+ throw new PermanentJobError("Invalid task engine");
799
965
  }
800
966
  wasm_tasks.set(taskEngine, wasmFileset);
801
967
  return wasmFileset;
@@ -841,29 +1007,20 @@ var getModelTask = async (model, options, onProgress, signal, TaskType) => {
841
1007
  wasm_reference_counts.set(taskEngine, (wasm_reference_counts.get(taskEngine) || 0) + 1);
842
1008
  return task;
843
1009
  };
844
- var getTextEmbedder = async (model, options, onProgress, signal) => {
845
- return getModelTask(model, options, onProgress, signal, TextEmbedder);
846
- };
847
- var getTextClassifier = async (model, options, onProgress, signal) => {
848
- return getModelTask(model, options, onProgress, signal, TextClassifier);
849
- };
850
- var getTextLanguageDetector = async (model, options, onProgress, signal) => {
851
- return getModelTask(model, options, onProgress, signal, LanguageDetector);
852
- };
853
1010
  var TFMP_Download = async (input, model, onProgress, signal) => {
854
1011
  let task;
855
1012
  switch (model?.providerConfig.pipeline) {
856
1013
  case "text-embedder":
857
- task = await getTextEmbedder(model, {}, onProgress, signal);
1014
+ task = await getModelTask(model, {}, onProgress, signal, TextEmbedder);
858
1015
  break;
859
1016
  case "text-classifier":
860
- task = await getTextClassifier(model, {}, onProgress, signal);
1017
+ task = await getModelTask(model, {}, onProgress, signal, TextClassifier);
861
1018
  break;
862
1019
  case "text-language-detector":
863
- task = await getTextLanguageDetector(model, {}, onProgress, signal);
1020
+ task = await getModelTask(model, {}, onProgress, signal, LanguageDetector);
864
1021
  break;
865
1022
  default:
866
- throw new PermanentJobError2("Invalid pipeline");
1023
+ throw new PermanentJobError("Invalid pipeline");
867
1024
  }
868
1025
  onProgress(0.9, "Pipeline loaded");
869
1026
  task.close();
@@ -874,23 +1031,23 @@ var TFMP_Download = async (input, model, onProgress, signal) => {
874
1031
  };
875
1032
  };
876
1033
  var TFMP_TextEmbedding = async (input, model, onProgress, signal) => {
877
- const textEmbedder = await getTextEmbedder(model, {}, onProgress, signal);
1034
+ const textEmbedder = await getModelTask(model, {}, onProgress, signal, TextEmbedder);
878
1035
  const result = textEmbedder.embed(input.text);
879
1036
  if (!result.embeddings?.[0]?.floatEmbedding) {
880
- throw new PermanentJobError2("Failed to generate embedding: Empty result");
1037
+ throw new PermanentJobError("Failed to generate embedding: Empty result");
881
1038
  }
882
1039
  const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);
883
1040
  return {
884
1041
  vector: embedding
885
1042
  };
886
1043
  };
887
- var TFMP_TextClassifier = async (input, model, onProgress, signal) => {
888
- const textClassifier = await getTextClassifier(model, {
1044
+ var TFMP_TextClassification = async (input, model, onProgress, signal) => {
1045
+ const TextClassification = await getModelTask(model, {
889
1046
  maxCategories: input.maxCategories
890
- }, onProgress, signal);
891
- const result = textClassifier.classify(input.text);
1047
+ }, onProgress, signal, TextClassifier);
1048
+ const result = TextClassification.classify(input.text);
892
1049
  if (!result.classifications?.[0]?.categories) {
893
- throw new PermanentJobError2("Failed to classify text: Empty result");
1050
+ throw new PermanentJobError("Failed to classify text: Empty result");
894
1051
  }
895
1052
  const categories = result.classifications[0].categories.map((category) => ({
896
1053
  label: category.categoryName,
@@ -902,12 +1059,12 @@ var TFMP_TextClassifier = async (input, model, onProgress, signal) => {
902
1059
  };
903
1060
  var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
904
1061
  const maxLanguages = input.maxLanguages === 0 ? -1 : input.maxLanguages;
905
- const textLanguageDetector = await getTextLanguageDetector(model, {
1062
+ const textLanguageDetector = await getModelTask(model, {
906
1063
  maxLanguages
907
- }, onProgress, signal);
1064
+ }, onProgress, signal, LanguageDetector);
908
1065
  const result = textLanguageDetector.detect(input.text);
909
1066
  if (!result.languages?.[0]?.languageCode) {
910
- throw new PermanentJobError2("Failed to detect language: Empty result");
1067
+ throw new PermanentJobError("Failed to detect language: Empty result");
911
1068
  }
912
1069
  const languages = result.languages.map((language) => ({
913
1070
  language: language.languageCode,
@@ -919,11 +1076,13 @@ var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
919
1076
  };
920
1077
  var TFMP_Unload = async (input, model, onProgress, signal) => {
921
1078
  const modelPath = model.providerConfig.modelPath;
1079
+ onProgress(10, "Unloading model");
922
1080
  if (modelTaskCache.has(modelPath)) {
923
1081
  const cachedTasks = modelTaskCache.get(modelPath);
924
1082
  for (const cachedTask of cachedTasks) {
925
1083
  const task = cachedTask.task;
926
- task.close();
1084
+ if ("close" in task && typeof task.close === "function")
1085
+ task.close();
927
1086
  const taskEngine = cachedTask.taskEngine;
928
1087
  const currentCount = wasm_reference_counts.get(taskEngine) || 0;
929
1088
  const newCount = currentCount - 1;
@@ -940,6 +1099,76 @@ var TFMP_Unload = async (input, model, onProgress, signal) => {
940
1099
  model: input.model
941
1100
  };
942
1101
  };
1102
+ var TFMP_ImageSegmentation = async (input, model, onProgress, signal) => {
1103
+ const imageSegmenter = await getModelTask(model, {}, onProgress, signal, ImageSegmenter);
1104
+ const result = imageSegmenter.segment(input.image);
1105
+ if (!result.categoryMask) {
1106
+ throw new PermanentJobError("Failed to segment image: Empty result");
1107
+ }
1108
+ const masks = [
1109
+ {
1110
+ label: "segment",
1111
+ score: 1,
1112
+ mask: {
1113
+ data: result.categoryMask.canvas,
1114
+ width: result.categoryMask.width,
1115
+ height: result.categoryMask.height
1116
+ }
1117
+ }
1118
+ ];
1119
+ return {
1120
+ masks
1121
+ };
1122
+ };
1123
+ var TFMP_ImageEmbedding = async (input, model, onProgress, signal) => {
1124
+ const imageEmbedder = await getModelTask(model, {}, onProgress, signal, ImageEmbedder);
1125
+ const result = imageEmbedder.embed(input.image);
1126
+ if (!result.embeddings?.[0]?.floatEmbedding) {
1127
+ throw new PermanentJobError("Failed to generate embedding: Empty result");
1128
+ }
1129
+ const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);
1130
+ return {
1131
+ vector: embedding
1132
+ };
1133
+ };
1134
+ var TFMP_ImageClassification = async (input, model, onProgress, signal) => {
1135
+ const imageClassifier = await getModelTask(model, {
1136
+ maxResults: input.maxCategories
1137
+ }, onProgress, signal, ImageClassifier);
1138
+ const result = imageClassifier.classify(input.image);
1139
+ if (!result.classifications?.[0]?.categories) {
1140
+ throw new PermanentJobError("Failed to classify image: Empty result");
1141
+ }
1142
+ const categories = result.classifications[0].categories.map((category) => ({
1143
+ label: category.categoryName,
1144
+ score: category.score
1145
+ }));
1146
+ return {
1147
+ categories
1148
+ };
1149
+ };
1150
+ var TFMP_ObjectDetection = async (input, model, onProgress, signal) => {
1151
+ const objectDetector = await getModelTask(model, {
1152
+ scoreThreshold: input.threshold
1153
+ }, onProgress, signal, ObjectDetector);
1154
+ const result = objectDetector.detect(input.image);
1155
+ if (!result.detections) {
1156
+ throw new PermanentJobError("Failed to detect objects: Empty result");
1157
+ }
1158
+ const detections = result.detections.map((detection) => ({
1159
+ label: detection.categories?.[0]?.categoryName || "unknown",
1160
+ score: detection.categories?.[0]?.score || 0,
1161
+ box: {
1162
+ x: detection.boundingBox?.originX || 0,
1163
+ y: detection.boundingBox?.originY || 0,
1164
+ width: detection.boundingBox?.width || 0,
1165
+ height: detection.boundingBox?.height || 0
1166
+ }
1167
+ }));
1168
+ return {
1169
+ detections
1170
+ };
1171
+ };
943
1172
  // src/tf-mediapipe/common/TFMP_ModelSchema.ts
944
1173
  import { ModelSchema as ModelSchema2 } from "@workglow/ai";
945
1174
  var TFMPModelSchema = {
@@ -999,7 +1228,11 @@ async function register_TFMP_ClientJobFns(worker, client) {
999
1228
  "UnloadModelTask",
1000
1229
  "TextEmbeddingTask",
1001
1230
  "TextLanguageDetectionTask",
1002
- "TextClassifierTask"
1231
+ "TextClassificationTask",
1232
+ "ImageSegmentationTask",
1233
+ "ImageEmbeddingTask",
1234
+ "ImageClassificationTask",
1235
+ "ObjectDetectionTask"
1003
1236
  ];
1004
1237
  for (const name of names) {
1005
1238
  aiProviderRegistry.registerAsWorkerRunFn(TENSORFLOW_MEDIAPIPE, name);
@@ -1032,7 +1265,11 @@ async function register_TFMP_InlineJobFns(client) {
1032
1265
  aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "UnloadModelTask", TFMP_Unload);
1033
1266
  aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "TextEmbeddingTask", TFMP_TextEmbedding);
1034
1267
  aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "TextLanguageDetectionTask", TFMP_TextLanguageDetection);
1035
- aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "TextClassifierTask", TFMP_TextClassifier);
1268
+ aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "TextClassificationTask", TFMP_TextClassification);
1269
+ aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "ImageSegmentationTask", TFMP_ImageSegmentation);
1270
+ aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "ImageEmbeddingTask", TFMP_ImageEmbedding);
1271
+ aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "ImageClassificationTask", TFMP_ImageClassification);
1272
+ aiProviderRegistry.registerRunFn(TENSORFLOW_MEDIAPIPE, "ObjectDetectionTask", TFMP_ObjectDetection);
1036
1273
  if (!client) {
1037
1274
  const storage = new InMemoryQueueStorage4(TENSORFLOW_MEDIAPIPE);
1038
1275
  await storage.setupDatabase();
@@ -1064,7 +1301,11 @@ var TFMP_WORKER_JOBRUN_REGISTER = globalServiceRegistry4.register(TFMP_WORKER_JO
1064
1301
  workerServer.registerFunction("UnloadModelTask", TFMP_Unload);
1065
1302
  workerServer.registerFunction("TextEmbeddingTask", TFMP_TextEmbedding);
1066
1303
  workerServer.registerFunction("TextLanguageDetectionTask", TFMP_TextLanguageDetection);
1067
- workerServer.registerFunction("TextClassifierTask", TFMP_TextClassifier);
1304
+ workerServer.registerFunction("TextClassificationTask", TFMP_TextClassification);
1305
+ workerServer.registerFunction("ImageSegmentationTask", TFMP_ImageSegmentation);
1306
+ workerServer.registerFunction("ImageEmbeddingTask", TFMP_ImageEmbedding);
1307
+ workerServer.registerFunction("ImageClassificationTask", TFMP_ImageClassification);
1308
+ workerServer.registerFunction("ObjectDetectionTask", TFMP_ObjectDetection);
1068
1309
  parentPort2.postMessage({ type: "ready" });
1069
1310
  console.log("TFMP_WORKER_JOBRUN registered");
1070
1311
  return workerServer;
@@ -1074,6 +1315,7 @@ export {
1074
1315
  register_TFMP_ClientJobFns,
1075
1316
  register_HFT_InlineJobFns,
1076
1317
  register_HFT_ClientJobFns,
1318
+ clearPipelineCache,
1077
1319
  VisionPipelineUseCase,
1078
1320
  TextPipelineUseCase,
1079
1321
  TextPipelineTask,
@@ -1082,7 +1324,11 @@ export {
1082
1324
  TFMP_Unload,
1083
1325
  TFMP_TextLanguageDetection,
1084
1326
  TFMP_TextEmbedding,
1085
- TFMP_TextClassifier,
1327
+ TFMP_TextClassification,
1328
+ TFMP_ObjectDetection,
1329
+ TFMP_ImageSegmentation,
1330
+ TFMP_ImageEmbedding,
1331
+ TFMP_ImageClassification,
1086
1332
  TFMP_Download,
1087
1333
  TFMPModelSchema,
1088
1334
  TENSORFLOW_MEDIAPIPE,
@@ -1104,9 +1350,15 @@ export {
1104
1350
  HFT_TextGeneration,
1105
1351
  HFT_TextFillMask,
1106
1352
  HFT_TextEmbedding,
1107
- HFT_TextClassifier,
1353
+ HFT_TextClassification,
1354
+ HFT_ObjectDetection,
1355
+ HFT_ImageToText,
1356
+ HFT_ImageSegmentation,
1357
+ HFT_ImageEmbedding,
1358
+ HFT_ImageClassification,
1108
1359
  HFT_Download,
1360
+ HFT_BackgroundRemoval,
1109
1361
  AudioPipelineUseCase
1110
1362
  };
1111
1363
 
1112
- //# debugId=AED2FBB7924C48F164756E2164756E21
1364
+ //# debugId=F27086207C0BB9CB64756E2164756E21
package/dist/index.js.map CHANGED
@@ -3,19 +3,19 @@
3
3
  "sources": ["../src/hf-transformers/common/HFT_Constants.ts", "../src/hf-transformers/common/HFT_JobRunFns.ts", "../src/hf-transformers/common/HFT_ModelSchema.ts", "../src/hf-transformers/registry/HFT_Client_RegisterJobFns.ts", "../src/hf-transformers/registry/HFT_Inline_RegisterJobFns.ts", "../src/hf-transformers/registry/HFT_Worker_RegisterJobFns.ts", "../src/tf-mediapipe/common/TFMP_Constants.ts", "../src/tf-mediapipe/common/TFMP_JobRunFns.ts", "../src/tf-mediapipe/common/TFMP_ModelSchema.ts", "../src/tf-mediapipe/registry/TFMP_Client_RegisterJobFns.ts", "../src/tf-mediapipe/registry/TFMP_Inline_RegisterJobFns.ts", "../src/tf-mediapipe/registry/TFMP_Worker_RegisterJobFns.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const HF_TRANSFORMERS_ONNX = \"HF_TRANSFORMERS_ONNX\";\nexport const HTF_CACHE_NAME = \"transformers-cache\";\n\nexport type QuantizationDataType =\n | \"auto\" // Auto-detect based on environment\n | \"fp32\"\n | \"fp16\"\n | \"q8\"\n | \"int8\"\n | \"uint8\"\n | \"q4\"\n | \"bnb4\"\n | \"q4f16\"; // fp16 model with int4 block weight quantization\n\nexport const QuantizationDataType = {\n auto: \"auto\",\n fp32: \"fp32\",\n fp16: \"fp16\",\n q8: \"q8\",\n int8: \"int8\",\n uint8: \"uint8\",\n q4: \"q4\",\n bnb4: \"bnb4\",\n q4f16: \"q4f16\",\n} as const satisfies Record<QuantizationDataType, QuantizationDataType>;\n\nexport type TextPipelineUseCase =\n | \"fill-mask\" // https://huggingface.co/tasks/fill-mask\n | \"token-classification\" // https://huggingface.co/tasks/token-classification\n | \"text-generation\" // https://huggingface.co/tasks/text-generation#completion-generation-models\n | \"text2text-generation\" // https://huggingface.co/tasks/text-generation#text-to-text-generation-models\n | \"text-classification\" // https://huggingface.co/tasks/text-classification\n | \"summarization\" // https://huggingface.co/tasks/sentence-similarity\n | \"translation\" // https://huggingface.co/tasks/translation\n | \"feature-extraction\" // https://huggingface.co/tasks/feature-extraction\n | \"zero-shot-classification\" // https://huggingface.co/tasks/zero-shot-classification\n | \"question-answering\"; // https://huggingface.co/tasks/question-answering\n\nexport const TextPipelineUseCase = {\n \"fill-mask\": \"fill-mask\",\n \"token-classification\": \"token-classification\",\n \"text-generation\": \"text-generation\",\n \"text2text-generation\": \"text2text-generation\",\n \"text-classification\": \"text-classification\",\n summarization: \"summarization\",\n translation: \"translation\",\n \"feature-extraction\": \"feature-extraction\",\n \"zero-shot-classification\": \"zero-shot-classification\",\n \"question-answering\": \"question-answering\",\n} as const satisfies Record<TextPipelineUseCase, TextPipelineUseCase>;\n\nexport type VisionPipelineUseCase =\n | \"background-removal\" // https://huggingface.co/tasks/image-segmentation#background-removal\n | \"image-segmentation\" // https://huggingface.co/tasks/image-segmentation\n | \"depth-estimation\" // https://huggingface.co/tasks/depth-estimation\n | \"image-classification\" // https://huggingface.co/tasks/image-classification\n | \"image-to-image\" // https://huggingface.co/tasks/image-to-image\n | \"object-detection\" // https://huggingface.co/tasks/object-detection\n | \"image-feature-extraction\"; // https://huggingface.co/tasks/image-feature-extraction\n\nexport const VisionPipelineUseCase = {\n \"background-removal\": \"background-removal\",\n \"image-segmentation\": \"image-segmentation\",\n \"depth-estimation\": \"depth-estimation\",\n \"image-classification\": \"image-classification\",\n \"image-to-image\": \"image-to-image\",\n \"object-detection\": \"object-detection\",\n \"image-feature-extraction\": \"image-feature-extraction\",\n} as const satisfies Record<VisionPipelineUseCase, VisionPipelineUseCase>;\n\nexport type AudioPipelineUseCase =\n | \"audio-classification\" // https://huggingface.co/tasks/audio-classification\n | \"automatic-speech-recognition\" // https://huggingface.co/tasks/automatic-speech-recognition\n | \"text-to-speech\"; // https://huggingface.co/tasks/text-to-speech\n\nexport const AudioPipelineUseCase = {\n \"audio-classification\": \"audio-classification\",\n \"automatic-speech-recognition\": \"automatic-speech-recognition\",\n \"text-to-speech\": \"text-to-speech\",\n} as const satisfies Record<AudioPipelineUseCase, AudioPipelineUseCase>;\n\nexport type MultimodalPipelineUseCase =\n | \"document-question-answering\" // https://huggingface.co/tasks/document-question-answering\n | \"image-to-text\" // https://huggingface.co/tasks/image-to-text\n | \"zero-shot-audio-classification\" // https://huggingface.co/tasks/zero-shot-audio-classification\n | \"zero-shot-image-classification\" // https://huggingface.co/tasks/zero-shot-image-classification\n | \"zero-shot-object-detection\"; // https://huggingface.co/tasks/zero-shot-object-detection\n\nexport const MultimodalPipelineUseCase = {\n \"document-question-answering\": \"document-question-answering\",\n \"image-to-text\": \"image-to-text\",\n \"zero-shot-audio-classification\": \"zero-shot-audio-classification\",\n \"zero-shot-image-classification\": \"zero-shot-image-classification\",\n \"zero-shot-object-detection\": \"zero-shot-object-detection\",\n} as const satisfies Record<MultimodalPipelineUseCase, MultimodalPipelineUseCase>;\n\nexport type PipelineUseCase =\n | TextPipelineUseCase\n | VisionPipelineUseCase\n | AudioPipelineUseCase\n | MultimodalPipelineUseCase;\n\nexport const PipelineUseCase = {\n ...TextPipelineUseCase,\n ...VisionPipelineUseCase,\n ...AudioPipelineUseCase,\n ...MultimodalPipelineUseCase,\n} as const satisfies Record<PipelineUseCase, PipelineUseCase>;\n",
6
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n DocumentQuestionAnsweringSingle,\n type FeatureExtractionPipeline,\n FillMaskPipeline,\n FillMaskSingle,\n pipeline,\n // @ts-ignore temporary \"fix\"\n type PretrainedModelOptions,\n QuestionAnsweringPipeline,\n SummarizationPipeline,\n SummarizationSingle,\n TextClassificationOutput,\n TextClassificationPipeline,\n type TextGenerationPipeline,\n TextGenerationSingle,\n TextStreamer,\n TokenClassificationPipeline,\n TokenClassificationSingle,\n TranslationPipeline,\n TranslationSingle,\n} from \"@sroussey/transformers\";\nimport {\n AiProviderRunFn,\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n TextClassifierTaskExecuteInput,\n TextClassifierTaskExecuteOutput,\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n TextFillMaskTaskExecuteInput,\n TextFillMaskTaskExecuteOutput,\n TextGenerationTaskExecuteInput,\n TextGenerationTaskExecuteOutput,\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n TextNamedEntityRecognitionTaskExecuteInput,\n TextNamedEntityRecognitionTaskExecuteOutput,\n TextQuestionAnswerTaskExecuteInput,\n TextQuestionAnswerTaskExecuteOutput,\n TextRewriterTaskExecuteInput,\n TextRewriterTaskExecuteOutput,\n TextSummaryTaskExecuteInput,\n TextSummaryTaskExecuteOutput,\n TextTranslationTaskExecuteInput,\n TextTranslationTaskExecuteOutput,\n TypedArray,\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n} from \"@workglow/ai\";\nimport { PermanentJobError } from \"@workglow/job-queue\";\nimport { CallbackStatus } from \"./HFT_CallbackStatus\";\nimport { HTF_CACHE_NAME } from \"./HFT_Constants\";\nimport { HfTransformersOnnxModelRecord } from \"./HFT_ModelSchema\";\n\nconst pipelines = new Map<string, any>();\n\n/**\n * Helper function to get a pipeline for a model\n * @param progressScaleMax - Maximum progress value for download phase (100 for download-only, 10 for download+run)\n */\nconst getPipeline = async (\n model: HfTransformersOnnxModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n options: PretrainedModelOptions = {},\n progressScaleMax: number = 10\n) => {\n if (pipelines.has(model.model_id)) {\n return pipelines.get(model.model_id);\n }\n\n // Track file sizes and progress for weighted calculation\n const fileSizes = new Map<string, number>();\n const fileProgress = new Map<string, number>();\n const fileCompleted = new Set<string>();\n const fileFirstSent = new Set<string>();\n const fileLastSent = new Set<string>();\n const fileLastEventTime = new Map<string, number>();\n const pendingProgressByFile = new Map<\n string,\n { progress: number; file: string; fileProgress: number }\n >();\n let throttleTimer: ReturnType<typeof setTimeout> | null = null;\n const THROTTLE_MS = 160;\n\n // Pre-estimate total download size based on typical model structure:\n // 3 tiny files (~1KB each) + 1 medium file (~20MB) + 0-2 large files (~1GB each if present)\n const estimatedTinyFiles = 3;\n const estimatedMediumFiles = 1;\n const estimatedTinySize = 1024; // 1KB\n const estimatedMediumSize = 20 * 1024 * 1024; // 20MB\n const estimatedLargeSize = 1024 * 1024 * 1024; // 1GB\n\n // Start with minimum estimate (4 files), add large files dynamically as we discover them\n const baseEstimate =\n estimatedTinyFiles * estimatedTinySize + estimatedMediumFiles * estimatedMediumSize;\n\n /**\n * Sends a progress event, respecting throttling but always sending first/last per file\n */\n const sendProgress = (\n overallProgress: number,\n file: string,\n fileProgressValue: number,\n isFirst: boolean,\n isLast: boolean\n ): void => {\n const now = Date.now();\n const lastTime = fileLastEventTime.get(file) || 0;\n const timeSinceLastEvent = now - lastTime;\n const shouldThrottle = !isFirst && !isLast && timeSinceLastEvent < THROTTLE_MS;\n\n if (shouldThrottle) {\n // Store pending progress for this file\n pendingProgressByFile.set(file, {\n progress: overallProgress,\n file,\n fileProgress: fileProgressValue,\n });\n // Schedule sending if not already scheduled\n if (!throttleTimer) {\n const timeRemaining = Math.max(1, THROTTLE_MS - timeSinceLastEvent);\n throttleTimer = setTimeout(() => {\n // Send all pending progress events\n for (const [pendingFile, pending] of pendingProgressByFile.entries()) {\n onProgress(Math.round(pending.progress), \"Downloading model\", {\n file: pendingFile,\n progress: pending.fileProgress,\n });\n fileLastEventTime.set(pendingFile, Date.now());\n }\n pendingProgressByFile.clear();\n throttleTimer = null;\n }, timeRemaining);\n }\n return;\n }\n\n // Send immediately\n onProgress(Math.round(overallProgress), \"Downloading model\", {\n file,\n progress: fileProgressValue,\n });\n fileLastEventTime.set(file, now);\n // Clear any pending progress for this file since we're sending it now\n pendingProgressByFile.delete(file);\n if (throttleTimer && pendingProgressByFile.size === 0) {\n clearTimeout(throttleTimer);\n throttleTimer = null;\n }\n };\n\n // Track whether we've seen a substantial file (to avoid premature progress reports for tiny config files)\n let hasSeenSubstantialFile = false;\n const substantialFileThreshold = 1024 * 1024; // 1MB - files larger than this are substantial\n\n // Get the abort signal from options if provided\n const abortSignal = options.abort_signal;\n\n // Create a callback status object for progress tracking\n const progressCallback = (status: CallbackStatus) => {\n // Check if operation has been aborted before processing progress\n if (abortSignal?.aborted) {\n return; // Don't process progress for aborted operations\n }\n\n if (status.status === \"progress\") {\n const file = status.file;\n const fileTotal = status.total;\n const fileProgressValue = status.progress;\n\n // Track file size on first progress event\n if (!fileSizes.has(file)) {\n fileSizes.set(file, fileTotal);\n fileProgress.set(file, 0);\n\n // Check if this is a substantial file\n if (fileTotal >= substantialFileThreshold) {\n hasSeenSubstantialFile = true;\n }\n }\n\n // Update file progress\n fileProgress.set(file, fileProgressValue);\n\n // Check if file is complete\n const isComplete = fileProgressValue >= 100;\n if (isComplete && !fileCompleted.has(file)) {\n fileCompleted.add(file);\n fileProgress.set(file, 100);\n }\n\n // Calculate actual loaded bytes and adjust estimated total\n let actualLoadedSize = 0;\n let actualTotalSize = 0;\n\n // Categorize seen files and track their actual sizes\n const tinyThreshold = 100 * 1024; // 100KB - files smaller are config/vocab\n const mediumThreshold = 100 * 1024 * 1024; // 100MB - tokenizer and small models\n let seenTinyCount = 0;\n let seenMediumCount = 0;\n let seenLargeCount = 0;\n\n for (const [trackedFile, size] of fileSizes.entries()) {\n actualTotalSize += size;\n const progress = fileProgress.get(trackedFile) || 0;\n actualLoadedSize += (size * progress) / 100;\n\n // Categorize file\n if (size < tinyThreshold) {\n seenTinyCount++;\n } else if (size < mediumThreshold) {\n seenMediumCount++;\n } else {\n seenLargeCount++;\n }\n }\n\n // Adjust estimated total size:\n // - Start with actual sizes of seen files\n // - Add estimates for unseen tiny/medium files\n // - For large files: conservatively assume 1 until we've seen all expected files\n const unseenTinyFiles = Math.max(0, estimatedTinyFiles - seenTinyCount);\n const unseenMediumFiles = Math.max(0, estimatedMediumFiles - seenMediumCount);\n\n // Dynamically estimate large files:\n // - If we've seen a large file, assume up to 2 total\n // - Otherwise, conservatively assume 1 large file might exist to prevent premature 100% progress\n // - This prevents the progress from jumping when a large file appears unexpectedly\n let estimatedLargeFiles: number;\n if (seenLargeCount > 0) {\n estimatedLargeFiles = 2; // We've seen at least one, expect up to 2\n } else {\n estimatedLargeFiles = 1; // Haven't seen any large files yet, but assume 1 might exist\n }\n const unseenLargeFiles = Math.max(0, estimatedLargeFiles - seenLargeCount);\n\n const adjustedTotalSize =\n actualTotalSize +\n unseenTinyFiles * estimatedTinySize +\n unseenMediumFiles * estimatedMediumSize +\n unseenLargeFiles * estimatedLargeSize;\n\n // Scale progress to the configured range (0-100 for download-only, 0-10 for download+run)\n const rawProgress = adjustedTotalSize > 0 ? (actualLoadedSize / adjustedTotalSize) * 100 : 0;\n const overallProgress = (rawProgress * progressScaleMax) / 100;\n\n // Determine if this is first or last event for this file\n const isFirst = !fileFirstSent.has(file);\n const isLast = isComplete && !fileLastSent.has(file);\n\n if (isFirst) {\n fileFirstSent.add(file);\n }\n if (isLast) {\n fileLastSent.add(file);\n }\n\n // Only report progress if we've seen a substantial file (to avoid premature 100% for tiny config files)\n if (hasSeenSubstantialFile) {\n sendProgress(overallProgress, file, fileProgressValue, isFirst, isLast);\n }\n } else if (status.status === \"done\" || status.status === \"download\") {\n // Handle file completion from bookend events\n const file = status.file;\n\n // Check if this file should mark the start of substantial downloads\n const fileSize = fileSizes.get(file) || 0;\n if (fileSize >= substantialFileThreshold) {\n hasSeenSubstantialFile = true;\n }\n\n if (!fileCompleted.has(file)) {\n fileCompleted.add(file);\n fileProgress.set(file, 100);\n\n // Recalculate overall progress using same logic as progress handler\n let actualLoadedSize = 0;\n let actualTotalSize = 0;\n\n const tinyThreshold = 100 * 1024; // 100KB - files smaller are config/vocab\n const mediumThreshold = 100 * 1024 * 1024; // 100MB - tokenizer and small models\n let seenTinyCount = 0;\n let seenMediumCount = 0;\n let seenLargeCount = 0;\n\n for (const [trackedFile, size] of fileSizes.entries()) {\n actualTotalSize += size;\n const progress = fileProgress.get(trackedFile) || 0;\n actualLoadedSize += (size * progress) / 100;\n\n // Categorize file\n if (size < tinyThreshold) {\n seenTinyCount++;\n } else if (size < mediumThreshold) {\n seenMediumCount++;\n } else {\n seenLargeCount++;\n }\n }\n\n // Adjust estimated total size (same logic as progress handler)\n const unseenTinyFiles = Math.max(0, estimatedTinyFiles - seenTinyCount);\n const unseenMediumFiles = Math.max(0, estimatedMediumFiles - seenMediumCount);\n\n // Dynamically estimate large files (same logic as progress handler)\n let estimatedLargeFiles: number;\n if (seenLargeCount > 0) {\n estimatedLargeFiles = 2;\n } else {\n estimatedLargeFiles = 1;\n }\n const unseenLargeFiles = Math.max(0, estimatedLargeFiles - seenLargeCount);\n\n const adjustedTotalSize =\n actualTotalSize +\n unseenTinyFiles * estimatedTinySize +\n unseenMediumFiles * estimatedMediumSize +\n unseenLargeFiles * estimatedLargeSize;\n\n // Scale progress to the configured range (0-100 for download-only, 0-10 for download+run)\n const rawProgress =\n adjustedTotalSize > 0 ? (actualLoadedSize / adjustedTotalSize) * 100 : 0;\n const overallProgress = (rawProgress * progressScaleMax) / 100;\n const isLast = !fileLastSent.has(file);\n if (isLast) {\n fileLastSent.add(file);\n // Only report if we've seen a substantial file\n if (hasSeenSubstantialFile) {\n sendProgress(overallProgress, file, 100, false, true);\n }\n }\n }\n }\n };\n\n const pipelineOptions: PretrainedModelOptions = {\n dtype: model.providerConfig.dType || \"q8\",\n ...(model.providerConfig.useExternalDataFormat\n ? { use_external_data_format: model.providerConfig.useExternalDataFormat }\n : {}),\n ...(model.providerConfig.device ? { device: model.providerConfig.device as any } : {}),\n ...options,\n progress_callback: progressCallback,\n };\n\n // Check if already aborted before starting\n if (abortSignal?.aborted) {\n throw new Error(\"Operation aborted before pipeline creation\");\n }\n\n const pipelineType = model.providerConfig.pipeline;\n\n // Wrap the pipeline call with abort handling\n // Create a promise that rejects when aborted\n const abortPromise = new Promise<never>((_, reject) => {\n if (abortSignal) {\n const handleAbort = () => {\n reject(new Error(\"Pipeline download aborted\"));\n };\n\n if (abortSignal.aborted) {\n handleAbort();\n } else {\n abortSignal.addEventListener(\"abort\", handleAbort, { once: true });\n }\n }\n });\n\n // Race between pipeline creation and abort\n const pipelinePromise = pipeline(pipelineType, model.providerConfig.modelPath, pipelineOptions);\n\n try {\n const result = await (abortSignal\n ? Promise.race([pipelinePromise, abortPromise])\n : pipelinePromise);\n\n // Check if aborted after pipeline creation\n if (abortSignal?.aborted) {\n throw new Error(\"Operation aborted after pipeline creation\");\n }\n\n pipelines.set(model.model_id, result);\n return result;\n } catch (error: any) {\n // If aborted, throw a clean abort error rather than internal stream errors\n if (abortSignal?.aborted) {\n throw new Error(\"Pipeline download aborted\");\n }\n // Otherwise, re-throw the original error\n throw error;\n }\n};\n\n/**\n * Core implementation for downloading and caching a Hugging Face Transformers model.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_Download: AiProviderRunFn<\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n // Download the model by creating a pipeline\n // Use 100 as progressScaleMax since this is download-only (0-100%)\n await getPipeline(model!, onProgress, { abort_signal: signal }, 100);\n\n return {\n model: input.model!,\n };\n};\n\n/**\n * Core implementation for unloading a Hugging Face Transformers model.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_Unload: AiProviderRunFn<\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n // Delete the pipeline from the in-memory map\n if (pipelines.has(model!.model_id)) {\n pipelines.delete(model!.model_id);\n onProgress(50, \"Pipeline removed from memory\");\n }\n\n // Delete model cache entries\n const modelPath = model!.providerConfig.modelPath;\n await deleteModelCache(modelPath);\n onProgress(100, \"Model cache deleted\");\n\n return {\n model: input.model!,\n };\n};\n\n/**\n * Deletes all cache entries for a given model path\n * @param modelPath - The model path to delete from cache\n */\nconst deleteModelCache = async (modelPath: string): Promise<void> => {\n const cache = await caches.open(HTF_CACHE_NAME);\n const keys = await cache.keys();\n const prefix = `/${modelPath}/`;\n\n // Collect all matching requests first\n const requestsToDelete: Request[] = [];\n for (const request of keys) {\n const url = new URL(request.url);\n if (url.pathname.startsWith(prefix)) {\n requestsToDelete.push(request);\n }\n }\n\n // Delete all matching requests\n let deletedCount = 0;\n for (const request of requestsToDelete) {\n try {\n const deleted = await cache.delete(request);\n if (deleted) {\n deletedCount++;\n } else {\n // If delete returns false, try with URL string as fallback\n const deletedByUrl = await cache.delete(request.url);\n if (deletedByUrl) {\n deletedCount++;\n }\n }\n } catch (error) {\n console.error(`Failed to delete cache entry: ${request.url}`, error);\n }\n }\n};\n\n/**\n * Core implementation for text embedding using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\n\nexport const HFT_TextEmbedding: AiProviderRunFn<\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateEmbedding: FeatureExtractionPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n // Generate the embedding\n const hfVector = await generateEmbedding(input.text, {\n pooling: \"mean\",\n normalize: model?.providerConfig.normalize,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n // Validate the embedding dimensions\n if (hfVector.size !== model?.providerConfig.nativeDimensions) {\n console.warn(\n `HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`,\n input,\n hfVector\n );\n throw new PermanentJobError(\n `HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`\n );\n }\n\n return { vector: hfVector.data as TypedArray };\n};\n\nexport const HFT_TextClassifier: AiProviderRunFn<\n TextClassifierTaskExecuteInput,\n TextClassifierTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const textClassifier: TextClassificationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const result = await textClassifier(input.text, {\n top_k: input.maxCategories || undefined,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (Array.isArray(result[0])) {\n return {\n categories: result[0].map((category) => ({\n label: category.label,\n score: category.score,\n })),\n };\n }\n\n return {\n categories: (result as TextClassificationOutput).map((category) => ({\n label: category.label,\n score: category.score,\n })),\n };\n};\n\nexport const HFT_TextLanguageDetection: AiProviderRunFn<\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const textClassifier: TextClassificationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const result = await textClassifier(input.text, {\n top_k: input.maxLanguages || undefined,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (Array.isArray(result[0])) {\n return {\n languages: result[0].map((category) => ({\n language: category.label,\n score: category.score,\n })),\n };\n }\n\n return {\n languages: (result as TextClassificationOutput).map((category) => ({\n language: category.label,\n score: category.score,\n })),\n };\n};\n\nexport const HFT_TextNamedEntityRecognition: AiProviderRunFn<\n TextNamedEntityRecognitionTaskExecuteInput,\n TextNamedEntityRecognitionTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const textNamedEntityRecognition: TokenClassificationPipeline = await getPipeline(\n model!,\n onProgress,\n {\n abort_signal: signal,\n }\n );\n let results = await textNamedEntityRecognition(input.text, {\n ignore_labels: input.blockList as string[] | undefined,\n ...(signal ? { abort_signal: signal } : {}),\n });\n let entities: TokenClassificationSingle[] = [];\n if (!Array.isArray(results)) {\n entities = [results];\n } else {\n entities = results as TokenClassificationSingle[];\n }\n return {\n entities: entities.map((entity) => ({\n entity: entity.entity,\n score: entity.score,\n word: entity.word,\n })),\n };\n};\n\nexport const HFT_TextFillMask: AiProviderRunFn<\n TextFillMaskTaskExecuteInput,\n TextFillMaskTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const unmasker: FillMaskPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n let results = await unmasker(input.text);\n let predictions: FillMaskSingle[] = [];\n if (!Array.isArray(results)) {\n predictions = [results];\n } else {\n predictions = results as FillMaskSingle[];\n }\n return {\n predictions: predictions.map((prediction) => ({\n entity: prediction.token_str,\n score: prediction.score,\n sequence: prediction.sequence,\n })),\n };\n};\n\n/**\n * Core implementation for text generation using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextGeneration: AiProviderRunFn<\n TextGenerationTaskExecuteInput,\n TextGenerationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateText: TextGenerationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n const streamer = createTextStreamer(generateText.tokenizer, onProgress, signal);\n\n let results = await generateText(input.prompt, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (!Array.isArray(results)) {\n results = [results];\n }\n let text = (results[0] as TextGenerationSingle)?.generated_text;\n\n if (Array.isArray(text)) {\n text = text[text.length - 1]?.content;\n }\n return {\n text,\n };\n};\n\n/**\n * Core implementation for text translation using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextTranslation: AiProviderRunFn<\n TextTranslationTaskExecuteInput,\n TextTranslationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const translate: TranslationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(translate.tokenizer, onProgress);\n\n const result = await translate(input.text, {\n src_lang: input.source_lang,\n tgt_lang: input.target_lang,\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n } as any);\n\n let translatedText: string | string[] = \"\";\n if (Array.isArray(result)) {\n translatedText = result.map((r) => (r as TranslationSingle)?.translation_text || \"\");\n } else {\n translatedText = (result as TranslationSingle)?.translation_text || \"\";\n }\n\n return {\n text: translatedText,\n target_lang: input.target_lang,\n };\n};\n\n/**\n * Core implementation for text rewriting using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextRewriter: AiProviderRunFn<\n TextRewriterTaskExecuteInput,\n TextRewriterTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateText: TextGenerationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(generateText.tokenizer, onProgress);\n\n // This lib doesn't support this kind of rewriting with a separate prompt vs text\n const promptedText = (input.prompt ? input.prompt + \"\\n\" : \"\") + input.text;\n\n let results = await generateText(promptedText, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (!Array.isArray(results)) {\n results = [results];\n }\n\n let text = (results[0] as TextGenerationSingle)?.generated_text;\n if (Array.isArray(text)) {\n text = text[text.length - 1]?.content;\n }\n\n if (text === promptedText) {\n throw new PermanentJobError(\"Rewriter failed to generate new text\");\n }\n\n return {\n text,\n };\n};\n\n/**\n * Core implementation for text summarization using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextSummary: AiProviderRunFn<\n TextSummaryTaskExecuteInput,\n TextSummaryTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateSummary: SummarizationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(generateSummary.tokenizer, onProgress);\n\n let result = await generateSummary(input.text, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n } as any);\n\n let summaryText = \"\";\n if (Array.isArray(result)) {\n summaryText = (result[0] as SummarizationSingle)?.summary_text || \"\";\n } else {\n summaryText = (result as SummarizationSingle)?.summary_text || \"\";\n }\n\n return {\n text: summaryText,\n };\n};\n\n/**\n * Core implementation for question answering using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextQuestionAnswer: AiProviderRunFn<\n TextQuestionAnswerTaskExecuteInput,\n TextQuestionAnswerTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n // Get the question answering pipeline\n const generateAnswer: QuestionAnsweringPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(generateAnswer.tokenizer, onProgress);\n\n const result = await generateAnswer(input.question, input.context, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n } as any);\n\n let answerText = \"\";\n if (Array.isArray(result)) {\n answerText = (result[0] as DocumentQuestionAnsweringSingle)?.answer || \"\";\n } else {\n answerText = (result as DocumentQuestionAnsweringSingle)?.answer || \"\";\n }\n\n return {\n text: answerText,\n };\n};\n\n/**\n * Create a text streamer for a given tokenizer and update progress function\n * @param tokenizer - The tokenizer to use for the streamer\n * @param updateProgress - The function to call to update the progress\n * @param signal - The signal to use for the streamer for aborting\n * @returns The text streamer\n */\nfunction createTextStreamer(\n tokenizer: any,\n updateProgress: (progress: number, message?: string, details?: any) => void,\n signal?: AbortSignal\n) {\n let count = 0;\n return new TextStreamer(tokenizer, {\n skip_prompt: true,\n decode_kwargs: { skip_special_tokens: true },\n callback_function: (text: string) => {\n count++;\n const result = 100 * (1 - Math.exp(-0.05 * count));\n const progress = Math.round(Math.min(result, 100));\n updateProgress(progress, \"Generating\", { text, progress });\n },\n ...(signal ? { abort_signal: signal } : {}),\n });\n}\n",
6
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type BackgroundRemovalPipeline,\n DocumentQuestionAnsweringSingle,\n type FeatureExtractionPipeline,\n FillMaskPipeline,\n FillMaskSingle,\n type ImageClassificationPipeline,\n type ImageFeatureExtractionPipeline,\n type ImageSegmentationPipeline,\n type ImageToTextPipeline,\n type ObjectDetectionPipeline,\n pipeline,\n // @ts-ignore temporary \"fix\"\n type PretrainedModelOptions,\n QuestionAnsweringPipeline,\n RawImage,\n SummarizationPipeline,\n SummarizationSingle,\n TextClassificationOutput,\n TextClassificationPipeline,\n type TextGenerationPipeline,\n TextGenerationSingle,\n TextStreamer,\n TokenClassificationPipeline,\n TokenClassificationSingle,\n TranslationPipeline,\n TranslationSingle,\n type ZeroShotClassificationPipeline,\n type ZeroShotImageClassificationPipeline,\n type ZeroShotObjectDetectionPipeline,\n} from \"@sroussey/transformers\";\nimport type {\n AiProviderRunFn,\n BackgroundRemovalTaskExecuteInput,\n BackgroundRemovalTaskExecuteOutput,\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n ImageClassificationTaskExecuteInput,\n ImageClassificationTaskExecuteOutput,\n ImageEmbeddingTaskExecuteInput,\n ImageEmbeddingTaskExecuteOutput,\n ImageSegmentationTaskExecuteInput,\n ImageSegmentationTaskExecuteOutput,\n ImageToTextTaskExecuteInput,\n ImageToTextTaskExecuteOutput,\n ObjectDetectionTaskExecuteInput,\n ObjectDetectionTaskExecuteOutput,\n TextClassificationTaskExecuteInput,\n TextClassificationTaskExecuteOutput,\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n TextFillMaskTaskExecuteInput,\n TextFillMaskTaskExecuteOutput,\n TextGenerationTaskExecuteInput,\n TextGenerationTaskExecuteOutput,\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n TextNamedEntityRecognitionTaskExecuteInput,\n TextNamedEntityRecognitionTaskExecuteOutput,\n TextQuestionAnswerTaskExecuteInput,\n TextQuestionAnswerTaskExecuteOutput,\n TextRewriterTaskExecuteInput,\n TextRewriterTaskExecuteOutput,\n TextSummaryTaskExecuteInput,\n TextSummaryTaskExecuteOutput,\n TextTranslationTaskExecuteInput,\n TextTranslationTaskExecuteOutput,\n TypedArray,\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n} from \"@workglow/ai\";\nimport { CallbackStatus } from \"./HFT_CallbackStatus\";\nimport { HTF_CACHE_NAME } from \"./HFT_Constants\";\nimport { HfTransformersOnnxModelRecord } from \"./HFT_ModelSchema\";\n\nconst pipelines = new Map<string, any>();\n\n/**\n * Clear all cached pipelines\n */\nexport function clearPipelineCache(): void {\n pipelines.clear();\n}\n\n/**\n * Helper function to get a pipeline for a model\n * @param progressScaleMax - Maximum progress value for download phase (100 for download-only, 10 for download+run)\n */\nconst getPipeline = async (\n model: HfTransformersOnnxModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n options: PretrainedModelOptions = {},\n progressScaleMax: number = 10\n) => {\n const cacheKey = `${model.model_id}:${model.providerConfig.pipeline}`;\n if (pipelines.has(cacheKey)) {\n return pipelines.get(cacheKey);\n }\n\n // Track file sizes and progress for weighted calculation\n const fileSizes = new Map<string, number>();\n const fileProgress = new Map<string, number>();\n const fileCompleted = new Set<string>();\n const fileFirstSent = new Set<string>();\n const fileLastSent = new Set<string>();\n const fileLastEventTime = new Map<string, number>();\n const pendingProgressByFile = new Map<\n string,\n { progress: number; file: string; fileProgress: number }\n >();\n let throttleTimer: ReturnType<typeof setTimeout> | null = null;\n const THROTTLE_MS = 160;\n\n // Pre-estimate total download size based on typical model structure:\n // 3 tiny files (~1KB each) + 1 medium file (~20MB) + 0-2 large files (~1GB each if present)\n const estimatedTinyFiles = 3;\n const estimatedMediumFiles = 1;\n const estimatedTinySize = 1024; // 1KB\n const estimatedMediumSize = 20 * 1024 * 1024; // 20MB\n const estimatedLargeSize = 1024 * 1024 * 1024; // 1GB\n\n // Start with minimum estimate (4 files), add large files dynamically as we discover them\n const baseEstimate =\n estimatedTinyFiles * estimatedTinySize + estimatedMediumFiles * estimatedMediumSize;\n\n /**\n * Sends a progress event, respecting throttling but always sending first/last per file\n */\n const sendProgress = (\n overallProgress: number,\n file: string,\n fileProgressValue: number,\n isFirst: boolean,\n isLast: boolean\n ): void => {\n const now = Date.now();\n const lastTime = fileLastEventTime.get(file) || 0;\n const timeSinceLastEvent = now - lastTime;\n const shouldThrottle = !isFirst && !isLast && timeSinceLastEvent < THROTTLE_MS;\n\n if (shouldThrottle) {\n // Store pending progress for this file\n pendingProgressByFile.set(file, {\n progress: overallProgress,\n file,\n fileProgress: fileProgressValue,\n });\n // Schedule sending if not already scheduled\n if (!throttleTimer) {\n const timeRemaining = Math.max(1, THROTTLE_MS - timeSinceLastEvent);\n throttleTimer = setTimeout(() => {\n // Send all pending progress events\n for (const [pendingFile, pending] of pendingProgressByFile.entries()) {\n onProgress(Math.round(pending.progress), \"Downloading model\", {\n file: pendingFile,\n progress: pending.fileProgress,\n });\n fileLastEventTime.set(pendingFile, Date.now());\n }\n pendingProgressByFile.clear();\n throttleTimer = null;\n }, timeRemaining);\n }\n return;\n }\n\n // Send immediately\n onProgress(Math.round(overallProgress), \"Downloading model\", {\n file,\n progress: fileProgressValue,\n });\n fileLastEventTime.set(file, now);\n // Clear any pending progress for this file since we're sending it now\n pendingProgressByFile.delete(file);\n if (throttleTimer && pendingProgressByFile.size === 0) {\n clearTimeout(throttleTimer);\n throttleTimer = null;\n }\n };\n\n // Track whether we've seen a substantial file (to avoid premature progress reports for tiny config files)\n let hasSeenSubstantialFile = false;\n const substantialFileThreshold = 1024 * 1024; // 1MB - files larger than this are substantial\n\n // Get the abort signal from options if provided\n const abortSignal = options.abort_signal;\n\n // Create a callback status object for progress tracking\n const progressCallback = (status: CallbackStatus) => {\n // Check if operation has been aborted before processing progress\n if (abortSignal?.aborted) {\n return; // Don't process progress for aborted operations\n }\n\n if (status.status === \"progress\") {\n const file = status.file;\n const fileTotal = status.total;\n const fileProgressValue = status.progress;\n\n // Track file size on first progress event\n if (!fileSizes.has(file)) {\n fileSizes.set(file, fileTotal);\n fileProgress.set(file, 0);\n\n // Check if this is a substantial file\n if (fileTotal >= substantialFileThreshold) {\n hasSeenSubstantialFile = true;\n }\n }\n\n // Update file progress\n fileProgress.set(file, fileProgressValue);\n\n // Check if file is complete\n const isComplete = fileProgressValue >= 100;\n if (isComplete && !fileCompleted.has(file)) {\n fileCompleted.add(file);\n fileProgress.set(file, 100);\n }\n\n // Calculate actual loaded bytes and adjust estimated total\n let actualLoadedSize = 0;\n let actualTotalSize = 0;\n\n // Categorize seen files and track their actual sizes\n const tinyThreshold = 100 * 1024; // 100KB - files smaller are config/vocab\n const mediumThreshold = 100 * 1024 * 1024; // 100MB - tokenizer and small models\n let seenTinyCount = 0;\n let seenMediumCount = 0;\n let seenLargeCount = 0;\n\n for (const [trackedFile, size] of fileSizes.entries()) {\n actualTotalSize += size;\n const progress = fileProgress.get(trackedFile) || 0;\n actualLoadedSize += (size * progress) / 100;\n\n // Categorize file\n if (size < tinyThreshold) {\n seenTinyCount++;\n } else if (size < mediumThreshold) {\n seenMediumCount++;\n } else {\n seenLargeCount++;\n }\n }\n\n // Adjust estimated total size:\n // - Start with actual sizes of seen files\n // - Add estimates for unseen tiny/medium files\n // - For large files: conservatively assume 1 until we've seen all expected files\n const unseenTinyFiles = Math.max(0, estimatedTinyFiles - seenTinyCount);\n const unseenMediumFiles = Math.max(0, estimatedMediumFiles - seenMediumCount);\n\n // Dynamically estimate large files:\n // - If we've seen a large file, assume up to 2 total\n // - Otherwise, conservatively assume 1 large file might exist to prevent premature 100% progress\n // - This prevents the progress from jumping when a large file appears unexpectedly\n let estimatedLargeFiles: number;\n if (seenLargeCount > 0) {\n estimatedLargeFiles = 2; // We've seen at least one, expect up to 2\n } else {\n estimatedLargeFiles = 1; // Haven't seen any large files yet, but assume 1 might exist\n }\n const unseenLargeFiles = Math.max(0, estimatedLargeFiles - seenLargeCount);\n\n const adjustedTotalSize =\n actualTotalSize +\n unseenTinyFiles * estimatedTinySize +\n unseenMediumFiles * estimatedMediumSize +\n unseenLargeFiles * estimatedLargeSize;\n\n // Scale progress to the configured range (0-100 for download-only, 0-10 for download+run)\n const rawProgress = adjustedTotalSize > 0 ? (actualLoadedSize / adjustedTotalSize) * 100 : 0;\n const overallProgress = (rawProgress * progressScaleMax) / 100;\n\n // Determine if this is first or last event for this file\n const isFirst = !fileFirstSent.has(file);\n const isLast = isComplete && !fileLastSent.has(file);\n\n if (isFirst) {\n fileFirstSent.add(file);\n }\n if (isLast) {\n fileLastSent.add(file);\n }\n\n // Only report progress if we've seen a substantial file (to avoid premature 100% for tiny config files)\n if (hasSeenSubstantialFile) {\n sendProgress(overallProgress, file, fileProgressValue, isFirst, isLast);\n }\n } else if (status.status === \"done\" || status.status === \"download\") {\n // Handle file completion from bookend events\n const file = status.file;\n\n // Check if this file should mark the start of substantial downloads\n const fileSize = fileSizes.get(file) || 0;\n if (fileSize >= substantialFileThreshold) {\n hasSeenSubstantialFile = true;\n }\n\n if (!fileCompleted.has(file)) {\n fileCompleted.add(file);\n fileProgress.set(file, 100);\n\n // Recalculate overall progress using same logic as progress handler\n let actualLoadedSize = 0;\n let actualTotalSize = 0;\n\n const tinyThreshold = 100 * 1024; // 100KB - files smaller are config/vocab\n const mediumThreshold = 100 * 1024 * 1024; // 100MB - tokenizer and small models\n let seenTinyCount = 0;\n let seenMediumCount = 0;\n let seenLargeCount = 0;\n\n for (const [trackedFile, size] of fileSizes.entries()) {\n actualTotalSize += size;\n const progress = fileProgress.get(trackedFile) || 0;\n actualLoadedSize += (size * progress) / 100;\n\n // Categorize file\n if (size < tinyThreshold) {\n seenTinyCount++;\n } else if (size < mediumThreshold) {\n seenMediumCount++;\n } else {\n seenLargeCount++;\n }\n }\n\n // Adjust estimated total size (same logic as progress handler)\n const unseenTinyFiles = Math.max(0, estimatedTinyFiles - seenTinyCount);\n const unseenMediumFiles = Math.max(0, estimatedMediumFiles - seenMediumCount);\n\n // Dynamically estimate large files (same logic as progress handler)\n let estimatedLargeFiles: number;\n if (seenLargeCount > 0) {\n estimatedLargeFiles = 2;\n } else {\n estimatedLargeFiles = 1;\n }\n const unseenLargeFiles = Math.max(0, estimatedLargeFiles - seenLargeCount);\n\n const adjustedTotalSize =\n actualTotalSize +\n unseenTinyFiles * estimatedTinySize +\n unseenMediumFiles * estimatedMediumSize +\n unseenLargeFiles * estimatedLargeSize;\n\n // Scale progress to the configured range (0-100 for download-only, 0-10 for download+run)\n const rawProgress =\n adjustedTotalSize > 0 ? (actualLoadedSize / adjustedTotalSize) * 100 : 0;\n const overallProgress = (rawProgress * progressScaleMax) / 100;\n const isLast = !fileLastSent.has(file);\n if (isLast) {\n fileLastSent.add(file);\n // Only report if we've seen a substantial file\n if (hasSeenSubstantialFile) {\n sendProgress(overallProgress, file, 100, false, true);\n }\n }\n }\n }\n };\n\n const pipelineOptions: PretrainedModelOptions = {\n dtype: model.providerConfig.dType || \"q8\",\n ...(model.providerConfig.useExternalDataFormat\n ? { use_external_data_format: model.providerConfig.useExternalDataFormat }\n : {}),\n ...(model.providerConfig.device ? { device: model.providerConfig.device as any } : {}),\n ...options,\n progress_callback: progressCallback,\n };\n\n // Check if already aborted before starting\n if (abortSignal?.aborted) {\n throw new Error(\"Operation aborted before pipeline creation\");\n }\n\n const pipelineType = model.providerConfig.pipeline;\n\n // Wrap the pipeline call with abort handling\n // Create a promise that rejects when aborted\n const abortPromise = new Promise<never>((_, reject) => {\n if (abortSignal) {\n const handleAbort = () => {\n reject(new Error(\"Pipeline download aborted\"));\n };\n\n if (abortSignal.aborted) {\n handleAbort();\n } else {\n abortSignal.addEventListener(\"abort\", handleAbort, { once: true });\n }\n }\n });\n\n // Race between pipeline creation and abort\n const pipelinePromise = pipeline(pipelineType, model.providerConfig.modelPath, pipelineOptions);\n\n try {\n const result = await (abortSignal\n ? Promise.race([pipelinePromise, abortPromise])\n : pipelinePromise);\n\n // Check if aborted after pipeline creation\n if (abortSignal?.aborted) {\n throw new Error(\"Operation aborted after pipeline creation\");\n }\n\n pipelines.set(cacheKey, result);\n return result;\n } catch (error: any) {\n // If aborted, throw a clean abort error rather than internal stream errors\n if (abortSignal?.aborted) {\n throw new Error(\"Pipeline download aborted\");\n }\n // Otherwise, re-throw the original error\n throw error;\n }\n};\n\n/**\n * Core implementation for downloading and caching a Hugging Face Transformers model.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_Download: AiProviderRunFn<\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n // Download the model by creating a pipeline\n // Use 100 as progressScaleMax since this is download-only (0-100%)\n await getPipeline(model!, onProgress, { abort_signal: signal }, 100);\n\n return {\n model: input.model!,\n };\n};\n\n/**\n * Core implementation for unloading a Hugging Face Transformers model.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_Unload: AiProviderRunFn<\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n // Delete the pipeline from the in-memory map\n if (pipelines.has(model!.model_id)) {\n pipelines.delete(model!.model_id);\n onProgress(50, \"Pipeline removed from memory\");\n }\n\n // Delete model cache entries\n const modelPath = model!.providerConfig.modelPath;\n await deleteModelCache(modelPath);\n onProgress(100, \"Model cache deleted\");\n\n return {\n model: input.model!,\n };\n};\n\n/**\n * Deletes all cache entries for a given model path\n * @param modelPath - The model path to delete from cache\n */\nconst deleteModelCache = async (modelPath: string): Promise<void> => {\n const cache = await caches.open(HTF_CACHE_NAME);\n const keys = await cache.keys();\n const prefix = `/${modelPath}/`;\n\n // Collect all matching requests first\n const requestsToDelete: Request[] = [];\n for (const request of keys) {\n const url = new URL(request.url);\n if (url.pathname.startsWith(prefix)) {\n requestsToDelete.push(request);\n }\n }\n\n // Delete all matching requests\n let deletedCount = 0;\n for (const request of requestsToDelete) {\n try {\n const deleted = await cache.delete(request);\n if (deleted) {\n deletedCount++;\n } else {\n // If delete returns false, try with URL string as fallback\n const deletedByUrl = await cache.delete(request.url);\n if (deletedByUrl) {\n deletedCount++;\n }\n }\n } catch (error) {\n console.error(`Failed to delete cache entry: ${request.url}`, error);\n }\n }\n};\n\n/**\n * Core implementation for text embedding using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\n\nexport const HFT_TextEmbedding: AiProviderRunFn<\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateEmbedding: FeatureExtractionPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n // Generate the embedding\n const hfVector = await generateEmbedding(input.text, {\n pooling: \"mean\",\n normalize: model?.providerConfig.normalize,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n // Validate the embedding dimensions\n if (hfVector.size !== model?.providerConfig.nativeDimensions) {\n console.warn(\n `HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`,\n input,\n hfVector\n );\n throw new Error(\n `HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${model?.providerConfig.nativeDimensions}`\n );\n }\n\n return { vector: hfVector.data as TypedArray };\n};\n\nexport const HFT_TextClassification: AiProviderRunFn<\n TextClassificationTaskExecuteInput,\n TextClassificationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n if (model?.providerConfig?.pipeline === \"zero-shot-classification\") {\n if (\n !input.candidateLabels ||\n !Array.isArray(input.candidateLabels) ||\n input.candidateLabels.length === 0\n ) {\n throw new Error(\"Zero-shot text classification requires candidate labels\");\n }\n\n const zeroShotClassifier: ZeroShotClassificationPipeline = await getPipeline(\n model!,\n onProgress,\n {\n abort_signal: signal,\n }\n );\n const result: any = await zeroShotClassifier(input.text, input.candidateLabels as string[], {});\n\n return {\n categories: result.labels.map((label: string, idx: number) => ({\n label,\n score: result.scores[idx],\n })),\n };\n }\n\n const TextClassification: TextClassificationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const result = await TextClassification(input.text, {\n top_k: input.maxCategories || undefined,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (Array.isArray(result[0])) {\n return {\n categories: result[0].map((category) => ({\n label: category.label,\n score: category.score,\n })),\n };\n }\n\n return {\n categories: (result as TextClassificationOutput).map((category) => ({\n label: category.label,\n score: category.score,\n })),\n };\n};\n\nexport const HFT_TextLanguageDetection: AiProviderRunFn<\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const TextClassification: TextClassificationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const result = await TextClassification(input.text, {\n top_k: input.maxLanguages || undefined,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (Array.isArray(result[0])) {\n return {\n languages: result[0].map((category) => ({\n language: category.label,\n score: category.score,\n })),\n };\n }\n\n return {\n languages: (result as TextClassificationOutput).map((category) => ({\n language: category.label,\n score: category.score,\n })),\n };\n};\n\nexport const HFT_TextNamedEntityRecognition: AiProviderRunFn<\n TextNamedEntityRecognitionTaskExecuteInput,\n TextNamedEntityRecognitionTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const textNamedEntityRecognition: TokenClassificationPipeline = await getPipeline(\n model!,\n onProgress,\n {\n abort_signal: signal,\n }\n );\n let results = await textNamedEntityRecognition(input.text, {\n ignore_labels: input.blockList as string[] | undefined,\n ...(signal ? { abort_signal: signal } : {}),\n });\n let entities: TokenClassificationSingle[] = [];\n if (!Array.isArray(results)) {\n entities = [results];\n } else {\n entities = results as TokenClassificationSingle[];\n }\n return {\n entities: entities.map((entity) => ({\n entity: entity.entity,\n score: entity.score,\n word: entity.word,\n })),\n };\n};\n\nexport const HFT_TextFillMask: AiProviderRunFn<\n TextFillMaskTaskExecuteInput,\n TextFillMaskTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const unmasker: FillMaskPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n let results = await unmasker(input.text);\n let predictions: FillMaskSingle[] = [];\n if (!Array.isArray(results)) {\n predictions = [results];\n } else {\n predictions = results as FillMaskSingle[];\n }\n return {\n predictions: predictions.map((prediction) => ({\n entity: prediction.token_str,\n score: prediction.score,\n sequence: prediction.sequence,\n })),\n };\n};\n\n/**\n * Core implementation for text generation using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextGeneration: AiProviderRunFn<\n TextGenerationTaskExecuteInput,\n TextGenerationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateText: TextGenerationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n const streamer = createTextStreamer(generateText.tokenizer, onProgress, signal);\n\n let results = await generateText(input.prompt, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (!Array.isArray(results)) {\n results = [results];\n }\n let text = (results[0] as TextGenerationSingle)?.generated_text;\n\n if (Array.isArray(text)) {\n text = text[text.length - 1]?.content;\n }\n return {\n text,\n };\n};\n\n/**\n * Core implementation for text translation using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextTranslation: AiProviderRunFn<\n TextTranslationTaskExecuteInput,\n TextTranslationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const translate: TranslationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(translate.tokenizer, onProgress);\n\n const result = await translate(input.text, {\n src_lang: input.source_lang,\n tgt_lang: input.target_lang,\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n } as any);\n\n let translatedText: string | string[] = \"\";\n if (Array.isArray(result)) {\n translatedText = result.map((r) => (r as TranslationSingle)?.translation_text || \"\");\n } else {\n translatedText = (result as TranslationSingle)?.translation_text || \"\";\n }\n\n return {\n text: translatedText,\n target_lang: input.target_lang,\n };\n};\n\n/**\n * Core implementation for text rewriting using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextRewriter: AiProviderRunFn<\n TextRewriterTaskExecuteInput,\n TextRewriterTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateText: TextGenerationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(generateText.tokenizer, onProgress);\n\n // This lib doesn't support this kind of rewriting with a separate prompt vs text\n const promptedText = (input.prompt ? input.prompt + \"\\n\" : \"\") + input.text;\n\n let results = await generateText(promptedText, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n if (!Array.isArray(results)) {\n results = [results];\n }\n\n let text = (results[0] as TextGenerationSingle)?.generated_text;\n if (Array.isArray(text)) {\n text = text[text.length - 1]?.content;\n }\n\n if (text === promptedText) {\n throw new Error(\"Rewriter failed to generate new text\");\n }\n\n return {\n text,\n };\n};\n\n/**\n * Core implementation for text summarization using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextSummary: AiProviderRunFn<\n TextSummaryTaskExecuteInput,\n TextSummaryTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const generateSummary: SummarizationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(generateSummary.tokenizer, onProgress);\n\n let result = await generateSummary(input.text, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n } as any);\n\n let summaryText = \"\";\n if (Array.isArray(result)) {\n summaryText = (result[0] as SummarizationSingle)?.summary_text || \"\";\n } else {\n summaryText = (result as SummarizationSingle)?.summary_text || \"\";\n }\n\n return {\n text: summaryText,\n };\n};\n\n/**\n * Core implementation for question answering using Hugging Face Transformers.\n * This is shared between inline and worker implementations.\n */\nexport const HFT_TextQuestionAnswer: AiProviderRunFn<\n TextQuestionAnswerTaskExecuteInput,\n TextQuestionAnswerTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n // Get the question answering pipeline\n const generateAnswer: QuestionAnsweringPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const streamer = createTextStreamer(generateAnswer.tokenizer, onProgress);\n\n const result = await generateAnswer(input.question, input.context, {\n streamer,\n ...(signal ? { abort_signal: signal } : {}),\n } as any);\n\n let answerText = \"\";\n if (Array.isArray(result)) {\n answerText = (result[0] as DocumentQuestionAnsweringSingle)?.answer || \"\";\n } else {\n answerText = (result as DocumentQuestionAnsweringSingle)?.answer || \"\";\n }\n\n return {\n text: answerText,\n };\n};\n\n/**\n * Core implementation for image segmentation using Hugging Face Transformers.\n */\nexport const HFT_ImageSegmentation: AiProviderRunFn<\n ImageSegmentationTaskExecuteInput,\n ImageSegmentationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const segmenter: ImageSegmentationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n const result = await segmenter(input.image as any, {\n threshold: input.threshold,\n mask_threshold: input.maskThreshold,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n const masks = Array.isArray(result) ? result : [result];\n\n const processedMasks = await Promise.all(\n masks.map(async (mask) => ({\n label: mask.label || \"\",\n score: mask.score || 0,\n mask: {} as { [x: string]: unknown },\n }))\n );\n\n return {\n masks: processedMasks,\n };\n};\n\n/**\n * Core implementation for image to text using Hugging Face Transformers.\n */\nexport const HFT_ImageToText: AiProviderRunFn<\n ImageToTextTaskExecuteInput,\n ImageToTextTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const captioner: ImageToTextPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n const result: any = await captioner(input.image as string, {\n max_new_tokens: input.maxTokens,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n const text = Array.isArray(result) ? result[0]?.generated_text : result?.generated_text;\n\n return {\n text: text || \"\",\n };\n};\n\n/**\n * Core implementation for background removal using Hugging Face Transformers.\n */\nexport const HFT_BackgroundRemoval: AiProviderRunFn<\n BackgroundRemovalTaskExecuteInput,\n BackgroundRemovalTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const remover: BackgroundRemovalPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n const result = await remover(input.image as string, {\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n const resultImage = Array.isArray(result) ? result[0] : result;\n\n return {\n image: imageToBase64(resultImage),\n };\n};\n\n/**\n * Core implementation for image embedding using Hugging Face Transformers.\n */\nexport const HFT_ImageEmbedding: AiProviderRunFn<\n ImageEmbeddingTaskExecuteInput,\n ImageEmbeddingTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n const embedder: ImageFeatureExtractionPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n\n const result: any = await embedder(input.image as string);\n\n return {\n vector: result.data as TypedArray,\n };\n};\n\n/**\n * Core implementation for image classification using Hugging Face Transformers.\n * Auto-selects between regular and zero-shot classification.\n */\nexport const HFT_ImageClassification: AiProviderRunFn<\n ImageClassificationTaskExecuteInput,\n ImageClassificationTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n if (model?.providerConfig?.pipeline === \"zero-shot-image-classification\") {\n if (!input.categories || !Array.isArray(input.categories) || input.categories.length === 0) {\n console.warn(\"Zero-shot image classification requires categories\", input);\n throw new Error(\"Zero-shot image classification requires categories\");\n }\n const zeroShotClassifier: ZeroShotImageClassificationPipeline = await getPipeline(\n model!,\n onProgress,\n {\n abort_signal: signal,\n }\n );\n const result: any = await zeroShotClassifier(\n input.image as string,\n input.categories! as string[],\n {}\n );\n\n const results = Array.isArray(result) ? result : [result];\n\n return {\n categories: results.map((r: any) => ({\n label: r.label,\n score: r.score,\n })),\n };\n }\n\n const classifier: ImageClassificationPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const result: any = await classifier(input.image as string, {\n top_k: (input as any).maxCategories,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n const results = Array.isArray(result) ? result : [result];\n\n return {\n categories: results.map((r: any) => ({\n label: r.label,\n score: r.score,\n })),\n };\n};\n\n/**\n * Core implementation for object detection using Hugging Face Transformers.\n * Auto-selects between regular and zero-shot detection.\n */\nexport const HFT_ObjectDetection: AiProviderRunFn<\n ObjectDetectionTaskExecuteInput,\n ObjectDetectionTaskExecuteOutput,\n HfTransformersOnnxModelRecord\n> = async (input, model, onProgress, signal) => {\n if (model?.providerConfig?.pipeline === \"zero-shot-object-detection\") {\n if (!input.labels || !Array.isArray(input.labels) || input.labels.length === 0) {\n throw new Error(\"Zero-shot object detection requires labels\");\n }\n const zeroShotDetector: ZeroShotObjectDetectionPipeline = await getPipeline(\n model!,\n onProgress,\n {\n abort_signal: signal,\n }\n );\n const result: any = await zeroShotDetector(input.image as string, Array.from(input.labels!), {\n threshold: (input as any).threshold,\n });\n\n const detections = Array.isArray(result) ? result : [result];\n\n return {\n detections: detections.map((d: any) => ({\n label: d.label,\n score: d.score,\n box: d.box,\n })),\n };\n }\n\n const detector: ObjectDetectionPipeline = await getPipeline(model!, onProgress, {\n abort_signal: signal,\n });\n const result: any = await detector(input.image as string, {\n threshold: (input as any).threshold,\n ...(signal ? { abort_signal: signal } : {}),\n });\n\n const detections = Array.isArray(result) ? result : [result];\n\n return {\n detections: detections.map((d: any) => ({\n label: d.label,\n score: d.score,\n box: d.box,\n })),\n };\n};\n/**\n * Helper function to convert RawImage to base64 PNG\n */\nfunction imageToBase64(image: RawImage): string {\n // Convert RawImage to base64 PNG\n // This is a simplified version - actual implementation would use canvas or similar\n return (image as any).toBase64?.() || \"\";\n}\n\n\n/**\n * Create a text streamer for a given tokenizer and update progress function\n * @param tokenizer - The tokenizer to use for the streamer\n * @param updateProgress - The function to call to update the progress\n * @param signal - The signal to use for the streamer for aborting\n * @returns The text streamer\n */\nfunction createTextStreamer(\n tokenizer: any,\n updateProgress: (progress: number, message?: string, details?: any) => void,\n signal?: AbortSignal\n) {\n let count = 0;\n return new TextStreamer(tokenizer, {\n skip_prompt: true,\n decode_kwargs: { skip_special_tokens: true },\n callback_function: (text: string) => {\n count++;\n const result = 100 * (1 - Math.exp(-0.05 * count));\n const progress = Math.round(Math.min(result, 100));\n updateProgress(progress, \"Generating\", { text, progress });\n },\n ...(signal ? { abort_signal: signal } : {}),\n });\n}\n",
7
7
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ModelSchema } from \"@workglow/ai\";\nimport { DataPortSchemaObject, FromSchema } from \"@workglow/util\";\nimport { HF_TRANSFORMERS_ONNX, PipelineUseCase, QuantizationDataType } from \"./HFT_Constants\";\n\nexport const HfTransformersOnnxModelSchema = {\n type: \"object\",\n properties: {\n provider: {\n const: HF_TRANSFORMERS_ONNX,\n description: \"Discriminator: ONNX runtime backend.\",\n },\n providerConfig: {\n type: \"object\",\n description: \"ONNX runtime-specific options.\",\n properties: {\n pipeline: {\n type: \"string\",\n enum: Object.values(PipelineUseCase),\n description: \"Pipeline type for the ONNX model.\",\n default: \"text-generation\",\n },\n modelPath: {\n type: \"string\",\n description: \"Filesystem path or URI for the ONNX model.\",\n },\n dType: {\n type: \"string\",\n enum: Object.values(QuantizationDataType),\n description: \"Data type for the ONNX model.\",\n default: \"float32\",\n },\n device: {\n type: \"string\",\n enum: [\"cpu\", \"gpu\", \"webgpu\", \"wasm\", \"metal\"],\n description: \"High-level device selection.\",\n default: \"webgpu\",\n },\n executionProviders: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Raw ONNX Runtime execution provider identifiers.\",\n },\n intraOpNumThreads: {\n type: \"integer\",\n minimum: 1,\n },\n interOpNumThreads: {\n type: \"integer\",\n minimum: 1,\n },\n useExternalDataFormat: {\n type: \"boolean\",\n description: \"Whether the model uses external data format.\",\n },\n nativeDimensions: {\n type: \"integer\",\n description: \"The native dimensions of the model.\",\n },\n normalize: {\n type: \"boolean\",\n description: \"Whether the model uses normalization.\",\n },\n languageStyle: {\n type: \"string\",\n description: \"The language style of the model.\",\n },\n },\n required: [\"modelPath\", \"pipeline\"],\n additionalProperties: false,\n if: {\n properties: {\n pipeline: {\n const: \"feature-extraction\",\n },\n },\n },\n then: {\n required: [\"nativeDimensions\"],\n },\n },\n },\n required: [\"provider\", \"providerConfig\"],\n additionalProperties: true,\n} as const satisfies DataPortSchemaObject;\n\nconst ExtendedModelSchema = {\n type: \"object\",\n properties: {\n ...ModelSchema.properties,\n ...HfTransformersOnnxModelSchema.properties,\n },\n required: [...ModelSchema.required, ...HfTransformersOnnxModelSchema.required],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\n\nexport type HfTransformersOnnxModelRecord = FromSchema<typeof ExtendedModelSchema>;\n",
8
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AiJob, AiJobInput, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { globalServiceRegistry, WORKER_MANAGER } from \"@workglow/util\";\nimport { HF_TRANSFORMERS_ONNX } from \"../common/HFT_Constants\";\n\n/**\n * Registers the HuggingFace Transformers client job functions with a web worker.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param worker - The web worker to use for job execution\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_HFT_ClientJobFns(\n worker: Worker,\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n const workerManager = globalServiceRegistry.get(WORKER_MANAGER);\n\n workerManager.registerWorker(HF_TRANSFORMERS_ONNX, worker);\n\n const ProviderRegistry = getAiProviderRegistry();\n const names = [\n \"DownloadModelTask\",\n \"UnloadModelTask\",\n \"TextEmbeddingTask\",\n \"TextLanguageDetectionTask\",\n \"TextClassifierTask\",\n \"TextFillMaskTask\",\n \"TextNamedEntityRecognitionTask\",\n \"TextGenerationTask\",\n \"TextTranslationTask\",\n \"TextRewriterTask\",\n \"TextSummaryTask\",\n \"TextQuestionAnswerTask\",\n ];\n for (const name of names) {\n ProviderRegistry.registerAsWorkerRunFn(HF_TRANSFORMERS_ONNX, name);\n }\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n HF_TRANSFORMERS_ONNX\n );\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n // await server.start();\n }\n}\n",
9
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { env } from \"@sroussey/transformers\";\nimport { AiJob, AiJobInput, AiProviderRunFn, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { HF_TRANSFORMERS_ONNX } from \"../common/HFT_Constants\";\nimport {\n HFT_Download,\n HFT_TextClassifier,\n HFT_TextEmbedding,\n HFT_TextFillMask,\n HFT_TextGeneration,\n HFT_TextLanguageDetection,\n HFT_TextNamedEntityRecognition,\n HFT_TextQuestionAnswer,\n HFT_TextRewriter,\n HFT_TextSummary,\n HFT_TextTranslation,\n HFT_Unload,\n} from \"../common/HFT_JobRunFns\";\n\n/**\n * Registers the HuggingFace Transformers inline job functions for same-thread execution.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_HFT_InlineJobFns(\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n // @ts-ignore\n env.backends.onnx.wasm.proxy = true;\n const ProviderRegistry = getAiProviderRegistry();\n const fns: Record<string, AiProviderRunFn<any, any, any>> = {\n [\"DownloadModelTask\"]: HFT_Download,\n [\"UnloadModelTask\"]: HFT_Unload,\n [\"TextEmbeddingTask\"]: HFT_TextEmbedding,\n [\"TextGenerationTask\"]: HFT_TextGeneration,\n [\"TextQuestionAnswerTask\"]: HFT_TextQuestionAnswer,\n [\"TextLanguageDetectionTask\"]: HFT_TextLanguageDetection,\n [\"TextClassifierTask\"]: HFT_TextClassifier,\n [\"TextFillMaskTask\"]: HFT_TextFillMask,\n [\"TextNamedEntityRecognitionTask\"]: HFT_TextNamedEntityRecognition,\n [\"TextRewriterTask\"]: HFT_TextRewriter,\n [\"TextSummaryTask\"]: HFT_TextSummary,\n [\"TextTranslationTask\"]: HFT_TextTranslation,\n };\n for (const [jobName, fn] of Object.entries(fns)) {\n ProviderRegistry.registerRunFn<any, any>(HF_TRANSFORMERS_ONNX, jobName, fn);\n }\n\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n HF_TRANSFORMERS_ONNX\n );\n await storage.setupDatabase();\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n await server.start();\n }\n}\n",
10
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createServiceToken,\n globalServiceRegistry,\n parentPort,\n WORKER_SERVER,\n} from \"@workglow/util\";\nimport {\n HFT_Download,\n HFT_TextClassifier,\n HFT_TextEmbedding,\n HFT_TextFillMask,\n HFT_TextGeneration,\n HFT_TextLanguageDetection,\n HFT_TextNamedEntityRecognition,\n HFT_TextQuestionAnswer,\n HFT_TextRewriter,\n HFT_TextSummary,\n HFT_TextTranslation,\n HFT_Unload,\n} from \"../common/HFT_JobRunFns\";\n\nexport const HFT_WORKER_JOBRUN = createServiceToken(\"worker.ai-provider.hft\");\n\nexport const HFT_WORKER_JOBRUN_REGISTER = globalServiceRegistry.register(\n HFT_WORKER_JOBRUN,\n () => {\n const workerServer = globalServiceRegistry.get(WORKER_SERVER);\n workerServer.registerFunction(\"DownloadModelTask\", HFT_Download);\n workerServer.registerFunction(\"UnloadModelTask\", HFT_Unload);\n workerServer.registerFunction(\"TextEmbeddingTask\", HFT_TextEmbedding);\n workerServer.registerFunction(\"TextGenerationTask\", HFT_TextGeneration);\n workerServer.registerFunction(\"TextLanguageDetectionTask\", HFT_TextLanguageDetection);\n workerServer.registerFunction(\"TextClassifierTask\", HFT_TextClassifier);\n workerServer.registerFunction(\"TextFillMaskTask\", HFT_TextFillMask);\n workerServer.registerFunction(\"TextNamedEntityRecognitionTask\", HFT_TextNamedEntityRecognition);\n workerServer.registerFunction(\"TextTranslationTask\", HFT_TextTranslation);\n workerServer.registerFunction(\"TextRewriterTask\", HFT_TextRewriter);\n workerServer.registerFunction(\"TextSummaryTask\", HFT_TextSummary);\n workerServer.registerFunction(\"TextQuestionAnswerTask\", HFT_TextQuestionAnswer);\n parentPort.postMessage({ type: \"ready\" });\n console.log(\"HFT_WORKER_JOBRUN registered\");\n return workerServer;\n },\n true\n);\n",
8
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AiJob, AiJobInput, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { globalServiceRegistry, WORKER_MANAGER } from \"@workglow/util\";\nimport { HF_TRANSFORMERS_ONNX } from \"../common/HFT_Constants\";\n\n/**\n * Registers the HuggingFace Transformers client job functions with a web worker.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param worker - The web worker to use for job execution\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_HFT_ClientJobFns(\n worker: Worker,\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n const workerManager = globalServiceRegistry.get(WORKER_MANAGER);\n\n workerManager.registerWorker(HF_TRANSFORMERS_ONNX, worker);\n\n const ProviderRegistry = getAiProviderRegistry();\n const names = [\n \"DownloadModelTask\",\n \"UnloadModelTask\",\n \"TextEmbeddingTask\",\n \"TextLanguageDetectionTask\",\n \"TextClassificationTask\",\n \"TextFillMaskTask\",\n \"TextNamedEntityRecognitionTask\",\n \"TextGenerationTask\",\n \"TextTranslationTask\",\n \"TextRewriterTask\",\n \"TextSummaryTask\",\n \"TextQuestionAnswerTask\",\n \"ImageSegmentationTask\",\n \"ImageToTextTask\",\n \"BackgroundRemovalTask\",\n \"ImageEmbeddingTask\",\n \"ImageClassificationTask\",\n \"ObjectDetectionTask\",\n ];\n for (const name of names) {\n ProviderRegistry.registerAsWorkerRunFn(HF_TRANSFORMERS_ONNX, name);\n }\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n HF_TRANSFORMERS_ONNX\n );\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n // await server.start();\n }\n}\n",
9
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { env } from \"@sroussey/transformers\";\nimport { AiJob, AiJobInput, AiProviderRunFn, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { HF_TRANSFORMERS_ONNX } from \"../common/HFT_Constants\";\nimport {\n HFT_BackgroundRemoval,\n HFT_Download,\n HFT_ImageClassification,\n HFT_ImageEmbedding,\n HFT_ImageSegmentation,\n HFT_ImageToText,\n HFT_ObjectDetection,\n HFT_TextClassification,\n HFT_TextEmbedding,\n HFT_TextFillMask,\n HFT_TextGeneration,\n HFT_TextLanguageDetection,\n HFT_TextNamedEntityRecognition,\n HFT_TextQuestionAnswer,\n HFT_TextRewriter,\n HFT_TextSummary,\n HFT_TextTranslation,\n HFT_Unload,\n} from \"../common/HFT_JobRunFns\";\n\n/**\n * Registers the HuggingFace Transformers inline job functions for same-thread execution.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_HFT_InlineJobFns(\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n // @ts-ignore\n env.backends.onnx.wasm.proxy = true;\n const ProviderRegistry = getAiProviderRegistry();\n const fns: Record<string, AiProviderRunFn<any, any, any>> = {\n [\"DownloadModelTask\"]: HFT_Download,\n [\"UnloadModelTask\"]: HFT_Unload,\n [\"TextEmbeddingTask\"]: HFT_TextEmbedding,\n [\"TextGenerationTask\"]: HFT_TextGeneration,\n [\"TextQuestionAnswerTask\"]: HFT_TextQuestionAnswer,\n [\"TextLanguageDetectionTask\"]: HFT_TextLanguageDetection,\n [\"TextClassificationTask\"]: HFT_TextClassification,\n [\"TextFillMaskTask\"]: HFT_TextFillMask,\n [\"TextNamedEntityRecognitionTask\"]: HFT_TextNamedEntityRecognition,\n [\"TextRewriterTask\"]: HFT_TextRewriter,\n [\"TextSummaryTask\"]: HFT_TextSummary,\n [\"TextTranslationTask\"]: HFT_TextTranslation,\n [\"ImageSegmentationTask\"]: HFT_ImageSegmentation,\n [\"ImageToTextTask\"]: HFT_ImageToText,\n [\"BackgroundRemovalTask\"]: HFT_BackgroundRemoval,\n [\"ImageEmbeddingTask\"]: HFT_ImageEmbedding,\n [\"ImageClassificationTask\"]: HFT_ImageClassification,\n [\"ObjectDetectionTask\"]: HFT_ObjectDetection,\n };\n for (const [jobName, fn] of Object.entries(fns)) {\n ProviderRegistry.registerRunFn<any, any>(HF_TRANSFORMERS_ONNX, jobName, fn);\n }\n\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n HF_TRANSFORMERS_ONNX\n );\n await storage.setupDatabase();\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: HF_TRANSFORMERS_ONNX,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n await server.start();\n }\n}\n",
10
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createServiceToken,\n globalServiceRegistry,\n parentPort,\n WORKER_SERVER,\n} from \"@workglow/util\";\nimport {\n HFT_BackgroundRemoval,\n HFT_Download,\n HFT_ImageClassification,\n HFT_ImageEmbedding,\n HFT_ImageSegmentation,\n HFT_ImageToText,\n HFT_ObjectDetection,\n HFT_TextClassification,\n HFT_TextEmbedding,\n HFT_TextFillMask,\n HFT_TextGeneration,\n HFT_TextLanguageDetection,\n HFT_TextNamedEntityRecognition,\n HFT_TextQuestionAnswer,\n HFT_TextRewriter,\n HFT_TextSummary,\n HFT_TextTranslation,\n HFT_Unload,\n} from \"../common/HFT_JobRunFns\";\n\nexport const HFT_WORKER_JOBRUN = createServiceToken(\"worker.ai-provider.hft\");\n\nexport const HFT_WORKER_JOBRUN_REGISTER = globalServiceRegistry.register(\n HFT_WORKER_JOBRUN,\n () => {\n const workerServer = globalServiceRegistry.get(WORKER_SERVER);\n workerServer.registerFunction(\"DownloadModelTask\", HFT_Download);\n workerServer.registerFunction(\"UnloadModelTask\", HFT_Unload);\n workerServer.registerFunction(\"TextEmbeddingTask\", HFT_TextEmbedding);\n workerServer.registerFunction(\"TextGenerationTask\", HFT_TextGeneration);\n workerServer.registerFunction(\"TextLanguageDetectionTask\", HFT_TextLanguageDetection);\n workerServer.registerFunction(\"TextClassificationTask\", HFT_TextClassification);\n workerServer.registerFunction(\"TextFillMaskTask\", HFT_TextFillMask);\n workerServer.registerFunction(\"TextNamedEntityRecognitionTask\", HFT_TextNamedEntityRecognition);\n workerServer.registerFunction(\"TextTranslationTask\", HFT_TextTranslation);\n workerServer.registerFunction(\"TextRewriterTask\", HFT_TextRewriter);\n workerServer.registerFunction(\"TextSummaryTask\", HFT_TextSummary);\n workerServer.registerFunction(\"TextQuestionAnswerTask\", HFT_TextQuestionAnswer);\n workerServer.registerFunction(\"ImageSegmentationTask\", HFT_ImageSegmentation);\n workerServer.registerFunction(\"ImageToTextTask\", HFT_ImageToText);\n workerServer.registerFunction(\"BackgroundRemovalTask\", HFT_BackgroundRemoval);\n workerServer.registerFunction(\"ImageEmbeddingTask\", HFT_ImageEmbedding);\n workerServer.registerFunction(\"ImageClassificationTask\", HFT_ImageClassification);\n workerServer.registerFunction(\"ObjectDetectionTask\", HFT_ObjectDetection);\n parentPort.postMessage({ type: \"ready\" });\n console.log(\"HFT_WORKER_JOBRUN registered\");\n return workerServer;\n },\n true\n);\n",
11
11
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const TENSORFLOW_MEDIAPIPE = \"TENSORFLOW_MEDIAPIPE\";\n\nexport type TextPipelineTask =\n | \"text-embedder\"\n | \"text-classifier\"\n | \"text-language-detector\"\n | \"genai-text\"\n | \"audio-classifier\"\n | \"audio-embedder\"\n | \"vision-face-detector\"\n | \"vision-face-landmarker\"\n | \"vision-face-stylizer\"\n | \"vision-gesture-recognizer\"\n | \"vision-hand-landmarker\"\n | \"vision-holistic-landmarker\"\n | \"vision-image-classifier\"\n | \"vision-image-embedder\"\n | \"vision-image-segmenter\"\n | \"vision-image-interactive-segmenter\"\n | \"vision-object-detector\"\n | \"vision-pose-landmarker\";\n\nexport const TextPipelineTask = {\n \"text-embedder\": \"text-embedder\",\n \"text-classifier\": \"text-classifier\",\n \"text-language-detector\": \"text-language-detector\",\n \"genai-text\": \"genai-text\",\n \"audio-classifier\": \"audio-classifier\",\n \"audio-embedder\": \"audio-embedder\",\n \"vision-face-detector\": \"vision-face-detector\",\n \"vision-face-landmarker\": \"vision-face-landmarker\",\n \"vision-face-stylizer\": \"vision-face-stylizer\",\n \"vision-gesture-recognizer\": \"vision-gesture-recognizer\",\n \"vision-hand-landmarker\": \"vision-hand-landmarker\",\n \"vision-holistic-landmarker\": \"vision-holistic-landmarker\",\n \"vision-image-classifier\": \"vision-image-classifier\",\n \"vision-image-embedder\": \"vision-image-embedder\",\n \"vision-image-segmenter\": \"vision-image-segmenter\",\n \"vision-image-interactive-segmenter\": \"vision-image-interactive-segmenter\",\n \"vision-object-detector\": \"vision-object-detector\",\n \"vision-pose-landmarker\": \"vision-pose-landmarker\",\n} as const satisfies Record<TextPipelineTask, TextPipelineTask>;\n",
12
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n FilesetResolver,\n LanguageDetector,\n TextClassifier,\n TextEmbedder,\n} from \"@mediapipe/tasks-text\";\nimport type {\n AiProviderRunFn,\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n TextClassifierTaskExecuteInput,\n TextClassifierTaskExecuteOutput,\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n} from \"@workglow/ai\";\nimport { PermanentJobError } from \"@workglow/job-queue\";\nimport { TFMPModelRecord } from \"./TFMP_ModelSchema\";\n\ninterface TFMPWasmFileset {\n /** The path to the Wasm loader script. */\n wasmLoaderPath: string;\n /** The path to the Wasm binary. */\n wasmBinaryPath: string;\n /** The optional path to the asset loader script. */\n assetLoaderPath?: string;\n /** The optional path to the assets binary. */\n assetBinaryPath?: string;\n}\n\n/**\n * Cache for WASM filesets by task engine (text, audio, vision, genai).\n * Multiple models may share the same WASM fileset.\n */\nconst wasm_tasks = new Map<string, TFMPWasmFileset>();\n\n/**\n * Reference counts tracking how many models are using each WASM fileset.\n * When count reaches 0, the WASM fileset can be safely unloaded.\n */\nconst wasm_reference_counts = new Map<string, number>();\n\n/**\n * Maps model paths to their corresponding task engine.\n * Used to determine which WASM fileset to decrement when a model is unloaded.\n */\nconst model_to_wasm_mapping = new Map<string, string>();\n\n/**\n * Helper function to get a WASM task for a model\n */\nconst getWasmTask = async (\n model: TFMPModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<TFMPWasmFileset> => {\n const taskEngine = model.providerConfig.taskEngine;\n\n if (wasm_tasks.has(taskEngine)) {\n return wasm_tasks.get(taskEngine)!;\n }\n\n if (signal.aborted) {\n throw new PermanentJobError(\"Aborted job\");\n }\n\n onProgress(0.1, \"Loading WASM task\");\n\n let wasmFileset: TFMPWasmFileset;\n\n switch (taskEngine) {\n case \"text\":\n wasmFileset = await FilesetResolver.forTextTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text@latest/wasm\"\n );\n break;\n case \"audio\":\n wasmFileset = await FilesetResolver.forAudioTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio@latest/wasm\"\n );\n break;\n case \"vision\":\n wasmFileset = await FilesetResolver.forVisionTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm\"\n );\n break;\n case \"genai\":\n wasmFileset = await FilesetResolver.forGenAiTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm\"\n );\n break;\n default:\n throw new PermanentJobError(\"Invalid task engine\");\n }\n\n wasm_tasks.set(taskEngine, wasmFileset);\n return wasmFileset;\n};\n\ninterface CachedModelTask {\n readonly task: TextEmbedder | TextClassifier | LanguageDetector;\n readonly options: Record<string, unknown>;\n readonly taskEngine: string;\n}\n\nconst modelTaskCache = new Map<string, CachedModelTask[]>();\n\ntype InferTaskInstance<T> = T extends typeof TextEmbedder\n ? TextEmbedder\n : T extends typeof TextClassifier\n ? TextClassifier\n : T extends typeof LanguageDetector\n ? LanguageDetector\n : never;\n\n/**\n * Checks if two option objects are deeply equal.\n */\nconst optionsMatch = (opts1: Record<string, unknown>, opts2: Record<string, unknown>): boolean => {\n const keys1 = Object.keys(opts1).sort();\n const keys2 = Object.keys(opts2).sort();\n\n if (keys1.length !== keys2.length) return false;\n\n return keys1.every((key) => {\n const val1 = opts1[key];\n const val2 = opts2[key];\n\n if (Array.isArray(val1) && Array.isArray(val2)) {\n return JSON.stringify(val1) === JSON.stringify(val2);\n }\n\n return val1 === val2;\n });\n};\n\nconst getModelTask = async <\n T extends typeof TextEmbedder | typeof TextClassifier | typeof LanguageDetector,\n>(\n model: TFMPModelRecord,\n options: Record<string, unknown>,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal,\n TaskType: T\n): Promise<InferTaskInstance<T>> => {\n const modelPath = model.providerConfig.modelPath;\n const taskEngine = model.providerConfig.taskEngine;\n\n // Check if we have a cached instance with matching options\n const cachedTasks = modelTaskCache.get(modelPath);\n if (cachedTasks) {\n const matchedTask = cachedTasks.find((cached) => optionsMatch(cached.options, options));\n if (matchedTask) {\n return matchedTask.task as InferTaskInstance<T>;\n }\n }\n\n // Load WASM if needed\n const wasmFileset = await getWasmTask(model, onProgress, signal);\n\n onProgress(0.2, \"Creating model task\");\n\n // Create new model instance\n const task = await TaskType.createFromOptions(wasmFileset, {\n baseOptions: {\n modelAssetPath: modelPath,\n },\n ...options,\n });\n\n // Cache the task with its options and task engine\n const cachedTask: CachedModelTask = { task, options, taskEngine };\n if (!modelTaskCache.has(modelPath)) {\n modelTaskCache.set(modelPath, []);\n }\n modelTaskCache.get(modelPath)!.push(cachedTask);\n\n // Increment WASM reference count for this cached task\n wasm_reference_counts.set(taskEngine, (wasm_reference_counts.get(taskEngine) || 0) + 1);\n\n return task as any;\n};\n\nconst getTextEmbedder = async (\n model: TFMPModelRecord,\n options: Record<string, unknown>,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<TextEmbedder> => {\n return getModelTask(model, options, onProgress, signal, TextEmbedder);\n};\n\nconst getTextClassifier = async (\n model: TFMPModelRecord,\n options: Record<string, unknown>,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<TextClassifier> => {\n return getModelTask(model, options, onProgress, signal, TextClassifier);\n};\n\nconst getTextLanguageDetector = async (\n model: TFMPModelRecord,\n options: Record<string, unknown>,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<LanguageDetector> => {\n return getModelTask(model, options, onProgress, signal, LanguageDetector);\n};\n\n/**\n * Core implementation for downloading and caching a MediaPipe TFJS model.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_Download: AiProviderRunFn<\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n let task: TextEmbedder | TextClassifier | LanguageDetector;\n switch (model?.providerConfig.pipeline) {\n case \"text-embedder\":\n task = await getTextEmbedder(model, {}, onProgress, signal);\n break;\n case \"text-classifier\":\n task = await getTextClassifier(model, {}, onProgress, signal);\n break;\n case \"text-language-detector\":\n task = await getTextLanguageDetector(model, {}, onProgress, signal);\n break;\n default:\n throw new PermanentJobError(\"Invalid pipeline\");\n }\n onProgress(0.9, \"Pipeline loaded\");\n task.close(); // Close the task to release the resources, but it is still in the browser cache\n // Decrease reference count for WASM fileset for this cached task since this is a fake model cache entry\n const taskEngine = model?.providerConfig.taskEngine;\n wasm_reference_counts.set(taskEngine, wasm_reference_counts.get(taskEngine)! - 1);\n\n return {\n model: input.model,\n };\n};\n\n/**\n * Core implementation for text embedding using MediaPipe TFJS.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_TextEmbedding: AiProviderRunFn<\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const textEmbedder = await getTextEmbedder(model!, {}, onProgress, signal);\n const result = textEmbedder.embed(input.text);\n\n if (!result.embeddings?.[0]?.floatEmbedding) {\n throw new PermanentJobError(\"Failed to generate embedding: Empty result\");\n }\n\n const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);\n\n return {\n vector: embedding,\n };\n};\n\n/**\n * Core implementation for text classification using MediaPipe TFJS.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_TextClassifier: AiProviderRunFn<\n TextClassifierTaskExecuteInput,\n TextClassifierTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const textClassifier = await getTextClassifier(\n model!,\n {\n maxCategories: input.maxCategories,\n // scoreThreshold: input.scoreThreshold,\n // allowList: input.allowList,\n // blockList: input.blockList,\n },\n onProgress,\n signal\n );\n const result = textClassifier.classify(input.text);\n\n if (!result.classifications?.[0]?.categories) {\n throw new PermanentJobError(\"Failed to classify text: Empty result\");\n }\n\n const categories = result.classifications[0].categories.map((category) => ({\n label: category.categoryName,\n score: category.score,\n }));\n\n return {\n categories,\n };\n};\n\n/**\n * Core implementation for language detection using MediaPipe TFJS.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_TextLanguageDetection: AiProviderRunFn<\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const maxLanguages = input.maxLanguages === 0 ? -1 : input.maxLanguages;\n\n const textLanguageDetector = await getTextLanguageDetector(\n model!,\n {\n maxLanguages,\n // scoreThreshold: input.scoreThreshold,\n // allowList: input.allowList,\n // blockList: input.blockList,\n },\n onProgress,\n signal\n );\n const result = textLanguageDetector.detect(input.text);\n\n if (!result.languages?.[0]?.languageCode) {\n throw new PermanentJobError(\"Failed to detect language: Empty result\");\n }\n\n const languages = result.languages.map((language) => ({\n language: language.languageCode,\n score: language.probability,\n }));\n\n return {\n languages,\n };\n};\n\n/**\n * Core implementation for unloading a MediaPipe TFJS model.\n * This is shared between inline and worker implementations.\n *\n * When a model is unloaded, this function:\n * 1. Disposes of all cached model instances for the given model path\n * 2. Decrements the reference count for the associated WASM fileset for each instance\n * 3. If no other models are using the WASM fileset (count reaches 0), unloads the WASM\n */\nexport const TFMP_Unload: AiProviderRunFn<\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const modelPath = model!.providerConfig.modelPath;\n\n // Dispose of all cached model tasks if they exist\n if (modelTaskCache.has(modelPath)) {\n const cachedTasks = modelTaskCache.get(modelPath)!;\n\n for (const cachedTask of cachedTasks) {\n const task = cachedTask.task;\n task.close();\n\n // Decrease reference count for WASM fileset for this cached task\n const taskEngine = cachedTask.taskEngine;\n const currentCount = wasm_reference_counts.get(taskEngine) || 0;\n const newCount = currentCount - 1;\n\n if (newCount <= 0) {\n // No more models using this WASM fileset, unload it\n wasm_tasks.delete(taskEngine);\n wasm_reference_counts.delete(taskEngine);\n } else {\n wasm_reference_counts.set(taskEngine, newCount);\n }\n }\n\n modelTaskCache.delete(modelPath);\n }\n\n return {\n model: input.model,\n };\n};\n",
12
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n FilesetResolver,\n LanguageDetector,\n TextClassifier,\n TextEmbedder,\n} from \"@mediapipe/tasks-text\";\nimport {\n ImageClassifier,\n ImageEmbedder,\n ImageSegmenter,\n ObjectDetector,\n} from \"@mediapipe/tasks-vision\";\nimport type {\n AiProviderRunFn,\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n ImageClassificationTaskExecuteInput,\n ImageClassificationTaskExecuteOutput,\n ImageEmbeddingTaskExecuteInput,\n ImageEmbeddingTaskExecuteOutput,\n ImageSegmentationTaskExecuteInput,\n ImageSegmentationTaskExecuteOutput,\n ObjectDetectionTaskExecuteInput,\n ObjectDetectionTaskExecuteOutput,\n TextClassificationTaskExecuteInput,\n TextClassificationTaskExecuteOutput,\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n} from \"@workglow/ai\";\nimport { PermanentJobError } from \"@workglow/job-queue\";\nimport { TFMPModelRecord } from \"./TFMP_ModelSchema\";\n\ninterface TFMPWasmFileset {\n /** The path to the Wasm loader script. */\n wasmLoaderPath: string;\n /** The path to the Wasm binary. */\n wasmBinaryPath: string;\n /** The optional path to the asset loader script. */\n assetLoaderPath?: string;\n /** The optional path to the assets binary. */\n assetBinaryPath?: string;\n}\n\n/**\n * Cache for WASM filesets by task engine (text, audio, vision, genai).\n * Multiple models may share the same WASM fileset.\n */\nconst wasm_tasks = new Map<string, TFMPWasmFileset>();\n\n/**\n * Reference counts tracking how many models are using each WASM fileset.\n * When count reaches 0, the WASM fileset can be safely unloaded.\n */\nconst wasm_reference_counts = new Map<string, number>();\n\n/**\n * Helper function to get a WASM task for a model\n */\nconst getWasmTask = async (\n model: TFMPModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<TFMPWasmFileset> => {\n const taskEngine = model.providerConfig.taskEngine;\n\n if (wasm_tasks.has(taskEngine)) {\n return wasm_tasks.get(taskEngine)!;\n }\n\n if (signal.aborted) {\n throw new PermanentJobError(\"Aborted job\");\n }\n\n onProgress(0.1, \"Loading WASM task\");\n\n let wasmFileset: TFMPWasmFileset;\n\n switch (taskEngine) {\n case \"text\":\n wasmFileset = await FilesetResolver.forTextTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text@latest/wasm\"\n );\n break;\n case \"audio\":\n wasmFileset = await FilesetResolver.forAudioTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio@latest/wasm\"\n );\n break;\n case \"vision\":\n wasmFileset = await FilesetResolver.forVisionTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm\"\n );\n break;\n case \"genai\":\n wasmFileset = await FilesetResolver.forGenAiTasks(\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm\"\n );\n break;\n default:\n throw new PermanentJobError(\"Invalid task engine\");\n }\n\n wasm_tasks.set(taskEngine, wasmFileset);\n return wasmFileset;\n};\n\ntype TaskType =\n | typeof TextEmbedder\n | typeof TextClassifier\n | typeof LanguageDetector\n | typeof ImageClassifier\n | typeof ImageEmbedder\n | typeof ImageSegmenter\n | typeof ObjectDetector;\n\ntype TaskInstance =\n | TextEmbedder\n | TextClassifier\n | LanguageDetector\n | ImageClassifier\n | ImageEmbedder\n | ImageSegmenter\n | ObjectDetector;\n\ninterface CachedModelTask {\n readonly task: TaskInstance;\n readonly options: Record<string, unknown>;\n readonly taskEngine: string;\n}\n\nconst modelTaskCache = new Map<string, CachedModelTask[]>();\n\ntype InferTaskInstance<T> = T extends typeof TextEmbedder\n ? TextEmbedder\n : T extends typeof TextClassifier\n ? TextClassifier\n : T extends typeof LanguageDetector\n ? LanguageDetector\n : T extends typeof ImageClassifier\n ? ImageClassifier\n : T extends typeof ImageEmbedder\n ? ImageEmbedder\n : T extends typeof ImageSegmenter\n ? ImageSegmenter\n : T extends typeof ObjectDetector\n ? ObjectDetector\n : never;\n\n/**\n * Checks if two option objects are deeply equal.\n */\nconst optionsMatch = (opts1: Record<string, unknown>, opts2: Record<string, unknown>): boolean => {\n const keys1 = Object.keys(opts1).sort();\n const keys2 = Object.keys(opts2).sort();\n\n if (keys1.length !== keys2.length) return false;\n\n return keys1.every((key) => {\n const val1 = opts1[key];\n const val2 = opts2[key];\n\n if (Array.isArray(val1) && Array.isArray(val2)) {\n return JSON.stringify(val1) === JSON.stringify(val2);\n }\n\n return val1 === val2;\n });\n};\n\nconst getModelTask = async <T extends TaskType>(\n model: TFMPModelRecord,\n options: Record<string, unknown>,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal,\n TaskType: T\n): Promise<InferTaskInstance<T>> => {\n const modelPath = model.providerConfig.modelPath;\n const taskEngine = model.providerConfig.taskEngine;\n\n // Check if we have a cached instance with matching options\n const cachedTasks = modelTaskCache.get(modelPath);\n if (cachedTasks) {\n const matchedTask = cachedTasks.find((cached) => optionsMatch(cached.options, options));\n if (matchedTask) {\n return matchedTask.task as InferTaskInstance<T>;\n }\n }\n\n // Load WASM if needed\n const wasmFileset = await getWasmTask(model, onProgress, signal);\n\n onProgress(0.2, \"Creating model task\");\n\n // Create new model instance\n const task = await TaskType.createFromOptions(wasmFileset, {\n baseOptions: {\n modelAssetPath: modelPath,\n },\n ...options,\n });\n\n // Cache the task with its options and task engine\n const cachedTask: CachedModelTask = { task, options, taskEngine };\n if (!modelTaskCache.has(modelPath)) {\n modelTaskCache.set(modelPath, []);\n }\n modelTaskCache.get(modelPath)!.push(cachedTask);\n\n // Increment WASM reference count for this cached task\n wasm_reference_counts.set(taskEngine, (wasm_reference_counts.get(taskEngine) || 0) + 1);\n\n return task as any;\n};\n\n/**\n * Core implementation for downloading and caching a MediaPipe TFJS model.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_Download: AiProviderRunFn<\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n let task: TextEmbedder | TextClassifier | LanguageDetector;\n switch (model?.providerConfig.pipeline) {\n case \"text-embedder\":\n task = await getModelTask(model, {}, onProgress, signal, TextEmbedder);\n break;\n case \"text-classifier\":\n task = await getModelTask(model, {}, onProgress, signal, TextClassifier);\n break;\n case \"text-language-detector\":\n task = await getModelTask(model, {}, onProgress, signal, LanguageDetector);\n break;\n default:\n throw new PermanentJobError(\"Invalid pipeline\");\n }\n onProgress(0.9, \"Pipeline loaded\");\n task.close(); // Close the task to release the resources, but it is still in the browser cache\n // Decrease reference count for WASM fileset for this cached task since this is a fake model cache entry\n const taskEngine = model?.providerConfig.taskEngine;\n wasm_reference_counts.set(taskEngine, wasm_reference_counts.get(taskEngine)! - 1);\n\n return {\n model: input.model,\n };\n};\n\n/**\n * Core implementation for text embedding using MediaPipe TFJS.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_TextEmbedding: AiProviderRunFn<\n TextEmbeddingTaskExecuteInput,\n TextEmbeddingTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const textEmbedder = await getModelTask(model!, {}, onProgress, signal, TextEmbedder);\n const result = textEmbedder.embed(input.text);\n\n if (!result.embeddings?.[0]?.floatEmbedding) {\n throw new PermanentJobError(\"Failed to generate embedding: Empty result\");\n }\n\n const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);\n\n return {\n vector: embedding,\n };\n};\n\n/**\n * Core implementation for text classification using MediaPipe TFJS.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_TextClassification: AiProviderRunFn<\n TextClassificationTaskExecuteInput,\n TextClassificationTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const TextClassification = await getModelTask(\n model!,\n {\n maxCategories: input.maxCategories,\n // scoreThreshold: input.scoreThreshold,\n // allowList: input.allowList,\n // blockList: input.blockList,\n },\n onProgress,\n signal,\n TextClassifier\n );\n const result = TextClassification.classify(input.text);\n\n if (!result.classifications?.[0]?.categories) {\n throw new PermanentJobError(\"Failed to classify text: Empty result\");\n }\n\n const categories = result.classifications[0].categories.map((category) => ({\n label: category.categoryName,\n score: category.score,\n }));\n\n return {\n categories,\n };\n};\n\n/**\n * Core implementation for language detection using MediaPipe TFJS.\n * This is shared between inline and worker implementations.\n */\nexport const TFMP_TextLanguageDetection: AiProviderRunFn<\n TextLanguageDetectionTaskExecuteInput,\n TextLanguageDetectionTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const maxLanguages = input.maxLanguages === 0 ? -1 : input.maxLanguages;\n\n const textLanguageDetector = await getModelTask(\n model!,\n {\n maxLanguages,\n // scoreThreshold: input.scoreThreshold,\n // allowList: input.allowList,\n // blockList: input.blockList,\n },\n onProgress,\n signal,\n LanguageDetector\n );\n const result = textLanguageDetector.detect(input.text);\n\n if (!result.languages?.[0]?.languageCode) {\n throw new PermanentJobError(\"Failed to detect language: Empty result\");\n }\n\n const languages = result.languages.map((language) => ({\n language: language.languageCode,\n score: language.probability,\n }));\n\n return {\n languages,\n };\n};\n\n/**\n * Core implementation for unloading a MediaPipe TFJS model.\n * This is shared between inline and worker implementations.\n *\n * When a model is unloaded, this function:\n * 1. Disposes of all cached model instances for the given model path\n * 2. Decrements the reference count for the associated WASM fileset for each instance\n * 3. If no other models are using the WASM fileset (count reaches 0), unloads the WASM\n */\nexport const TFMP_Unload: AiProviderRunFn<\n UnloadModelTaskExecuteInput,\n UnloadModelTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const modelPath = model!.providerConfig.modelPath;\n onProgress(10, \"Unloading model\");\n // Dispose of all cached model tasks if they exist\n if (modelTaskCache.has(modelPath)) {\n const cachedTasks = modelTaskCache.get(modelPath)!;\n\n for (const cachedTask of cachedTasks) {\n const task = cachedTask.task;\n if (\"close\" in task && typeof task.close === \"function\") task.close();\n\n // Decrease reference count for WASM fileset for this cached task\n const taskEngine = cachedTask.taskEngine;\n const currentCount = wasm_reference_counts.get(taskEngine) || 0;\n const newCount = currentCount - 1;\n\n if (newCount <= 0) {\n // No more models using this WASM fileset, unload it\n wasm_tasks.delete(taskEngine);\n wasm_reference_counts.delete(taskEngine);\n } else {\n wasm_reference_counts.set(taskEngine, newCount);\n }\n }\n\n modelTaskCache.delete(modelPath);\n }\n\n return {\n model: input.model,\n };\n};\n\n/**\n * Core implementation for image segmentation using MediaPipe.\n */\nexport const TFMP_ImageSegmentation: AiProviderRunFn<\n ImageSegmentationTaskExecuteInput,\n ImageSegmentationTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const imageSegmenter = await getModelTask(model!, {}, onProgress, signal, ImageSegmenter);\n const result = imageSegmenter.segment(input.image as any);\n\n if (!result.categoryMask) {\n throw new PermanentJobError(\"Failed to segment image: Empty result\");\n }\n\n // MediaPipe returns a single mask, create a placeholder result\n const masks = [\n {\n label: \"segment\",\n score: 1.0,\n mask: {\n data: result.categoryMask.canvas,\n width: result.categoryMask.width,\n height: result.categoryMask.height,\n },\n },\n ];\n\n return {\n masks,\n };\n};\n\n/**\n * Core implementation for image embedding using MediaPipe.\n */\nexport const TFMP_ImageEmbedding: AiProviderRunFn<\n ImageEmbeddingTaskExecuteInput,\n ImageEmbeddingTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const imageEmbedder = await getModelTask(model!, {}, onProgress, signal, ImageEmbedder);\n const result = imageEmbedder.embed(input.image as any);\n\n if (!result.embeddings?.[0]?.floatEmbedding) {\n throw new PermanentJobError(\"Failed to generate embedding: Empty result\");\n }\n\n const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);\n\n return {\n vector: embedding,\n };\n};\n\n/**\n * Core implementation for image classification using MediaPipe.\n */\nexport const TFMP_ImageClassification: AiProviderRunFn<\n ImageClassificationTaskExecuteInput,\n ImageClassificationTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const imageClassifier = await getModelTask(\n model!,\n {\n maxResults: (input as any).maxCategories,\n },\n onProgress,\n signal,\n ImageClassifier\n );\n const result = imageClassifier.classify(input.image as any);\n\n if (!result.classifications?.[0]?.categories) {\n throw new PermanentJobError(\"Failed to classify image: Empty result\");\n }\n\n const categories = result.classifications[0].categories.map((category: any) => ({\n label: category.categoryName,\n score: category.score,\n }));\n\n return {\n categories,\n };\n};\n\n/**\n * Core implementation for object detection using MediaPipe.\n */\nexport const TFMP_ObjectDetection: AiProviderRunFn<\n ObjectDetectionTaskExecuteInput,\n ObjectDetectionTaskExecuteOutput,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n const objectDetector = await getModelTask(\n model!,\n {\n scoreThreshold: (input as any).threshold,\n },\n onProgress,\n signal,\n ObjectDetector\n );\n const result = objectDetector.detect(input.image as any);\n\n if (!result.detections) {\n throw new PermanentJobError(\"Failed to detect objects: Empty result\");\n }\n\n const detections = result.detections.map((detection: any) => ({\n label: detection.categories?.[0]?.categoryName || \"unknown\",\n score: detection.categories?.[0]?.score || 0,\n box: {\n x: detection.boundingBox?.originX || 0,\n y: detection.boundingBox?.originY || 0,\n width: detection.boundingBox?.width || 0,\n height: detection.boundingBox?.height || 0,\n },\n }));\n\n return {\n detections,\n };\n};\n",
13
13
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ModelSchema } from \"@workglow/ai\";\nimport { DataPortSchemaObject, FromSchema } from \"@workglow/util\";\nimport { TENSORFLOW_MEDIAPIPE, TextPipelineTask } from \"../common/TFMP_Constants\";\n\nexport const TFMPModelSchema = {\n type: \"object\",\n properties: {\n provider: {\n const: TENSORFLOW_MEDIAPIPE,\n description: \"Discriminator: TensorFlow MediaPipe backend.\",\n },\n providerConfig: {\n type: \"object\",\n description: \"TensorFlow MediaPipe-specific options.\",\n properties: {\n modelPath: {\n type: \"string\",\n description: \"Filesystem path or URI for the ONNX model.\",\n },\n taskEngine: {\n type: \"string\",\n enum: [\"text\", \"audio\", \"vision\", \"genai\"],\n description: \"Task engine for the MediaPipe model.\",\n },\n pipeline: {\n type: \"string\",\n enum: Object.values(TextPipelineTask),\n description: \"Pipeline task type for the MediaPipe model.\",\n },\n },\n required: [\"modelPath\", \"taskEngine\", \"pipeline\"],\n additionalProperties: false,\n },\n },\n required: [\"provider\", \"providerConfig\"],\n additionalProperties: true,\n} as const satisfies DataPortSchemaObject;\n\nconst ExtendedModelSchema = {\n type: \"object\",\n properties: {\n ...ModelSchema.properties,\n ...TFMPModelSchema.properties,\n },\n required: [...ModelSchema.required, ...TFMPModelSchema.required],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\n\nexport type TFMPModelRecord = FromSchema<typeof ExtendedModelSchema>;\n",
14
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AiJob, AiJobInput, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { globalServiceRegistry, WORKER_MANAGER } from \"@workglow/util\";\nimport { TENSORFLOW_MEDIAPIPE } from \"../common/TFMP_Constants\";\n\n/**\n * Registers the TensorFlow MediaPipe client job functions with a web worker.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param worker - The web worker to use for job execution\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_TFMP_ClientJobFns(\n worker: Worker,\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n const workerManager = globalServiceRegistry.get(WORKER_MANAGER);\n workerManager.registerWorker(TENSORFLOW_MEDIAPIPE, worker);\n\n const aiProviderRegistry = getAiProviderRegistry();\n const names = [\n \"DownloadModelTask\",\n \"UnloadModelTask\",\n \"TextEmbeddingTask\",\n \"TextLanguageDetectionTask\",\n \"TextClassifierTask\",\n ];\n for (const name of names) {\n aiProviderRegistry.registerAsWorkerRunFn(TENSORFLOW_MEDIAPIPE, name);\n }\n\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n TENSORFLOW_MEDIAPIPE\n );\n await storage.setupDatabase();\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n await server.start();\n }\n}\n",
15
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AiJob, AiJobInput, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { TENSORFLOW_MEDIAPIPE } from \"../common/TFMP_Constants\";\nimport {\n TFMP_Download,\n TFMP_TextClassifier,\n TFMP_TextEmbedding,\n TFMP_TextLanguageDetection,\n TFMP_Unload,\n} from \"../common/TFMP_JobRunFns\";\n\n/**\n * Registers the TensorFlow MediaPipe inline job functions for same-thread execution.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_TFMP_InlineJobFns(\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n const aiProviderRegistry = getAiProviderRegistry();\n\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"DownloadModelTask\",\n TFMP_Download as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"UnloadModelTask\",\n TFMP_Unload as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"TextEmbeddingTask\",\n TFMP_TextEmbedding as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"TextLanguageDetectionTask\",\n TFMP_TextLanguageDetection as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"TextClassifierTask\",\n TFMP_TextClassifier as any\n );\n\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n TENSORFLOW_MEDIAPIPE\n );\n await storage.setupDatabase();\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n await server.start();\n }\n}\n",
16
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createServiceToken,\n globalServiceRegistry,\n parentPort,\n WORKER_SERVER,\n} from \"@workglow/util\";\nimport {\n TFMP_Download,\n TFMP_TextClassifier,\n TFMP_TextEmbedding,\n TFMP_TextLanguageDetection,\n TFMP_Unload,\n} from \"../common/TFMP_JobRunFns\";\n\n// Register the worker functions\nexport const TFMP_WORKER_JOBRUN = createServiceToken(\"worker.ai-provider.tfmp\");\n\nexport const TFMP_WORKER_JOBRUN_REGISTER = globalServiceRegistry.register(\n TFMP_WORKER_JOBRUN,\n () => {\n const workerServer = globalServiceRegistry.get(WORKER_SERVER);\n workerServer.registerFunction(\"DownloadModelTask\", TFMP_Download);\n workerServer.registerFunction(\"UnloadModelTask\", TFMP_Unload);\n workerServer.registerFunction(\"TextEmbeddingTask\", TFMP_TextEmbedding);\n workerServer.registerFunction(\"TextLanguageDetectionTask\", TFMP_TextLanguageDetection);\n workerServer.registerFunction(\"TextClassifierTask\", TFMP_TextClassifier);\n parentPort.postMessage({ type: \"ready\" });\n console.log(\"TFMP_WORKER_JOBRUN registered\");\n return workerServer;\n },\n true\n);\n"
14
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AiJob, AiJobInput, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { globalServiceRegistry, WORKER_MANAGER } from \"@workglow/util\";\nimport { TENSORFLOW_MEDIAPIPE } from \"../common/TFMP_Constants\";\n\n/**\n * Registers the TensorFlow MediaPipe client job functions with a web worker.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param worker - The web worker to use for job execution\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_TFMP_ClientJobFns(\n worker: Worker,\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n const workerManager = globalServiceRegistry.get(WORKER_MANAGER);\n workerManager.registerWorker(TENSORFLOW_MEDIAPIPE, worker);\n\n const aiProviderRegistry = getAiProviderRegistry();\n const names = [\n \"DownloadModelTask\",\n \"UnloadModelTask\",\n \"TextEmbeddingTask\",\n \"TextLanguageDetectionTask\",\n \"TextClassificationTask\",\n \"ImageSegmentationTask\",\n \"ImageEmbeddingTask\",\n \"ImageClassificationTask\",\n \"ObjectDetectionTask\",\n ];\n for (const name of names) {\n aiProviderRegistry.registerAsWorkerRunFn(TENSORFLOW_MEDIAPIPE, name);\n }\n\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n TENSORFLOW_MEDIAPIPE\n );\n await storage.setupDatabase();\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n await server.start();\n }\n}\n",
15
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AiJob, AiJobInput, getAiProviderRegistry } from \"@workglow/ai\";\nimport { ConcurrencyLimiter, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage } from \"@workglow/storage\";\nimport { getTaskQueueRegistry, TaskInput, TaskOutput } from \"@workglow/task-graph\";\nimport { TENSORFLOW_MEDIAPIPE } from \"../common/TFMP_Constants\";\nimport {\n TFMP_Download,\n TFMP_ImageClassification,\n TFMP_ImageEmbedding,\n TFMP_ImageSegmentation,\n TFMP_ObjectDetection,\n TFMP_TextClassification,\n TFMP_TextEmbedding,\n TFMP_TextLanguageDetection,\n TFMP_Unload,\n} from \"../common/TFMP_JobRunFns\";\n\n/**\n * Registers the TensorFlow MediaPipe inline job functions for same-thread execution.\n * If no client is provided, creates a default in-memory queue and registers it.\n *\n * @param client - Optional existing JobQueueClient. If not provided, creates a default in-memory queue.\n */\nexport async function register_TFMP_InlineJobFns(\n client?: JobQueueClient<AiJobInput<TaskInput>, TaskOutput>\n): Promise<void> {\n const aiProviderRegistry = getAiProviderRegistry();\n\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"DownloadModelTask\",\n TFMP_Download as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"UnloadModelTask\",\n TFMP_Unload as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"TextEmbeddingTask\",\n TFMP_TextEmbedding as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"TextLanguageDetectionTask\",\n TFMP_TextLanguageDetection as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"TextClassificationTask\",\n TFMP_TextClassification as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"ImageSegmentationTask\",\n TFMP_ImageSegmentation as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"ImageEmbeddingTask\",\n TFMP_ImageEmbedding as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"ImageClassificationTask\",\n TFMP_ImageClassification as any\n );\n aiProviderRegistry.registerRunFn<any, any>(\n TENSORFLOW_MEDIAPIPE,\n \"ObjectDetectionTask\",\n TFMP_ObjectDetection as any\n );\n\n // If no client provided, create a default in-memory queue\n if (!client) {\n const storage = new InMemoryQueueStorage<AiJobInput<TaskInput>, TaskOutput>(\n TENSORFLOW_MEDIAPIPE\n );\n await storage.setupDatabase();\n\n const server = new JobQueueServer<AiJobInput<TaskInput>, TaskOutput>(AiJob, {\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n limiter: new ConcurrencyLimiter(1, 100),\n });\n\n client = new JobQueueClient<AiJobInput<TaskInput>, TaskOutput>({\n storage,\n queueName: TENSORFLOW_MEDIAPIPE,\n });\n\n client.attach(server);\n\n getTaskQueueRegistry().registerQueue({ server, client, storage });\n await server.start();\n }\n}\n",
16
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createServiceToken,\n globalServiceRegistry,\n parentPort,\n WORKER_SERVER,\n} from \"@workglow/util\";\nimport {\n TFMP_Download,\n TFMP_ImageClassification,\n TFMP_ImageEmbedding,\n TFMP_ImageSegmentation,\n TFMP_ObjectDetection,\n TFMP_TextClassification,\n TFMP_TextEmbedding,\n TFMP_TextLanguageDetection,\n TFMP_Unload,\n} from \"../common/TFMP_JobRunFns\";\n\n// Register the worker functions\nexport const TFMP_WORKER_JOBRUN = createServiceToken(\"worker.ai-provider.tfmp\");\n\nexport const TFMP_WORKER_JOBRUN_REGISTER = globalServiceRegistry.register(\n TFMP_WORKER_JOBRUN,\n () => {\n const workerServer = globalServiceRegistry.get(WORKER_SERVER);\n workerServer.registerFunction(\"DownloadModelTask\", TFMP_Download);\n workerServer.registerFunction(\"UnloadModelTask\", TFMP_Unload);\n workerServer.registerFunction(\"TextEmbeddingTask\", TFMP_TextEmbedding);\n workerServer.registerFunction(\"TextLanguageDetectionTask\", TFMP_TextLanguageDetection);\n workerServer.registerFunction(\"TextClassificationTask\", TFMP_TextClassification);\n workerServer.registerFunction(\"ImageSegmentationTask\", TFMP_ImageSegmentation);\n workerServer.registerFunction(\"ImageEmbeddingTask\", TFMP_ImageEmbedding);\n workerServer.registerFunction(\"ImageClassificationTask\", TFMP_ImageClassification);\n workerServer.registerFunction(\"ObjectDetectionTask\", TFMP_ObjectDetection);\n parentPort.postMessage({ type: \"ready\" });\n console.log(\"TFMP_WORKER_JOBRUN registered\");\n return workerServer;\n },\n true\n);\n"
17
17
  ],
18
- "mappings": "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",
19
- "debugId": "AED2FBB7924C48F164756E2164756E21",
18
+ "mappings": "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",
19
+ "debugId": "F27086207C0BB9CB64756E2164756E21",
20
20
  "names": []
21
21
  }
@@ -3,7 +3,7 @@
3
3
  * Copyright 2025 Steven Roussey <sroussey@gmail.com>
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import type { AiProviderRunFn, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput } from "@workglow/ai";
6
+ import type { AiProviderRunFn, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, ImageClassificationTaskExecuteInput, ImageClassificationTaskExecuteOutput, ImageEmbeddingTaskExecuteInput, ImageEmbeddingTaskExecuteOutput, ImageSegmentationTaskExecuteInput, ImageSegmentationTaskExecuteOutput, ObjectDetectionTaskExecuteInput, ObjectDetectionTaskExecuteOutput, TextClassificationTaskExecuteInput, TextClassificationTaskExecuteOutput, TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput } from "@workglow/ai";
7
7
  import { TFMPModelRecord } from "./TFMP_ModelSchema";
8
8
  /**
9
9
  * Core implementation for downloading and caching a MediaPipe TFJS model.
@@ -19,7 +19,7 @@ export declare const TFMP_TextEmbedding: AiProviderRunFn<TextEmbeddingTaskExecut
19
19
  * Core implementation for text classification using MediaPipe TFJS.
20
20
  * This is shared between inline and worker implementations.
21
21
  */
22
- export declare const TFMP_TextClassifier: AiProviderRunFn<TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, TFMPModelRecord>;
22
+ export declare const TFMP_TextClassification: AiProviderRunFn<TextClassificationTaskExecuteInput, TextClassificationTaskExecuteOutput, TFMPModelRecord>;
23
23
  /**
24
24
  * Core implementation for language detection using MediaPipe TFJS.
25
25
  * This is shared between inline and worker implementations.
@@ -35,4 +35,20 @@ export declare const TFMP_TextLanguageDetection: AiProviderRunFn<TextLanguageDet
35
35
  * 3. If no other models are using the WASM fileset (count reaches 0), unloads the WASM
36
36
  */
37
37
  export declare const TFMP_Unload: AiProviderRunFn<UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput, TFMPModelRecord>;
38
+ /**
39
+ * Core implementation for image segmentation using MediaPipe.
40
+ */
41
+ export declare const TFMP_ImageSegmentation: AiProviderRunFn<ImageSegmentationTaskExecuteInput, ImageSegmentationTaskExecuteOutput, TFMPModelRecord>;
42
+ /**
43
+ * Core implementation for image embedding using MediaPipe.
44
+ */
45
+ export declare const TFMP_ImageEmbedding: AiProviderRunFn<ImageEmbeddingTaskExecuteInput, ImageEmbeddingTaskExecuteOutput, TFMPModelRecord>;
46
+ /**
47
+ * Core implementation for image classification using MediaPipe.
48
+ */
49
+ export declare const TFMP_ImageClassification: AiProviderRunFn<ImageClassificationTaskExecuteInput, ImageClassificationTaskExecuteOutput, TFMPModelRecord>;
50
+ /**
51
+ * Core implementation for object detection using MediaPipe.
52
+ */
53
+ export declare const TFMP_ObjectDetection: AiProviderRunFn<ObjectDetectionTaskExecuteInput, ObjectDetectionTaskExecuteOutput, TFMPModelRecord>;
38
54
  //# sourceMappingURL=TFMP_JobRunFns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TFMP_JobRunFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/common/TFMP_JobRunFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EACV,eAAe,EACf,6BAA6B,EAC7B,8BAA8B,EAC9B,8BAA8B,EAC9B,+BAA+B,EAC/B,6BAA6B,EAC7B,8BAA8B,EAC9B,qCAAqC,EACrC,sCAAsC,EACtC,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAiMrD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CACzC,6BAA6B,EAC7B,8BAA8B,EAC9B,eAAe,CAyBhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,6BAA6B,EAC7B,8BAA8B,EAC9B,eAAe,CAchB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAC/C,8BAA8B,EAC9B,+BAA+B,EAC/B,eAAe,CA2BhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAAe,CACtD,qCAAqC,EACrC,sCAAsC,EACtC,eAAe,CA6BhB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,eAAe,CACvC,2BAA2B,EAC3B,4BAA4B,EAC5B,eAAe,CAgChB,CAAC"}
1
+ {"version":3,"file":"TFMP_JobRunFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/common/TFMP_JobRunFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,KAAK,EACV,eAAe,EACf,6BAA6B,EAC7B,8BAA8B,EAC9B,mCAAmC,EACnC,oCAAoC,EACpC,8BAA8B,EAC9B,+BAA+B,EAC/B,iCAAiC,EACjC,kCAAkC,EAClC,+BAA+B,EAC/B,gCAAgC,EAChC,kCAAkC,EAClC,mCAAmC,EACnC,6BAA6B,EAC7B,8BAA8B,EAC9B,qCAAqC,EACrC,sCAAsC,EACtC,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAwLrD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CACzC,6BAA6B,EAC7B,8BAA8B,EAC9B,eAAe,CAyBhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,6BAA6B,EAC7B,8BAA8B,EAC9B,eAAe,CAchB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,eAAe,CACnD,kCAAkC,EAClC,mCAAmC,EACnC,eAAe,CA4BhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAAe,CACtD,qCAAqC,EACrC,sCAAsC,EACtC,eAAe,CA8BhB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,eAAe,CACvC,2BAA2B,EAC3B,4BAA4B,EAC5B,eAAe,CAgChB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAAe,CAClD,iCAAiC,EACjC,kCAAkC,EAClC,eAAe,CAyBhB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAC/C,8BAA8B,EAC9B,+BAA+B,EAC/B,eAAe,CAchB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAAe,CACpD,mCAAmC,EACnC,oCAAoC,EACpC,eAAe,CAyBhB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,eAAe,CAChD,+BAA+B,EAC/B,gCAAgC,EAChC,eAAe,CA+BhB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"TFMP_Client_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/registry/TFMP_Client_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,UAAU,EAAyB,MAAM,cAAc,CAAC;AACxE,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAInF;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAuCf"}
1
+ {"version":3,"file":"TFMP_Client_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/registry/TFMP_Client_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,UAAU,EAAyB,MAAM,cAAc,CAAC;AACxE,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAInF;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
@@ -1 +1 @@
1
- {"version":3,"file":"TFMP_Inline_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/registry/TFMP_Inline_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,UAAU,EAAyB,MAAM,cAAc,CAAC;AACxE,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAUnF;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAoDf"}
1
+ {"version":3,"file":"TFMP_Inline_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/registry/TFMP_Inline_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,UAAU,EAAyB,MAAM,cAAc,CAAC;AACxE,OAAO,EAAsB,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAwB,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAcnF;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAwEf"}
@@ -1 +1 @@
1
- {"version":3,"file":"TFMP_Worker_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/registry/TFMP_Worker_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,eAAO,MAAM,kBAAkB,gDAAgD,CAAC;AAEhF,eAAO,MAAM,2BAA2B,MAcvC,CAAC"}
1
+ {"version":3,"file":"TFMP_Worker_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/tf-mediapipe/registry/TFMP_Worker_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,eAAO,MAAM,kBAAkB,gDAAgD,CAAC;AAEhF,eAAO,MAAM,2BAA2B,MAkBvC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workglow/ai-provider",
3
3
  "type": "module",
4
- "version": "0.0.71",
4
+ "version": "0.0.72",
5
5
  "description": "AI provider integrations for Workglow, supporting OpenAI, Hugging Face Transformers, MediaPipe, and GGML models.",
6
6
  "scripts": {
7
7
  "watch": "concurrently -c 'auto' 'bun:watch-*'",
@@ -30,11 +30,11 @@
30
30
  "access": "public"
31
31
  },
32
32
  "peerDependencies": {
33
- "@workglow/ai": "0.0.71",
34
- "@workglow/job-queue": "0.0.71",
35
- "@workglow/storage": "0.0.71",
36
- "@workglow/task-graph": "0.0.71",
37
- "@workglow/util": "0.0.71",
33
+ "@workglow/ai": "0.0.72",
34
+ "@workglow/job-queue": "0.0.72",
35
+ "@workglow/storage": "0.0.72",
36
+ "@workglow/task-graph": "0.0.72",
37
+ "@workglow/util": "0.0.72",
38
38
  "@sroussey/transformers": "3.8.2",
39
39
  "@mediapipe/tasks-text": "^0.10.22-rc.20250304",
40
40
  "@mediapipe/tasks-vision": "^0.10.22-rc.20250304",
@@ -59,11 +59,11 @@
59
59
  }
60
60
  },
61
61
  "devDependencies": {
62
- "@workglow/ai": "0.0.71",
63
- "@workglow/job-queue": "0.0.71",
64
- "@workglow/storage": "0.0.71",
65
- "@workglow/task-graph": "0.0.71",
66
- "@workglow/util": "0.0.71",
62
+ "@workglow/ai": "0.0.72",
63
+ "@workglow/job-queue": "0.0.72",
64
+ "@workglow/storage": "0.0.72",
65
+ "@workglow/task-graph": "0.0.72",
66
+ "@workglow/util": "0.0.72",
67
67
  "@sroussey/transformers": "3.8.2",
68
68
  "@mediapipe/tasks-text": "^0.10.22-rc.20250304",
69
69
  "@mediapipe/tasks-vision": "^0.10.22-rc.20250304",