@workglow/tf-mediapipe 0.2.28

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 (65) hide show
  1. package/dist/ai-provider/TensorFlowMediaPipeProvider.d.ts +26 -0
  2. package/dist/ai-provider/TensorFlowMediaPipeProvider.d.ts.map +1 -0
  3. package/dist/ai-provider/TensorFlowMediaPipeQueuedProvider.d.ts +18 -0
  4. package/dist/ai-provider/TensorFlowMediaPipeQueuedProvider.d.ts.map +1 -0
  5. package/dist/ai-provider/common/TFMP_Client.d.ts +8 -0
  6. package/dist/ai-provider/common/TFMP_Client.d.ts.map +1 -0
  7. package/dist/ai-provider/common/TFMP_Constants.d.ts +29 -0
  8. package/dist/ai-provider/common/TFMP_Constants.d.ts.map +1 -0
  9. package/dist/ai-provider/common/TFMP_Download.d.ts +9 -0
  10. package/dist/ai-provider/common/TFMP_Download.d.ts.map +1 -0
  11. package/dist/ai-provider/common/TFMP_FaceDetector.d.ts +9 -0
  12. package/dist/ai-provider/common/TFMP_FaceDetector.d.ts.map +1 -0
  13. package/dist/ai-provider/common/TFMP_FaceLandmarker.d.ts +9 -0
  14. package/dist/ai-provider/common/TFMP_FaceLandmarker.d.ts.map +1 -0
  15. package/dist/ai-provider/common/TFMP_GestureRecognizer.d.ts +9 -0
  16. package/dist/ai-provider/common/TFMP_GestureRecognizer.d.ts.map +1 -0
  17. package/dist/ai-provider/common/TFMP_HandLandmarker.d.ts +9 -0
  18. package/dist/ai-provider/common/TFMP_HandLandmarker.d.ts.map +1 -0
  19. package/dist/ai-provider/common/TFMP_ImageClassification.d.ts +9 -0
  20. package/dist/ai-provider/common/TFMP_ImageClassification.d.ts.map +1 -0
  21. package/dist/ai-provider/common/TFMP_ImageEmbedding.d.ts +9 -0
  22. package/dist/ai-provider/common/TFMP_ImageEmbedding.d.ts.map +1 -0
  23. package/dist/ai-provider/common/TFMP_ImageSegmentation.d.ts +9 -0
  24. package/dist/ai-provider/common/TFMP_ImageSegmentation.d.ts.map +1 -0
  25. package/dist/ai-provider/common/TFMP_JobRunFns.d.ts +10 -0
  26. package/dist/ai-provider/common/TFMP_JobRunFns.d.ts.map +1 -0
  27. package/dist/ai-provider/common/TFMP_ModelInfo.d.ts +9 -0
  28. package/dist/ai-provider/common/TFMP_ModelInfo.d.ts.map +1 -0
  29. package/dist/ai-provider/common/TFMP_ModelSchema.d.ts +152 -0
  30. package/dist/ai-provider/common/TFMP_ModelSchema.d.ts.map +1 -0
  31. package/dist/ai-provider/common/TFMP_ModelSearch.d.ts +9 -0
  32. package/dist/ai-provider/common/TFMP_ModelSearch.d.ts.map +1 -0
  33. package/dist/ai-provider/common/TFMP_ObjectDetection.d.ts +9 -0
  34. package/dist/ai-provider/common/TFMP_ObjectDetection.d.ts.map +1 -0
  35. package/dist/ai-provider/common/TFMP_PoseLandmarker.d.ts +9 -0
  36. package/dist/ai-provider/common/TFMP_PoseLandmarker.d.ts.map +1 -0
  37. package/dist/ai-provider/common/TFMP_Runtime.d.ts +30 -0
  38. package/dist/ai-provider/common/TFMP_Runtime.d.ts.map +1 -0
  39. package/dist/ai-provider/common/TFMP_TextClassification.d.ts +9 -0
  40. package/dist/ai-provider/common/TFMP_TextClassification.d.ts.map +1 -0
  41. package/dist/ai-provider/common/TFMP_TextEmbedding.d.ts +9 -0
  42. package/dist/ai-provider/common/TFMP_TextEmbedding.d.ts.map +1 -0
  43. package/dist/ai-provider/common/TFMP_TextLanguageDetection.d.ts +9 -0
  44. package/dist/ai-provider/common/TFMP_TextLanguageDetection.d.ts.map +1 -0
  45. package/dist/ai-provider/common/TFMP_Unload.d.ts +9 -0
  46. package/dist/ai-provider/common/TFMP_Unload.d.ts.map +1 -0
  47. package/dist/ai-provider/index.d.ts +9 -0
  48. package/dist/ai-provider/index.d.ts.map +1 -0
  49. package/dist/ai-provider/registerTensorFlowMediaPipe.d.ts +10 -0
  50. package/dist/ai-provider/registerTensorFlowMediaPipe.d.ts.map +1 -0
  51. package/dist/ai-provider/registerTensorFlowMediaPipeInline.d.ts +8 -0
  52. package/dist/ai-provider/registerTensorFlowMediaPipeInline.d.ts.map +1 -0
  53. package/dist/ai-provider/registerTensorFlowMediaPipeWorker.d.ts +7 -0
  54. package/dist/ai-provider/registerTensorFlowMediaPipeWorker.d.ts.map +1 -0
  55. package/dist/ai-provider/runtime.d.ts +16 -0
  56. package/dist/ai-provider/runtime.d.ts.map +1 -0
  57. package/dist/ai-provider-runtime.d.ts +7 -0
  58. package/dist/ai-provider-runtime.d.ts.map +1 -0
  59. package/dist/ai-provider-runtime.js +761 -0
  60. package/dist/ai-provider-runtime.js.map +33 -0
  61. package/dist/ai-provider.d.ts +7 -0
  62. package/dist/ai-provider.d.ts.map +1 -0
  63. package/dist/ai-provider.js +134 -0
  64. package/dist/ai-provider.js.map +13 -0
  65. package/package.json +71 -0
@@ -0,0 +1,761 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/ai-provider/common/TFMP_Client.ts
10
+ var _tasksText;
11
+ var _tasksVision;
12
+ async function loadTfmpTasksTextSDK() {
13
+ if (!_tasksText) {
14
+ try {
15
+ _tasksText = await import("@mediapipe/tasks-text");
16
+ } catch {
17
+ throw new Error("@mediapipe/tasks-text is required for TensorFlow MediaPipe text (and related) tasks. Install with: bun add @mediapipe/tasks-text");
18
+ }
19
+ }
20
+ return _tasksText;
21
+ }
22
+ async function loadTfmpTasksVisionSDK() {
23
+ if (!_tasksVision) {
24
+ try {
25
+ _tasksVision = await import("@mediapipe/tasks-vision");
26
+ } catch {
27
+ throw new Error("@mediapipe/tasks-vision is required for TensorFlow MediaPipe vision tasks. Install with: bun add @mediapipe/tasks-vision");
28
+ }
29
+ }
30
+ return _tasksVision;
31
+ }
32
+
33
+ // src/ai-provider/registerTensorFlowMediaPipeInline.ts
34
+ import { registerProviderInline } from "@workglow/ai-provider/common";
35
+
36
+ // src/ai-provider/common/TFMP_ModelSearch.ts
37
+ import { filterLabeledModelsByQuery } from "@workglow/ai-provider/common";
38
+
39
+ // src/ai-provider/common/TFMP_Constants.ts
40
+ var TENSORFLOW_MEDIAPIPE = "TENSORFLOW_MEDIAPIPE";
41
+ var TFMP_DEFAULT_TASK_TYPES = [
42
+ "DownloadModelTask",
43
+ "UnloadModelTask",
44
+ "ModelInfoTask",
45
+ "TextEmbeddingTask",
46
+ "TextLanguageDetectionTask",
47
+ "TextClassificationTask",
48
+ "ImageSegmentationTask",
49
+ "ImageEmbeddingTask",
50
+ "ImageClassificationTask",
51
+ "ObjectDetectionTask",
52
+ "GestureRecognizerTask",
53
+ "HandLandmarkerTask",
54
+ "FaceDetectorTask",
55
+ "FaceLandmarkerTask",
56
+ "PoseLandmarkerTask",
57
+ "ModelSearchTask"
58
+ ];
59
+ var TextPipelineTask = {
60
+ "text-embedder": "text-embedder",
61
+ "text-classifier": "text-classifier",
62
+ "text-language-detector": "text-language-detector",
63
+ "genai-text": "genai-text",
64
+ "audio-classifier": "audio-classifier",
65
+ "audio-embedder": "audio-embedder",
66
+ "vision-face-detector": "vision-face-detector",
67
+ "vision-face-landmarker": "vision-face-landmarker",
68
+ "vision-face-stylizer": "vision-face-stylizer",
69
+ "vision-gesture-recognizer": "vision-gesture-recognizer",
70
+ "vision-hand-landmarker": "vision-hand-landmarker",
71
+ "vision-holistic-landmarker": "vision-holistic-landmarker",
72
+ "vision-image-classifier": "vision-image-classifier",
73
+ "vision-image-embedder": "vision-image-embedder",
74
+ "vision-image-segmenter": "vision-image-segmenter",
75
+ "vision-image-interactive-segmenter": "vision-image-interactive-segmenter",
76
+ "vision-object-detector": "vision-object-detector",
77
+ "vision-pose-landmarker": "vision-pose-landmarker"
78
+ };
79
+
80
+ // src/ai-provider/common/TFMP_ModelSearch.ts
81
+ var TFMP_MODELS = [
82
+ { label: "text-embedder Universal Sentence Encoder", value: "text-embedder" }
83
+ ];
84
+ function createTFMPModelSearch(providerId) {
85
+ return async (input) => {
86
+ const models = filterLabeledModelsByQuery(TFMP_MODELS, input.query);
87
+ const results = models.map((m) => ({
88
+ id: m.value,
89
+ label: m.label,
90
+ description: "",
91
+ record: {
92
+ model_id: m.value,
93
+ provider: providerId,
94
+ title: m.value,
95
+ description: "",
96
+ tasks: [],
97
+ provider_config: { model_path: m.value },
98
+ metadata: {}
99
+ },
100
+ raw: m
101
+ }));
102
+ return { results };
103
+ };
104
+ }
105
+ var TFMP_ModelSearch = createTFMPModelSearch(TENSORFLOW_MEDIAPIPE);
106
+
107
+ // src/ai-provider/common/TFMP_Download.ts
108
+ import { PermanentJobError as PermanentJobError2 } from "@workglow/job-queue";
109
+
110
+ // src/ai-provider/common/TFMP_Runtime.ts
111
+ import { PermanentJobError } from "@workglow/job-queue";
112
+ var wasm_tasks = new Map;
113
+ var wasm_reference_counts = new Map;
114
+ var modelTaskCache = new Map;
115
+ var optionsMatch = (opts1, opts2) => {
116
+ const keys1 = Object.keys(opts1).sort();
117
+ const keys2 = Object.keys(opts2).sort();
118
+ if (keys1.length !== keys2.length)
119
+ return false;
120
+ return keys1.every((key) => {
121
+ const val1 = opts1[key];
122
+ const val2 = opts2[key];
123
+ if (Array.isArray(val1) && Array.isArray(val2)) {
124
+ return JSON.stringify(val1) === JSON.stringify(val2);
125
+ }
126
+ return val1 === val2;
127
+ });
128
+ };
129
+ var getWasmTask = async (model, onProgress, signal) => {
130
+ const task_engine = model.provider_config.task_engine;
131
+ if (wasm_tasks.has(task_engine)) {
132
+ return wasm_tasks.get(task_engine);
133
+ }
134
+ if (signal.aborted) {
135
+ throw new PermanentJobError("Aborted job");
136
+ }
137
+ onProgress(0.1, "Loading WASM task");
138
+ let wasmFileset;
139
+ switch (task_engine) {
140
+ case "vision": {
141
+ const { FilesetResolver } = await loadTfmpTasksVisionSDK();
142
+ wasmFileset = await FilesetResolver.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm");
143
+ break;
144
+ }
145
+ case "text": {
146
+ const { FilesetResolver } = await loadTfmpTasksTextSDK();
147
+ wasmFileset = await FilesetResolver.forTextTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text@latest/wasm");
148
+ break;
149
+ }
150
+ case "audio": {
151
+ const { FilesetResolver } = await loadTfmpTasksTextSDK();
152
+ wasmFileset = await FilesetResolver.forAudioTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio@latest/wasm");
153
+ break;
154
+ }
155
+ case "genai": {
156
+ const { FilesetResolver } = await loadTfmpTasksTextSDK();
157
+ wasmFileset = await FilesetResolver.forGenAiTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm");
158
+ break;
159
+ }
160
+ default:
161
+ throw new PermanentJobError("Invalid task engine");
162
+ }
163
+ wasm_tasks.set(task_engine, wasmFileset);
164
+ return wasmFileset;
165
+ };
166
+ var getModelTask = async (model, options, onProgress, signal, TaskType) => {
167
+ const model_path = model.provider_config.model_path;
168
+ const task_engine = model.provider_config.task_engine;
169
+ const cachedTasks = modelTaskCache.get(model_path);
170
+ if (cachedTasks) {
171
+ const matchedTask = cachedTasks.find((cached) => optionsMatch(cached.options, options));
172
+ if (matchedTask) {
173
+ return matchedTask.task;
174
+ }
175
+ }
176
+ const wasmFileset = await getWasmTask(model, onProgress, signal);
177
+ onProgress(0.2, "Creating model task");
178
+ const task = await TaskType.createFromOptions(wasmFileset, {
179
+ baseOptions: {
180
+ modelAssetPath: model_path
181
+ },
182
+ ...options
183
+ });
184
+ const cachedTask = { task, options, task_engine };
185
+ if (!modelTaskCache.has(model_path)) {
186
+ modelTaskCache.set(model_path, []);
187
+ }
188
+ modelTaskCache.get(model_path).push(cachedTask);
189
+ wasm_reference_counts.set(task_engine, (wasm_reference_counts.get(task_engine) || 0) + 1);
190
+ return task;
191
+ };
192
+
193
+ // src/ai-provider/common/TFMP_Download.ts
194
+ var TFMP_Download = async (input, model, onProgress, signal) => {
195
+ let task;
196
+ switch (model?.provider_config.pipeline) {
197
+ case "text-embedder": {
198
+ const { TextEmbedder } = await loadTfmpTasksTextSDK();
199
+ task = await getModelTask(model, {}, onProgress, signal, TextEmbedder);
200
+ break;
201
+ }
202
+ case "text-classifier": {
203
+ const { TextClassifier } = await loadTfmpTasksTextSDK();
204
+ task = await getModelTask(model, {}, onProgress, signal, TextClassifier);
205
+ break;
206
+ }
207
+ case "text-language-detector": {
208
+ const { LanguageDetector } = await loadTfmpTasksTextSDK();
209
+ task = await getModelTask(model, {}, onProgress, signal, LanguageDetector);
210
+ break;
211
+ }
212
+ case "vision-image-classifier": {
213
+ const { ImageClassifier } = await loadTfmpTasksVisionSDK();
214
+ task = await getModelTask(model, {}, onProgress, signal, ImageClassifier);
215
+ break;
216
+ }
217
+ case "vision-image-embedder": {
218
+ const { ImageEmbedder } = await loadTfmpTasksVisionSDK();
219
+ task = await getModelTask(model, {}, onProgress, signal, ImageEmbedder);
220
+ break;
221
+ }
222
+ case "vision-image-segmenter": {
223
+ const { ImageSegmenter } = await loadTfmpTasksVisionSDK();
224
+ task = await getModelTask(model, {}, onProgress, signal, ImageSegmenter);
225
+ break;
226
+ }
227
+ case "vision-object-detector": {
228
+ const { ObjectDetector } = await loadTfmpTasksVisionSDK();
229
+ task = await getModelTask(model, {}, onProgress, signal, ObjectDetector);
230
+ break;
231
+ }
232
+ case "vision-face-detector": {
233
+ const { FaceDetector } = await loadTfmpTasksVisionSDK();
234
+ task = await getModelTask(model, {}, onProgress, signal, FaceDetector);
235
+ break;
236
+ }
237
+ case "vision-face-landmarker": {
238
+ const { FaceLandmarker } = await loadTfmpTasksVisionSDK();
239
+ task = await getModelTask(model, {}, onProgress, signal, FaceLandmarker);
240
+ break;
241
+ }
242
+ case "vision-gesture-recognizer": {
243
+ const { GestureRecognizer } = await loadTfmpTasksVisionSDK();
244
+ task = await getModelTask(model, {}, onProgress, signal, GestureRecognizer);
245
+ break;
246
+ }
247
+ case "vision-hand-landmarker": {
248
+ const { HandLandmarker } = await loadTfmpTasksVisionSDK();
249
+ task = await getModelTask(model, {}, onProgress, signal, HandLandmarker);
250
+ break;
251
+ }
252
+ case "vision-pose-landmarker": {
253
+ const { PoseLandmarker } = await loadTfmpTasksVisionSDK();
254
+ task = await getModelTask(model, {}, onProgress, signal, PoseLandmarker);
255
+ break;
256
+ }
257
+ default:
258
+ 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`);
259
+ }
260
+ onProgress(0.9, "Pipeline loaded");
261
+ task.close();
262
+ const task_engine = model?.provider_config.task_engine;
263
+ wasm_reference_counts.set(task_engine, wasm_reference_counts.get(task_engine) - 1);
264
+ return {
265
+ model: input.model
266
+ };
267
+ };
268
+
269
+ // src/ai-provider/common/TFMP_FaceDetector.ts
270
+ import { PermanentJobError as PermanentJobError3 } from "@workglow/job-queue";
271
+ var TFMP_FaceDetector = async (input, model, onProgress, signal) => {
272
+ const { FaceDetector } = await loadTfmpTasksVisionSDK();
273
+ const faceDetector = await getModelTask(model, {
274
+ minDetectionConfidence: input.minDetectionConfidence,
275
+ minSuppressionThreshold: input.minSuppressionThreshold
276
+ }, onProgress, signal, FaceDetector);
277
+ const result = faceDetector.detect(input.image);
278
+ if (!result.detections) {
279
+ throw new PermanentJobError3("Failed to detect faces: Empty result");
280
+ }
281
+ const faces = result.detections.map((detection) => ({
282
+ box: {
283
+ x: detection.boundingBox?.originX || 0,
284
+ y: detection.boundingBox?.originY || 0,
285
+ width: detection.boundingBox?.width || 0,
286
+ height: detection.boundingBox?.height || 0
287
+ },
288
+ keypoints: detection.keypoints?.map((kp) => ({
289
+ x: kp.x,
290
+ y: kp.y,
291
+ label: kp.label
292
+ })) || [],
293
+ score: detection.categories?.[0]?.score || 0
294
+ }));
295
+ return {
296
+ faces
297
+ };
298
+ };
299
+
300
+ // src/ai-provider/common/TFMP_FaceLandmarker.ts
301
+ import { PermanentJobError as PermanentJobError4 } from "@workglow/job-queue";
302
+ var TFMP_FaceLandmarker = async (input, model, onProgress, signal) => {
303
+ const { FaceLandmarker } = await loadTfmpTasksVisionSDK();
304
+ const faceLandmarker = await getModelTask(model, {
305
+ numFaces: input.numFaces,
306
+ minFaceDetectionConfidence: input.minFaceDetectionConfidence,
307
+ minFacePresenceConfidence: input.minFacePresenceConfidence,
308
+ minTrackingConfidence: input.minTrackingConfidence,
309
+ outputFaceBlendshapes: input.outputFaceBlendshapes,
310
+ outputFacialTransformationMatrixes: input.outputFacialTransformationMatrixes
311
+ }, onProgress, signal, FaceLandmarker);
312
+ const result = faceLandmarker.detect(input.image);
313
+ if (!result.faceLandmarks) {
314
+ throw new PermanentJobError4("Failed to detect face landmarks: Empty result");
315
+ }
316
+ const faces = result.faceLandmarks.map((landmarks, index) => {
317
+ const face = {
318
+ landmarks: landmarks.map((l) => ({
319
+ x: l.x,
320
+ y: l.y,
321
+ z: l.z
322
+ }))
323
+ };
324
+ if (result.faceBlendshapes && result.faceBlendshapes[index]) {
325
+ face.blendshapes = result.faceBlendshapes[index].categories.map((b) => ({
326
+ label: b.categoryName,
327
+ score: b.score
328
+ }));
329
+ }
330
+ if (result.facialTransformationMatrixes && result.facialTransformationMatrixes[index]) {
331
+ face.transformationMatrix = Array.from(result.facialTransformationMatrixes[index].data);
332
+ }
333
+ return face;
334
+ });
335
+ return {
336
+ faces
337
+ };
338
+ };
339
+
340
+ // src/ai-provider/common/TFMP_GestureRecognizer.ts
341
+ import { PermanentJobError as PermanentJobError5 } from "@workglow/job-queue";
342
+ var TFMP_GestureRecognizer = async (input, model, onProgress, signal) => {
343
+ const { GestureRecognizer } = await loadTfmpTasksVisionSDK();
344
+ const gestureRecognizer = await getModelTask(model, {
345
+ numHands: input.numHands,
346
+ minHandDetectionConfidence: input.minHandDetectionConfidence,
347
+ minHandPresenceConfidence: input.minHandPresenceConfidence,
348
+ minTrackingConfidence: input.minTrackingConfidence
349
+ }, onProgress, signal, GestureRecognizer);
350
+ const result = gestureRecognizer.recognize(input.image);
351
+ if (!result.gestures || !result.landmarks) {
352
+ throw new PermanentJobError5("Failed to recognize gestures: Empty result");
353
+ }
354
+ const hands = result.gestures.map((gestures, index) => ({
355
+ gestures: gestures.map((g) => ({
356
+ label: g.categoryName,
357
+ score: g.score
358
+ })),
359
+ handedness: result.handedness[index].map((h) => ({
360
+ label: h.categoryName,
361
+ score: h.score
362
+ })),
363
+ landmarks: result.landmarks[index].map((l) => ({
364
+ x: l.x,
365
+ y: l.y,
366
+ z: l.z
367
+ })),
368
+ worldLandmarks: result.worldLandmarks[index].map((l) => ({
369
+ x: l.x,
370
+ y: l.y,
371
+ z: l.z
372
+ }))
373
+ }));
374
+ return {
375
+ hands
376
+ };
377
+ };
378
+
379
+ // src/ai-provider/common/TFMP_HandLandmarker.ts
380
+ import { PermanentJobError as PermanentJobError6 } from "@workglow/job-queue";
381
+ var TFMP_HandLandmarker = async (input, model, onProgress, signal) => {
382
+ const { HandLandmarker } = await loadTfmpTasksVisionSDK();
383
+ const handLandmarker = await getModelTask(model, {
384
+ numHands: input.numHands,
385
+ minHandDetectionConfidence: input.minHandDetectionConfidence,
386
+ minHandPresenceConfidence: input.minHandPresenceConfidence,
387
+ minTrackingConfidence: input.minTrackingConfidence
388
+ }, onProgress, signal, HandLandmarker);
389
+ const result = handLandmarker.detect(input.image);
390
+ if (!result.landmarks) {
391
+ throw new PermanentJobError6("Failed to detect hand landmarks: Empty result");
392
+ }
393
+ const hands = result.landmarks.map((landmarks, index) => ({
394
+ handedness: result.handedness[index].map((h) => ({
395
+ label: h.categoryName,
396
+ score: h.score
397
+ })),
398
+ landmarks: landmarks.map((l) => ({
399
+ x: l.x,
400
+ y: l.y,
401
+ z: l.z
402
+ })),
403
+ worldLandmarks: result.worldLandmarks[index].map((l) => ({
404
+ x: l.x,
405
+ y: l.y,
406
+ z: l.z
407
+ }))
408
+ }));
409
+ return {
410
+ hands
411
+ };
412
+ };
413
+
414
+ // src/ai-provider/common/TFMP_ImageClassification.ts
415
+ import { PermanentJobError as PermanentJobError7 } from "@workglow/job-queue";
416
+ var TFMP_ImageClassification = async (input, model, onProgress, signal) => {
417
+ const { ImageClassifier } = await loadTfmpTasksVisionSDK();
418
+ const imageClassifier = await getModelTask(model, {
419
+ maxResults: input.maxCategories
420
+ }, onProgress, signal, ImageClassifier);
421
+ const result = imageClassifier.classify(input.image);
422
+ if (!result.classifications?.[0]?.categories) {
423
+ throw new PermanentJobError7("Failed to classify image: Empty result");
424
+ }
425
+ const categories = result.classifications[0].categories.map((category) => ({
426
+ label: category.categoryName,
427
+ score: category.score
428
+ }));
429
+ return {
430
+ categories
431
+ };
432
+ };
433
+
434
+ // src/ai-provider/common/TFMP_ImageEmbedding.ts
435
+ import { PermanentJobError as PermanentJobError8 } from "@workglow/job-queue";
436
+ var TFMP_ImageEmbedding = async (input, model, onProgress, signal) => {
437
+ const { ImageEmbedder } = await loadTfmpTasksVisionSDK();
438
+ const imageEmbedder = await getModelTask(model, {}, onProgress, signal, ImageEmbedder);
439
+ if (Array.isArray(input.image)) {
440
+ const vectors = [];
441
+ for (const image of input.image) {
442
+ const result2 = imageEmbedder.embed(image);
443
+ if (!result2.embeddings?.[0]?.floatEmbedding) {
444
+ throw new PermanentJobError8("Failed to generate embedding: Empty result");
445
+ }
446
+ vectors.push(Float32Array.from(result2.embeddings[0].floatEmbedding));
447
+ }
448
+ return { vector: vectors };
449
+ }
450
+ const result = imageEmbedder.embed(input.image);
451
+ if (!result.embeddings?.[0]?.floatEmbedding) {
452
+ throw new PermanentJobError8("Failed to generate embedding: Empty result");
453
+ }
454
+ const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);
455
+ return {
456
+ vector: embedding
457
+ };
458
+ };
459
+
460
+ // src/ai-provider/common/TFMP_ImageSegmentation.ts
461
+ import { PermanentJobError as PermanentJobError9 } from "@workglow/job-queue";
462
+ var TFMP_ImageSegmentation = async (input, model, onProgress, signal) => {
463
+ const { ImageSegmenter } = await loadTfmpTasksVisionSDK();
464
+ const imageSegmenter = await getModelTask(model, {}, onProgress, signal, ImageSegmenter);
465
+ const result = imageSegmenter.segment(input.image);
466
+ if (!result.categoryMask) {
467
+ throw new PermanentJobError9("Failed to segment image: Empty result");
468
+ }
469
+ const masks = [
470
+ {
471
+ label: "segment",
472
+ score: 1,
473
+ mask: {
474
+ data: result.categoryMask.canvas,
475
+ width: result.categoryMask.width,
476
+ height: result.categoryMask.height
477
+ }
478
+ }
479
+ ];
480
+ return {
481
+ masks
482
+ };
483
+ };
484
+
485
+ // src/ai-provider/common/TFMP_ModelInfo.ts
486
+ var TFMP_EMBEDDING_DIMENSIONS = {
487
+ "universal-sentence-encoder": { native_dimensions: 512, mrl: false }
488
+ };
489
+ var TFMP_ModelInfo = async (input, model) => {
490
+ if (input.detail === "dimensions") {
491
+ const pc = model?.provider_config;
492
+ let native_dimensions = typeof pc?.native_dimensions === "number" ? pc.native_dimensions : undefined;
493
+ const mrl = typeof pc?.mrl === "boolean" ? pc.mrl : false;
494
+ if (native_dimensions === undefined) {
495
+ const modelPath = pc?.model_path ?? "";
496
+ const known = TFMP_EMBEDDING_DIMENSIONS[modelPath];
497
+ if (known) {
498
+ native_dimensions = known.native_dimensions;
499
+ }
500
+ }
501
+ return {
502
+ model: input.model,
503
+ is_local: true,
504
+ is_remote: false,
505
+ supports_browser: true,
506
+ supports_node: false,
507
+ is_cached: false,
508
+ is_loaded: false,
509
+ file_sizes: null,
510
+ ...native_dimensions !== undefined ? { native_dimensions } : {},
511
+ ...mrl ? { mrl } : {}
512
+ };
513
+ }
514
+ const model_path = model.provider_config.model_path;
515
+ const is_loaded = modelTaskCache.has(model_path);
516
+ return {
517
+ model: input.model,
518
+ is_local: true,
519
+ is_remote: false,
520
+ supports_browser: true,
521
+ supports_node: false,
522
+ is_cached: is_loaded,
523
+ is_loaded,
524
+ file_sizes: null
525
+ };
526
+ };
527
+
528
+ // src/ai-provider/common/TFMP_ObjectDetection.ts
529
+ import { PermanentJobError as PermanentJobError10 } from "@workglow/job-queue";
530
+ var TFMP_ObjectDetection = async (input, model, onProgress, signal) => {
531
+ const { ObjectDetector } = await loadTfmpTasksVisionSDK();
532
+ const objectDetector = await getModelTask(model, {
533
+ scoreThreshold: input.threshold
534
+ }, onProgress, signal, ObjectDetector);
535
+ const result = objectDetector.detect(input.image);
536
+ if (!result.detections) {
537
+ throw new PermanentJobError10("Failed to detect objects: Empty result");
538
+ }
539
+ const detections = result.detections.map((detection) => ({
540
+ label: detection.categories?.[0]?.categoryName || "unknown",
541
+ score: detection.categories?.[0]?.score || 0,
542
+ box: {
543
+ x: detection.boundingBox?.originX || 0,
544
+ y: detection.boundingBox?.originY || 0,
545
+ width: detection.boundingBox?.width || 0,
546
+ height: detection.boundingBox?.height || 0
547
+ }
548
+ }));
549
+ return {
550
+ detections
551
+ };
552
+ };
553
+
554
+ // src/ai-provider/common/TFMP_PoseLandmarker.ts
555
+ import { PermanentJobError as PermanentJobError11 } from "@workglow/job-queue";
556
+ var TFMP_PoseLandmarker = async (input, model, onProgress, signal) => {
557
+ const { PoseLandmarker } = await loadTfmpTasksVisionSDK();
558
+ const poseLandmarker = await getModelTask(model, {
559
+ numPoses: input.numPoses,
560
+ minPoseDetectionConfidence: input.minPoseDetectionConfidence,
561
+ minPosePresenceConfidence: input.minPosePresenceConfidence,
562
+ minTrackingConfidence: input.minTrackingConfidence,
563
+ outputSegmentationMasks: input.outputSegmentationMasks
564
+ }, onProgress, signal, PoseLandmarker);
565
+ const result = poseLandmarker.detect(input.image);
566
+ if (!result.landmarks) {
567
+ throw new PermanentJobError11("Failed to detect pose landmarks: Empty result");
568
+ }
569
+ const poses = result.landmarks.map((landmarks, index) => {
570
+ const pose = {
571
+ landmarks: landmarks.map((l) => ({
572
+ x: l.x,
573
+ y: l.y,
574
+ z: l.z,
575
+ visibility: l.visibility,
576
+ presence: l.presence
577
+ })),
578
+ worldLandmarks: result.worldLandmarks[index].map((l) => ({
579
+ x: l.x,
580
+ y: l.y,
581
+ z: l.z,
582
+ visibility: l.visibility,
583
+ presence: l.presence
584
+ }))
585
+ };
586
+ if (result.segmentationMasks && result.segmentationMasks[index]) {
587
+ const mask = result.segmentationMasks[index];
588
+ pose.segmentationMask = {
589
+ data: mask.canvas || mask,
590
+ width: mask.width,
591
+ height: mask.height
592
+ };
593
+ }
594
+ return pose;
595
+ });
596
+ return {
597
+ poses
598
+ };
599
+ };
600
+
601
+ // src/ai-provider/common/TFMP_TextClassification.ts
602
+ import { PermanentJobError as PermanentJobError12 } from "@workglow/job-queue";
603
+ var TFMP_TextClassification = async (input, model, onProgress, signal) => {
604
+ const { TextClassifier } = await loadTfmpTasksTextSDK();
605
+ const TextClassification = await getModelTask(model, {
606
+ maxCategories: input.maxCategories
607
+ }, onProgress, signal, TextClassifier);
608
+ const result = TextClassification.classify(input.text);
609
+ if (!result.classifications?.[0]?.categories) {
610
+ throw new PermanentJobError12("Failed to classify text: Empty result");
611
+ }
612
+ const categories = result.classifications[0].categories.map((category) => ({
613
+ label: category.categoryName,
614
+ score: category.score
615
+ }));
616
+ return {
617
+ categories
618
+ };
619
+ };
620
+
621
+ // src/ai-provider/common/TFMP_TextEmbedding.ts
622
+ import { PermanentJobError as PermanentJobError13 } from "@workglow/job-queue";
623
+ var TFMP_TextEmbedding = async (input, model, onProgress, signal) => {
624
+ const { TextEmbedder } = await loadTfmpTasksTextSDK();
625
+ const textEmbedder = await getModelTask(model, {}, onProgress, signal, TextEmbedder);
626
+ if (Array.isArray(input.text)) {
627
+ const embeddings = input.text.map((text) => {
628
+ const result2 = textEmbedder.embed(text);
629
+ if (!result2.embeddings?.[0]?.floatEmbedding) {
630
+ throw new PermanentJobError13("Failed to generate embedding: Empty result");
631
+ }
632
+ return Float32Array.from(result2.embeddings[0].floatEmbedding);
633
+ });
634
+ return {
635
+ vector: embeddings
636
+ };
637
+ }
638
+ const result = textEmbedder.embed(input.text);
639
+ if (!result.embeddings?.[0]?.floatEmbedding) {
640
+ throw new PermanentJobError13("Failed to generate embedding: Empty result");
641
+ }
642
+ const embedding = Float32Array.from(result.embeddings[0].floatEmbedding);
643
+ return {
644
+ vector: embedding
645
+ };
646
+ };
647
+
648
+ // src/ai-provider/common/TFMP_TextLanguageDetection.ts
649
+ import { PermanentJobError as PermanentJobError14 } from "@workglow/job-queue";
650
+ var TFMP_TextLanguageDetection = async (input, model, onProgress, signal) => {
651
+ const maxLanguages = input.maxLanguages === 0 ? -1 : input.maxLanguages;
652
+ const { LanguageDetector } = await loadTfmpTasksTextSDK();
653
+ const textLanguageDetector = await getModelTask(model, {
654
+ maxLanguages
655
+ }, onProgress, signal, LanguageDetector);
656
+ const result = textLanguageDetector.detect(input.text);
657
+ if (!result.languages?.[0]?.languageCode) {
658
+ throw new PermanentJobError14("Failed to detect language: Empty result");
659
+ }
660
+ const languages = result.languages.map((language) => ({
661
+ language: language.languageCode,
662
+ score: language.probability
663
+ }));
664
+ return {
665
+ languages
666
+ };
667
+ };
668
+
669
+ // src/ai-provider/common/TFMP_Unload.ts
670
+ var TFMP_Unload = async (input, model, onProgress, _signal) => {
671
+ const model_path = model.provider_config.model_path;
672
+ onProgress(10, "Unloading model");
673
+ if (modelTaskCache.has(model_path)) {
674
+ const cachedTasks = modelTaskCache.get(model_path);
675
+ for (const cachedTask of cachedTasks) {
676
+ const task = cachedTask.task;
677
+ if ("close" in task && typeof task.close === "function")
678
+ task.close();
679
+ const task_engine = cachedTask.task_engine;
680
+ const currentCount = wasm_reference_counts.get(task_engine) || 0;
681
+ const newCount = currentCount - 1;
682
+ if (newCount <= 0) {
683
+ wasm_tasks.delete(task_engine);
684
+ wasm_reference_counts.delete(task_engine);
685
+ } else {
686
+ wasm_reference_counts.set(task_engine, newCount);
687
+ }
688
+ }
689
+ modelTaskCache.delete(model_path);
690
+ }
691
+ return {
692
+ model: input.model
693
+ };
694
+ };
695
+
696
+ // src/ai-provider/common/TFMP_JobRunFns.ts
697
+ var TFMP_TASKS = {
698
+ DownloadModelTask: TFMP_Download,
699
+ UnloadModelTask: TFMP_Unload,
700
+ ModelInfoTask: TFMP_ModelInfo,
701
+ TextEmbeddingTask: TFMP_TextEmbedding,
702
+ TextLanguageDetectionTask: TFMP_TextLanguageDetection,
703
+ TextClassificationTask: TFMP_TextClassification,
704
+ ImageSegmentationTask: TFMP_ImageSegmentation,
705
+ ImageEmbeddingTask: TFMP_ImageEmbedding,
706
+ ImageClassificationTask: TFMP_ImageClassification,
707
+ ObjectDetectionTask: TFMP_ObjectDetection,
708
+ GestureRecognizerTask: TFMP_GestureRecognizer,
709
+ HandLandmarkerTask: TFMP_HandLandmarker,
710
+ FaceDetectorTask: TFMP_FaceDetector,
711
+ FaceLandmarkerTask: TFMP_FaceLandmarker,
712
+ PoseLandmarkerTask: TFMP_PoseLandmarker,
713
+ ModelSearchTask: TFMP_ModelSearch
714
+ };
715
+
716
+ // src/ai-provider/TensorFlowMediaPipeQueuedProvider.ts
717
+ import { AiProvider } from "@workglow/ai";
718
+ class TensorFlowMediaPipeQueuedProvider extends AiProvider {
719
+ name = TENSORFLOW_MEDIAPIPE;
720
+ displayName = "TensorFlow MediaPipe";
721
+ isLocal = true;
722
+ supportsBrowser = true;
723
+ taskTypes = TFMP_DEFAULT_TASK_TYPES;
724
+ constructor(tasks, previewTasks) {
725
+ super(tasks, undefined, previewTasks);
726
+ }
727
+ }
728
+
729
+ // src/ai-provider/registerTensorFlowMediaPipeInline.ts
730
+ async function registerTensorFlowMediaPipeInline(options) {
731
+ await registerProviderInline(new TensorFlowMediaPipeQueuedProvider(TFMP_TASKS), "TensorFlow MediaPipe", options);
732
+ }
733
+
734
+ // src/ai-provider/registerTensorFlowMediaPipeWorker.ts
735
+ import { registerProviderWorker } from "@workglow/ai-provider/common";
736
+
737
+ // src/ai-provider/TensorFlowMediaPipeProvider.ts
738
+ import { AiProvider as AiProvider2 } from "@workglow/ai/worker";
739
+ class TensorFlowMediaPipeProvider extends AiProvider2 {
740
+ name = TENSORFLOW_MEDIAPIPE;
741
+ displayName = "TensorFlow MediaPipe";
742
+ isLocal = true;
743
+ supportsBrowser = true;
744
+ taskTypes = TFMP_DEFAULT_TASK_TYPES;
745
+ constructor(tasks, previewTasks) {
746
+ super(tasks, undefined, previewTasks);
747
+ }
748
+ }
749
+
750
+ // src/ai-provider/registerTensorFlowMediaPipeWorker.ts
751
+ async function registerTensorFlowMediaPipeWorker() {
752
+ await registerProviderWorker((ws) => new TensorFlowMediaPipeProvider(TFMP_TASKS).registerOnWorkerServer(ws), "TensorFlow MediaPipe");
753
+ }
754
+ export {
755
+ registerTensorFlowMediaPipeWorker,
756
+ registerTensorFlowMediaPipeInline,
757
+ loadTfmpTasksVisionSDK,
758
+ loadTfmpTasksTextSDK
759
+ };
760
+
761
+ //# debugId=C2FBE955556A6BD164756E2164756E21