@workglow/tf-mediapipe 0.2.33 → 0.2.35

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.
Files changed (42) hide show
  1. package/dist/ai/TensorFlowMediaPipeProvider.d.ts +8 -10
  2. package/dist/ai/TensorFlowMediaPipeProvider.d.ts.map +1 -1
  3. package/dist/ai/TensorFlowMediaPipeQueuedProvider.d.ts +6 -3
  4. package/dist/ai/TensorFlowMediaPipeQueuedProvider.d.ts.map +1 -1
  5. package/dist/ai/common/TFMP_Capabilities.d.ts +24 -0
  6. package/dist/ai/common/TFMP_Capabilities.d.ts.map +1 -0
  7. package/dist/ai/common/TFMP_CapabilitySets.d.ts +23 -0
  8. package/dist/ai/common/TFMP_CapabilitySets.d.ts.map +1 -0
  9. package/dist/ai/common/TFMP_Constants.d.ts +1 -1
  10. package/dist/ai/common/TFMP_Constants.d.ts.map +1 -1
  11. package/dist/ai/common/TFMP_Download.d.ts +14 -2
  12. package/dist/ai/common/TFMP_Download.d.ts.map +1 -1
  13. package/dist/ai/common/TFMP_FaceDetector.d.ts.map +1 -1
  14. package/dist/ai/common/TFMP_FaceLandmarker.d.ts.map +1 -1
  15. package/dist/ai/common/TFMP_GestureRecognizer.d.ts.map +1 -1
  16. package/dist/ai/common/TFMP_HandLandmarker.d.ts.map +1 -1
  17. package/dist/ai/common/TFMP_ImageClassification.d.ts.map +1 -1
  18. package/dist/ai/common/TFMP_ImageEmbedding.d.ts.map +1 -1
  19. package/dist/ai/common/TFMP_ImageSegmentation.d.ts.map +1 -1
  20. package/dist/ai/common/TFMP_JobRunFns.d.ts +9 -2
  21. package/dist/ai/common/TFMP_JobRunFns.d.ts.map +1 -1
  22. package/dist/ai/common/TFMP_ModelInfo.d.ts.map +1 -1
  23. package/dist/ai/common/TFMP_ModelSchema.d.ts +3 -3
  24. package/dist/ai/common/TFMP_ObjectDetection.d.ts.map +1 -1
  25. package/dist/ai/common/TFMP_PoseLandmarker.d.ts.map +1 -1
  26. package/dist/ai/common/TFMP_Runtime.d.ts +2 -1
  27. package/dist/ai/common/TFMP_Runtime.d.ts.map +1 -1
  28. package/dist/ai/common/TFMP_TextClassification.d.ts.map +1 -1
  29. package/dist/ai/common/TFMP_TextEmbedding.d.ts.map +1 -1
  30. package/dist/ai/common/TFMP_TextLanguageDetection.d.ts.map +1 -1
  31. package/dist/ai/common/TFMP_Unload.d.ts +2 -2
  32. package/dist/ai/common/TFMP_Unload.d.ts.map +1 -1
  33. package/dist/ai/index.d.ts +25 -0
  34. package/dist/ai/index.d.ts.map +1 -1
  35. package/dist/ai/runtime.d.ts.map +1 -1
  36. package/dist/ai-runtime.d.ts.map +1 -1
  37. package/dist/ai-runtime.js +482 -395
  38. package/dist/ai-runtime.js.map +28 -26
  39. package/dist/ai.d.ts.map +1 -1
  40. package/dist/ai.js +735 -22
  41. package/dist/ai.js.map +27 -6
  42. package/package.json +12 -13
@@ -27,261 +27,45 @@ async function loadTfmpTasksVisionSDK() {
27
27
  // src/ai/registerTensorFlowMediaPipeInline.ts
28
28
  import { registerProviderInline } from "@workglow/ai/provider-utils";
29
29
 
30
- // src/ai/common/TFMP_ModelSearch.ts
31
- import { filterModelSearchResultsByQuery } from "@workglow/ai/provider-utils";
32
-
33
- // src/ai/common/TFMP_Constants.ts
34
- var TENSORFLOW_MEDIAPIPE = "TENSORFLOW_MEDIAPIPE";
35
- var TFMP_DEFAULT_TASK_TYPES = [
36
- "DownloadModelTask",
37
- "UnloadModelTask",
38
- "ModelInfoTask",
39
- "TextEmbeddingTask",
40
- "TextLanguageDetectionTask",
41
- "TextClassificationTask",
42
- "ImageSegmentationTask",
43
- "ImageEmbeddingTask",
44
- "ImageClassificationTask",
45
- "ObjectDetectionTask",
46
- "GestureRecognizerTask",
47
- "HandLandmarkerTask",
48
- "FaceDetectorTask",
49
- "FaceLandmarkerTask",
50
- "PoseLandmarkerTask",
51
- "ModelSearchTask"
30
+ // src/ai/common/TFMP_CapabilitySets.ts
31
+ var TFMP_TEXT_EMBEDDING = ["text.embedding"];
32
+ var TFMP_TEXT_CLASSIFICATION = ["text.classification"];
33
+ var TFMP_TEXT_LANGUAGE_DETECTION = [
34
+ "text.language-detection"
52
35
  ];
53
- var TextPipelineTask = {
54
- "text-embedder": "text-embedder",
55
- "text-classifier": "text-classifier",
56
- "text-language-detector": "text-language-detector",
57
- "genai-text": "genai-text",
58
- "audio-classifier": "audio-classifier",
59
- "audio-embedder": "audio-embedder",
60
- "vision-face-detector": "vision-face-detector",
61
- "vision-face-landmarker": "vision-face-landmarker",
62
- "vision-face-stylizer": "vision-face-stylizer",
63
- "vision-gesture-recognizer": "vision-gesture-recognizer",
64
- "vision-hand-landmarker": "vision-hand-landmarker",
65
- "vision-holistic-landmarker": "vision-holistic-landmarker",
66
- "vision-image-classifier": "vision-image-classifier",
67
- "vision-image-embedder": "vision-image-embedder",
68
- "vision-image-segmenter": "vision-image-segmenter",
69
- "vision-image-interactive-segmenter": "vision-image-interactive-segmenter",
70
- "vision-object-detector": "vision-object-detector",
71
- "vision-pose-landmarker": "vision-pose-landmarker"
72
- };
73
-
74
- // src/ai/common/TFMP_ModelSearch.ts
75
- var TFMP_MODEL_RESULTS = [
76
- {
77
- id: "universal-sentence-encoder",
78
- label: "Universal Sentence Encoder",
79
- description: "Text embedding model",
80
- record: {
81
- provider: TENSORFLOW_MEDIAPIPE,
82
- title: "Universal Sentence Encoder",
83
- description: "Universal Sentence Encoder",
84
- tasks: ["TextEmbeddingTask"],
85
- provider_config: {
86
- model_path: "https://storage.googleapis.com/mediapipe-tasks/text_embedder/universal_sentence_encoder.tflite",
87
- task_engine: "text",
88
- pipeline: "text-embedder"
89
- },
90
- metadata: {}
91
- },
92
- raw: { source: "mediapipe" }
93
- },
94
- {
95
- id: "language-detector",
96
- label: "MediaPipe Language Detector",
97
- description: "Language detection model",
98
- record: {
99
- provider: TENSORFLOW_MEDIAPIPE,
100
- title: "MediaPipe Language Detector",
101
- description: "MediaPipe Language Detector",
102
- tasks: ["TextLanguageDetectionTask"],
103
- provider_config: {
104
- model_path: "https://storage.googleapis.com/mediapipe-models/language_detector/language_detector/float32/latest/language_detector.tflite",
105
- task_engine: "text",
106
- pipeline: "text-language-detector"
107
- },
108
- metadata: {}
109
- },
110
- raw: { source: "mediapipe" }
111
- },
112
- {
113
- id: "bert-text-classifier",
114
- label: "MediaPipe BERT Text Classifier",
115
- description: "Text classification model",
116
- record: {
117
- provider: TENSORFLOW_MEDIAPIPE,
118
- title: "MediaPipe BERT Text Classifier",
119
- description: "MediaPipe BERT Text Classifier",
120
- tasks: ["TextClassificationTask"],
121
- provider_config: {
122
- model_path: "https://storage.googleapis.com/mediapipe-tasks/text_classifier/bert_text_classifier.tflite",
123
- task_engine: "text",
124
- pipeline: "text-classifier"
125
- },
126
- metadata: {}
127
- },
128
- raw: { source: "mediapipe" }
129
- },
130
- {
131
- id: "image-embedder",
132
- label: "MediaPipe Image Embedder",
133
- description: "Image embedding model",
134
- record: {
135
- provider: TENSORFLOW_MEDIAPIPE,
136
- title: "MediaPipe Image Embedder",
137
- description: "MediaPipe Image Embedder",
138
- tasks: ["ImageEmbeddingTask"],
139
- provider_config: {
140
- model_path: "https://storage.googleapis.com/mediapipe-models/image_embedder/mobilenet_v3_small/float32/1/mobilenet_v3_small.tflite",
141
- task_engine: "vision",
142
- pipeline: "vision-image-embedder"
143
- },
144
- metadata: {}
145
- },
146
- raw: { source: "mediapipe" }
147
- },
148
- {
149
- id: "efficientnet-lite0",
150
- label: "EfficientNet Lite0",
151
- description: "Image classification model",
152
- record: {
153
- provider: TENSORFLOW_MEDIAPIPE,
154
- title: "EfficientNet Lite0",
155
- description: "Image classification model",
156
- tasks: ["ImageClassificationTask"],
157
- provider_config: {
158
- model_path: "https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite",
159
- task_engine: "vision",
160
- pipeline: "vision-image-classifier"
161
- },
162
- metadata: {}
163
- },
164
- raw: { source: "mediapipe" }
165
- },
166
- {
167
- id: "efficientdet-lite0",
168
- label: "Efficient Object Detector Lite0",
169
- description: "Object detection model",
170
- record: {
171
- provider: TENSORFLOW_MEDIAPIPE,
172
- title: "Efficient Object Detector Lite0",
173
- description: "Object detection model",
174
- tasks: ["ObjectDetectionTask"],
175
- provider_config: {
176
- model_path: "https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/float32/1/efficientdet_lite0.tflite",
177
- task_engine: "vision",
178
- pipeline: "vision-object-detector"
179
- },
180
- metadata: {}
181
- },
182
- raw: { source: "mediapipe" }
183
- },
184
- {
185
- id: "deeplabv3",
186
- label: "Efficient Image Segmenter Lite0",
187
- description: "Image segmentation model",
188
- record: {
189
- provider: TENSORFLOW_MEDIAPIPE,
190
- title: "Efficient Image Segmenter Lite0",
191
- description: "Image segmentation model",
192
- tasks: ["ImageSegmentationTask"],
193
- provider_config: {
194
- model_path: "https://storage.googleapis.com/mediapipe-assets/deeplabv3.tflite?generation=1661875711618421",
195
- task_engine: "vision",
196
- pipeline: "vision-image-segmenter"
197
- },
198
- metadata: {}
199
- },
200
- raw: { source: "mediapipe" }
201
- },
202
- {
203
- id: "face-landmarker",
204
- label: "Face Landmarker",
205
- description: "Detects 478 facial landmarks with blendshapes",
206
- record: {
207
- provider: TENSORFLOW_MEDIAPIPE,
208
- title: "Face Landmarker",
209
- description: "Detects 478 facial landmarks with blendshapes",
210
- tasks: ["FaceLandmarkerTask"],
211
- provider_config: {
212
- model_path: "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task",
213
- task_engine: "vision",
214
- pipeline: "vision-face-landmarker"
215
- },
216
- metadata: {}
217
- },
218
- raw: { source: "mediapipe" }
219
- },
220
- {
221
- id: "gesture-recognizer",
222
- label: "Gesture Recognizer",
223
- description: "Recognizes hand gestures such as thumbs up and victory",
224
- record: {
225
- provider: TENSORFLOW_MEDIAPIPE,
226
- title: "Gesture Recognizer",
227
- description: "Recognizes hand gestures such as thumbs up and victory",
228
- tasks: ["GestureRecognizerTask"],
229
- provider_config: {
230
- model_path: "https://storage.googleapis.com/mediapipe-models/gesture_recognizer/gesture_recognizer/float16/1/gesture_recognizer.task",
231
- task_engine: "vision",
232
- pipeline: "vision-gesture-recognizer"
233
- },
234
- metadata: {}
235
- },
236
- raw: { source: "mediapipe" }
237
- },
238
- {
239
- id: "hand-landmarker",
240
- label: "Hand Landmarker",
241
- description: "Detects 21 hand landmarks",
242
- record: {
243
- provider: TENSORFLOW_MEDIAPIPE,
244
- title: "Hand Landmarker",
245
- description: "Detects 21 hand landmarks",
246
- tasks: ["HandLandmarkerTask"],
247
- provider_config: {
248
- model_path: "https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task",
249
- task_engine: "vision",
250
- pipeline: "vision-hand-landmarker"
251
- },
252
- metadata: {}
253
- },
254
- raw: { source: "mediapipe" }
255
- },
256
- {
257
- id: "pose-landmarker",
258
- label: "Pose Landmarker",
259
- description: "Detects 33 body pose landmarks",
260
- record: {
261
- provider: TENSORFLOW_MEDIAPIPE,
262
- title: "Pose Landmarker",
263
- description: "Detects 33 body pose landmarks",
264
- tasks: ["PoseLandmarkerTask"],
265
- provider_config: {
266
- model_path: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task",
267
- task_engine: "vision",
268
- pipeline: "vision-pose-landmarker"
269
- },
270
- metadata: {}
271
- },
272
- raw: { source: "mediapipe" }
273
- }
36
+ var TFMP_IMAGE_CLASSIFICATION = ["image.classification"];
37
+ var TFMP_IMAGE_EMBEDDING = ["image.embedding"];
38
+ var TFMP_IMAGE_SEGMENTATION = ["image.segmentation"];
39
+ var TFMP_IMAGE_OBJECT_DETECTION = [
40
+ "image.object-detection"
41
+ ];
42
+ var TFMP_VISION_FACE_DETECTION = ["vision.face-detection"];
43
+ var TFMP_VISION_FACE_LANDMARKS = ["vision.face-landmarks"];
44
+ var TFMP_VISION_HAND_LANDMARKS = ["vision.hand-landmarks"];
45
+ var TFMP_VISION_POSE_LANDMARKS = ["vision.pose-landmarks"];
46
+ var TFMP_VISION_GESTURE = ["vision.gesture"];
47
+ var TFMP_MODEL_DOWNLOAD = ["model.download"];
48
+ var TFMP_MODEL_UNLOAD = ["model.download-remove"];
49
+ var TFMP_MODEL_SEARCH = ["model.search"];
50
+ var TFMP_MODEL_INFO = ["model.info"];
51
+ var TFMP_CAPABILITY_SETS = [
52
+ TFMP_TEXT_EMBEDDING,
53
+ TFMP_TEXT_CLASSIFICATION,
54
+ TFMP_TEXT_LANGUAGE_DETECTION,
55
+ TFMP_IMAGE_CLASSIFICATION,
56
+ TFMP_IMAGE_EMBEDDING,
57
+ TFMP_IMAGE_SEGMENTATION,
58
+ TFMP_IMAGE_OBJECT_DETECTION,
59
+ TFMP_VISION_FACE_DETECTION,
60
+ TFMP_VISION_FACE_LANDMARKS,
61
+ TFMP_VISION_HAND_LANDMARKS,
62
+ TFMP_VISION_POSE_LANDMARKS,
63
+ TFMP_VISION_GESTURE,
64
+ TFMP_MODEL_DOWNLOAD,
65
+ TFMP_MODEL_UNLOAD,
66
+ TFMP_MODEL_SEARCH,
67
+ TFMP_MODEL_INFO
274
68
  ];
275
- function createTFMPModelSearch(providerId) {
276
- return async (input) => {
277
- const results = filterModelSearchResultsByQuery(TFMP_MODEL_RESULTS.map((result) => ({
278
- ...result,
279
- record: { ...result.record, provider: providerId }
280
- })), input.query);
281
- return { results };
282
- };
283
- }
284
- var TFMP_ModelSearch = createTFMPModelSearch(TENSORFLOW_MEDIAPIPE);
285
69
 
286
70
  // src/ai/common/TFMP_Download.ts
287
71
  import { PermanentJobError as PermanentJobError2 } from "@workglow/job-queue";
@@ -305,7 +89,7 @@ var optionsMatch = (opts1, opts2) => {
305
89
  return val1 === val2;
306
90
  });
307
91
  };
308
- var getWasmTask = async (model, onProgress, signal) => {
92
+ var getWasmTask = async (model, emit, signal) => {
309
93
  const task_engine = model.provider_config.task_engine;
310
94
  if (wasm_tasks.has(task_engine)) {
311
95
  return wasm_tasks.get(task_engine);
@@ -313,7 +97,7 @@ var getWasmTask = async (model, onProgress, signal) => {
313
97
  if (signal.aborted) {
314
98
  throw new PermanentJobError("Aborted job");
315
99
  }
316
- onProgress(0.1, "Loading WASM task");
100
+ emit({ type: "phase", message: "Loading WASM task", progress: 0.1 });
317
101
  let wasmFileset;
318
102
  switch (task_engine) {
319
103
  case "vision": {
@@ -342,7 +126,7 @@ var getWasmTask = async (model, onProgress, signal) => {
342
126
  wasm_tasks.set(task_engine, wasmFileset);
343
127
  return wasmFileset;
344
128
  };
345
- var getModelTask = async (model, options, onProgress, signal, TaskType) => {
129
+ var getModelTask = async (model, options, emit, signal, TaskType) => {
346
130
  const model_path = model.provider_config.model_path;
347
131
  const task_engine = model.provider_config.task_engine;
348
132
  const cachedTasks = modelTaskCache.get(model_path);
@@ -352,8 +136,8 @@ var getModelTask = async (model, options, onProgress, signal, TaskType) => {
352
136
  return matchedTask.task;
353
137
  }
354
138
  }
355
- const wasmFileset = await getWasmTask(model, onProgress, signal);
356
- onProgress(0.2, "Creating model task");
139
+ const wasmFileset = await getWasmTask(model, emit, signal);
140
+ emit({ type: "phase", message: "Creating model task", progress: 0.2 });
357
141
  const task = await TaskType.createFromOptions(wasmFileset, {
358
142
  baseOptions: {
359
143
  modelAssetPath: model_path
@@ -370,89 +154,88 @@ var getModelTask = async (model, options, onProgress, signal, TaskType) => {
370
154
  };
371
155
 
372
156
  // src/ai/common/TFMP_Download.ts
373
- var TFMP_Download = async (input, model, onProgress, signal) => {
157
+ var TFMP_Download = async (input, model, signal, emit) => {
158
+ const pipeline = model?.provider_config.pipeline;
374
159
  let task;
375
- switch (model?.provider_config.pipeline) {
160
+ switch (pipeline) {
376
161
  case "text-embedder": {
377
162
  const { TextEmbedder } = await loadTfmpTasksTextSDK();
378
- task = await getModelTask(model, {}, onProgress, signal, TextEmbedder);
163
+ task = await getModelTask(model, {}, emit, signal, TextEmbedder);
379
164
  break;
380
165
  }
381
166
  case "text-classifier": {
382
167
  const { TextClassifier } = await loadTfmpTasksTextSDK();
383
- task = await getModelTask(model, {}, onProgress, signal, TextClassifier);
168
+ task = await getModelTask(model, {}, emit, signal, TextClassifier);
384
169
  break;
385
170
  }
386
171
  case "text-language-detector": {
387
172
  const { LanguageDetector } = await loadTfmpTasksTextSDK();
388
- task = await getModelTask(model, {}, onProgress, signal, LanguageDetector);
173
+ task = await getModelTask(model, {}, emit, signal, LanguageDetector);
389
174
  break;
390
175
  }
391
176
  case "vision-image-classifier": {
392
177
  const { ImageClassifier } = await loadTfmpTasksVisionSDK();
393
- task = await getModelTask(model, {}, onProgress, signal, ImageClassifier);
178
+ task = await getModelTask(model, {}, emit, signal, ImageClassifier);
394
179
  break;
395
180
  }
396
181
  case "vision-image-embedder": {
397
182
  const { ImageEmbedder } = await loadTfmpTasksVisionSDK();
398
- task = await getModelTask(model, {}, onProgress, signal, ImageEmbedder);
183
+ task = await getModelTask(model, {}, emit, signal, ImageEmbedder);
399
184
  break;
400
185
  }
401
186
  case "vision-image-segmenter": {
402
187
  const { ImageSegmenter } = await loadTfmpTasksVisionSDK();
403
- task = await getModelTask(model, {}, onProgress, signal, ImageSegmenter);
188
+ task = await getModelTask(model, {}, emit, signal, ImageSegmenter);
404
189
  break;
405
190
  }
406
191
  case "vision-object-detector": {
407
192
  const { ObjectDetector } = await loadTfmpTasksVisionSDK();
408
- task = await getModelTask(model, {}, onProgress, signal, ObjectDetector);
193
+ task = await getModelTask(model, {}, emit, signal, ObjectDetector);
409
194
  break;
410
195
  }
411
196
  case "vision-face-detector": {
412
197
  const { FaceDetector } = await loadTfmpTasksVisionSDK();
413
- task = await getModelTask(model, {}, onProgress, signal, FaceDetector);
198
+ task = await getModelTask(model, {}, emit, signal, FaceDetector);
414
199
  break;
415
200
  }
416
201
  case "vision-face-landmarker": {
417
202
  const { FaceLandmarker } = await loadTfmpTasksVisionSDK();
418
- task = await getModelTask(model, {}, onProgress, signal, FaceLandmarker);
203
+ task = await getModelTask(model, {}, emit, signal, FaceLandmarker);
419
204
  break;
420
205
  }
421
206
  case "vision-gesture-recognizer": {
422
207
  const { GestureRecognizer } = await loadTfmpTasksVisionSDK();
423
- task = await getModelTask(model, {}, onProgress, signal, GestureRecognizer);
208
+ task = await getModelTask(model, {}, emit, signal, GestureRecognizer);
424
209
  break;
425
210
  }
426
211
  case "vision-hand-landmarker": {
427
212
  const { HandLandmarker } = await loadTfmpTasksVisionSDK();
428
- task = await getModelTask(model, {}, onProgress, signal, HandLandmarker);
213
+ task = await getModelTask(model, {}, emit, signal, HandLandmarker);
429
214
  break;
430
215
  }
431
216
  case "vision-pose-landmarker": {
432
217
  const { PoseLandmarker } = await loadTfmpTasksVisionSDK();
433
- task = await getModelTask(model, {}, onProgress, signal, PoseLandmarker);
218
+ task = await getModelTask(model, {}, emit, signal, PoseLandmarker);
434
219
  break;
435
220
  }
436
221
  default:
437
- throw new PermanentJobError2(`Invalid pipeline: ${model?.provider_config.pipeline}. Supported pipelines: text-embedder, text-classifier, text-language-detector, vision-image-classifier, vision-image-embedder, vision-image-segmenter, vision-object-detector, vision-face-detector, vision-face-landmarker, vision-gesture-recognizer, vision-hand-landmarker, vision-pose-landmarker`);
222
+ throw new PermanentJobError2(`Invalid pipeline: ${pipeline}. Supported pipelines: text-embedder, text-classifier, text-language-detector, vision-image-classifier, vision-image-embedder, vision-image-segmenter, vision-object-detector, vision-face-detector, vision-face-landmarker, vision-gesture-recognizer, vision-hand-landmarker, vision-pose-landmarker`);
438
223
  }
439
- onProgress(0.9, "Pipeline loaded");
224
+ emit({ type: "phase", message: "Pipeline loaded", progress: 0.9 });
440
225
  task.close();
441
- const task_engine = model?.provider_config.task_engine;
226
+ const task_engine = model.provider_config.task_engine;
442
227
  wasm_reference_counts.set(task_engine, wasm_reference_counts.get(task_engine) - 1);
443
- return {
444
- model: input.model
445
- };
228
+ emit({ type: "finish", data: { model: input.model } });
446
229
  };
447
230
 
448
231
  // src/ai/common/TFMP_FaceDetector.ts
449
232
  import { PermanentJobError as PermanentJobError3 } from "@workglow/job-queue";
450
- var TFMP_FaceDetector = async (input, model, onProgress, signal) => {
233
+ var TFMP_FaceDetector = async (input, model, signal, emit) => {
451
234
  const { FaceDetector } = await loadTfmpTasksVisionSDK();
452
235
  const faceDetector = await getModelTask(model, {
453
236
  minDetectionConfidence: input.minDetectionConfidence,
454
237
  minSuppressionThreshold: input.minSuppressionThreshold
455
- }, onProgress, signal, FaceDetector);
238
+ }, emit, signal, FaceDetector);
456
239
  const result = faceDetector.detect(input.image);
457
240
  if (!result.detections) {
458
241
  throw new PermanentJobError3("Failed to detect faces: Empty result");
@@ -471,14 +254,12 @@ var TFMP_FaceDetector = async (input, model, onProgress, signal) => {
471
254
  })) || [],
472
255
  score: detection.categories?.[0]?.score || 0
473
256
  }));
474
- return {
475
- faces
476
- };
257
+ emit({ type: "finish", data: { faces } });
477
258
  };
478
259
 
479
260
  // src/ai/common/TFMP_FaceLandmarker.ts
480
261
  import { PermanentJobError as PermanentJobError4 } from "@workglow/job-queue";
481
- var TFMP_FaceLandmarker = async (input, model, onProgress, signal) => {
262
+ var TFMP_FaceLandmarker = async (input, model, signal, emit) => {
482
263
  const { FaceLandmarker } = await loadTfmpTasksVisionSDK();
483
264
  const faceLandmarker = await getModelTask(model, {
484
265
  numFaces: input.numFaces,
@@ -487,7 +268,7 @@ var TFMP_FaceLandmarker = async (input, model, onProgress, signal) => {
487
268
  minTrackingConfidence: input.minTrackingConfidence,
488
269
  outputFaceBlendshapes: input.outputFaceBlendshapes,
489
270
  outputFacialTransformationMatrixes: input.outputFacialTransformationMatrixes
490
- }, onProgress, signal, FaceLandmarker);
271
+ }, emit, signal, FaceLandmarker);
491
272
  const result = faceLandmarker.detect(input.image);
492
273
  if (!result.faceLandmarks) {
493
274
  throw new PermanentJobError4("Failed to detect face landmarks: Empty result");
@@ -511,21 +292,19 @@ var TFMP_FaceLandmarker = async (input, model, onProgress, signal) => {
511
292
  }
512
293
  return face;
513
294
  });
514
- return {
515
- faces
516
- };
295
+ emit({ type: "finish", data: { faces } });
517
296
  };
518
297
 
519
298
  // src/ai/common/TFMP_GestureRecognizer.ts
520
299
  import { PermanentJobError as PermanentJobError5 } from "@workglow/job-queue";
521
- var TFMP_GestureRecognizer = async (input, model, onProgress, signal) => {
300
+ var TFMP_GestureRecognizer = async (input, model, signal, emit) => {
522
301
  const { GestureRecognizer } = await loadTfmpTasksVisionSDK();
523
302
  const gestureRecognizer = await getModelTask(model, {
524
303
  numHands: input.numHands,
525
304
  minHandDetectionConfidence: input.minHandDetectionConfidence,
526
305
  minHandPresenceConfidence: input.minHandPresenceConfidence,
527
306
  minTrackingConfidence: input.minTrackingConfidence
528
- }, onProgress, signal, GestureRecognizer);
307
+ }, emit, signal, GestureRecognizer);
529
308
  const result = gestureRecognizer.recognize(input.image);
530
309
  if (!result.gestures || !result.landmarks) {
531
310
  throw new PermanentJobError5("Failed to recognize gestures: Empty result");
@@ -550,21 +329,19 @@ var TFMP_GestureRecognizer = async (input, model, onProgress, signal) => {
550
329
  z: l.z
551
330
  }))
552
331
  }));
553
- return {
554
- hands
555
- };
332
+ emit({ type: "finish", data: { hands } });
556
333
  };
557
334
 
558
335
  // src/ai/common/TFMP_HandLandmarker.ts
559
336
  import { PermanentJobError as PermanentJobError6 } from "@workglow/job-queue";
560
- var TFMP_HandLandmarker = async (input, model, onProgress, signal) => {
337
+ var TFMP_HandLandmarker = async (input, model, signal, emit) => {
561
338
  const { HandLandmarker } = await loadTfmpTasksVisionSDK();
562
339
  const handLandmarker = await getModelTask(model, {
563
340
  numHands: input.numHands,
564
341
  minHandDetectionConfidence: input.minHandDetectionConfidence,
565
342
  minHandPresenceConfidence: input.minHandPresenceConfidence,
566
343
  minTrackingConfidence: input.minTrackingConfidence
567
- }, onProgress, signal, HandLandmarker);
344
+ }, emit, signal, HandLandmarker);
568
345
  const result = handLandmarker.detect(input.image);
569
346
  if (!result.landmarks) {
570
347
  throw new PermanentJobError6("Failed to detect hand landmarks: Empty result");
@@ -585,18 +362,16 @@ var TFMP_HandLandmarker = async (input, model, onProgress, signal) => {
585
362
  z: l.z
586
363
  }))
587
364
  }));
588
- return {
589
- hands
590
- };
365
+ emit({ type: "finish", data: { hands } });
591
366
  };
592
367
 
593
368
  // src/ai/common/TFMP_ImageClassification.ts
594
369
  import { PermanentJobError as PermanentJobError7 } from "@workglow/job-queue";
595
- var TFMP_ImageClassification = async (input, model, onProgress, signal) => {
370
+ var TFMP_ImageClassification = async (input, model, signal, emit) => {
596
371
  const { ImageClassifier } = await loadTfmpTasksVisionSDK();
597
372
  const imageClassifier = await getModelTask(model, {
598
373
  maxResults: input.maxCategories
599
- }, onProgress, signal, ImageClassifier);
374
+ }, emit, signal, ImageClassifier);
600
375
  const result = imageClassifier.classify(input.image);
601
376
  if (!result.classifications?.[0]?.categories) {
602
377
  throw new PermanentJobError7("Failed to classify image: Empty result");
@@ -605,16 +380,14 @@ var TFMP_ImageClassification = async (input, model, onProgress, signal) => {
605
380
  label: category.categoryName,
606
381
  score: category.score
607
382
  }));
608
- return {
609
- categories
610
- };
383
+ emit({ type: "finish", data: { categories } });
611
384
  };
612
385
 
613
386
  // src/ai/common/TFMP_ImageEmbedding.ts
614
387
  import { PermanentJobError as PermanentJobError8 } from "@workglow/job-queue";
615
- var TFMP_ImageEmbedding = async (input, model, onProgress, signal) => {
388
+ var TFMP_ImageEmbedding = async (input, model, signal, emit) => {
616
389
  const { ImageEmbedder } = await loadTfmpTasksVisionSDK();
617
- const imageEmbedder = await getModelTask(model, {}, onProgress, signal, ImageEmbedder);
390
+ const imageEmbedder = await getModelTask(model, {}, emit, signal, ImageEmbedder);
618
391
  if (Array.isArray(input.image)) {
619
392
  const vectors = [];
620
393
  for (const image of input.image) {
@@ -624,23 +397,22 @@ var TFMP_ImageEmbedding = async (input, model, onProgress, signal) => {
624
397
  }
625
398
  vectors.push(Float32Array.from(result2.embeddings[0].floatEmbedding));
626
399
  }
627
- return { vector: vectors };
400
+ emit({ type: "finish", data: { vector: vectors } });
401
+ return;
628
402
  }
629
403
  const result = imageEmbedder.embed(input.image);
630
404
  if (!result.embeddings?.[0]?.floatEmbedding) {
631
405
  throw new PermanentJobError8("Failed to generate embedding: Empty result");
632
406
  }
633
407
  const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);
634
- return {
635
- vector: embedding
636
- };
408
+ emit({ type: "finish", data: { vector: embedding } });
637
409
  };
638
410
 
639
411
  // src/ai/common/TFMP_ImageSegmentation.ts
640
412
  import { PermanentJobError as PermanentJobError9 } from "@workglow/job-queue";
641
- var TFMP_ImageSegmentation = async (input, model, onProgress, signal) => {
413
+ var TFMP_ImageSegmentation = async (input, model, signal, emit) => {
642
414
  const { ImageSegmenter } = await loadTfmpTasksVisionSDK();
643
- const imageSegmenter = await getModelTask(model, {}, onProgress, signal, ImageSegmenter);
415
+ const imageSegmenter = await getModelTask(model, {}, emit, signal, ImageSegmenter);
644
416
  const result = imageSegmenter.segment(input.image);
645
417
  if (!result.categoryMask) {
646
418
  throw new PermanentJobError9("Failed to segment image: Empty result");
@@ -656,16 +428,14 @@ var TFMP_ImageSegmentation = async (input, model, onProgress, signal) => {
656
428
  }
657
429
  }
658
430
  ];
659
- return {
660
- masks
661
- };
431
+ emit({ type: "finish", data: { masks } });
662
432
  };
663
433
 
664
434
  // src/ai/common/TFMP_ModelInfo.ts
665
435
  var TFMP_EMBEDDING_DIMENSIONS = {
666
436
  "universal-sentence-encoder": { native_dimensions: 512, mrl: false }
667
437
  };
668
- var TFMP_ModelInfo = async (input, model) => {
438
+ var TFMP_ModelInfo = async (input, model, _signal, emit) => {
669
439
  if (input.detail === "dimensions") {
670
440
  const pc = model?.provider_config;
671
441
  let native_dimensions = typeof pc?.native_dimensions === "number" ? pc.native_dimensions : undefined;
@@ -677,40 +447,303 @@ var TFMP_ModelInfo = async (input, model) => {
677
447
  native_dimensions = known.native_dimensions;
678
448
  }
679
449
  }
680
- return {
450
+ emit({
451
+ type: "finish",
452
+ data: {
453
+ model: input.model,
454
+ is_local: true,
455
+ is_remote: false,
456
+ supports_browser: true,
457
+ supports_node: false,
458
+ is_cached: false,
459
+ is_loaded: false,
460
+ file_sizes: null,
461
+ ...native_dimensions !== undefined ? { native_dimensions } : {},
462
+ ...mrl ? { mrl } : {}
463
+ }
464
+ });
465
+ return;
466
+ }
467
+ const model_path = model.provider_config.model_path;
468
+ const is_loaded = modelTaskCache.has(model_path);
469
+ emit({
470
+ type: "finish",
471
+ data: {
681
472
  model: input.model,
682
473
  is_local: true,
683
474
  is_remote: false,
684
475
  supports_browser: true,
685
476
  supports_node: false,
686
- is_cached: false,
687
- is_loaded: false,
688
- file_sizes: null,
689
- ...native_dimensions !== undefined ? { native_dimensions } : {},
690
- ...mrl ? { mrl } : {}
691
- };
692
- }
693
- const model_path = model.provider_config.model_path;
694
- const is_loaded = modelTaskCache.has(model_path);
695
- return {
696
- model: input.model,
697
- is_local: true,
698
- is_remote: false,
699
- supports_browser: true,
700
- supports_node: false,
701
- is_cached: is_loaded,
702
- is_loaded,
703
- file_sizes: null
704
- };
477
+ is_cached: is_loaded,
478
+ is_loaded,
479
+ file_sizes: null
480
+ }
481
+ });
705
482
  };
706
483
 
484
+ // src/ai/common/TFMP_ModelSearch.ts
485
+ import { filterModelSearchResultsByQuery } from "@workglow/ai/provider-utils";
486
+
487
+ // src/ai/common/TFMP_Constants.ts
488
+ var TENSORFLOW_MEDIAPIPE = "TENSORFLOW_MEDIAPIPE";
489
+ var TFMP_DEFAULT_TASK_TYPES = [
490
+ "ModelDownloadTask",
491
+ "ModelDownloadRemoveTask",
492
+ "ModelInfoTask",
493
+ "TextEmbeddingTask",
494
+ "TextLanguageDetectionTask",
495
+ "TextClassificationTask",
496
+ "ImageSegmentationTask",
497
+ "ImageEmbeddingTask",
498
+ "ImageClassificationTask",
499
+ "ObjectDetectionTask",
500
+ "GestureRecognizerTask",
501
+ "HandLandmarkerTask",
502
+ "FaceDetectorTask",
503
+ "FaceLandmarkerTask",
504
+ "PoseLandmarkerTask",
505
+ "ModelSearchTask"
506
+ ];
507
+ var TextPipelineTask = {
508
+ "text-embedder": "text-embedder",
509
+ "text-classifier": "text-classifier",
510
+ "text-language-detector": "text-language-detector",
511
+ "genai-text": "genai-text",
512
+ "audio-classifier": "audio-classifier",
513
+ "audio-embedder": "audio-embedder",
514
+ "vision-face-detector": "vision-face-detector",
515
+ "vision-face-landmarker": "vision-face-landmarker",
516
+ "vision-face-stylizer": "vision-face-stylizer",
517
+ "vision-gesture-recognizer": "vision-gesture-recognizer",
518
+ "vision-hand-landmarker": "vision-hand-landmarker",
519
+ "vision-holistic-landmarker": "vision-holistic-landmarker",
520
+ "vision-image-classifier": "vision-image-classifier",
521
+ "vision-image-embedder": "vision-image-embedder",
522
+ "vision-image-segmenter": "vision-image-segmenter",
523
+ "vision-image-interactive-segmenter": "vision-image-interactive-segmenter",
524
+ "vision-object-detector": "vision-object-detector",
525
+ "vision-pose-landmarker": "vision-pose-landmarker"
526
+ };
527
+
528
+ // src/ai/common/TFMP_ModelSearch.ts
529
+ var TFMP_MODEL_RESULTS = [
530
+ {
531
+ id: "universal-sentence-encoder",
532
+ label: "Universal Sentence Encoder",
533
+ description: "Text embedding model",
534
+ record: {
535
+ provider: TENSORFLOW_MEDIAPIPE,
536
+ title: "Universal Sentence Encoder",
537
+ description: "Universal Sentence Encoder",
538
+ capabilities: ["text.embedding"],
539
+ provider_config: {
540
+ model_path: "https://storage.googleapis.com/mediapipe-tasks/text_embedder/universal_sentence_encoder.tflite",
541
+ task_engine: "text",
542
+ pipeline: "text-embedder"
543
+ },
544
+ metadata: {}
545
+ },
546
+ raw: { source: "mediapipe" }
547
+ },
548
+ {
549
+ id: "language-detector",
550
+ label: "MediaPipe Language Detector",
551
+ description: "Language detection model",
552
+ record: {
553
+ provider: TENSORFLOW_MEDIAPIPE,
554
+ title: "MediaPipe Language Detector",
555
+ description: "MediaPipe Language Detector",
556
+ capabilities: ["text.language-detection"],
557
+ provider_config: {
558
+ model_path: "https://storage.googleapis.com/mediapipe-models/language_detector/language_detector/float32/latest/language_detector.tflite",
559
+ task_engine: "text",
560
+ pipeline: "text-language-detector"
561
+ },
562
+ metadata: {}
563
+ },
564
+ raw: { source: "mediapipe" }
565
+ },
566
+ {
567
+ id: "bert-text-classifier",
568
+ label: "MediaPipe BERT Text Classifier",
569
+ description: "Text classification model",
570
+ record: {
571
+ provider: TENSORFLOW_MEDIAPIPE,
572
+ title: "MediaPipe BERT Text Classifier",
573
+ description: "MediaPipe BERT Text Classifier",
574
+ capabilities: ["text.classification"],
575
+ provider_config: {
576
+ model_path: "https://storage.googleapis.com/mediapipe-tasks/text_classifier/bert_text_classifier.tflite",
577
+ task_engine: "text",
578
+ pipeline: "text-classifier"
579
+ },
580
+ metadata: {}
581
+ },
582
+ raw: { source: "mediapipe" }
583
+ },
584
+ {
585
+ id: "image-embedder",
586
+ label: "MediaPipe Image Embedder",
587
+ description: "Image embedding model",
588
+ record: {
589
+ provider: TENSORFLOW_MEDIAPIPE,
590
+ title: "MediaPipe Image Embedder",
591
+ description: "MediaPipe Image Embedder",
592
+ capabilities: ["image.embedding"],
593
+ provider_config: {
594
+ model_path: "https://storage.googleapis.com/mediapipe-models/image_embedder/mobilenet_v3_small/float32/1/mobilenet_v3_small.tflite",
595
+ task_engine: "vision",
596
+ pipeline: "vision-image-embedder"
597
+ },
598
+ metadata: {}
599
+ },
600
+ raw: { source: "mediapipe" }
601
+ },
602
+ {
603
+ id: "efficientnet-lite0",
604
+ label: "EfficientNet Lite0",
605
+ description: "Image classification model",
606
+ record: {
607
+ provider: TENSORFLOW_MEDIAPIPE,
608
+ title: "EfficientNet Lite0",
609
+ description: "Image classification model",
610
+ capabilities: ["image.classification"],
611
+ provider_config: {
612
+ model_path: "https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite",
613
+ task_engine: "vision",
614
+ pipeline: "vision-image-classifier"
615
+ },
616
+ metadata: {}
617
+ },
618
+ raw: { source: "mediapipe" }
619
+ },
620
+ {
621
+ id: "efficientdet-lite0",
622
+ label: "Efficient Object Detector Lite0",
623
+ description: "Object detection model",
624
+ record: {
625
+ provider: TENSORFLOW_MEDIAPIPE,
626
+ title: "Efficient Object Detector Lite0",
627
+ description: "Object detection model",
628
+ capabilities: ["image.object-detection"],
629
+ provider_config: {
630
+ model_path: "https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/float32/1/efficientdet_lite0.tflite",
631
+ task_engine: "vision",
632
+ pipeline: "vision-object-detector"
633
+ },
634
+ metadata: {}
635
+ },
636
+ raw: { source: "mediapipe" }
637
+ },
638
+ {
639
+ id: "deeplabv3",
640
+ label: "Efficient Image Segmenter Lite0",
641
+ description: "Image segmentation model",
642
+ record: {
643
+ provider: TENSORFLOW_MEDIAPIPE,
644
+ title: "Efficient Image Segmenter Lite0",
645
+ description: "Image segmentation model",
646
+ capabilities: ["image.segmentation"],
647
+ provider_config: {
648
+ model_path: "https://storage.googleapis.com/mediapipe-assets/deeplabv3.tflite?generation=1661875711618421",
649
+ task_engine: "vision",
650
+ pipeline: "vision-image-segmenter"
651
+ },
652
+ metadata: {}
653
+ },
654
+ raw: { source: "mediapipe" }
655
+ },
656
+ {
657
+ id: "face-landmarker",
658
+ label: "Face Landmarker",
659
+ description: "Detects 478 facial landmarks with blendshapes",
660
+ record: {
661
+ provider: TENSORFLOW_MEDIAPIPE,
662
+ title: "Face Landmarker",
663
+ description: "Detects 478 facial landmarks with blendshapes",
664
+ capabilities: ["vision.face-landmarks"],
665
+ provider_config: {
666
+ model_path: "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task",
667
+ task_engine: "vision",
668
+ pipeline: "vision-face-landmarker"
669
+ },
670
+ metadata: {}
671
+ },
672
+ raw: { source: "mediapipe" }
673
+ },
674
+ {
675
+ id: "gesture-recognizer",
676
+ label: "Gesture Recognizer",
677
+ description: "Recognizes hand gestures such as thumbs up and victory",
678
+ record: {
679
+ provider: TENSORFLOW_MEDIAPIPE,
680
+ title: "Gesture Recognizer",
681
+ description: "Recognizes hand gestures such as thumbs up and victory",
682
+ capabilities: ["vision.gesture"],
683
+ provider_config: {
684
+ model_path: "https://storage.googleapis.com/mediapipe-models/gesture_recognizer/gesture_recognizer/float16/1/gesture_recognizer.task",
685
+ task_engine: "vision",
686
+ pipeline: "vision-gesture-recognizer"
687
+ },
688
+ metadata: {}
689
+ },
690
+ raw: { source: "mediapipe" }
691
+ },
692
+ {
693
+ id: "hand-landmarker",
694
+ label: "Hand Landmarker",
695
+ description: "Detects 21 hand landmarks",
696
+ record: {
697
+ provider: TENSORFLOW_MEDIAPIPE,
698
+ title: "Hand Landmarker",
699
+ description: "Detects 21 hand landmarks",
700
+ capabilities: ["vision.hand-landmarks"],
701
+ provider_config: {
702
+ model_path: "https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task",
703
+ task_engine: "vision",
704
+ pipeline: "vision-hand-landmarker"
705
+ },
706
+ metadata: {}
707
+ },
708
+ raw: { source: "mediapipe" }
709
+ },
710
+ {
711
+ id: "pose-landmarker",
712
+ label: "Pose Landmarker",
713
+ description: "Detects 33 body pose landmarks",
714
+ record: {
715
+ provider: TENSORFLOW_MEDIAPIPE,
716
+ title: "Pose Landmarker",
717
+ description: "Detects 33 body pose landmarks",
718
+ capabilities: ["vision.pose-landmarks"],
719
+ provider_config: {
720
+ model_path: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task",
721
+ task_engine: "vision",
722
+ pipeline: "vision-pose-landmarker"
723
+ },
724
+ metadata: {}
725
+ },
726
+ raw: { source: "mediapipe" }
727
+ }
728
+ ];
729
+ function createTFMPModelSearch(providerId) {
730
+ return async (input, _model, _signal, emit) => {
731
+ const results = filterModelSearchResultsByQuery(TFMP_MODEL_RESULTS.map((result) => ({
732
+ ...result,
733
+ record: { ...result.record, provider: providerId }
734
+ })), input.query);
735
+ emit({ type: "finish", data: { results } });
736
+ };
737
+ }
738
+ var TFMP_ModelSearch = createTFMPModelSearch(TENSORFLOW_MEDIAPIPE);
739
+
707
740
  // src/ai/common/TFMP_ObjectDetection.ts
708
741
  import { PermanentJobError as PermanentJobError10 } from "@workglow/job-queue";
709
- var TFMP_ObjectDetection = async (input, model, onProgress, signal) => {
742
+ var TFMP_ObjectDetection = async (input, model, signal, emit) => {
710
743
  const { ObjectDetector } = await loadTfmpTasksVisionSDK();
711
744
  const objectDetector = await getModelTask(model, {
712
745
  scoreThreshold: input.threshold
713
- }, onProgress, signal, ObjectDetector);
746
+ }, emit, signal, ObjectDetector);
714
747
  const result = objectDetector.detect(input.image);
715
748
  if (!result.detections) {
716
749
  throw new PermanentJobError10("Failed to detect objects: Empty result");
@@ -725,14 +758,12 @@ var TFMP_ObjectDetection = async (input, model, onProgress, signal) => {
725
758
  height: detection.boundingBox?.height || 0
726
759
  }
727
760
  }));
728
- return {
729
- detections
730
- };
761
+ emit({ type: "finish", data: { detections } });
731
762
  };
732
763
 
733
764
  // src/ai/common/TFMP_PoseLandmarker.ts
734
765
  import { PermanentJobError as PermanentJobError11 } from "@workglow/job-queue";
735
- var TFMP_PoseLandmarker = async (input, model, onProgress, signal) => {
766
+ var TFMP_PoseLandmarker = async (input, model, signal, emit) => {
736
767
  const { PoseLandmarker } = await loadTfmpTasksVisionSDK();
737
768
  const poseLandmarker = await getModelTask(model, {
738
769
  numPoses: input.numPoses,
@@ -740,7 +771,7 @@ var TFMP_PoseLandmarker = async (input, model, onProgress, signal) => {
740
771
  minPosePresenceConfidence: input.minPosePresenceConfidence,
741
772
  minTrackingConfidence: input.minTrackingConfidence,
742
773
  outputSegmentationMasks: input.outputSegmentationMasks
743
- }, onProgress, signal, PoseLandmarker);
774
+ }, emit, signal, PoseLandmarker);
744
775
  const result = poseLandmarker.detect(input.image);
745
776
  if (!result.landmarks) {
746
777
  throw new PermanentJobError11("Failed to detect pose landmarks: Empty result");
@@ -772,18 +803,16 @@ var TFMP_PoseLandmarker = async (input, model, onProgress, signal) => {
772
803
  }
773
804
  return pose;
774
805
  });
775
- return {
776
- poses
777
- };
806
+ emit({ type: "finish", data: { poses } });
778
807
  };
779
808
 
780
809
  // src/ai/common/TFMP_TextClassification.ts
781
810
  import { PermanentJobError as PermanentJobError12 } from "@workglow/job-queue";
782
- var TFMP_TextClassification = async (input, model, onProgress, signal) => {
811
+ var TFMP_TextClassification = async (input, model, signal, emit) => {
783
812
  const { TextClassifier } = await loadTfmpTasksTextSDK();
784
813
  const TextClassification = await getModelTask(model, {
785
814
  maxCategories: input.maxCategories
786
- }, onProgress, signal, TextClassifier);
815
+ }, emit, signal, TextClassifier);
787
816
  const result = TextClassification.classify(input.text);
788
817
  if (!result.classifications?.[0]?.categories) {
789
818
  throw new PermanentJobError12("Failed to classify text: Empty result");
@@ -792,16 +821,14 @@ var TFMP_TextClassification = async (input, model, onProgress, signal) => {
792
821
  label: category.categoryName,
793
822
  score: category.score
794
823
  }));
795
- return {
796
- categories
797
- };
824
+ emit({ type: "finish", data: { categories } });
798
825
  };
799
826
 
800
827
  // src/ai/common/TFMP_TextEmbedding.ts
801
828
  import { PermanentJobError as PermanentJobError13 } from "@workglow/job-queue";
802
- var TFMP_TextEmbedding = async (input, model, onProgress, signal) => {
829
+ var TFMP_TextEmbedding = async (input, model, signal, emit) => {
803
830
  const { TextEmbedder } = await loadTfmpTasksTextSDK();
804
- const textEmbedder = await getModelTask(model, {}, onProgress, signal, TextEmbedder);
831
+ const textEmbedder = await getModelTask(model, {}, emit, signal, TextEmbedder);
805
832
  if (Array.isArray(input.text)) {
806
833
  const embeddings = input.text.map((text) => {
807
834
  const result2 = textEmbedder.embed(text);
@@ -810,28 +837,25 @@ var TFMP_TextEmbedding = async (input, model, onProgress, signal) => {
810
837
  }
811
838
  return Float32Array.from(result2.embeddings[0].floatEmbedding);
812
839
  });
813
- return {
814
- vector: embeddings
815
- };
840
+ emit({ type: "finish", data: { vector: embeddings } });
841
+ return;
816
842
  }
817
843
  const result = textEmbedder.embed(input.text);
818
844
  if (!result.embeddings?.[0]?.floatEmbedding) {
819
845
  throw new PermanentJobError13("Failed to generate embedding: Empty result");
820
846
  }
821
847
  const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);
822
- return {
823
- vector: embedding
824
- };
848
+ emit({ type: "finish", data: { vector: embedding } });
825
849
  };
826
850
 
827
851
  // src/ai/common/TFMP_TextLanguageDetection.ts
828
852
  import { PermanentJobError as PermanentJobError14 } from "@workglow/job-queue";
829
- var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
853
+ var TFMP_TextLanguageDetection = async (input, model, signal, emit) => {
830
854
  const maxLanguages = input.maxLanguages === 0 ? -1 : input.maxLanguages;
831
855
  const { LanguageDetector } = await loadTfmpTasksTextSDK();
832
856
  const textLanguageDetector = await getModelTask(model, {
833
857
  maxLanguages
834
- }, onProgress, signal, LanguageDetector);
858
+ }, emit, signal, LanguageDetector);
835
859
  const result = textLanguageDetector.detect(input.text);
836
860
  if (!result.languages?.[0]?.languageCode) {
837
861
  throw new PermanentJobError14("Failed to detect language: Empty result");
@@ -840,15 +864,12 @@ var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
840
864
  language: language.languageCode,
841
865
  score: language.probability
842
866
  }));
843
- return {
844
- languages
845
- };
867
+ emit({ type: "finish", data: { languages } });
846
868
  };
847
869
 
848
870
  // src/ai/common/TFMP_Unload.ts
849
- var TFMP_Unload = async (input, model, onProgress, _signal) => {
871
+ var TFMP_Unload = async (input, model, _signal, emit) => {
850
872
  const model_path = model.provider_config.model_path;
851
- onProgress(10, "Unloading model");
852
873
  if (modelTaskCache.has(model_path)) {
853
874
  const cachedTasks = modelTaskCache.get(model_path);
854
875
  for (const cachedTask of cachedTasks) {
@@ -867,47 +888,108 @@ var TFMP_Unload = async (input, model, onProgress, _signal) => {
867
888
  }
868
889
  modelTaskCache.delete(model_path);
869
890
  }
870
- return {
871
- model: input.model
872
- };
891
+ emit({ type: "finish", data: { model: input.model } });
873
892
  };
874
893
 
875
894
  // src/ai/common/TFMP_JobRunFns.ts
876
- var TFMP_TASKS = {
877
- DownloadModelTask: TFMP_Download,
878
- UnloadModelTask: TFMP_Unload,
879
- ModelInfoTask: TFMP_ModelInfo,
880
- TextEmbeddingTask: TFMP_TextEmbedding,
881
- TextLanguageDetectionTask: TFMP_TextLanguageDetection,
882
- TextClassificationTask: TFMP_TextClassification,
883
- ImageSegmentationTask: TFMP_ImageSegmentation,
884
- ImageEmbeddingTask: TFMP_ImageEmbedding,
885
- ImageClassificationTask: TFMP_ImageClassification,
886
- ObjectDetectionTask: TFMP_ObjectDetection,
887
- GestureRecognizerTask: TFMP_GestureRecognizer,
888
- HandLandmarkerTask: TFMP_HandLandmarker,
889
- FaceDetectorTask: TFMP_FaceDetector,
890
- FaceLandmarkerTask: TFMP_FaceLandmarker,
891
- PoseLandmarkerTask: TFMP_PoseLandmarker,
892
- ModelSearchTask: TFMP_ModelSearch
893
- };
895
+ var TFMP_RUN_FNS = [
896
+ { serves: TFMP_TEXT_EMBEDDING, runFn: TFMP_TextEmbedding },
897
+ { serves: TFMP_TEXT_CLASSIFICATION, runFn: TFMP_TextClassification },
898
+ { serves: TFMP_TEXT_LANGUAGE_DETECTION, runFn: TFMP_TextLanguageDetection },
899
+ { serves: TFMP_IMAGE_CLASSIFICATION, runFn: TFMP_ImageClassification },
900
+ { serves: TFMP_IMAGE_EMBEDDING, runFn: TFMP_ImageEmbedding },
901
+ { serves: TFMP_IMAGE_SEGMENTATION, runFn: TFMP_ImageSegmentation },
902
+ { serves: TFMP_IMAGE_OBJECT_DETECTION, runFn: TFMP_ObjectDetection },
903
+ { serves: TFMP_VISION_FACE_DETECTION, runFn: TFMP_FaceDetector },
904
+ { serves: TFMP_VISION_FACE_LANDMARKS, runFn: TFMP_FaceLandmarker },
905
+ { serves: TFMP_VISION_HAND_LANDMARKS, runFn: TFMP_HandLandmarker },
906
+ { serves: TFMP_VISION_POSE_LANDMARKS, runFn: TFMP_PoseLandmarker },
907
+ { serves: TFMP_VISION_GESTURE, runFn: TFMP_GestureRecognizer },
908
+ { serves: TFMP_MODEL_DOWNLOAD, runFn: TFMP_Download },
909
+ { serves: TFMP_MODEL_UNLOAD, runFn: TFMP_Unload },
910
+ { serves: TFMP_MODEL_SEARCH, runFn: TFMP_ModelSearch },
911
+ { serves: TFMP_MODEL_INFO, runFn: TFMP_ModelInfo }
912
+ ];
894
913
 
895
914
  // src/ai/TensorFlowMediaPipeQueuedProvider.ts
896
915
  import { AiProvider } from "@workglow/ai";
916
+
917
+ // src/ai/common/TFMP_Capabilities.ts
918
+ var TFMP_RUN_FN_SPECS = TFMP_CAPABILITY_SETS.map((serves) => ({ serves }));
919
+ function tfmpWorkerRunFnSpecs() {
920
+ return TFMP_RUN_FN_SPECS;
921
+ }
922
+ function inferTfmpCapabilities(model) {
923
+ const declared = model.capabilities ?? [];
924
+ if (declared.length > 0)
925
+ return declared;
926
+ const id = String(model.model_id ?? model.provider_config?.model_path ?? model.provider_config?.model_name ?? "");
927
+ const baseName = (id.split("/").pop() ?? id).toLowerCase();
928
+ if (/gesture_recognizer/.test(baseName)) {
929
+ return [
930
+ "vision.gesture",
931
+ "vision.hand-landmarks",
932
+ "model.download-remove",
933
+ "model.info",
934
+ "model.search"
935
+ ];
936
+ }
937
+ if (/hand_landmarker/.test(baseName)) {
938
+ return ["vision.hand-landmarks", "model.download-remove", "model.info", "model.search"];
939
+ }
940
+ if (/face_landmarker/.test(baseName)) {
941
+ return ["vision.face-landmarks", "model.download-remove", "model.info", "model.search"];
942
+ }
943
+ if (/face_detector|blaze_face/.test(baseName)) {
944
+ return ["vision.face-detection", "model.download-remove", "model.info", "model.search"];
945
+ }
946
+ if (/pose_landmarker/.test(baseName)) {
947
+ return ["vision.pose-landmarks", "model.download-remove", "model.info", "model.search"];
948
+ }
949
+ if (/object_detector|efficientdet|ssd_mobilenet|yolo/.test(baseName)) {
950
+ return ["image.object-detection", "model.download-remove", "model.info", "model.search"];
951
+ }
952
+ if (/segmenter|deeplab|selfie/.test(baseName)) {
953
+ return ["image.segmentation", "model.download-remove", "model.info", "model.search"];
954
+ }
955
+ if (/image_classifier|efficientnet|mobilenet/.test(baseName)) {
956
+ return ["image.classification", "model.download-remove", "model.info", "model.search"];
957
+ }
958
+ if (/image_embed/.test(baseName)) {
959
+ return ["image.embedding", "model.download-remove", "model.info", "model.search"];
960
+ }
961
+ if (/text_embed|universal_sentence_encoder|use_/.test(baseName)) {
962
+ return ["text.embedding", "model.download-remove", "model.info", "model.search"];
963
+ }
964
+ if (/text_classifier|bert_classifier/.test(baseName)) {
965
+ return ["text.classification", "model.download-remove", "model.info", "model.search"];
966
+ }
967
+ if (/language_detector/.test(baseName)) {
968
+ return ["text.language-detection", "model.download-remove", "model.info", "model.search"];
969
+ }
970
+ return ["model.search", "model.info"];
971
+ }
972
+
973
+ // src/ai/TensorFlowMediaPipeQueuedProvider.ts
897
974
  class TensorFlowMediaPipeQueuedProvider extends AiProvider {
898
975
  name = TENSORFLOW_MEDIAPIPE;
899
976
  displayName = "TensorFlow MediaPipe";
900
977
  isLocal = true;
901
978
  supportsBrowser = true;
902
- taskTypes = TFMP_DEFAULT_TASK_TYPES;
903
- constructor(tasks, previewTasks) {
904
- super(tasks, undefined, previewTasks);
979
+ constructor(promiseRunFns, previewTasks) {
980
+ super(promiseRunFns, previewTasks);
981
+ }
982
+ inferCapabilities(model) {
983
+ return inferTfmpCapabilities(model);
984
+ }
985
+ workerRunFnSpecs() {
986
+ return tfmpWorkerRunFnSpecs();
905
987
  }
906
988
  }
907
989
 
908
990
  // src/ai/registerTensorFlowMediaPipeInline.ts
909
991
  async function registerTensorFlowMediaPipeInline(options) {
910
- await registerProviderInline(new TensorFlowMediaPipeQueuedProvider(TFMP_TASKS), "TensorFlow MediaPipe", options);
992
+ await registerProviderInline(new TensorFlowMediaPipeQueuedProvider(TFMP_RUN_FNS), "TensorFlow MediaPipe", options);
911
993
  }
912
994
 
913
995
  // src/ai/registerTensorFlowMediaPipeWorker.ts
@@ -920,15 +1002,20 @@ class TensorFlowMediaPipeProvider extends AiProvider2 {
920
1002
  displayName = "TensorFlow MediaPipe";
921
1003
  isLocal = true;
922
1004
  supportsBrowser = true;
923
- taskTypes = TFMP_DEFAULT_TASK_TYPES;
924
- constructor(tasks, previewTasks) {
925
- super(tasks, undefined, previewTasks);
1005
+ constructor(promiseRunFns, previewTasks) {
1006
+ super(promiseRunFns, previewTasks);
1007
+ }
1008
+ inferCapabilities(model) {
1009
+ return inferTfmpCapabilities(model);
1010
+ }
1011
+ workerRunFnSpecs() {
1012
+ return tfmpWorkerRunFnSpecs();
926
1013
  }
927
1014
  }
928
1015
 
929
1016
  // src/ai/registerTensorFlowMediaPipeWorker.ts
930
1017
  async function registerTensorFlowMediaPipeWorker() {
931
- await registerProviderWorker((ws) => new TensorFlowMediaPipeProvider(TFMP_TASKS).registerOnWorkerServer(ws), "TensorFlow MediaPipe");
1018
+ await registerProviderWorker((ws) => new TensorFlowMediaPipeProvider(TFMP_RUN_FNS).registerOnWorkerServer(ws), "TensorFlow MediaPipe");
932
1019
  }
933
1020
  export {
934
1021
  registerTensorFlowMediaPipeWorker,
@@ -937,4 +1024,4 @@ export {
937
1024
  loadTfmpTasksTextSDK
938
1025
  };
939
1026
 
940
- //# debugId=CB3FDA3C7C718E4C64756E2164756E21
1027
+ //# debugId=271A8EDB1D7FB3E564756E2164756E21