@workglow/ai-provider 0.0.69 → 0.0.71

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,7 +3,7 @@
3
3
  * Copyright 2025 Steven Roussey <sroussey@gmail.com>
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { AiProviderRunFn, type DeReplicateFromSchema, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, TextClassifierInputSchema, TextClassifierOutputSchema, TextEmbeddingInputSchema, TextEmbeddingOutputSchema, TextGenerationInputSchema, TextGenerationOutputSchema, TextLanguageDetectionInputSchema, TextLanguageDetectionOutputSchema, TextQuestionAnswerInputSchema, TextQuestionAnswerOutputSchema, TextRewriterInputSchema, TextRewriterOutputSchema, TextSummaryInputSchema, TextSummaryOutputSchema, TextTranslationInputSchema, TextTranslationOutputSchema, UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput } from "@workglow/ai";
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";
7
7
  import { HfTransformersOnnxModelRecord } from "./HFT_ModelSchema";
8
8
  /**
9
9
  * Core implementation for downloading and caching a Hugging Face Transformers model.
@@ -19,32 +19,34 @@ export declare const HFT_Unload: AiProviderRunFn<UnloadModelTaskExecuteInput, Un
19
19
  * Core implementation for text embedding using Hugging Face Transformers.
20
20
  * This is shared between inline and worker implementations.
21
21
  */
22
- export declare const HFT_TextEmbedding: AiProviderRunFn<DeReplicateFromSchema<typeof TextEmbeddingInputSchema>, DeReplicateFromSchema<typeof TextEmbeddingOutputSchema>, HfTransformersOnnxModelRecord>;
23
- export declare const HFT_TextClassifier: AiProviderRunFn<DeReplicateFromSchema<typeof TextClassifierInputSchema>, DeReplicateFromSchema<typeof TextClassifierOutputSchema>, HfTransformersOnnxModelRecord>;
24
- export declare const HFT_TextLanguageDetection: AiProviderRunFn<DeReplicateFromSchema<typeof TextLanguageDetectionInputSchema>, DeReplicateFromSchema<typeof TextLanguageDetectionOutputSchema>, HfTransformersOnnxModelRecord>;
22
+ export declare const HFT_TextEmbedding: AiProviderRunFn<TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, HfTransformersOnnxModelRecord>;
23
+ export declare const HFT_TextClassifier: AiProviderRunFn<TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, HfTransformersOnnxModelRecord>;
24
+ export declare const HFT_TextLanguageDetection: AiProviderRunFn<TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, HfTransformersOnnxModelRecord>;
25
+ export declare const HFT_TextNamedEntityRecognition: AiProviderRunFn<TextNamedEntityRecognitionTaskExecuteInput, TextNamedEntityRecognitionTaskExecuteOutput, HfTransformersOnnxModelRecord>;
26
+ export declare const HFT_TextFillMask: AiProviderRunFn<TextFillMaskTaskExecuteInput, TextFillMaskTaskExecuteOutput, HfTransformersOnnxModelRecord>;
25
27
  /**
26
28
  * Core implementation for text generation using Hugging Face Transformers.
27
29
  * This is shared between inline and worker implementations.
28
30
  */
29
- export declare const HFT_TextGeneration: AiProviderRunFn<DeReplicateFromSchema<typeof TextGenerationInputSchema>, DeReplicateFromSchema<typeof TextGenerationOutputSchema>, HfTransformersOnnxModelRecord>;
31
+ export declare const HFT_TextGeneration: AiProviderRunFn<TextGenerationTaskExecuteInput, TextGenerationTaskExecuteOutput, HfTransformersOnnxModelRecord>;
30
32
  /**
31
33
  * Core implementation for text translation using Hugging Face Transformers.
32
34
  * This is shared between inline and worker implementations.
33
35
  */
34
- export declare const HFT_TextTranslation: AiProviderRunFn<DeReplicateFromSchema<typeof TextTranslationInputSchema>, DeReplicateFromSchema<typeof TextTranslationOutputSchema>, HfTransformersOnnxModelRecord>;
36
+ export declare const HFT_TextTranslation: AiProviderRunFn<TextTranslationTaskExecuteInput, TextTranslationTaskExecuteOutput, HfTransformersOnnxModelRecord>;
35
37
  /**
36
38
  * Core implementation for text rewriting using Hugging Face Transformers.
37
39
  * This is shared between inline and worker implementations.
38
40
  */
39
- export declare const HFT_TextRewriter: AiProviderRunFn<DeReplicateFromSchema<typeof TextRewriterInputSchema>, DeReplicateFromSchema<typeof TextRewriterOutputSchema>, HfTransformersOnnxModelRecord>;
41
+ export declare const HFT_TextRewriter: AiProviderRunFn<TextRewriterTaskExecuteInput, TextRewriterTaskExecuteOutput, HfTransformersOnnxModelRecord>;
40
42
  /**
41
43
  * Core implementation for text summarization using Hugging Face Transformers.
42
44
  * This is shared between inline and worker implementations.
43
45
  */
44
- export declare const HFT_TextSummary: AiProviderRunFn<DeReplicateFromSchema<typeof TextSummaryInputSchema>, DeReplicateFromSchema<typeof TextSummaryOutputSchema>, HfTransformersOnnxModelRecord>;
46
+ export declare const HFT_TextSummary: AiProviderRunFn<TextSummaryTaskExecuteInput, TextSummaryTaskExecuteOutput, HfTransformersOnnxModelRecord>;
45
47
  /**
46
48
  * Core implementation for question answering using Hugging Face Transformers.
47
49
  * This is shared between inline and worker implementations.
48
50
  */
49
- export declare const HFT_TextQuestionAnswer: AiProviderRunFn<DeReplicateFromSchema<typeof TextQuestionAnswerInputSchema>, DeReplicateFromSchema<typeof TextQuestionAnswerOutputSchema>, HfTransformersOnnxModelRecord>;
51
+ export declare const HFT_TextQuestionAnswer: AiProviderRunFn<TextQuestionAnswerTaskExecuteInput, TextQuestionAnswerTaskExecuteOutput, HfTransformersOnnxModelRecord>;
50
52
  //# 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;AAmBH,OAAO,EACL,eAAe,EACf,KAAK,qBAAqB,EAC1B,6BAA6B,EAC7B,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,iCAAiC,EACjC,6BAA6B,EAC7B,8BAA8B,EAC9B,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAE3B,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AA2ClE;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,eAAe,CACxC,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,CAQ9B,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,qBAAqB,CAAC,OAAO,wBAAwB,CAAC,EACtD,qBAAqB,CAAC,OAAO,yBAAyB,CAAC,EACvD,6BAA6B,CA0B9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,qBAAqB,CAAC,OAAO,yBAAyB,CAAC,EACvD,qBAAqB,CAAC,OAAO,0BAA0B,CAAC,EACxD,6BAA6B,CAyB9B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,eAAe,CACrD,qBAAqB,CAAC,OAAO,gCAAgC,CAAC,EAC9D,qBAAqB,CAAC,OAAO,iCAAiC,CAAC,EAC/D,6BAA6B,CAyB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,qBAAqB,CAAC,OAAO,yBAAyB,CAAC,EACvD,qBAAqB,CAAC,OAAO,0BAA0B,CAAC,EACxD,6BAA6B,CAwB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAC/C,qBAAqB,CAAC,OAAO,0BAA0B,CAAC,EACxD,qBAAqB,CAAC,OAAO,2BAA2B,CAAC,EACzD,6BAA6B,CAyB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAC5C,qBAAqB,CAAC,OAAO,uBAAuB,CAAC,EACrD,qBAAqB,CAAC,OAAO,wBAAwB,CAAC,EACtD,6BAA6B,CA+B9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,eAAe,CAC3C,qBAAqB,CAAC,OAAO,sBAAsB,CAAC,EACpD,qBAAqB,CAAC,OAAO,uBAAuB,CAAC,EACrD,6BAA6B,CAsB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAAe,CAClD,qBAAqB,CAAC,OAAO,6BAA6B,CAAC,EAC3D,qBAAqB,CAAC,OAAO,8BAA8B,CAAC,EAC5D,6BAA6B,CAuB9B,CAAC"}
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"}
@@ -71,6 +71,16 @@ export declare const HfTransformersOnnxModelSchema: {
71
71
  };
72
72
  readonly required: readonly ["modelPath", "pipeline"];
73
73
  readonly additionalProperties: false;
74
+ readonly if: {
75
+ readonly properties: {
76
+ readonly pipeline: {
77
+ readonly const: "feature-extraction";
78
+ };
79
+ };
80
+ };
81
+ readonly then: {
82
+ readonly required: readonly ["nativeDimensions"];
83
+ };
74
84
  };
75
85
  };
76
86
  readonly required: readonly ["provider", "providerConfig"];
@@ -143,6 +153,16 @@ declare const ExtendedModelSchema: {
143
153
  };
144
154
  readonly required: readonly ["modelPath", "pipeline"];
145
155
  readonly additionalProperties: false;
156
+ readonly if: {
157
+ readonly properties: {
158
+ readonly pipeline: {
159
+ readonly const: "feature-extraction";
160
+ };
161
+ };
162
+ };
163
+ readonly then: {
164
+ readonly required: readonly ["nativeDimensions"];
165
+ };
146
166
  };
147
167
  readonly model_id: {
148
168
  readonly type: "string";
@@ -1 +1 @@
1
- {"version":3,"file":"HFT_ModelSchema.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/common/HFT_ModelSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAwB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGlE,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqED,CAAC;AAE1C,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQgB,CAAC;AAE1C,MAAM,MAAM,6BAA6B,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"HFT_ModelSchema.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/common/HFT_ModelSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAwB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGlE,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ED,CAAC;AAE1C,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQgB,CAAC;AAE1C,MAAM,MAAM,6BAA6B,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -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,CA2Cf"}
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 +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;AAenF;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
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 +1 @@
1
- {"version":3,"file":"HFT_Worker_RegisterJobFns.d.ts","sourceRoot":"","sources":["../../../src/hf-transformers/registry/HFT_Worker_RegisterJobFns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,eAAO,MAAM,iBAAiB,gDAA+C,CAAC;AAE9E,eAAO,MAAM,0BAA0B,MAmBtC,CAAC"}
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"}
package/dist/index.js CHANGED
@@ -58,17 +58,177 @@ import {
58
58
  } from "@sroussey/transformers";
59
59
  import { PermanentJobError } from "@workglow/job-queue";
60
60
  var pipelines = new Map;
61
- var getPipeline = async (model, onProgress, options = {}) => {
61
+ var getPipeline = async (model, onProgress, options = {}, progressScaleMax = 10) => {
62
62
  if (pipelines.has(model.model_id)) {
63
63
  return pipelines.get(model.model_id);
64
64
  }
65
+ const fileSizes = new Map;
66
+ const fileProgress = new Map;
67
+ const fileCompleted = new Set;
68
+ const fileFirstSent = new Set;
69
+ const fileLastSent = new Set;
70
+ const fileLastEventTime = new Map;
71
+ const pendingProgressByFile = new Map;
72
+ let throttleTimer = null;
73
+ const THROTTLE_MS = 160;
74
+ const estimatedTinyFiles = 3;
75
+ const estimatedMediumFiles = 1;
76
+ const estimatedTinySize = 1024;
77
+ const estimatedMediumSize = 20 * 1024 * 1024;
78
+ const estimatedLargeSize = 1024 * 1024 * 1024;
79
+ const baseEstimate = estimatedTinyFiles * estimatedTinySize + estimatedMediumFiles * estimatedMediumSize;
80
+ const sendProgress = (overallProgress, file, fileProgressValue, isFirst, isLast) => {
81
+ const now = Date.now();
82
+ const lastTime = fileLastEventTime.get(file) || 0;
83
+ const timeSinceLastEvent = now - lastTime;
84
+ const shouldThrottle = !isFirst && !isLast && timeSinceLastEvent < THROTTLE_MS;
85
+ if (shouldThrottle) {
86
+ pendingProgressByFile.set(file, {
87
+ progress: overallProgress,
88
+ file,
89
+ fileProgress: fileProgressValue
90
+ });
91
+ if (!throttleTimer) {
92
+ const timeRemaining = Math.max(1, THROTTLE_MS - timeSinceLastEvent);
93
+ throttleTimer = setTimeout(() => {
94
+ for (const [pendingFile, pending] of pendingProgressByFile.entries()) {
95
+ onProgress(Math.round(pending.progress), "Downloading model", {
96
+ file: pendingFile,
97
+ progress: pending.fileProgress
98
+ });
99
+ fileLastEventTime.set(pendingFile, Date.now());
100
+ }
101
+ pendingProgressByFile.clear();
102
+ throttleTimer = null;
103
+ }, timeRemaining);
104
+ }
105
+ return;
106
+ }
107
+ onProgress(Math.round(overallProgress), "Downloading model", {
108
+ file,
109
+ progress: fileProgressValue
110
+ });
111
+ fileLastEventTime.set(file, now);
112
+ pendingProgressByFile.delete(file);
113
+ if (throttleTimer && pendingProgressByFile.size === 0) {
114
+ clearTimeout(throttleTimer);
115
+ throttleTimer = null;
116
+ }
117
+ };
118
+ let hasSeenSubstantialFile = false;
119
+ const substantialFileThreshold = 1024 * 1024;
120
+ const abortSignal = options.abort_signal;
65
121
  const progressCallback = (status) => {
66
- const progress = status.status === "progress" ? Math.round(status.progress) : 0;
122
+ if (abortSignal?.aborted) {
123
+ return;
124
+ }
67
125
  if (status.status === "progress") {
68
- onProgress(progress, "Downloading model", {
69
- file: status.file,
70
- progress: status.progress
71
- });
126
+ const file = status.file;
127
+ const fileTotal = status.total;
128
+ const fileProgressValue = status.progress;
129
+ if (!fileSizes.has(file)) {
130
+ fileSizes.set(file, fileTotal);
131
+ fileProgress.set(file, 0);
132
+ if (fileTotal >= substantialFileThreshold) {
133
+ hasSeenSubstantialFile = true;
134
+ }
135
+ }
136
+ fileProgress.set(file, fileProgressValue);
137
+ const isComplete = fileProgressValue >= 100;
138
+ if (isComplete && !fileCompleted.has(file)) {
139
+ fileCompleted.add(file);
140
+ fileProgress.set(file, 100);
141
+ }
142
+ let actualLoadedSize = 0;
143
+ let actualTotalSize = 0;
144
+ const tinyThreshold = 100 * 1024;
145
+ const mediumThreshold = 100 * 1024 * 1024;
146
+ let seenTinyCount = 0;
147
+ let seenMediumCount = 0;
148
+ let seenLargeCount = 0;
149
+ for (const [trackedFile, size] of fileSizes.entries()) {
150
+ actualTotalSize += size;
151
+ const progress = fileProgress.get(trackedFile) || 0;
152
+ actualLoadedSize += size * progress / 100;
153
+ if (size < tinyThreshold) {
154
+ seenTinyCount++;
155
+ } else if (size < mediumThreshold) {
156
+ seenMediumCount++;
157
+ } else {
158
+ seenLargeCount++;
159
+ }
160
+ }
161
+ const unseenTinyFiles = Math.max(0, estimatedTinyFiles - seenTinyCount);
162
+ const unseenMediumFiles = Math.max(0, estimatedMediumFiles - seenMediumCount);
163
+ let estimatedLargeFiles;
164
+ if (seenLargeCount > 0) {
165
+ estimatedLargeFiles = 2;
166
+ } else {
167
+ estimatedLargeFiles = 1;
168
+ }
169
+ const unseenLargeFiles = Math.max(0, estimatedLargeFiles - seenLargeCount);
170
+ const adjustedTotalSize = actualTotalSize + unseenTinyFiles * estimatedTinySize + unseenMediumFiles * estimatedMediumSize + unseenLargeFiles * estimatedLargeSize;
171
+ const rawProgress = adjustedTotalSize > 0 ? actualLoadedSize / adjustedTotalSize * 100 : 0;
172
+ const overallProgress = rawProgress * progressScaleMax / 100;
173
+ const isFirst = !fileFirstSent.has(file);
174
+ const isLast = isComplete && !fileLastSent.has(file);
175
+ if (isFirst) {
176
+ fileFirstSent.add(file);
177
+ }
178
+ if (isLast) {
179
+ fileLastSent.add(file);
180
+ }
181
+ if (hasSeenSubstantialFile) {
182
+ sendProgress(overallProgress, file, fileProgressValue, isFirst, isLast);
183
+ }
184
+ } else if (status.status === "done" || status.status === "download") {
185
+ const file = status.file;
186
+ const fileSize = fileSizes.get(file) || 0;
187
+ if (fileSize >= substantialFileThreshold) {
188
+ hasSeenSubstantialFile = true;
189
+ }
190
+ if (!fileCompleted.has(file)) {
191
+ fileCompleted.add(file);
192
+ fileProgress.set(file, 100);
193
+ let actualLoadedSize = 0;
194
+ let actualTotalSize = 0;
195
+ const tinyThreshold = 100 * 1024;
196
+ const mediumThreshold = 100 * 1024 * 1024;
197
+ let seenTinyCount = 0;
198
+ let seenMediumCount = 0;
199
+ let seenLargeCount = 0;
200
+ for (const [trackedFile, size] of fileSizes.entries()) {
201
+ actualTotalSize += size;
202
+ const progress = fileProgress.get(trackedFile) || 0;
203
+ actualLoadedSize += size * progress / 100;
204
+ if (size < tinyThreshold) {
205
+ seenTinyCount++;
206
+ } else if (size < mediumThreshold) {
207
+ seenMediumCount++;
208
+ } else {
209
+ seenLargeCount++;
210
+ }
211
+ }
212
+ const unseenTinyFiles = Math.max(0, estimatedTinyFiles - seenTinyCount);
213
+ const unseenMediumFiles = Math.max(0, estimatedMediumFiles - seenMediumCount);
214
+ let estimatedLargeFiles;
215
+ if (seenLargeCount > 0) {
216
+ estimatedLargeFiles = 2;
217
+ } else {
218
+ estimatedLargeFiles = 1;
219
+ }
220
+ const unseenLargeFiles = Math.max(0, estimatedLargeFiles - seenLargeCount);
221
+ const adjustedTotalSize = actualTotalSize + unseenTinyFiles * estimatedTinySize + unseenMediumFiles * estimatedMediumSize + unseenLargeFiles * estimatedLargeSize;
222
+ const rawProgress = adjustedTotalSize > 0 ? actualLoadedSize / adjustedTotalSize * 100 : 0;
223
+ const overallProgress = rawProgress * progressScaleMax / 100;
224
+ const isLast = !fileLastSent.has(file);
225
+ if (isLast) {
226
+ fileLastSent.add(file);
227
+ if (hasSeenSubstantialFile) {
228
+ sendProgress(overallProgress, file, 100, false, true);
229
+ }
230
+ }
231
+ }
72
232
  }
73
233
  };
74
234
  const pipelineOptions = {
@@ -78,13 +238,39 @@ var getPipeline = async (model, onProgress, options = {}) => {
78
238
  ...options,
79
239
  progress_callback: progressCallback
80
240
  };
241
+ if (abortSignal?.aborted) {
242
+ throw new Error("Operation aborted before pipeline creation");
243
+ }
81
244
  const pipelineType = model.providerConfig.pipeline;
82
- const result = await pipeline(pipelineType, model.providerConfig.modelPath, pipelineOptions);
83
- pipelines.set(model.model_id, result);
84
- return result;
245
+ const abortPromise = new Promise((_, reject) => {
246
+ if (abortSignal) {
247
+ const handleAbort = () => {
248
+ reject(new Error("Pipeline download aborted"));
249
+ };
250
+ if (abortSignal.aborted) {
251
+ handleAbort();
252
+ } else {
253
+ abortSignal.addEventListener("abort", handleAbort, { once: true });
254
+ }
255
+ }
256
+ });
257
+ const pipelinePromise = pipeline(pipelineType, model.providerConfig.modelPath, pipelineOptions);
258
+ try {
259
+ const result = await (abortSignal ? Promise.race([pipelinePromise, abortPromise]) : pipelinePromise);
260
+ if (abortSignal?.aborted) {
261
+ throw new Error("Operation aborted after pipeline creation");
262
+ }
263
+ pipelines.set(model.model_id, result);
264
+ return result;
265
+ } catch (error) {
266
+ if (abortSignal?.aborted) {
267
+ throw new Error("Pipeline download aborted");
268
+ }
269
+ throw error;
270
+ }
85
271
  };
86
272
  var HFT_Download = async (input, model, onProgress, signal) => {
87
- await getPipeline(model, onProgress, { abort_signal: signal });
273
+ await getPipeline(model, onProgress, { abort_signal: signal }, 100);
88
274
  return {
89
275
  model: input.model
90
276
  };
@@ -190,6 +376,47 @@ var HFT_TextLanguageDetection = async (input, model, onProgress, signal) => {
190
376
  }))
191
377
  };
192
378
  };
379
+ var HFT_TextNamedEntityRecognition = async (input, model, onProgress, signal) => {
380
+ const textNamedEntityRecognition = await getPipeline(model, onProgress, {
381
+ abort_signal: signal
382
+ });
383
+ let results = await textNamedEntityRecognition(input.text, {
384
+ ignore_labels: input.blockList,
385
+ ...signal ? { abort_signal: signal } : {}
386
+ });
387
+ let entities = [];
388
+ if (!Array.isArray(results)) {
389
+ entities = [results];
390
+ } else {
391
+ entities = results;
392
+ }
393
+ return {
394
+ entities: entities.map((entity) => ({
395
+ entity: entity.entity,
396
+ score: entity.score,
397
+ word: entity.word
398
+ }))
399
+ };
400
+ };
401
+ var HFT_TextFillMask = async (input, model, onProgress, signal) => {
402
+ const unmasker = await getPipeline(model, onProgress, {
403
+ abort_signal: signal
404
+ });
405
+ let results = await unmasker(input.text);
406
+ let predictions = [];
407
+ if (!Array.isArray(results)) {
408
+ predictions = [results];
409
+ } else {
410
+ predictions = results;
411
+ }
412
+ return {
413
+ predictions: predictions.map((prediction) => ({
414
+ entity: prediction.token_str,
415
+ score: prediction.score,
416
+ sequence: prediction.sequence
417
+ }))
418
+ };
419
+ };
193
420
  var HFT_TextGeneration = async (input, model, onProgress, signal) => {
194
421
  const generateText = await getPipeline(model, onProgress, {
195
422
  abort_signal: signal
@@ -375,7 +602,17 @@ var HfTransformersOnnxModelSchema = {
375
602
  }
376
603
  },
377
604
  required: ["modelPath", "pipeline"],
378
- additionalProperties: false
605
+ additionalProperties: false,
606
+ if: {
607
+ properties: {
608
+ pipeline: {
609
+ const: "feature-extraction"
610
+ }
611
+ }
612
+ },
613
+ then: {
614
+ required: ["nativeDimensions"]
615
+ }
379
616
  }
380
617
  },
381
618
  required: ["provider", "providerConfig"],
@@ -406,6 +643,8 @@ async function register_HFT_ClientJobFns(worker, client) {
406
643
  "TextEmbeddingTask",
407
644
  "TextLanguageDetectionTask",
408
645
  "TextClassifierTask",
646
+ "TextFillMaskTask",
647
+ "TextNamedEntityRecognitionTask",
409
648
  "TextGenerationTask",
410
649
  "TextTranslationTask",
411
650
  "TextRewriterTask",
@@ -447,6 +686,8 @@ async function register_HFT_InlineJobFns(client) {
447
686
  ["TextQuestionAnswerTask"]: HFT_TextQuestionAnswer,
448
687
  ["TextLanguageDetectionTask"]: HFT_TextLanguageDetection,
449
688
  ["TextClassifierTask"]: HFT_TextClassifier,
689
+ ["TextFillMaskTask"]: HFT_TextFillMask,
690
+ ["TextNamedEntityRecognitionTask"]: HFT_TextNamedEntityRecognition,
450
691
  ["TextRewriterTask"]: HFT_TextRewriter,
451
692
  ["TextSummaryTask"]: HFT_TextSummary,
452
693
  ["TextTranslationTask"]: HFT_TextTranslation
@@ -487,6 +728,8 @@ var HFT_WORKER_JOBRUN_REGISTER = globalServiceRegistry2.register(HFT_WORKER_JOBR
487
728
  workerServer.registerFunction("TextGenerationTask", HFT_TextGeneration);
488
729
  workerServer.registerFunction("TextLanguageDetectionTask", HFT_TextLanguageDetection);
489
730
  workerServer.registerFunction("TextClassifierTask", HFT_TextClassifier);
731
+ workerServer.registerFunction("TextFillMaskTask", HFT_TextFillMask);
732
+ workerServer.registerFunction("TextNamedEntityRecognitionTask", HFT_TextNamedEntityRecognition);
490
733
  workerServer.registerFunction("TextTranslationTask", HFT_TextTranslation);
491
734
  workerServer.registerFunction("TextRewriterTask", HFT_TextRewriter);
492
735
  workerServer.registerFunction("TextSummaryTask", HFT_TextSummary);
@@ -558,54 +801,80 @@ var getWasmTask = async (model, onProgress, signal) => {
558
801
  return wasmFileset;
559
802
  };
560
803
  var modelTaskCache = new Map;
561
- var getModelTask = async (model, onProgress, signal, TaskType) => {
804
+ var optionsMatch = (opts1, opts2) => {
805
+ const keys1 = Object.keys(opts1).sort();
806
+ const keys2 = Object.keys(opts2).sort();
807
+ if (keys1.length !== keys2.length)
808
+ return false;
809
+ return keys1.every((key) => {
810
+ const val1 = opts1[key];
811
+ const val2 = opts2[key];
812
+ if (Array.isArray(val1) && Array.isArray(val2)) {
813
+ return JSON.stringify(val1) === JSON.stringify(val2);
814
+ }
815
+ return val1 === val2;
816
+ });
817
+ };
818
+ var getModelTask = async (model, options, onProgress, signal, TaskType) => {
562
819
  const modelPath = model.providerConfig.modelPath;
563
820
  const taskEngine = model.providerConfig.taskEngine;
564
- if (modelTaskCache.has(modelPath)) {
565
- return modelTaskCache.get(modelPath);
821
+ const cachedTasks = modelTaskCache.get(modelPath);
822
+ if (cachedTasks) {
823
+ const matchedTask = cachedTasks.find((cached) => optionsMatch(cached.options, options));
824
+ if (matchedTask) {
825
+ return matchedTask.task;
826
+ }
566
827
  }
567
828
  const wasmFileset = await getWasmTask(model, onProgress, signal);
829
+ onProgress(0.2, "Creating model task");
568
830
  const task = await TaskType.createFromOptions(wasmFileset, {
569
831
  baseOptions: {
570
832
  modelAssetPath: modelPath
571
- }
833
+ },
834
+ ...options
572
835
  });
573
- modelTaskCache.set(modelPath, task);
574
- model_to_wasm_mapping.set(modelPath, taskEngine);
836
+ const cachedTask = { task, options, taskEngine };
837
+ if (!modelTaskCache.has(modelPath)) {
838
+ modelTaskCache.set(modelPath, []);
839
+ }
840
+ modelTaskCache.get(modelPath).push(cachedTask);
575
841
  wasm_reference_counts.set(taskEngine, (wasm_reference_counts.get(taskEngine) || 0) + 1);
576
842
  return task;
577
843
  };
578
- var getTextEmbedder = async (model, onProgress, signal) => {
579
- return getModelTask(model, onProgress, signal, TextEmbedder);
844
+ var getTextEmbedder = async (model, options, onProgress, signal) => {
845
+ return getModelTask(model, options, onProgress, signal, TextEmbedder);
580
846
  };
581
- var getTextClassifier = async (model, onProgress, signal) => {
582
- return getModelTask(model, onProgress, signal, TextClassifier);
847
+ var getTextClassifier = async (model, options, onProgress, signal) => {
848
+ return getModelTask(model, options, onProgress, signal, TextClassifier);
583
849
  };
584
- var getTextLanguageDetector = async (model, onProgress, signal) => {
585
- return getModelTask(model, onProgress, signal, LanguageDetector);
850
+ var getTextLanguageDetector = async (model, options, onProgress, signal) => {
851
+ return getModelTask(model, options, onProgress, signal, LanguageDetector);
586
852
  };
587
853
  var TFMP_Download = async (input, model, onProgress, signal) => {
854
+ let task;
588
855
  switch (model?.providerConfig.pipeline) {
589
856
  case "text-embedder":
590
- await getTextEmbedder(model, onProgress, signal);
857
+ task = await getTextEmbedder(model, {}, onProgress, signal);
591
858
  break;
592
859
  case "text-classifier":
593
- await getTextClassifier(model, onProgress, signal);
860
+ task = await getTextClassifier(model, {}, onProgress, signal);
594
861
  break;
595
862
  case "text-language-detector":
596
- await getTextLanguageDetector(model, onProgress, signal);
863
+ task = await getTextLanguageDetector(model, {}, onProgress, signal);
597
864
  break;
598
865
  default:
599
866
  throw new PermanentJobError2("Invalid pipeline");
600
867
  }
601
868
  onProgress(0.9, "Pipeline loaded");
869
+ task.close();
870
+ const taskEngine = model?.providerConfig.taskEngine;
871
+ wasm_reference_counts.set(taskEngine, wasm_reference_counts.get(taskEngine) - 1);
602
872
  return {
603
873
  model: input.model
604
874
  };
605
875
  };
606
876
  var TFMP_TextEmbedding = async (input, model, onProgress, signal) => {
607
- onProgress(0.1, "Model loaded");
608
- const textEmbedder = await getTextEmbedder(model, onProgress, signal);
877
+ const textEmbedder = await getTextEmbedder(model, {}, onProgress, signal);
609
878
  const result = textEmbedder.embed(input.text);
610
879
  if (!result.embeddings?.[0]?.floatEmbedding) {
611
880
  throw new PermanentJobError2("Failed to generate embedding: Empty result");
@@ -616,8 +885,9 @@ var TFMP_TextEmbedding = async (input, model, onProgress, signal) => {
616
885
  };
617
886
  };
618
887
  var TFMP_TextClassifier = async (input, model, onProgress, signal) => {
619
- onProgress(0.1, "Model loaded");
620
- const textClassifier = await getTextClassifier(model, onProgress, signal);
888
+ const textClassifier = await getTextClassifier(model, {
889
+ maxCategories: input.maxCategories
890
+ }, onProgress, signal);
621
891
  const result = textClassifier.classify(input.text);
622
892
  if (!result.classifications?.[0]?.categories) {
623
893
  throw new PermanentJobError2("Failed to classify text: Empty result");
@@ -631,8 +901,10 @@ var TFMP_TextClassifier = async (input, model, onProgress, signal) => {
631
901
  };
632
902
  };
633
903
  var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
634
- onProgress(0.1, "Model loaded");
635
- const textLanguageDetector = await getTextLanguageDetector(model, onProgress, signal);
904
+ const maxLanguages = input.maxLanguages === 0 ? -1 : input.maxLanguages;
905
+ const textLanguageDetector = await getTextLanguageDetector(model, {
906
+ maxLanguages
907
+ }, onProgress, signal);
636
908
  const result = textLanguageDetector.detect(input.text);
637
909
  if (!result.languages?.[0]?.languageCode) {
638
910
  throw new PermanentJobError2("Failed to detect language: Empty result");
@@ -648,24 +920,22 @@ var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
648
920
  var TFMP_Unload = async (input, model, onProgress, signal) => {
649
921
  const modelPath = model.providerConfig.modelPath;
650
922
  if (modelTaskCache.has(modelPath)) {
651
- const item = modelTaskCache.get(modelPath);
652
- if ("dispose" in item && typeof item.dispose === "function") {
653
- item.dispose();
923
+ const cachedTasks = modelTaskCache.get(modelPath);
924
+ for (const cachedTask of cachedTasks) {
925
+ const task = cachedTask.task;
926
+ task.close();
927
+ const taskEngine = cachedTask.taskEngine;
928
+ const currentCount = wasm_reference_counts.get(taskEngine) || 0;
929
+ const newCount = currentCount - 1;
930
+ if (newCount <= 0) {
931
+ wasm_tasks.delete(taskEngine);
932
+ wasm_reference_counts.delete(taskEngine);
933
+ } else {
934
+ wasm_reference_counts.set(taskEngine, newCount);
935
+ }
654
936
  }
655
937
  modelTaskCache.delete(modelPath);
656
938
  }
657
- const taskEngine = model_to_wasm_mapping.get(modelPath);
658
- if (taskEngine) {
659
- const currentCount = wasm_reference_counts.get(taskEngine) || 0;
660
- const newCount = currentCount - 1;
661
- if (newCount <= 0) {
662
- wasm_tasks.delete(taskEngine);
663
- wasm_reference_counts.delete(taskEngine);
664
- } else {
665
- wasm_reference_counts.set(taskEngine, newCount);
666
- }
667
- model_to_wasm_mapping.delete(modelPath);
668
- }
669
939
  return {
670
940
  model: input.model
671
941
  };
@@ -829,12 +1099,14 @@ export {
829
1099
  HFT_TextSummary,
830
1100
  HFT_TextRewriter,
831
1101
  HFT_TextQuestionAnswer,
1102
+ HFT_TextNamedEntityRecognition,
832
1103
  HFT_TextLanguageDetection,
833
1104
  HFT_TextGeneration,
1105
+ HFT_TextFillMask,
834
1106
  HFT_TextEmbedding,
835
1107
  HFT_TextClassifier,
836
1108
  HFT_Download,
837
1109
  AudioPipelineUseCase
838
1110
  };
839
1111
 
840
- //# debugId=5ED8FAC61AA8526D64756E2164756E21
1112
+ //# debugId=AED2FBB7924C48F164756E2164756E21
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 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 TranslationPipeline,\n TranslationSingle,\n} from \"@sroussey/transformers\";\nimport {\n AiProviderRunFn,\n type DeReplicateFromSchema,\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n TextClassifierInputSchema,\n TextClassifierOutputSchema,\n TextEmbeddingInputSchema,\n TextEmbeddingOutputSchema,\n TextGenerationInputSchema,\n TextGenerationOutputSchema,\n TextLanguageDetectionInputSchema,\n TextLanguageDetectionOutputSchema,\n TextQuestionAnswerInputSchema,\n TextQuestionAnswerOutputSchema,\n TextRewriterInputSchema,\n TextRewriterOutputSchema,\n TextSummaryInputSchema,\n TextSummaryOutputSchema,\n TextTranslationInputSchema,\n TextTranslationOutputSchema,\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 */\nconst getPipeline = async (\n model: HfTransformersOnnxModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n options: PretrainedModelOptions = {}\n) => {\n if (pipelines.has(model.model_id)) {\n return pipelines.get(model.model_id);\n }\n\n // Create a callback status object for progress tracking\n const progressCallback = (status: CallbackStatus) => {\n const progress = status.status === \"progress\" ? Math.round(status.progress) : 0;\n if (status.status === \"progress\") {\n onProgress(progress, \"Downloading model\", {\n file: status.file,\n progress: status.progress,\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 const pipelineType = model.providerConfig.pipeline;\n const result = await pipeline(pipelineType, model.providerConfig.modelPath, pipelineOptions);\n pipelines.set(model.model_id, result);\n return result;\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 await getPipeline(model!, onProgress, { abort_signal: signal });\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 DeReplicateFromSchema<typeof TextEmbeddingInputSchema>,\n DeReplicateFromSchema<typeof TextEmbeddingOutputSchema>,\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 DeReplicateFromSchema<typeof TextClassifierInputSchema>,\n DeReplicateFromSchema<typeof TextClassifierOutputSchema>,\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 DeReplicateFromSchema<typeof TextLanguageDetectionInputSchema>,\n DeReplicateFromSchema<typeof TextLanguageDetectionOutputSchema>,\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\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 DeReplicateFromSchema<typeof TextGenerationInputSchema>,\n DeReplicateFromSchema<typeof TextGenerationOutputSchema>,\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 DeReplicateFromSchema<typeof TextTranslationInputSchema>,\n DeReplicateFromSchema<typeof TextTranslationOutputSchema>,\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 DeReplicateFromSchema<typeof TextRewriterInputSchema>,\n DeReplicateFromSchema<typeof TextRewriterOutputSchema>,\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 DeReplicateFromSchema<typeof TextSummaryInputSchema>,\n DeReplicateFromSchema<typeof TextSummaryOutputSchema>,\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 DeReplicateFromSchema<typeof TextQuestionAnswerInputSchema>,\n DeReplicateFromSchema<typeof TextQuestionAnswerOutputSchema>,\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",
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 },\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 \"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_TextGeneration,\n HFT_TextLanguageDetection,\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 [\"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_TextGeneration,\n HFT_TextLanguageDetection,\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(\"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",
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",
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",
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 DeReplicateFromSchema,\n DownloadModelTaskExecuteInput,\n DownloadModelTaskExecuteOutput,\n TextClassifierInputSchema,\n TextClassifierOutputSchema,\n TextEmbeddingInputSchema,\n TextEmbeddingOutputSchema,\n TextLanguageDetectionInputSchema,\n TextLanguageDetectionOutputSchema,\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\nconst modelTaskCache = new Map<string, TextEmbedder | TextClassifier | LanguageDetector>();\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\nconst getModelTask = async <\n T extends typeof TextEmbedder | typeof TextClassifier | typeof LanguageDetector,\n>(\n model: TFMPModelRecord,\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 if (modelTaskCache.has(modelPath)) {\n return modelTaskCache.get(modelPath)! as any;\n }\n\n // Load WASM if needed\n const wasmFileset = await getWasmTask(model, onProgress, signal);\n\n // Create new model instance\n const task = await TaskType.createFromOptions(wasmFileset, {\n baseOptions: {\n modelAssetPath: modelPath,\n },\n });\n\n // Cache the model\n modelTaskCache.set(modelPath, task);\n\n // Track WASM usage for this model and increment reference count\n model_to_wasm_mapping.set(modelPath, taskEngine);\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 onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<TextEmbedder> => {\n return getModelTask(model, onProgress, signal, TextEmbedder);\n};\n\nconst getTextClassifier = async (\n model: TFMPModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<TextClassifier> => {\n return getModelTask(model, onProgress, signal, TextClassifier);\n};\n\nconst getTextLanguageDetector = async (\n model: TFMPModelRecord,\n onProgress: (progress: number, message?: string, details?: any) => void,\n signal: AbortSignal\n): Promise<LanguageDetector> => {\n return getModelTask(model, 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 switch (model?.providerConfig.pipeline) {\n case \"text-embedder\":\n await getTextEmbedder(model, onProgress, signal);\n break;\n case \"text-classifier\":\n await getTextClassifier(model, onProgress, signal);\n break;\n case \"text-language-detector\":\n await getTextLanguageDetector(model, onProgress, signal);\n break;\n default:\n throw new PermanentJobError(\"Invalid pipeline\");\n }\n onProgress(0.9, \"Pipeline loaded\");\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 DeReplicateFromSchema<typeof TextEmbeddingInputSchema>,\n DeReplicateFromSchema<typeof TextEmbeddingOutputSchema>,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n onProgress(0.1, \"Model loaded\");\n\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 DeReplicateFromSchema<typeof TextClassifierInputSchema>,\n DeReplicateFromSchema<typeof TextClassifierOutputSchema>,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n onProgress(0.1, \"Model loaded\");\n\n const textClassifier = await getTextClassifier(model!, onProgress, signal);\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 DeReplicateFromSchema<typeof TextLanguageDetectionInputSchema>,\n DeReplicateFromSchema<typeof TextLanguageDetectionOutputSchema>,\n TFMPModelRecord\n> = async (input, model, onProgress, signal) => {\n onProgress(0.1, \"Model loaded\");\n\n const textLanguageDetector = await getTextLanguageDetector(model!, onProgress, signal);\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 the model instance\n * 2. Decrements the reference count for the associated WASM fileset\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 the model task if it exists\n if (modelTaskCache.has(modelPath)) {\n const item = modelTaskCache.get(modelPath)!;\n if (\"dispose\" in item && typeof item.dispose === \"function\") {\n item.dispose();\n }\n modelTaskCache.delete(modelPath);\n }\n\n // Decrease reference count for WASM fileset\n const taskEngine = model_to_wasm_mapping.get(modelPath);\n if (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 model_to_wasm_mapping.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 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",
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
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
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
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"
17
17
  ],
18
- "mappings": "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",
19
- "debugId": "5ED8FAC61AA8526D64756E2164756E21",
18
+ "mappings": "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",
19
+ "debugId": "AED2FBB7924C48F164756E2164756E21",
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, DeReplicateFromSchema, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, TextClassifierInputSchema, TextClassifierOutputSchema, TextEmbeddingInputSchema, TextEmbeddingOutputSchema, TextLanguageDetectionInputSchema, TextLanguageDetectionOutputSchema, UnloadModelTaskExecuteInput, UnloadModelTaskExecuteOutput } from "@workglow/ai";
6
+ import type { AiProviderRunFn, DownloadModelTaskExecuteInput, DownloadModelTaskExecuteOutput, TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, 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.
@@ -14,24 +14,24 @@ export declare const TFMP_Download: AiProviderRunFn<DownloadModelTaskExecuteInpu
14
14
  * Core implementation for text embedding using MediaPipe TFJS.
15
15
  * This is shared between inline and worker implementations.
16
16
  */
17
- export declare const TFMP_TextEmbedding: AiProviderRunFn<DeReplicateFromSchema<typeof TextEmbeddingInputSchema>, DeReplicateFromSchema<typeof TextEmbeddingOutputSchema>, TFMPModelRecord>;
17
+ export declare const TFMP_TextEmbedding: AiProviderRunFn<TextEmbeddingTaskExecuteInput, TextEmbeddingTaskExecuteOutput, TFMPModelRecord>;
18
18
  /**
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<DeReplicateFromSchema<typeof TextClassifierInputSchema>, DeReplicateFromSchema<typeof TextClassifierOutputSchema>, TFMPModelRecord>;
22
+ export declare const TFMP_TextClassifier: AiProviderRunFn<TextClassifierTaskExecuteInput, TextClassifierTaskExecuteOutput, TFMPModelRecord>;
23
23
  /**
24
24
  * Core implementation for language detection using MediaPipe TFJS.
25
25
  * This is shared between inline and worker implementations.
26
26
  */
27
- export declare const TFMP_TextLanguageDetection: AiProviderRunFn<DeReplicateFromSchema<typeof TextLanguageDetectionInputSchema>, DeReplicateFromSchema<typeof TextLanguageDetectionOutputSchema>, TFMPModelRecord>;
27
+ export declare const TFMP_TextLanguageDetection: AiProviderRunFn<TextLanguageDetectionTaskExecuteInput, TextLanguageDetectionTaskExecuteOutput, TFMPModelRecord>;
28
28
  /**
29
29
  * Core implementation for unloading a MediaPipe TFJS model.
30
30
  * This is shared between inline and worker implementations.
31
31
  *
32
32
  * When a model is unloaded, this function:
33
- * 1. Disposes of the model instance
34
- * 2. Decrements the reference count for the associated WASM fileset
33
+ * 1. Disposes of all cached model instances for the given model path
34
+ * 2. Decrements the reference count for the associated WASM fileset for each instance
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>;
@@ -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,qBAAqB,EACrB,6BAA6B,EAC7B,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,yBAAyB,EACzB,gCAAgC,EAChC,iCAAiC,EACjC,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAuJrD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CACzC,6BAA6B,EAC7B,8BAA8B,EAC9B,eAAe,CAoBhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C,qBAAqB,CAAC,OAAO,wBAAwB,CAAC,EACtD,qBAAqB,CAAC,OAAO,yBAAyB,CAAC,EACvD,eAAe,CAgBhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAC/C,qBAAqB,CAAC,OAAO,yBAAyB,CAAC,EACvD,qBAAqB,CAAC,OAAO,0BAA0B,CAAC,EACxD,eAAe,CAmBhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAAe,CACtD,qBAAqB,CAAC,OAAO,gCAAgC,CAAC,EAC9D,qBAAqB,CAAC,OAAO,iCAAiC,CAAC,EAC/D,eAAe,CAmBhB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,eAAe,CACvC,2BAA2B,EAC3B,4BAA4B,EAC5B,eAAe,CAiChB,CAAC"}
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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workglow/ai-provider",
3
3
  "type": "module",
4
- "version": "0.0.69",
4
+ "version": "0.0.71",
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,12 +30,12 @@
30
30
  "access": "public"
31
31
  },
32
32
  "peerDependencies": {
33
- "@workglow/ai": "0.0.69",
34
- "@workglow/job-queue": "0.0.69",
35
- "@workglow/storage": "0.0.69",
36
- "@workglow/task-graph": "0.0.69",
37
- "@workglow/util": "0.0.69",
38
- "@sroussey/transformers": "3.8.1",
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",
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",
41
41
  "@mediapipe/tasks-audio": "^0.10.22-rc.20250304",
@@ -59,12 +59,12 @@
59
59
  }
60
60
  },
61
61
  "devDependencies": {
62
- "@workglow/ai": "0.0.69",
63
- "@workglow/job-queue": "0.0.69",
64
- "@workglow/storage": "0.0.69",
65
- "@workglow/task-graph": "0.0.69",
66
- "@workglow/util": "0.0.69",
67
- "@sroussey/transformers": "3.8.1",
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",
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",
70
70
  "@mediapipe/tasks-audio": "^0.10.22-rc.20250304",