@workglow/huggingface-transformers 0.2.34 → 0.2.36

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/HuggingFaceTransformersProvider.d.ts +9 -8
  2. package/dist/ai/HuggingFaceTransformersProvider.d.ts.map +1 -1
  3. package/dist/ai/HuggingFaceTransformersQueuedProvider.d.ts +10 -8
  4. package/dist/ai/HuggingFaceTransformersQueuedProvider.d.ts.map +1 -1
  5. package/dist/ai/common/HFT_BackgroundRemoval.d.ts.map +1 -1
  6. package/dist/ai/common/HFT_Capabilities.d.ts +28 -0
  7. package/dist/ai/common/HFT_Capabilities.d.ts.map +1 -0
  8. package/dist/ai/common/HFT_CapabilitySets.d.ts +40 -0
  9. package/dist/ai/common/HFT_CapabilitySets.d.ts.map +1 -0
  10. package/dist/ai/common/HFT_Chat.d.ts +1 -2
  11. package/dist/ai/common/HFT_Chat.d.ts.map +1 -1
  12. package/dist/ai/common/HFT_CountTokens.d.ts.map +1 -1
  13. package/dist/ai/common/HFT_Download.d.ts +7 -2
  14. package/dist/ai/common/HFT_Download.d.ts.map +1 -1
  15. package/dist/ai/common/{HFT_Unload.d.ts → HFT_DownloadRemove.d.ts} +3 -3
  16. package/dist/ai/common/HFT_DownloadRemove.d.ts.map +1 -0
  17. package/dist/ai/common/HFT_ImageClassification.d.ts.map +1 -1
  18. package/dist/ai/common/HFT_ImageEmbedding.d.ts.map +1 -1
  19. package/dist/ai/common/HFT_ImageSegmentation.d.ts.map +1 -1
  20. package/dist/ai/common/HFT_ImageToText.d.ts.map +1 -1
  21. package/dist/ai/common/HFT_JobRunFns.d.ts +9 -9
  22. package/dist/ai/common/HFT_JobRunFns.d.ts.map +1 -1
  23. package/dist/ai/common/HFT_ModelInfo.d.ts.map +1 -1
  24. package/dist/ai/common/HFT_ModelSchema.d.ts +3 -3
  25. package/dist/ai/common/HFT_ObjectDetection.d.ts.map +1 -1
  26. package/dist/ai/common/HFT_Pipeline.d.ts +30 -4
  27. package/dist/ai/common/HFT_Pipeline.d.ts.map +1 -1
  28. package/dist/ai/common/HFT_Streaming.d.ts +5 -12
  29. package/dist/ai/common/HFT_Streaming.d.ts.map +1 -1
  30. package/dist/ai/common/HFT_StructuredGeneration.d.ts +1 -2
  31. package/dist/ai/common/HFT_StructuredGeneration.d.ts.map +1 -1
  32. package/dist/ai/common/HFT_TextClassification.d.ts.map +1 -1
  33. package/dist/ai/common/HFT_TextEmbedding.d.ts +4 -0
  34. package/dist/ai/common/HFT_TextEmbedding.d.ts.map +1 -1
  35. package/dist/ai/common/HFT_TextFillMask.d.ts.map +1 -1
  36. package/dist/ai/common/HFT_TextGeneration.d.ts +1 -6
  37. package/dist/ai/common/HFT_TextGeneration.d.ts.map +1 -1
  38. package/dist/ai/common/HFT_TextLanguageDetection.d.ts.map +1 -1
  39. package/dist/ai/common/HFT_TextNamedEntityRecognition.d.ts.map +1 -1
  40. package/dist/ai/common/HFT_TextQuestionAnswer.d.ts +1 -6
  41. package/dist/ai/common/HFT_TextQuestionAnswer.d.ts.map +1 -1
  42. package/dist/ai/common/HFT_TextReranker.d.ts +42 -0
  43. package/dist/ai/common/HFT_TextReranker.d.ts.map +1 -0
  44. package/dist/ai/common/HFT_TextRewriter.d.ts +1 -6
  45. package/dist/ai/common/HFT_TextRewriter.d.ts.map +1 -1
  46. package/dist/ai/common/HFT_TextSummary.d.ts +1 -6
  47. package/dist/ai/common/HFT_TextSummary.d.ts.map +1 -1
  48. package/dist/ai/common/HFT_TextTranslation.d.ts +1 -6
  49. package/dist/ai/common/HFT_TextTranslation.d.ts.map +1 -1
  50. package/dist/ai/common/HFT_ToolCalling.d.ts +1 -2
  51. package/dist/ai/common/HFT_ToolCalling.d.ts.map +1 -1
  52. package/dist/ai/index.d.ts +53 -2
  53. package/dist/ai/index.d.ts.map +1 -1
  54. package/dist/ai/registerHuggingFaceTransformersInline.d.ts.map +1 -1
  55. package/dist/ai/registerHuggingFaceTransformersWorker.d.ts.map +1 -1
  56. package/dist/ai/runtime.d.ts +1 -0
  57. package/dist/ai/runtime.d.ts.map +1 -1
  58. package/dist/ai-runtime.d.ts.map +1 -1
  59. package/dist/ai-runtime.js +665 -858
  60. package/dist/ai-runtime.js.map +38 -36
  61. package/dist/ai.d.ts.map +1 -1
  62. package/dist/ai.js +1434 -183
  63. package/dist/ai.js.map +38 -8
  64. package/package.json +12 -13
  65. package/dist/ai/common/HFT_Unload.d.ts.map +0 -1
@@ -197,14 +197,29 @@ function disposeHftSessionsForModel(modelPath) {
197
197
  }
198
198
  }
199
199
  }
200
- function clearPipelineCache() {
200
+ async function clearPipelineCache() {
201
+ const snapshot = Array.from(pipelines.values());
201
202
  pipelines.clear();
203
+ await Promise.allSettled(snapshot.map(async (pipeline) => {
204
+ try {
205
+ const model = pipeline?.model;
206
+ await model?.dispose?.();
207
+ } catch {}
208
+ }));
202
209
  }
203
210
  function hasCachedPipeline(cacheKey) {
204
211
  return pipelines.has(cacheKey);
205
212
  }
206
- function removeCachedPipeline(cacheKey) {
207
- return pipelines.delete(cacheKey);
213
+ async function removeCachedPipeline(cacheKey) {
214
+ const pipeline = pipelines.get(cacheKey);
215
+ const deleted = pipelines.delete(cacheKey);
216
+ if (pipeline) {
217
+ try {
218
+ const model = pipeline?.model;
219
+ await model?.dispose?.();
220
+ } catch {}
221
+ }
222
+ return deleted;
208
223
  }
209
224
  function isBrowserEnv() {
210
225
  if (typeof globalThis === "undefined")
@@ -221,7 +236,10 @@ function getPipelineCacheKey(model) {
221
236
  const revision = model.provider_config.revision || "main";
222
237
  return `${model.provider_config.model_path}:${model.provider_config.pipeline}:${dtype}:${device}:${revision}`;
223
238
  }
224
- async function getPipeline(model, onProgress, options = {}, signal, progressScaleMax = 10) {
239
+ async function getPipeline(model, emit, options = {}, signal, progressScaleMax = 10) {
240
+ if (signal?.aborted) {
241
+ throw signal?.reason ?? new Error("Aborted");
242
+ }
225
243
  const cacheKey = getPipelineCacheKey(model);
226
244
  if (pipelines.has(cacheKey)) {
227
245
  getLogger().debug("HFT pipeline cache hit", { cacheKey });
@@ -236,28 +254,18 @@ async function getPipeline(model, onProgress, options = {}, signal, progressScal
236
254
  if (cached)
237
255
  return cached;
238
256
  }
239
- const loadPromise = doGetPipeline(model, onProgress, options, progressScaleMax, cacheKey, signal).finally(() => {
257
+ const loadPromise = doGetPipeline(model, emit, options, progressScaleMax, cacheKey, signal).finally(() => {
240
258
  pipelineLoadPromises.delete(cacheKey);
241
259
  });
242
260
  pipelineLoadPromises.set(cacheKey, loadPromise);
243
261
  return loadPromise;
244
262
  }
245
- var _transformersSdk, _cacheDir, _loadPromise, modelAbortControllers, pipelines, hftSessions, pipelineLoadPromises, IMAGE_PIPELINE_TYPES, HFT_NULL_PROCESSOR_PREFIX = "HFT_NULL_PROCESSOR:", doGetPipeline = async (model, onProgress, options, progressScaleMax, cacheKey, signal) => {
263
+ var _transformersSdk, _cacheDir, _loadPromise, modelAbortControllers, pipelines, hftSessions, pipelineLoadPromises, IMAGE_PIPELINE_TYPES, HFT_NULL_PROCESSOR_PREFIX = "HFT_NULL_PROCESSOR:", doGetPipeline = async (model, emit, options, progressScaleMax, cacheKey, signal) => {
246
264
  let lastProgressTime = 0;
247
265
  let pendingProgress = null;
248
266
  let throttleTimer = null;
249
267
  const THROTTLE_MS = 160;
250
- const buildProgressDetails = (file, fileProgress, filesMap) => {
251
- const details = {
252
- file,
253
- progress: fileProgress
254
- };
255
- if (filesMap && Object.keys(filesMap).length > 0) {
256
- details.files = filesMap;
257
- }
258
- return details;
259
- };
260
- const sendProgress = (progress, file, fileProgress, filesMap) => {
268
+ const sendProgress = (progress) => {
261
269
  const now = Date.now();
262
270
  const timeSinceLastEvent = now - lastProgressTime;
263
271
  const isFirst = lastProgressTime === 0;
@@ -268,19 +276,22 @@ var _transformersSdk, _cacheDir, _loadPromise, modelAbortControllers, pipelines,
268
276
  throttleTimer = null;
269
277
  }
270
278
  pendingProgress = null;
271
- onProgress(Math.round(progress), "Downloading model", buildProgressDetails(file, fileProgress, filesMap));
279
+ emit({ type: "phase", message: "Downloading model", progress: Math.round(progress) });
272
280
  lastProgressTime = now;
273
281
  return;
274
282
  }
275
283
  if (timeSinceLastEvent < THROTTLE_MS) {
276
- pendingProgress = { progress, file, fileProgress, filesMap };
284
+ pendingProgress = progress;
277
285
  if (!throttleTimer) {
278
286
  const timeRemaining = Math.max(1, THROTTLE_MS - timeSinceLastEvent);
279
287
  throttleTimer = setTimeout(() => {
280
288
  throttleTimer = null;
281
- if (pendingProgress) {
282
- const p = pendingProgress;
283
- onProgress(Math.round(p.progress), "Downloading model", buildProgressDetails(p.file, p.fileProgress, p.filesMap));
289
+ if (pendingProgress !== null) {
290
+ emit({
291
+ type: "phase",
292
+ message: "Downloading model",
293
+ progress: Math.round(pendingProgress)
294
+ });
284
295
  lastProgressTime = Date.now();
285
296
  pendingProgress = null;
286
297
  }
@@ -288,7 +299,7 @@ var _transformersSdk, _cacheDir, _loadPromise, modelAbortControllers, pipelines,
288
299
  }
289
300
  return;
290
301
  }
291
- onProgress(Math.round(progress), "Downloading model", buildProgressDetails(file, fileProgress, filesMap));
302
+ emit({ type: "phase", message: "Downloading model", progress: Math.round(progress) });
292
303
  lastProgressTime = now;
293
304
  pendingProgress = null;
294
305
  };
@@ -307,28 +318,8 @@ var _transformersSdk, _cacheDir, _loadPromise, modelAbortControllers, pipelines,
307
318
  if (abortSignal?.aborted)
308
319
  return;
309
320
  if (status.status === "progress_total") {
310
- const totalStatus = status;
311
- const scaledProgress = totalStatus.progress * progressScaleMax / 100;
312
- let activeFile = "";
313
- let activeFileProgress = 0;
314
- const files = totalStatus.files;
315
- if (files) {
316
- for (const [file, info] of Object.entries(files)) {
317
- if (info.loaded < info.total) {
318
- activeFile = file;
319
- activeFileProgress = info.total > 0 ? info.loaded / info.total * 100 : 0;
320
- break;
321
- }
322
- }
323
- if (!activeFile) {
324
- const fileNames = Object.keys(files);
325
- if (fileNames.length > 0) {
326
- activeFile = fileNames[fileNames.length - 1];
327
- activeFileProgress = 100;
328
- }
329
- }
330
- }
331
- sendProgress(scaledProgress, activeFile, activeFileProgress, files);
321
+ const scaledProgress = status.progress * progressScaleMax / 100;
322
+ sendProgress(scaledProgress);
332
323
  }
333
324
  };
334
325
  let device = model.provider_config.device;
@@ -371,9 +362,12 @@ var _transformersSdk, _cacheDir, _loadPromise, modelAbortControllers, pipelines,
371
362
  clearTimeout(throttleTimer);
372
363
  throttleTimer = null;
373
364
  }
374
- const finalPending = pendingProgress;
375
- if (finalPending) {
376
- onProgress(Math.round(finalPending.progress), "Downloading model", buildProgressDetails(finalPending.file, finalPending.fileProgress, finalPending.filesMap));
365
+ if (pendingProgress !== null) {
366
+ emit({
367
+ type: "phase",
368
+ message: "Downloading model",
369
+ progress: Math.round(pendingProgress)
370
+ });
377
371
  pendingProgress = null;
378
372
  }
379
373
  if (abortSignal?.aborted) {
@@ -662,6 +656,54 @@ function parseOnnxQuantizations(params) {
662
656
  });
663
657
  }
664
658
 
659
+ // src/ai/common/HFT_TextReranker.ts
660
+ init_HFT_Pipeline();
661
+ import { KbRerankerOutputError } from "@workglow/ai";
662
+ import { getLogger as getLogger2 } from "@workglow/util/worker";
663
+ function isScored(v) {
664
+ return typeof v === "object" && v !== null && typeof v.score === "number";
665
+ }
666
+ function truncateShape(value) {
667
+ try {
668
+ const json = JSON.stringify(value);
669
+ if (typeof json !== "string")
670
+ return String(value);
671
+ return json.length > 200 ? `${json.slice(0, 200)}…` : json;
672
+ } catch {
673
+ return String(value);
674
+ }
675
+ }
676
+ function validateAndExtractRerankerScores(rawResults, modelPath) {
677
+ if (!Array.isArray(rawResults)) {
678
+ throw new KbRerankerOutputError(`HFT_TextReranker: unexpected pipeline output shape for model ${modelPath}`, truncateShape(rawResults));
679
+ }
680
+ const scores = new Array(rawResults.length);
681
+ for (let i = 0;i < rawResults.length; i++) {
682
+ const entry = rawResults[i];
683
+ const candidate = Array.isArray(entry) ? entry[0] : entry;
684
+ if (!isScored(candidate)) {
685
+ throw new KbRerankerOutputError(`HFT_TextReranker: unexpected pipeline output shape for model ${modelPath}`, truncateShape(entry));
686
+ }
687
+ scores[i] = candidate.score;
688
+ }
689
+ return scores;
690
+ }
691
+ var HFT_TextReranker = async (input, model, signal, emit) => {
692
+ const logger = getLogger2();
693
+ const modelPath = model?.provider_config.model_path;
694
+ const timerLabel = `hft:TextReranker:${modelPath}`;
695
+ logger.time(timerLabel, { docs: input.documents.length });
696
+ const reranker = await getPipeline(model, emit, {}, signal);
697
+ const pairs = input.documents.map((doc) => ({ text: input.query, text_pair: doc }));
698
+ const callable = reranker;
699
+ const rawResults = await callable(pairs, { top_k: 1 });
700
+ const scores = validateAndExtractRerankerScores(rawResults, modelPath);
701
+ const indices = scores.map((score, idx) => ({ score, idx })).sort((a, b) => b.score - a.score).map((p) => p.idx);
702
+ const limited = typeof input.topK === "number" ? indices.slice(0, input.topK) : indices;
703
+ logger.timeEnd(timerLabel, { docs: input.documents.length });
704
+ emit({ type: "finish", data: { scores, indices: limited } });
705
+ };
706
+
665
707
  // src/ai/common/HFT_ToolMarkup.ts
666
708
  function createToolCallMarkupFilter(emit) {
667
709
  const OPEN_TAG = "<tool_call>";
@@ -734,31 +776,68 @@ import { registerProviderInline } from "@workglow/ai/provider-utils";
734
776
  // src/ai/common/HFT_InlineLifecycle.ts
735
777
  async function clearHftInlinePipelineCache() {
736
778
  const { clearPipelineCache: clearPipelineCache2 } = await Promise.resolve().then(() => (init_HFT_Pipeline(), exports_HFT_Pipeline));
737
- clearPipelineCache2();
779
+ await clearPipelineCache2();
738
780
  }
739
781
 
740
- // src/ai/common/HFT_ModelSearch.ts
741
- import { searchHfModels, mapHfModelResult } from "@workglow/ai/provider-utils";
742
- var HFT_ModelSearch = async (input, _model, _onProgress, signal) => {
743
- const entries = await searchHfModels(input.query?.trim() ?? "", { filter: "onnx" }, ["siblings"], signal);
744
- const results = entries.map((entry) => {
745
- const item = mapHfModelResult(entry, HF_TRANSFORMERS_ONNX);
746
- if (entry.siblings && entry.siblings.length > 0) {
747
- const filePaths = entry.siblings.map((s) => s.rfilename);
748
- const quantizations = parseOnnxQuantizations({ filePaths });
749
- if (quantizations.length > 0) {
750
- const record = item.record;
751
- const providerConfig = record.provider_config ?? {};
752
- providerConfig.quantizations = quantizations;
753
- record.provider_config = providerConfig;
754
- }
755
- }
756
- const raw = item.raw;
757
- delete raw.siblings;
758
- return item;
759
- });
760
- return { results };
761
- };
782
+ // src/ai/common/HFT_CapabilitySets.ts
783
+ var HFT_TEXT_GENERATION = ["text.generation"];
784
+ var HFT_TOOL_USE = ["text.generation", "tool-use"];
785
+ var HFT_JSON_MODE = ["text.generation", "json-mode"];
786
+ var HFT_TEXT_REWRITER = ["text.rewriter"];
787
+ var HFT_TEXT_SUMMARY = ["text.summary"];
788
+ var HFT_TEXT_TRANSLATION = ["text.translation"];
789
+ var HFT_TEXT_QUESTION_ANSWERING = [
790
+ "text.question-answering"
791
+ ];
792
+ var HFT_TEXT_EMBEDDING = ["text.embedding"];
793
+ var HFT_TEXT_CLASSIFICATION = ["text.classification"];
794
+ var HFT_TEXT_LANGUAGE_DETECTION = [
795
+ "text.language-detection"
796
+ ];
797
+ var HFT_TEXT_RERANKING = ["text.reranking"];
798
+ var HFT_TEXT_FILL_MASK = ["text.fill-mask"];
799
+ var HFT_TEXT_NER = ["text.ner"];
800
+ var HFT_IMAGE_CLASSIFICATION = ["image.classification"];
801
+ var HFT_IMAGE_EMBEDDING = ["image.embedding"];
802
+ var HFT_IMAGE_SEGMENTATION = ["image.segmentation"];
803
+ var HFT_IMAGE_TO_TEXT = ["image.to-text"];
804
+ var HFT_IMAGE_BACKGROUND_REMOVAL = [
805
+ "image.background-removal"
806
+ ];
807
+ var HFT_IMAGE_OBJECT_DETECTION = [
808
+ "image.object-detection"
809
+ ];
810
+ var HFT_COUNT_TOKENS = ["model.count-tokens"];
811
+ var HFT_MODEL_DOWNLOAD_REMOVE = ["model.download-remove"];
812
+ var HFT_MODEL_DOWNLOAD = ["model.download"];
813
+ var HFT_MODEL_SEARCH = ["model.search"];
814
+ var HFT_MODEL_INFO = ["model.info"];
815
+ var HFT_CAPABILITY_SETS = [
816
+ HFT_TEXT_GENERATION,
817
+ HFT_TOOL_USE,
818
+ HFT_JSON_MODE,
819
+ HFT_TEXT_REWRITER,
820
+ HFT_TEXT_SUMMARY,
821
+ HFT_TEXT_TRANSLATION,
822
+ HFT_TEXT_QUESTION_ANSWERING,
823
+ HFT_TEXT_EMBEDDING,
824
+ HFT_TEXT_CLASSIFICATION,
825
+ HFT_TEXT_LANGUAGE_DETECTION,
826
+ HFT_TEXT_RERANKING,
827
+ HFT_TEXT_FILL_MASK,
828
+ HFT_TEXT_NER,
829
+ HFT_IMAGE_CLASSIFICATION,
830
+ HFT_IMAGE_EMBEDDING,
831
+ HFT_IMAGE_SEGMENTATION,
832
+ HFT_IMAGE_TO_TEXT,
833
+ HFT_IMAGE_BACKGROUND_REMOVAL,
834
+ HFT_IMAGE_OBJECT_DETECTION,
835
+ HFT_COUNT_TOKENS,
836
+ HFT_MODEL_DOWNLOAD_REMOVE,
837
+ HFT_MODEL_DOWNLOAD,
838
+ HFT_MODEL_SEARCH,
839
+ HFT_MODEL_INFO
840
+ ];
762
841
 
763
842
  // src/ai/common/HFT_BackgroundRemoval.ts
764
843
  init_HFT_Pipeline();
@@ -770,15 +849,18 @@ function rawImageToBase64Png(image) {
770
849
  }
771
850
  return fn.call(image);
772
851
  }
773
- var HFT_BackgroundRemoval = async (input, model, onProgress, signal) => {
774
- const remover = await getPipeline(model, onProgress, {}, signal);
852
+ var HFT_BackgroundRemoval = async (input, model, signal, emit) => {
853
+ const remover = await getPipeline(model, emit, {}, signal);
775
854
  const imageArg = await imageValueToBlob(input.image);
776
855
  const result = await remover(imageArg);
777
856
  const resultImage = Array.isArray(result) ? result[0] : result;
778
857
  const dataUri = `data:image/png;base64,${rawImageToBase64Png(resultImage)}`;
779
- return {
780
- image: await dataUriToImageValue(dataUri)
781
- };
858
+ emit({
859
+ type: "finish",
860
+ data: {
861
+ image: await dataUriToImageValue(dataUri)
862
+ }
863
+ });
782
864
  };
783
865
 
784
866
  // src/ai/common/HFT_Chat.ts
@@ -800,64 +882,11 @@ import {
800
882
  } from "@workglow/ai/provider-utils";
801
883
 
802
884
  // src/ai/common/HFT_Streaming.ts
803
- function createStreamEventQueue() {
804
- const buffer = [];
805
- let resolve = null;
806
- let finished = false;
807
- let err = null;
808
- const push = (event) => {
809
- if (resolve) {
810
- const r = resolve;
811
- resolve = null;
812
- r({ value: event, done: false });
813
- } else {
814
- buffer.push(event);
815
- }
816
- };
817
- const done = () => {
818
- finished = true;
819
- if (resolve) {
820
- const r = resolve;
821
- resolve = null;
822
- r({ value: undefined, done: true });
823
- }
824
- };
825
- const error = (e) => {
826
- err = e;
827
- if (resolve) {
828
- const r = resolve;
829
- resolve = null;
830
- r({ value: undefined, done: true });
831
- }
832
- };
833
- const iterable = {
834
- [Symbol.asyncIterator]() {
835
- return {
836
- next() {
837
- if (err)
838
- return Promise.reject(err);
839
- if (buffer.length > 0) {
840
- return Promise.resolve({ value: buffer.shift(), done: false });
841
- }
842
- if (finished) {
843
- return Promise.resolve({ value: undefined, done: true });
844
- }
845
- return new Promise((r) => {
846
- resolve = r;
847
- });
848
- }
849
- };
850
- }
851
- };
852
- return { push, done, error, iterable };
853
- }
854
- function createStreamingTextStreamer(tokenizer, queue, textStreamer) {
885
+ function createStreamingTextStreamer(tokenizer, onText, textStreamer) {
855
886
  return new textStreamer(tokenizer, {
856
887
  skip_prompt: true,
857
888
  decode_kwargs: { skip_special_tokens: true },
858
- callback_function: (text) => {
859
- queue.push({ type: "text-delta", port: "text", textDelta: text });
860
- }
889
+ callback_function: onText
861
890
  });
862
891
  }
863
892
  function createTextStreamer(tokenizer, updateProgress, textStreamer) {
@@ -1025,76 +1054,19 @@ function buildPromptAndPrefix(tokenizer, input, modelFamily) {
1025
1054
  responsePrefix
1026
1055
  };
1027
1056
  }
1028
- var HFT_ToolCalling = async (input, model, onProgress, signal, _outputSchema, sessionId) => {
1029
- const generateText = await getPipeline(model, onProgress, {}, signal);
1030
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1031
- const hfTokenizer = generateText.tokenizer;
1032
- const hfModel = generateText.model;
1033
- const streamer = createTextStreamer(hfTokenizer, onProgress, TextStreamer);
1034
- const stopping_criteria = new InterruptableStoppingCriteria;
1035
- if (signal) {
1036
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1037
- }
1038
- const modelFamily = detectModelFamilyFromConfig(model);
1039
- const { prompt, responsePrefix } = buildPromptAndPrefix(hfTokenizer, input, modelFamily);
1040
- const inputs = hfTokenizer(prompt, { return_tensor: true });
1041
- const modelPath = model.provider_config.model_path;
1042
- let session = sessionId ? getHftSession(sessionId) : undefined;
1043
- let past_key_values = undefined;
1044
- if (sessionId && !session) {
1045
- const { DynamicCache } = await loadTransformersSDK();
1046
- const cache = new DynamicCache;
1047
- await hfModel.generate({
1048
- ...inputs,
1049
- max_new_tokens: 0,
1050
- past_key_values: cache
1051
- });
1052
- const baseEntries = {};
1053
- for (const key of Object.keys(cache)) {
1054
- baseEntries[key] = cache[key];
1055
- }
1056
- const newSession = {
1057
- mode: "prefix-rewind",
1058
- baseEntries,
1059
- baseSeqLength: cache.get_seq_length(),
1060
- modelPath
1061
- };
1062
- setHftSession(sessionId, newSession);
1063
- session = newSession;
1064
- }
1065
- if (session?.mode === "prefix-rewind") {
1066
- const { DynamicCache } = await loadTransformersSDK();
1067
- past_key_values = new DynamicCache(session.baseEntries);
1068
- }
1069
- const output = await hfModel.generate({
1070
- ...inputs,
1071
- max_new_tokens: input.maxTokens ?? 1024,
1072
- streamer,
1073
- stopping_criteria: [stopping_criteria],
1074
- ...past_key_values ? { past_key_values } : {}
1075
- });
1076
- const promptLen = inputs.input_ids.dims[1];
1077
- const seqLen = output.dims[1];
1078
- const newTokens = output.slice(0, [promptLen, seqLen], null);
1079
- const decoded = hfTokenizer.decode(newTokens, {
1080
- skip_special_tokens: false
1081
- });
1082
- const parseableText = responsePrefix ? `${responsePrefix}${decoded}` : decoded;
1083
- const { text, toolCalls } = adaptParserResult(parseToolCalls(parseableText, { parser: modelFamily }));
1084
- return {
1085
- text,
1086
- toolCalls: filterValidToolCalls(normalizeParsedToolCalls(input, toolCalls), input.tools)
1087
- };
1088
- };
1089
- var HFT_ToolCalling_Stream = async function* (input, model, signal, _outputSchema, sessionId) {
1090
- const noopProgress = () => {};
1091
- const generateText = await getPipeline(model, noopProgress, {}, signal);
1057
+ var HFT_ToolCalling = async (input, model, signal, emit, _outputSchema, sessionId) => {
1058
+ const generateText = await getPipeline(model, emit, {}, signal);
1092
1059
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1093
1060
  const modelFamily = detectModelFamilyFromConfig(model);
1094
1061
  const { prompt, responsePrefix } = buildPromptAndPrefix(generateText.tokenizer, input, modelFamily);
1095
- const innerQueue = createStreamEventQueue();
1096
- const outerQueue = createStreamEventQueue();
1097
- const streamer = createStreamingTextStreamer(generateText.tokenizer, innerQueue, TextStreamer);
1062
+ let fullText = "";
1063
+ const filter = createToolCallMarkupFilter((text) => {
1064
+ emit({ type: "text-delta", port: "text", textDelta: text });
1065
+ });
1066
+ const streamer = createStreamingTextStreamer(generateText.tokenizer, (text) => {
1067
+ fullText += text;
1068
+ filter.feed(text);
1069
+ }, TextStreamer);
1098
1070
  const stopping_criteria = new InterruptableStoppingCriteria;
1099
1071
  if (signal) {
1100
1072
  signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
@@ -1130,57 +1102,33 @@ var HFT_ToolCalling_Stream = async function* (input, model, signal, _outputSchem
1130
1102
  const { DynamicCache } = await loadTransformersSDK();
1131
1103
  past_key_values = new DynamicCache(session.baseEntries);
1132
1104
  }
1133
- let fullText = "";
1134
- const filter = createToolCallMarkupFilter((text) => {
1135
- outerQueue.push({ type: "text-delta", port: "text", textDelta: text });
1136
- });
1137
- const originalPush = innerQueue.push;
1138
- innerQueue.push = (event) => {
1139
- if (event.type === "text-delta" && "textDelta" in event) {
1140
- fullText += event.textDelta;
1141
- filter.feed(event.textDelta);
1142
- } else {
1143
- outerQueue.push(event);
1144
- }
1145
- originalPush(event);
1146
- };
1147
- const originalDone = innerQueue.done;
1148
- innerQueue.done = () => {
1149
- filter.flush();
1150
- outerQueue.done();
1151
- originalDone();
1152
- };
1153
- const originalError = innerQueue.error;
1154
- innerQueue.error = (e) => {
1105
+ try {
1106
+ await generateText(prompt, {
1107
+ max_new_tokens: input.maxTokens ?? 1024,
1108
+ temperature: input.temperature ?? undefined,
1109
+ return_full_text: false,
1110
+ streamer,
1111
+ stopping_criteria: [stopping_criteria],
1112
+ ...past_key_values ? { past_key_values } : {}
1113
+ });
1114
+ } finally {
1155
1115
  filter.flush();
1156
- outerQueue.error(e);
1157
- originalError(e);
1158
- };
1159
- const pipelinePromise = generateText(prompt, {
1160
- max_new_tokens: input.maxTokens ?? 1024,
1161
- temperature: input.temperature ?? undefined,
1162
- return_full_text: false,
1163
- streamer,
1164
- stopping_criteria: [stopping_criteria],
1165
- ...past_key_values ? { past_key_values } : {}
1166
- }).then(() => innerQueue.done(), (err) => innerQueue.error(err));
1167
- yield* outerQueue.iterable;
1168
- await pipelinePromise;
1116
+ }
1169
1117
  const parseableFullText = responsePrefix ? `${responsePrefix}${fullText}` : fullText;
1170
1118
  const { text: cleanedText, toolCalls } = adaptParserResult(parseToolCalls(parseableFullText, { parser: modelFamily }));
1171
1119
  const validToolCalls = filterValidToolCalls(normalizeParsedToolCalls(input, toolCalls), input.tools);
1172
1120
  if (validToolCalls.length > 0) {
1173
- yield { type: "object-delta", port: "toolCalls", objectDelta: [...validToolCalls] };
1121
+ emit({ type: "object-delta", port: "toolCalls", objectDelta: [...validToolCalls] });
1174
1122
  }
1175
- yield {
1123
+ emit({
1176
1124
  type: "finish",
1177
1125
  data: { text: cleanedText, toolCalls: validToolCalls }
1178
- };
1126
+ });
1179
1127
  };
1180
1128
 
1181
1129
  // src/ai/common/HFT_Chat.ts
1182
- async function generateTurn(input, model, sessionId, onProgress, signal, onDelta) {
1183
- const generateText = await getPipeline(model, onProgress, {}, signal);
1130
+ async function generateTurn(input, model, sessionId, emit, signal, onDelta) {
1131
+ const generateText = await getPipeline(model, emit, {}, signal);
1184
1132
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1185
1133
  const hfTokenizer = generateText.tokenizer;
1186
1134
  const hfModel = generateText.model;
@@ -1205,16 +1153,12 @@ async function generateTurn(input, model, sessionId, onProgress, signal, onDelta
1205
1153
  let accumulated = "";
1206
1154
  let streamer;
1207
1155
  if (onDelta) {
1208
- const queue = createStreamEventQueue();
1209
- streamer = createStreamingTextStreamer(hfTokenizer, queue, TextStreamer);
1210
- queue.push = (event) => {
1211
- if (event.type === "text-delta" && "textDelta" in event) {
1212
- accumulated += event.textDelta;
1213
- onDelta(event.textDelta);
1214
- }
1215
- };
1156
+ streamer = createStreamingTextStreamer(hfTokenizer, (text) => {
1157
+ accumulated += text;
1158
+ onDelta(text);
1159
+ }, TextStreamer);
1216
1160
  } else {
1217
- streamer = createTextStreamer(hfTokenizer, onProgress, TextStreamer);
1161
+ streamer = createTextStreamer(hfTokenizer, (progress, message) => emit({ type: "phase", message: message ?? "", progress }), TextStreamer);
1218
1162
  }
1219
1163
  const output = await hfModel.generate({
1220
1164
  ...inputs,
@@ -1252,112 +1196,140 @@ async function generateTurn(input, model, sessionId, onProgress, signal, onDelta
1252
1196
  }
1253
1197
  return accumulated;
1254
1198
  }
1255
- var HFT_Chat = async (input, model, update_progress, signal, _outputSchema, sessionId) => {
1256
- update_progress(0, "HFT chat turn");
1257
- const text = await generateTurn(input, model, sessionId, update_progress, signal, undefined);
1258
- update_progress(100, "Turn complete");
1259
- return { text };
1260
- };
1261
- var HFT_Chat_Stream = async function* (input, model, signal, _outputSchema, sessionId) {
1262
- const noopProgress = () => {};
1263
- const queue = [];
1264
- let done = false;
1265
- let resolver;
1266
- const task = (async () => {
1267
- try {
1268
- await generateTurn(input, model, sessionId, noopProgress, signal, (piece) => {
1269
- queue.push(piece);
1270
- resolver?.();
1271
- });
1272
- } finally {
1273
- done = true;
1274
- resolver?.();
1275
- }
1276
- })();
1277
- while (!done || queue.length > 0) {
1278
- if (queue.length === 0 && !done) {
1279
- await new Promise((res) => resolver = res);
1280
- resolver = undefined;
1281
- }
1282
- while (queue.length > 0) {
1283
- yield { type: "text-delta", port: "text", textDelta: queue.shift() };
1284
- }
1285
- }
1286
- await task;
1287
- yield { type: "finish", data: {} };
1199
+ var HFT_Chat = async (input, model, signal, emit, _outputSchema, sessionId) => {
1200
+ await generateTurn(input, model, sessionId, emit, signal, (piece) => {
1201
+ emit({ type: "text-delta", port: "text", textDelta: piece });
1202
+ });
1203
+ emit({ type: "finish", data: {} });
1288
1204
  };
1289
1205
 
1290
1206
  // src/ai/common/HFT_CountTokens.ts
1291
1207
  init_HFT_Pipeline();
1292
- var HFT_CountTokens = async (input, model, onProgress, _signal) => {
1208
+ async function countTokens(input, model) {
1293
1209
  const { AutoTokenizer } = await loadTransformersSDK();
1294
- const tokenizer = await AutoTokenizer.from_pretrained(model.provider_config.model_path, {
1295
- progress_callback: (progress) => onProgress(progress?.progress ?? 0)
1296
- });
1210
+ const tokenizer = await AutoTokenizer.from_pretrained(model.provider_config.model_path, {});
1297
1211
  const tokenIds = tokenizer.encode(input.text);
1298
1212
  return { count: tokenIds.length };
1213
+ }
1214
+ var HFT_CountTokens = async (input, model, _signal, emit) => {
1215
+ const data = await countTokens(input, model);
1216
+ emit({ type: "finish", data });
1299
1217
  };
1300
1218
  var HFT_CountTokens_Preview = async (input, model) => {
1301
- return HFT_CountTokens(input, model, () => {}, new AbortController().signal);
1219
+ return countTokens(input, model);
1302
1220
  };
1303
1221
 
1304
1222
  // src/ai/common/HFT_Download.ts
1305
1223
  init_HFT_Pipeline();
1306
- import { getLogger as getLogger2 } from "@workglow/util/worker";
1307
- var HFT_Download = async (input, model, onProgress, signal) => {
1308
- const logger = getLogger2();
1224
+ import { getLogger as getLogger3 } from "@workglow/util/worker";
1225
+ var HFT_Download = async (input, model, signal, emit) => {
1226
+ const logger = getLogger3();
1309
1227
  const timerLabel = `hft:Download:${model?.provider_config.model_path}`;
1310
1228
  logger.time(timerLabel, { model: model?.provider_config.model_path });
1311
- await getPipeline(model, onProgress, {}, signal, 100);
1229
+ await getPipeline(model, emit, {}, signal, 100);
1312
1230
  logger.timeEnd(timerLabel, { model: model?.provider_config.model_path });
1313
- return {
1314
- model: input.model
1315
- };
1231
+ emit({ type: "finish", data: { model: input.model } });
1232
+ };
1233
+
1234
+ // src/ai/common/HFT_DownloadRemove.ts
1235
+ init_HFT_Pipeline();
1236
+ function hasBrowserCacheStorage() {
1237
+ return typeof globalThis !== "undefined" && "caches" in globalThis && typeof globalThis.caches?.open === "function";
1238
+ }
1239
+ async function deleteModelCacheFromBrowser(model_path) {
1240
+ const cachesApi = globalThis.caches;
1241
+ const cache = await cachesApi.open(HTF_CACHE_NAME);
1242
+ const keys = await cache.keys();
1243
+ const prefix = `/${model_path}/`;
1244
+ const requestsToDelete = [];
1245
+ for (const request of keys) {
1246
+ const url = new URL(request.url);
1247
+ if (url.pathname.startsWith(prefix)) {
1248
+ requestsToDelete.push(request);
1249
+ }
1250
+ }
1251
+ for (const request of requestsToDelete) {
1252
+ try {
1253
+ const deleted = await cache.delete(request);
1254
+ if (!deleted) {
1255
+ const deletedByUrl = await cache.delete(request.url);
1256
+ if (!deletedByUrl) {}
1257
+ }
1258
+ } catch (error) {
1259
+ console.error(`Failed to delete cache entry: ${request.url}`, error);
1260
+ }
1261
+ }
1262
+ }
1263
+ async function deleteModelCacheFromFilesystem(model) {
1264
+ const { ModelRegistry } = await loadTransformersSDK();
1265
+ const { pipeline: pipelineType, model_path, dtype } = model.provider_config;
1266
+ await ModelRegistry.clear_pipeline_cache(pipelineType, model_path, {
1267
+ ...dtype ? { dtype } : {}
1268
+ });
1269
+ }
1270
+ var HFT_DownloadRemove = async (input, model, _signal, emit) => {
1271
+ const cacheKey = getPipelineCacheKey(model);
1272
+ await removeCachedPipeline(cacheKey);
1273
+ const model_path = model.provider_config.model_path;
1274
+ disposeHftSessionsForModel(model_path);
1275
+ if (hasBrowserCacheStorage()) {
1276
+ await deleteModelCacheFromBrowser(model_path);
1277
+ } else {
1278
+ await deleteModelCacheFromFilesystem(model);
1279
+ }
1280
+ emit({ type: "finish", data: { model: input.model } });
1316
1281
  };
1317
1282
 
1318
1283
  // src/ai/common/HFT_ImageClassification.ts
1319
1284
  init_HFT_Pipeline();
1320
1285
  import { imageValueToBlob as imageValueToBlob2 } from "@workglow/ai/provider-utils";
1321
- var HFT_ImageClassification = async (input, model, onProgress, signal) => {
1286
+ var HFT_ImageClassification = async (input, model, signal, emit) => {
1322
1287
  if (model?.provider_config?.pipeline === "zero-shot-image-classification") {
1323
1288
  if (!input.categories || !Array.isArray(input.categories) || input.categories.length === 0) {
1324
1289
  console.warn("Zero-shot image classification requires categories", input);
1325
1290
  throw new Error("Zero-shot image classification requires categories");
1326
1291
  }
1327
- const zeroShotClassifier = await getPipeline(model, onProgress, {}, signal);
1292
+ const zeroShotClassifier = await getPipeline(model, emit, {}, signal);
1328
1293
  const imageArg2 = await imageValueToBlob2(input.image);
1329
1294
  const result2 = await zeroShotClassifier(imageArg2, input.categories, {});
1330
1295
  const results2 = Array.isArray(result2) ? result2 : [result2];
1331
- return {
1332
- categories: results2.map((r) => ({
1333
- label: r.label,
1334
- score: r.score
1335
- }))
1336
- };
1296
+ emit({
1297
+ type: "finish",
1298
+ data: {
1299
+ categories: results2.map((r) => ({
1300
+ label: r.label,
1301
+ score: r.score
1302
+ }))
1303
+ }
1304
+ });
1305
+ return;
1337
1306
  }
1338
- const classifier = await getPipeline(model, onProgress, {}, signal);
1307
+ const classifier = await getPipeline(model, emit, {}, signal);
1339
1308
  const imageArg = await imageValueToBlob2(input.image);
1340
1309
  const result = await classifier(imageArg, {
1341
1310
  top_k: input.maxCategories
1342
1311
  });
1343
1312
  const results = Array.isArray(result) ? result : [result];
1344
- return {
1345
- categories: results.map((r) => ({
1346
- label: r.label,
1347
- score: r.score
1348
- }))
1349
- };
1313
+ emit({
1314
+ type: "finish",
1315
+ data: {
1316
+ categories: results.map((r) => ({
1317
+ label: r.label,
1318
+ score: r.score
1319
+ }))
1320
+ }
1321
+ });
1350
1322
  };
1351
1323
 
1352
1324
  // src/ai/common/HFT_ImageEmbedding.ts
1353
1325
  init_HFT_Pipeline();
1354
- import { getLogger as getLogger3 } from "@workglow/util/worker";
1326
+ import { getLogger as getLogger4 } from "@workglow/util/worker";
1355
1327
  import { imageValueToBlob as imageValueToBlob3 } from "@workglow/ai/provider-utils";
1356
- var HFT_ImageEmbedding = async (input, model, onProgress, signal) => {
1357
- const logger = getLogger3();
1328
+ var HFT_ImageEmbedding = async (input, model, signal, emit) => {
1329
+ const logger = getLogger4();
1358
1330
  const timerLabel = `hft:ImageEmbedding:${model?.provider_config.model_path}`;
1359
1331
  logger.time(timerLabel, { model: model?.provider_config.model_path });
1360
- const embedder = await getPipeline(model, onProgress, {}, signal);
1332
+ const embedder = await getPipeline(model, emit, {}, signal);
1361
1333
  logger.debug("HFT ImageEmbedding: pipeline ready, generating embedding", {
1362
1334
  model: model?.provider_config.model_path
1363
1335
  });
@@ -1369,21 +1341,23 @@ var HFT_ImageEmbedding = async (input, model, onProgress, signal) => {
1369
1341
  vectors.push(result2.data);
1370
1342
  }
1371
1343
  logger.timeEnd(timerLabel, { count: vectors.length });
1372
- return { vector: vectors };
1344
+ emit({ type: "finish", data: { vector: vectors } });
1345
+ return;
1373
1346
  }
1374
1347
  const imageArg = await imageValueToBlob3(input.image);
1375
1348
  const result = await embedder(imageArg);
1376
1349
  logger.timeEnd(timerLabel, { dimensions: result?.data?.length });
1377
- return {
1378
- vector: result.data
1379
- };
1350
+ emit({
1351
+ type: "finish",
1352
+ data: { vector: result.data }
1353
+ });
1380
1354
  };
1381
1355
 
1382
1356
  // src/ai/common/HFT_ImageSegmentation.ts
1383
1357
  init_HFT_Pipeline();
1384
1358
  import { imageValueToBlob as imageValueToBlob4 } from "@workglow/ai/provider-utils";
1385
- var HFT_ImageSegmentation = async (input, model, onProgress, signal) => {
1386
- const segmenter = await getPipeline(model, onProgress, {}, signal);
1359
+ var HFT_ImageSegmentation = async (input, model, signal, emit) => {
1360
+ const segmenter = await getPipeline(model, emit, {}, signal);
1387
1361
  const imageArg = await imageValueToBlob4(input.image);
1388
1362
  const result = await segmenter(imageArg, {
1389
1363
  threshold: input.threshold,
@@ -1395,30 +1369,36 @@ var HFT_ImageSegmentation = async (input, model, onProgress, signal) => {
1395
1369
  score: mask.score || 0,
1396
1370
  mask: {}
1397
1371
  })));
1398
- return {
1399
- masks: processedMasks
1400
- };
1372
+ emit({
1373
+ type: "finish",
1374
+ data: {
1375
+ masks: processedMasks
1376
+ }
1377
+ });
1401
1378
  };
1402
1379
 
1403
1380
  // src/ai/common/HFT_ImageToText.ts
1404
1381
  init_HFT_Pipeline();
1405
1382
  import { imageValueToBlob as imageValueToBlob5 } from "@workglow/ai/provider-utils";
1406
- var HFT_ImageToText = async (input, model, onProgress, signal) => {
1407
- const captioner = await getPipeline(model, onProgress, {}, signal);
1383
+ var HFT_ImageToText = async (input, model, signal, emit) => {
1384
+ const captioner = await getPipeline(model, emit, {}, signal);
1408
1385
  const imageArg = await imageValueToBlob5(input.image);
1409
1386
  const result = await captioner(imageArg, {
1410
1387
  max_new_tokens: input.maxTokens
1411
1388
  });
1412
1389
  const text = Array.isArray(result[0]) ? result[0][0]?.generated_text : result[0]?.generated_text;
1413
- return {
1414
- text: text || ""
1415
- };
1390
+ emit({
1391
+ type: "finish",
1392
+ data: {
1393
+ text: text || ""
1394
+ }
1395
+ });
1416
1396
  };
1417
1397
 
1418
1398
  // src/ai/common/HFT_ModelInfo.ts
1419
- import { getLogger as getLogger4 } from "@workglow/util/worker";
1399
+ import { getLogger as getLogger5 } from "@workglow/util/worker";
1420
1400
  init_HFT_Pipeline();
1421
- var HFT_ModelInfo = async (input, model) => {
1401
+ var HFT_ModelInfo = async (input, model, _signal, emit) => {
1422
1402
  if (input.detail === "dimensions") {
1423
1403
  if (!model)
1424
1404
  throw new Error("Model config is required for ModelInfoTask.");
@@ -1436,20 +1416,24 @@ var HFT_ModelInfo = async (input, model) => {
1436
1416
  }
1437
1417
  } catch {}
1438
1418
  }
1439
- return {
1440
- model: input.model,
1441
- is_local: true,
1442
- is_remote: false,
1443
- supports_browser: true,
1444
- supports_node: true,
1445
- is_cached: false,
1446
- is_loaded: false,
1447
- file_sizes: null,
1448
- ...native_dimensions !== undefined ? { native_dimensions } : {},
1449
- ...mrl ? { mrl } : {}
1450
- };
1419
+ emit({
1420
+ type: "finish",
1421
+ data: {
1422
+ model: input.model,
1423
+ is_local: true,
1424
+ is_remote: false,
1425
+ supports_browser: true,
1426
+ supports_node: true,
1427
+ is_cached: false,
1428
+ is_loaded: false,
1429
+ file_sizes: null,
1430
+ ...native_dimensions !== undefined ? { native_dimensions } : {},
1431
+ ...mrl ? { mrl } : {}
1432
+ }
1433
+ });
1434
+ return;
1451
1435
  }
1452
- const logger = getLogger4();
1436
+ const logger = getLogger5();
1453
1437
  const { ModelRegistry } = await loadTransformersSDK();
1454
1438
  const timerLabel = `hft:ModelInfo:${model?.provider_config.model_path}`;
1455
1439
  logger.time(timerLabel, { model: model?.provider_config.model_path });
@@ -1494,79 +1478,90 @@ var HFT_ModelInfo = async (input, model) => {
1494
1478
  }
1495
1479
  }
1496
1480
  logger.timeEnd(timerLabel, { model: model?.provider_config.model_path });
1497
- return {
1498
- model: input.model,
1499
- is_local: true,
1500
- is_remote: false,
1501
- supports_browser: true,
1502
- supports_node: true,
1503
- is_cached,
1504
- is_loaded,
1505
- file_sizes,
1506
- ...quantizations ? { quantizations } : {}
1507
- };
1508
- };
1509
-
1481
+ emit({
1482
+ type: "finish",
1483
+ data: {
1484
+ model: input.model,
1485
+ is_local: true,
1486
+ is_remote: false,
1487
+ supports_browser: true,
1488
+ supports_node: true,
1489
+ is_cached,
1490
+ is_loaded,
1491
+ file_sizes,
1492
+ ...quantizations ? { quantizations } : {}
1493
+ }
1494
+ });
1495
+ };
1496
+
1497
+ // src/ai/common/HFT_ModelSearch.ts
1498
+ import { searchHfModels, mapHfModelResult } from "@workglow/ai/provider-utils";
1499
+ var HFT_ModelSearch = async (input, _model, signal, emit) => {
1500
+ const entries = await searchHfModels(input.query?.trim() ?? "", { filter: "onnx" }, ["siblings"], signal);
1501
+ const results = entries.map((entry) => {
1502
+ const item = mapHfModelResult(entry, HF_TRANSFORMERS_ONNX);
1503
+ if (entry.siblings && entry.siblings.length > 0) {
1504
+ const filePaths = entry.siblings.map((s) => s.rfilename);
1505
+ const quantizations = parseOnnxQuantizations({ filePaths });
1506
+ if (quantizations.length > 0) {
1507
+ const record = item.record;
1508
+ const providerConfig = record.provider_config ?? {};
1509
+ providerConfig.quantizations = quantizations;
1510
+ record.provider_config = providerConfig;
1511
+ }
1512
+ }
1513
+ const raw = item.raw;
1514
+ delete raw.siblings;
1515
+ return item;
1516
+ });
1517
+ emit({ type: "finish", data: { results } });
1518
+ };
1519
+
1510
1520
  // src/ai/common/HFT_ObjectDetection.ts
1511
1521
  init_HFT_Pipeline();
1512
1522
  import { imageValueToBlob as imageValueToBlob6 } from "@workglow/ai/provider-utils";
1513
- var HFT_ObjectDetection = async (input, model, onProgress, signal) => {
1523
+ var HFT_ObjectDetection = async (input, model, signal, emit) => {
1514
1524
  if (model?.provider_config?.pipeline === "zero-shot-object-detection") {
1515
1525
  if (!input.labels || !Array.isArray(input.labels) || input.labels.length === 0) {
1516
1526
  throw new Error("Zero-shot object detection requires labels");
1517
1527
  }
1518
- const zeroShotDetector = await getPipeline(model, onProgress, {}, signal);
1528
+ const zeroShotDetector = await getPipeline(model, emit, {}, signal);
1519
1529
  const imageArg2 = await imageValueToBlob6(input.image);
1520
1530
  const result = await zeroShotDetector(imageArg2, Array.from(input.labels), {
1521
1531
  threshold: input.threshold
1522
1532
  });
1523
- return {
1524
- detections: result.map((d) => ({
1525
- label: d.label,
1526
- score: d.score,
1527
- box: d.box
1528
- }))
1529
- };
1533
+ emit({
1534
+ type: "finish",
1535
+ data: {
1536
+ detections: result.map((d) => ({
1537
+ label: d.label,
1538
+ score: d.score,
1539
+ box: d.box
1540
+ }))
1541
+ }
1542
+ });
1543
+ return;
1530
1544
  }
1531
- const detector = await getPipeline(model, onProgress, {}, signal);
1545
+ const detector = await getPipeline(model, emit, {}, signal);
1532
1546
  const imageArg = await imageValueToBlob6(input.image);
1533
1547
  const detections = await detector(imageArg, {
1534
1548
  threshold: input.threshold
1535
1549
  });
1536
- return {
1537
- detections: detections.map((d) => ({
1538
- label: d.label,
1539
- score: d.score,
1540
- box: d.box
1541
- }))
1542
- };
1550
+ emit({
1551
+ type: "finish",
1552
+ data: {
1553
+ detections: detections.map((d) => ({
1554
+ label: d.label,
1555
+ score: d.score,
1556
+ box: d.box
1557
+ }))
1558
+ }
1559
+ });
1543
1560
  };
1544
1561
 
1545
1562
  // src/ai/common/HFT_StructuredGeneration.ts
1546
1563
  init_HFT_Pipeline();
1547
1564
  import { parsePartialJson } from "@workglow/util/worker";
1548
-
1549
- // src/ai/common/HFT_TextOutput.ts
1550
- function extractGeneratedText(generatedText) {
1551
- if (generatedText == null)
1552
- return "";
1553
- if (typeof generatedText === "string")
1554
- return generatedText;
1555
- const lastMessage = generatedText[generatedText.length - 1];
1556
- if (!lastMessage)
1557
- return "";
1558
- const content = lastMessage.content;
1559
- if (typeof content === "string")
1560
- return content;
1561
- for (const part of content) {
1562
- if (part.type === "text" && "text" in part) {
1563
- return part.text;
1564
- }
1565
- }
1566
- return "";
1567
- }
1568
-
1569
- // src/ai/common/HFT_StructuredGeneration.ts
1570
1565
  function buildStructuredGenerationPrompt(input) {
1571
1566
  const schemaStr = JSON.stringify(input.outputSchema, null, 2);
1572
1567
  return `${input.prompt}
@@ -1595,37 +1590,8 @@ function extractJsonFromText(text) {
1595
1590
  return {};
1596
1591
  }
1597
1592
  }
1598
- var HFT_StructuredGeneration = async (input, model, onProgress, signal) => {
1599
- const generateText = await getPipeline(model, onProgress, {}, signal);
1600
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1601
- const prompt = buildStructuredGenerationPrompt(input);
1602
- const messages = [{ role: "user", content: prompt }];
1603
- const formattedPrompt = generateText.tokenizer.apply_chat_template(messages, {
1604
- tokenize: false,
1605
- add_generation_prompt: true
1606
- });
1607
- const streamer = createTextStreamer(generateText.tokenizer, onProgress, TextStreamer);
1608
- const stopping_criteria = new InterruptableStoppingCriteria;
1609
- if (signal) {
1610
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1611
- }
1612
- let results = await generateText(formattedPrompt, {
1613
- max_new_tokens: input.maxTokens ?? 1024,
1614
- temperature: input.temperature ?? undefined,
1615
- return_full_text: false,
1616
- streamer,
1617
- stopping_criteria: [stopping_criteria]
1618
- });
1619
- if (!Array.isArray(results)) {
1620
- results = [results];
1621
- }
1622
- const responseText = extractGeneratedText(results[0]?.generated_text).trim();
1623
- const object = extractJsonFromText(responseText);
1624
- return { object };
1625
- };
1626
- var HFT_StructuredGeneration_Stream = async function* (input, model, signal) {
1627
- const noopProgress = () => {};
1628
- const generateText = await getPipeline(model, noopProgress, {}, signal);
1593
+ var HFT_StructuredGeneration = async (input, model, signal, emit) => {
1594
+ const generateText = await getPipeline(model, emit, {}, signal);
1629
1595
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1630
1596
  const prompt = buildStructuredGenerationPrompt(input);
1631
1597
  const messages = [{ role: "user", content: prompt }];
@@ -1633,110 +1599,105 @@ var HFT_StructuredGeneration_Stream = async function* (input, model, signal) {
1633
1599
  tokenize: false,
1634
1600
  add_generation_prompt: true
1635
1601
  });
1636
- const queue = createStreamEventQueue();
1637
- const streamer = createStreamingTextStreamer(generateText.tokenizer, queue, TextStreamer);
1638
- const stopping_criteria = new InterruptableStoppingCriteria;
1639
- if (signal) {
1640
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1641
- }
1642
1602
  let fullText = "";
1643
1603
  let cleanedText = "";
1644
1604
  let inThinkBlock = false;
1645
1605
  let jsonStart = -1;
1646
- const originalPush = queue.push;
1647
- queue.push = (event) => {
1648
- if (event.type === "text-delta" && "textDelta" in event) {
1649
- const delta = event.textDelta;
1650
- fullText += delta;
1651
- let remaining = delta;
1652
- while (remaining.length > 0) {
1653
- if (inThinkBlock) {
1654
- const closeIdx = remaining.indexOf("</think>");
1655
- if (closeIdx !== -1) {
1656
- inThinkBlock = false;
1657
- remaining = remaining.slice(closeIdx + "</think>".length);
1658
- } else {
1659
- remaining = "";
1660
- }
1606
+ const streamer = createStreamingTextStreamer(generateText.tokenizer, (delta) => {
1607
+ fullText += delta;
1608
+ let remaining = delta;
1609
+ while (remaining.length > 0) {
1610
+ if (inThinkBlock) {
1611
+ const closeIdx = remaining.indexOf("</think>");
1612
+ if (closeIdx !== -1) {
1613
+ inThinkBlock = false;
1614
+ remaining = remaining.slice(closeIdx + "</think>".length);
1661
1615
  } else {
1662
- const openIdx = remaining.indexOf("<think>");
1663
- if (openIdx !== -1) {
1664
- cleanedText += remaining.slice(0, openIdx).replace(/<\|[a-z_]+\|>/g, "");
1665
- inThinkBlock = true;
1666
- remaining = remaining.slice(openIdx + "<think>".length);
1667
- } else {
1668
- cleanedText += remaining.replace(/<\|[a-z_]+\|>/g, "");
1669
- remaining = "";
1670
- }
1616
+ remaining = "";
1671
1617
  }
1672
- }
1673
- if (jsonStart === -1) {
1674
- jsonStart = cleanedText.indexOf("{");
1675
- }
1676
- if (jsonStart !== -1) {
1677
- const partial = parsePartialJson(cleanedText.slice(jsonStart));
1678
- if (partial !== undefined) {
1679
- originalPush({
1680
- type: "object-delta",
1681
- port: "object",
1682
- objectDelta: partial
1683
- });
1684
- return;
1618
+ } else {
1619
+ const openIdx = remaining.indexOf("<think>");
1620
+ if (openIdx !== -1) {
1621
+ cleanedText += remaining.slice(0, openIdx).replace(/<\|[a-z_]+\|>/g, "");
1622
+ inThinkBlock = true;
1623
+ remaining = remaining.slice(openIdx + "<think>".length);
1624
+ } else {
1625
+ cleanedText += remaining.replace(/<\|[a-z_]+\|>/g, "");
1626
+ remaining = "";
1685
1627
  }
1686
1628
  }
1687
1629
  }
1688
- originalPush(event);
1689
- };
1690
- const pipelinePromise = generateText(formattedPrompt, {
1630
+ if (jsonStart === -1) {
1631
+ jsonStart = cleanedText.indexOf("{");
1632
+ }
1633
+ if (jsonStart !== -1) {
1634
+ const partial = parsePartialJson(cleanedText.slice(jsonStart));
1635
+ if (partial !== undefined) {
1636
+ emit({ type: "object-delta", port: "object", objectDelta: partial });
1637
+ return;
1638
+ }
1639
+ }
1640
+ emit({ type: "text-delta", port: "text", textDelta: delta });
1641
+ }, TextStreamer);
1642
+ const stopping_criteria = new InterruptableStoppingCriteria;
1643
+ if (signal) {
1644
+ signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1645
+ }
1646
+ await generateText(formattedPrompt, {
1691
1647
  max_new_tokens: input.maxTokens ?? 1024,
1692
1648
  temperature: input.temperature ?? undefined,
1693
1649
  return_full_text: false,
1694
1650
  streamer,
1695
1651
  stopping_criteria: [stopping_criteria]
1696
- }).then(() => queue.done(), (err) => queue.error(err));
1697
- yield* queue.iterable;
1698
- await pipelinePromise;
1652
+ });
1699
1653
  const object = extractJsonFromText(fullText);
1700
- yield { type: "finish", data: { object } };
1654
+ emit({ type: "finish", data: { object } });
1701
1655
  };
1702
1656
 
1703
1657
  // src/ai/common/HFT_TextClassification.ts
1704
1658
  init_HFT_Pipeline();
1705
- var HFT_TextClassification = async (input, model, onProgress, signal) => {
1659
+ var HFT_TextClassification = async (input, model, signal, emit) => {
1706
1660
  if (model?.provider_config?.pipeline === "zero-shot-classification") {
1707
1661
  if (!input.candidateLabels || !Array.isArray(input.candidateLabels) || input.candidateLabels.length === 0) {
1708
1662
  throw new Error("Zero-shot text classification requires candidate labels");
1709
1663
  }
1710
- const zeroShotClassifier = await getPipeline(model, onProgress, {}, signal);
1664
+ const zeroShotClassifier = await getPipeline(model, emit, {}, signal);
1711
1665
  const result2 = await zeroShotClassifier(input.text, input.candidateLabels, {});
1712
- return {
1713
- categories: result2.labels.map((label, idx) => ({
1714
- label,
1715
- score: result2.scores[idx]
1716
- }))
1717
- };
1666
+ emit({
1667
+ type: "finish",
1668
+ data: {
1669
+ categories: result2.labels.map((label, idx) => ({
1670
+ label,
1671
+ score: result2.scores[idx]
1672
+ }))
1673
+ }
1674
+ });
1675
+ return;
1718
1676
  }
1719
- const TextClassification = await getPipeline(model, onProgress, {}, signal);
1677
+ const TextClassification = await getPipeline(model, emit, {}, signal);
1720
1678
  const result = await TextClassification(input.text, {
1721
1679
  top_k: input.maxCategories || undefined
1722
1680
  });
1723
- return {
1724
- categories: result.map((category) => ({
1725
- label: category.label,
1726
- score: category.score
1727
- }))
1728
- };
1681
+ emit({
1682
+ type: "finish",
1683
+ data: {
1684
+ categories: result.map((category) => ({
1685
+ label: category.label,
1686
+ score: category.score
1687
+ }))
1688
+ }
1689
+ });
1729
1690
  };
1730
1691
 
1731
1692
  // src/ai/common/HFT_TextEmbedding.ts
1732
1693
  init_HFT_Pipeline();
1733
- import { getLogger as getLogger5 } from "@workglow/util/worker";
1734
- var HFT_TextEmbedding = async (input, model, onProgress, signal) => {
1735
- const logger = getLogger5();
1694
+ import { getLogger as getLogger6 } from "@workglow/util/worker";
1695
+ var HFT_TextEmbedding = async (input, model, signal, emit) => {
1696
+ const logger = getLogger6();
1736
1697
  const uuid = crypto.randomUUID();
1737
1698
  const timerLabel = `hft:TextEmbedding:${model?.provider_config.model_path}:${uuid}`;
1738
1699
  logger.time(timerLabel, { model: model?.provider_config.model_path });
1739
- const generateEmbedding = await getPipeline(model, onProgress, {}, signal);
1700
+ const generateEmbedding = await getPipeline(model, emit, {}, signal);
1740
1701
  logger.debug("HFT TextEmbedding: pipeline ready, generating embedding", {
1741
1702
  model: model?.provider_config.model_path,
1742
1703
  inputLength: Array.isArray(input.text) ? input.text.length : input.text?.length
@@ -1757,7 +1718,8 @@ var HFT_TextEmbedding = async (input, model, onProgress, signal) => {
1757
1718
  }
1758
1719
  const vectors = Array.from({ length: numTexts }, (_, i) => hfVector[i].data.slice());
1759
1720
  logger.timeEnd(timerLabel, { batchSize: numTexts, dimensions: vectorDim });
1760
- return { vector: vectors };
1721
+ emit({ type: "finish", data: { vector: vectors } });
1722
+ return;
1761
1723
  }
1762
1724
  if (hfVector.size !== embeddingDim) {
1763
1725
  logger.timeEnd(timerLabel, { status: "error", reason: "dimension mismatch" });
@@ -1765,38 +1727,32 @@ var HFT_TextEmbedding = async (input, model, onProgress, signal) => {
1765
1727
  throw new Error(`HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${embeddingDim}`);
1766
1728
  }
1767
1729
  logger.timeEnd(timerLabel, { dimensions: hfVector.size });
1768
- return { vector: hfVector.data };
1730
+ emit({ type: "finish", data: { vector: hfVector.data } });
1769
1731
  };
1770
1732
 
1771
1733
  // src/ai/common/HFT_TextFillMask.ts
1772
1734
  init_HFT_Pipeline();
1773
- var HFT_TextFillMask = async (input, model, onProgress, signal) => {
1774
- const unmasker = await getPipeline(model, onProgress, {}, signal);
1735
+ var HFT_TextFillMask = async (input, model, signal, emit) => {
1736
+ const unmasker = await getPipeline(model, emit, {}, signal);
1775
1737
  const predictions = await unmasker(input.text);
1776
- return {
1777
- predictions: predictions.map((prediction) => ({
1778
- entity: prediction.token_str,
1779
- score: prediction.score,
1780
- sequence: prediction.sequence
1781
- }))
1782
- };
1738
+ emit({
1739
+ type: "finish",
1740
+ data: {
1741
+ predictions: predictions.map((prediction) => ({
1742
+ entity: prediction.token_str,
1743
+ score: prediction.score,
1744
+ sequence: prediction.sequence
1745
+ }))
1746
+ }
1747
+ });
1783
1748
  };
1784
1749
 
1785
1750
  // src/ai/common/HFT_TextGeneration.ts
1786
1751
  init_HFT_Pipeline();
1787
- import { getLogger as getLogger6 } from "@workglow/util/worker";
1788
- var HFT_TextGeneration = async (input, model, onProgress, signal, _outputSchema, sessionId) => {
1789
- signal?.throwIfAborted?.();
1790
- const logger = getLogger6();
1791
- const timerLabel = `hft:TextGeneration:${model?.provider_config.model_path}`;
1792
- logger.time(timerLabel, { model: model?.provider_config.model_path });
1793
- const generateText = await getPipeline(model, onProgress, {}, signal);
1752
+ var HFT_TextGeneration = async (input, model, signal, emit, _outputSchema, sessionId) => {
1753
+ const generateText = await getPipeline(model, emit, {}, signal);
1794
1754
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1795
- logger.debug("HFT TextGeneration: pipeline ready, generating text", {
1796
- model: model?.provider_config.model_path,
1797
- promptLength: input.prompt?.length
1798
- });
1799
- const streamer = createTextStreamer(generateText.tokenizer, onProgress, TextStreamer);
1755
+ const streamer = createStreamingTextStreamer(generateText.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
1800
1756
  const stopping_criteria = new InterruptableStoppingCriteria;
1801
1757
  if (signal) {
1802
1758
  signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
@@ -1819,366 +1775,161 @@ var HFT_TextGeneration = async (input, model, onProgress, signal, _outputSchema,
1819
1775
  past_key_values = session.cache;
1820
1776
  }
1821
1777
  const messages = [{ role: "user", content: input.prompt }];
1822
- let results = await generateText(messages, {
1778
+ await generateText(messages, {
1823
1779
  streamer,
1824
1780
  do_sample: false,
1825
1781
  max_new_tokens: input.maxTokens ?? 4 * 1024,
1826
1782
  stopping_criteria: [stopping_criteria],
1827
1783
  ...past_key_values ? { past_key_values } : {}
1828
1784
  });
1829
- if (!Array.isArray(results)) {
1830
- results = [results];
1831
- }
1832
- const text = extractGeneratedText(results[0]?.generated_text);
1833
- logger.timeEnd(timerLabel, { outputLength: text?.length });
1834
- return {
1835
- text
1836
- };
1837
- };
1838
- var HFT_TextGeneration_Stream = async function* (input, model, signal, _outputSchema, sessionId) {
1839
- const noopProgress = () => {};
1840
- const generateText = await getPipeline(model, noopProgress, {}, signal);
1841
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1842
- const queue = createStreamEventQueue();
1843
- const streamer = createStreamingTextStreamer(generateText.tokenizer, queue, TextStreamer);
1844
- const stopping_criteria = new InterruptableStoppingCriteria;
1845
- if (signal) {
1846
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1847
- }
1848
- const modelPath = model.provider_config.model_path;
1849
- let session = sessionId ? getHftSession(sessionId) : undefined;
1850
- let past_key_values = undefined;
1851
- if (sessionId && !session) {
1852
- const sdk = await loadTransformersSDK();
1853
- const cache = new sdk.DynamicCache;
1854
- const newSession = {
1855
- mode: "progressive",
1856
- cache,
1857
- modelPath
1858
- };
1859
- setHftSession(sessionId, newSession);
1860
- session = newSession;
1861
- }
1862
- if (session?.mode === "progressive") {
1863
- past_key_values = session.cache;
1864
- }
1865
- const messages = [{ role: "user", content: input.prompt }];
1866
- const pipelinePromise = generateText(messages, {
1867
- streamer,
1868
- do_sample: false,
1869
- max_new_tokens: input.maxTokens ?? 4 * 1024,
1870
- stopping_criteria: [stopping_criteria],
1871
- ...past_key_values ? { past_key_values } : {}
1872
- }).then(() => queue.done(), (err) => queue.error(err));
1873
- yield* queue.iterable;
1874
- await pipelinePromise;
1875
- yield { type: "finish", data: {} };
1785
+ emit({ type: "finish", data: {} });
1876
1786
  };
1877
1787
 
1878
1788
  // src/ai/common/HFT_TextLanguageDetection.ts
1879
1789
  init_HFT_Pipeline();
1880
- var HFT_TextLanguageDetection = async (input, model, onProgress, signal) => {
1881
- const TextClassification = await getPipeline(model, onProgress, {}, signal);
1790
+ var HFT_TextLanguageDetection = async (input, model, signal, emit) => {
1791
+ const TextClassification = await getPipeline(model, emit, {}, signal);
1882
1792
  const result = await TextClassification(input.text, {
1883
1793
  top_k: input.maxLanguages || undefined
1884
1794
  });
1885
- return {
1886
- languages: result.map((category) => ({
1887
- language: category.label,
1888
- score: category.score
1889
- }))
1890
- };
1795
+ emit({
1796
+ type: "finish",
1797
+ data: {
1798
+ languages: result.map((category) => ({
1799
+ language: category.label,
1800
+ score: category.score
1801
+ }))
1802
+ }
1803
+ });
1891
1804
  };
1892
1805
 
1893
1806
  // src/ai/common/HFT_TextNamedEntityRecognition.ts
1894
1807
  init_HFT_Pipeline();
1895
- var HFT_TextNamedEntityRecognition = async (input, model, onProgress, signal) => {
1896
- const textNamedEntityRecognition = await getPipeline(model, onProgress, {}, signal);
1808
+ var HFT_TextNamedEntityRecognition = async (input, model, signal, emit) => {
1809
+ const textNamedEntityRecognition = await getPipeline(model, emit, {}, signal);
1897
1810
  const results = await textNamedEntityRecognition(input.text, {
1898
1811
  ignore_labels: input.blockList
1899
1812
  });
1900
- return {
1901
- entities: results.map((entity) => ({
1902
- entity: entity.entity,
1903
- score: entity.score,
1904
- word: entity.word
1905
- }))
1906
- };
1813
+ emit({
1814
+ type: "finish",
1815
+ data: {
1816
+ entities: results.map((entity) => ({
1817
+ entity: entity.entity,
1818
+ score: entity.score,
1819
+ word: entity.word
1820
+ }))
1821
+ }
1822
+ });
1907
1823
  };
1908
1824
 
1909
1825
  // src/ai/common/HFT_TextQuestionAnswer.ts
1910
1826
  init_HFT_Pipeline();
1911
- var HFT_TextQuestionAnswer = async (input, model, onProgress, signal) => {
1912
- const generateAnswer = await getPipeline(model, onProgress, {}, signal);
1827
+ var HFT_TextQuestionAnswer = async (input, model, signal, emit) => {
1828
+ const generateAnswer = await getPipeline(model, emit, {}, signal);
1913
1829
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1914
- const streamer = createTextStreamer(generateAnswer.tokenizer, onProgress, TextStreamer);
1830
+ const streamer = createStreamingTextStreamer(generateAnswer.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
1915
1831
  const stopping_criteria = new InterruptableStoppingCriteria;
1916
1832
  if (signal) {
1917
1833
  signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1918
1834
  }
1919
- const result = await generateAnswer(input.question, input.context, {
1835
+ const pipelineResult = await generateAnswer(input.question, input.context, {
1920
1836
  streamer,
1921
1837
  stopping_criteria: [stopping_criteria]
1922
1838
  });
1923
- const answerText = result?.answer || "";
1924
- return { text: answerText };
1925
- };
1926
- var HFT_TextQuestionAnswer_Stream = async function* (input, model, signal) {
1927
- const noopProgress = () => {};
1928
- const generateAnswer = await getPipeline(model, noopProgress, {}, signal);
1929
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1930
- const queue = createStreamEventQueue();
1931
- const streamer = createStreamingTextStreamer(generateAnswer.tokenizer, queue, TextStreamer);
1932
- const stopping_criteria = new InterruptableStoppingCriteria;
1933
- if (signal) {
1934
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1935
- }
1936
- let pipelineResult;
1937
- const pipelinePromise = generateAnswer(input.question, input.context, {
1938
- streamer,
1939
- stopping_criteria: [stopping_criteria]
1940
- }).then((result) => {
1941
- pipelineResult = result;
1942
- queue.done();
1943
- }, (err) => queue.error(err));
1944
- yield* queue.iterable;
1945
- await pipelinePromise;
1946
- let answerText = "";
1947
- if (pipelineResult !== undefined) {
1948
- if (Array.isArray(pipelineResult)) {
1949
- answerText = pipelineResult[0]?.answer ?? "";
1950
- } else {
1951
- answerText = pipelineResult?.answer ?? "";
1952
- }
1953
- }
1954
- yield { type: "finish", data: { text: answerText } };
1839
+ const answerText = Array.isArray(pipelineResult) ? pipelineResult[0]?.answer ?? "" : pipelineResult?.answer ?? "";
1840
+ emit({ type: "finish", data: { text: answerText } });
1955
1841
  };
1956
1842
 
1957
1843
  // src/ai/common/HFT_TextRewriter.ts
1958
1844
  init_HFT_Pipeline();
1959
- var HFT_TextRewriter = async (input, model, onProgress, signal) => {
1960
- const generateText = await getPipeline(model, onProgress, {}, signal);
1845
+ var HFT_TextRewriter = async (input, model, signal, emit) => {
1846
+ const generateText = await getPipeline(model, emit, {}, signal);
1961
1847
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1962
- const streamer = createTextStreamer(generateText.tokenizer, onProgress, TextStreamer);
1848
+ const streamer = createStreamingTextStreamer(generateText.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
1963
1849
  const stopping_criteria = new InterruptableStoppingCriteria;
1964
1850
  if (signal) {
1965
1851
  signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1966
1852
  }
1967
1853
  const promptedText = (input.prompt ? input.prompt + `
1968
1854
  ` : "") + input.text;
1969
- let results = await generateText(promptedText, {
1855
+ await generateText(promptedText, {
1970
1856
  streamer,
1971
1857
  stopping_criteria: [stopping_criteria]
1972
1858
  });
1973
- if (!Array.isArray(results)) {
1974
- results = [results];
1975
- }
1976
- const text = extractGeneratedText(results[0]?.generated_text);
1977
- if (text === promptedText) {
1978
- throw new Error("Rewriter failed to generate new text");
1979
- }
1980
- return {
1981
- text
1982
- };
1983
- };
1984
- var HFT_TextRewriter_Stream = async function* (input, model, signal) {
1985
- const noopProgress = () => {};
1986
- const generateText = await getPipeline(model, noopProgress, {}, signal);
1987
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
1988
- const queue = createStreamEventQueue();
1989
- const streamer = createStreamingTextStreamer(generateText.tokenizer, queue, TextStreamer);
1990
- const stopping_criteria = new InterruptableStoppingCriteria;
1991
- if (signal) {
1992
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
1993
- }
1994
- const promptedText = (input.prompt ? input.prompt + `
1995
- ` : "") + input.text;
1996
- const pipelinePromise = generateText(promptedText, {
1997
- streamer,
1998
- stopping_criteria: [stopping_criteria]
1999
- }).then(() => queue.done(), (err) => queue.error(err));
2000
- yield* queue.iterable;
2001
- await pipelinePromise;
2002
- yield { type: "finish", data: {} };
1859
+ emit({ type: "finish", data: {} });
2003
1860
  };
2004
1861
 
2005
1862
  // src/ai/common/HFT_TextSummary.ts
2006
1863
  init_HFT_Pipeline();
2007
- var HFT_TextSummary = async (input, model, onProgress, signal) => {
2008
- const generateSummary = await getPipeline(model, onProgress, {}, signal);
1864
+ var HFT_TextSummary = async (input, model, signal, emit) => {
1865
+ const generateSummary = await getPipeline(model, emit, {}, signal);
2009
1866
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
2010
- const streamer = createTextStreamer(generateSummary.tokenizer, onProgress, TextStreamer);
1867
+ const streamer = createStreamingTextStreamer(generateSummary.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
2011
1868
  const stopping_criteria = new InterruptableStoppingCriteria;
2012
1869
  if (signal) {
2013
1870
  signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
2014
1871
  }
2015
- const result = await generateSummary(input.text, {
1872
+ await generateSummary(input.text, {
2016
1873
  streamer,
2017
1874
  stopping_criteria: [stopping_criteria]
2018
1875
  });
2019
- let summaryText = "";
2020
- if (Array.isArray(result)) {
2021
- summaryText = result[0]?.summary_text || "";
2022
- } else {
2023
- summaryText = result?.summary_text || "";
2024
- }
2025
- return {
2026
- text: summaryText
2027
- };
2028
- };
2029
- var HFT_TextSummary_Stream = async function* (input, model, signal) {
2030
- const noopProgress = () => {};
2031
- const generateSummary = await getPipeline(model, noopProgress, {}, signal);
2032
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
2033
- const queue = createStreamEventQueue();
2034
- const streamer = createStreamingTextStreamer(generateSummary.tokenizer, queue, TextStreamer);
2035
- const stopping_criteria = new InterruptableStoppingCriteria;
2036
- if (signal) {
2037
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
2038
- }
2039
- const pipelinePromise = generateSummary(input.text, {
2040
- streamer,
2041
- stopping_criteria: [stopping_criteria]
2042
- }).then(() => queue.done(), (err) => queue.error(err));
2043
- yield* queue.iterable;
2044
- await pipelinePromise;
2045
- yield { type: "finish", data: {} };
1876
+ emit({ type: "finish", data: {} });
2046
1877
  };
2047
1878
 
2048
1879
  // src/ai/common/HFT_TextTranslation.ts
2049
1880
  init_HFT_Pipeline();
2050
- var HFT_TextTranslation = async (input, model, onProgress, signal) => {
2051
- const translate = await getPipeline(model, onProgress, {}, signal);
1881
+ var HFT_TextTranslation = async (input, model, signal, emit) => {
1882
+ const translate = await getPipeline(model, emit, {}, signal);
2052
1883
  const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
2053
- const streamer = createTextStreamer(translate.tokenizer, onProgress, TextStreamer);
1884
+ const streamer = createStreamingTextStreamer(translate.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
2054
1885
  const stopping_criteria = new InterruptableStoppingCriteria;
2055
1886
  if (signal) {
2056
1887
  signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
2057
1888
  }
2058
- const result = await translate(input.text, {
1889
+ await translate(input.text, {
2059
1890
  src_lang: input.source_lang,
2060
1891
  tgt_lang: input.target_lang,
2061
1892
  streamer,
2062
1893
  stopping_criteria: [stopping_criteria]
2063
1894
  });
2064
- const translatedText = Array.isArray(result) ? result[0]?.translation_text || "" : result?.translation_text || "";
2065
- return {
2066
- text: translatedText,
2067
- target_lang: input.target_lang
2068
- };
2069
- };
2070
- var HFT_TextTranslation_Stream = async function* (input, model, signal) {
2071
- const noopProgress = () => {};
2072
- const translate = await getPipeline(model, noopProgress, {}, signal);
2073
- const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
2074
- const queue = createStreamEventQueue();
2075
- const streamer = createStreamingTextStreamer(translate.tokenizer, queue, TextStreamer);
2076
- const stopping_criteria = new InterruptableStoppingCriteria;
2077
- if (signal) {
2078
- signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
2079
- }
2080
- const pipelinePromise = translate(input.text, {
2081
- src_lang: input.source_lang,
2082
- tgt_lang: input.target_lang,
2083
- streamer,
2084
- stopping_criteria: [stopping_criteria]
2085
- }).then(() => queue.done(), (err) => queue.error(err));
2086
- yield* queue.iterable;
2087
- await pipelinePromise;
2088
- yield { type: "finish", data: { target_lang: input.target_lang } };
1895
+ emit({ type: "finish", data: { target_lang: input.target_lang } });
2089
1896
  };
2090
1897
 
2091
- // src/ai/common/HFT_Unload.ts
2092
- init_HFT_Pipeline();
2093
- function hasBrowserCacheStorage() {
2094
- return typeof globalThis !== "undefined" && "caches" in globalThis && typeof globalThis.caches?.open === "function";
2095
- }
2096
- async function deleteModelCacheFromBrowser(model_path) {
2097
- const cachesApi = globalThis.caches;
2098
- const cache = await cachesApi.open(HTF_CACHE_NAME);
2099
- const keys = await cache.keys();
2100
- const prefix = `/${model_path}/`;
2101
- const requestsToDelete = [];
2102
- for (const request of keys) {
2103
- const url = new URL(request.url);
2104
- if (url.pathname.startsWith(prefix)) {
2105
- requestsToDelete.push(request);
2106
- }
2107
- }
2108
- for (const request of requestsToDelete) {
2109
- try {
2110
- const deleted = await cache.delete(request);
2111
- if (!deleted) {
2112
- const deletedByUrl = await cache.delete(request.url);
2113
- if (!deletedByUrl) {}
2114
- }
2115
- } catch (error) {
2116
- console.error(`Failed to delete cache entry: ${request.url}`, error);
2117
- }
2118
- }
2119
- }
2120
- async function deleteModelCacheFromFilesystem(model) {
2121
- const { ModelRegistry } = await loadTransformersSDK();
2122
- const { pipeline: pipelineType, model_path, dtype } = model.provider_config;
2123
- await ModelRegistry.clear_pipeline_cache(pipelineType, model_path, {
2124
- ...dtype ? { dtype } : {}
2125
- });
2126
- }
2127
- var HFT_Unload = async (input, model, onProgress, _signal) => {
2128
- const cacheKey = getPipelineCacheKey(model);
2129
- if (removeCachedPipeline(cacheKey)) {
2130
- onProgress(50, "Pipeline removed from memory");
2131
- }
2132
- const model_path = model.provider_config.model_path;
2133
- disposeHftSessionsForModel(model_path);
2134
- if (hasBrowserCacheStorage()) {
2135
- await deleteModelCacheFromBrowser(model_path);
1898
+ // src/ai/common/HFT_JobRunFns.ts
1899
+ var HFT_TextGeneration_Unified = async (input, model, signal, emit, outputSchema, sessionId) => {
1900
+ const maybeMessages = input.messages;
1901
+ if (Array.isArray(maybeMessages) && maybeMessages.length > 0) {
1902
+ await HFT_Chat(input, model, signal, emit, outputSchema, sessionId);
2136
1903
  } else {
2137
- await deleteModelCacheFromFilesystem(model);
1904
+ await HFT_TextGeneration(input, model, signal, emit, outputSchema, sessionId);
2138
1905
  }
2139
- onProgress(100, "Model cache deleted");
2140
- return {
2141
- model: input.model
2142
- };
2143
- };
2144
-
2145
- // src/ai/common/HFT_JobRunFns.ts
2146
- var HFT_TASKS = {
2147
- AiChatTask: HFT_Chat,
2148
- DownloadModelTask: HFT_Download,
2149
- UnloadModelTask: HFT_Unload,
2150
- ModelInfoTask: HFT_ModelInfo,
2151
- CountTokensTask: HFT_CountTokens,
2152
- TextEmbeddingTask: HFT_TextEmbedding,
2153
- TextGenerationTask: HFT_TextGeneration,
2154
- TextQuestionAnswerTask: HFT_TextQuestionAnswer,
2155
- TextLanguageDetectionTask: HFT_TextLanguageDetection,
2156
- TextClassificationTask: HFT_TextClassification,
2157
- TextFillMaskTask: HFT_TextFillMask,
2158
- TextNamedEntityRecognitionTask: HFT_TextNamedEntityRecognition,
2159
- TextRewriterTask: HFT_TextRewriter,
2160
- TextSummaryTask: HFT_TextSummary,
2161
- TextTranslationTask: HFT_TextTranslation,
2162
- ImageSegmentationTask: HFT_ImageSegmentation,
2163
- ImageToTextTask: HFT_ImageToText,
2164
- BackgroundRemovalTask: HFT_BackgroundRemoval,
2165
- ImageEmbeddingTask: HFT_ImageEmbedding,
2166
- ImageClassificationTask: HFT_ImageClassification,
2167
- ObjectDetectionTask: HFT_ObjectDetection,
2168
- ToolCallingTask: HFT_ToolCalling,
2169
- StructuredGenerationTask: HFT_StructuredGeneration,
2170
- ModelSearchTask: HFT_ModelSearch
2171
- };
2172
- var HFT_STREAM_TASKS = {
2173
- AiChatTask: HFT_Chat_Stream,
2174
- TextGenerationTask: HFT_TextGeneration_Stream,
2175
- TextRewriterTask: HFT_TextRewriter_Stream,
2176
- TextSummaryTask: HFT_TextSummary_Stream,
2177
- TextQuestionAnswerTask: HFT_TextQuestionAnswer_Stream,
2178
- TextTranslationTask: HFT_TextTranslation_Stream,
2179
- ToolCallingTask: HFT_ToolCalling_Stream,
2180
- StructuredGenerationTask: HFT_StructuredGeneration_Stream
2181
1906
  };
1907
+ var HFT_RUN_FNS = [
1908
+ { serves: HFT_TEXT_GENERATION, runFn: HFT_TextGeneration_Unified },
1909
+ { serves: HFT_TOOL_USE, runFn: HFT_ToolCalling },
1910
+ { serves: HFT_JSON_MODE, runFn: HFT_StructuredGeneration },
1911
+ { serves: HFT_TEXT_REWRITER, runFn: HFT_TextRewriter },
1912
+ { serves: HFT_TEXT_SUMMARY, runFn: HFT_TextSummary },
1913
+ { serves: HFT_TEXT_TRANSLATION, runFn: HFT_TextTranslation },
1914
+ { serves: HFT_TEXT_QUESTION_ANSWERING, runFn: HFT_TextQuestionAnswer },
1915
+ { serves: HFT_TEXT_EMBEDDING, runFn: HFT_TextEmbedding },
1916
+ { serves: HFT_TEXT_CLASSIFICATION, runFn: HFT_TextClassification },
1917
+ { serves: HFT_TEXT_LANGUAGE_DETECTION, runFn: HFT_TextLanguageDetection },
1918
+ { serves: HFT_TEXT_RERANKING, runFn: HFT_TextReranker },
1919
+ { serves: HFT_TEXT_FILL_MASK, runFn: HFT_TextFillMask },
1920
+ { serves: HFT_TEXT_NER, runFn: HFT_TextNamedEntityRecognition },
1921
+ { serves: HFT_IMAGE_CLASSIFICATION, runFn: HFT_ImageClassification },
1922
+ { serves: HFT_IMAGE_EMBEDDING, runFn: HFT_ImageEmbedding },
1923
+ { serves: HFT_IMAGE_SEGMENTATION, runFn: HFT_ImageSegmentation },
1924
+ { serves: HFT_IMAGE_TO_TEXT, runFn: HFT_ImageToText },
1925
+ { serves: HFT_IMAGE_BACKGROUND_REMOVAL, runFn: HFT_BackgroundRemoval },
1926
+ { serves: HFT_IMAGE_OBJECT_DETECTION, runFn: HFT_ObjectDetection },
1927
+ { serves: HFT_COUNT_TOKENS, runFn: HFT_CountTokens },
1928
+ { serves: HFT_MODEL_DOWNLOAD_REMOVE, runFn: HFT_DownloadRemove },
1929
+ { serves: HFT_MODEL_DOWNLOAD, runFn: HFT_Download },
1930
+ { serves: HFT_MODEL_SEARCH, runFn: HFT_ModelSearch },
1931
+ { serves: HFT_MODEL_INFO, runFn: HFT_ModelInfo }
1932
+ ];
2182
1933
  var HFT_PREVIEW_TASKS = {
2183
1934
  CountTokensTask: HFT_CountTokens_Preview
2184
1935
  };
@@ -2188,6 +1939,100 @@ init_HFT_Pipeline();
2188
1939
 
2189
1940
  // src/ai/HuggingFaceTransformersQueuedProvider.ts
2190
1941
  import { QueuedAiProvider } from "@workglow/ai";
1942
+
1943
+ // src/ai/common/HFT_Capabilities.ts
1944
+ var HFT_RUN_FN_SPECS = HFT_CAPABILITY_SETS.map((serves) => ({ serves }));
1945
+ function hftWorkerRunFnSpecs() {
1946
+ return HFT_RUN_FN_SPECS;
1947
+ }
1948
+ function inferHftCapabilities(model) {
1949
+ const declared = model.capabilities ?? [];
1950
+ if (declared.length > 0)
1951
+ return declared;
1952
+ const id = String(model.model_id ?? model.provider_config?.model_path ?? model.provider_config?.model_name ?? "");
1953
+ const pipelineTask = model.provider_config?.pipeline_task ?? "";
1954
+ switch (pipelineTask) {
1955
+ case "text-generation":
1956
+ return [
1957
+ "text.generation",
1958
+ "text.rewriter",
1959
+ "text.summary",
1960
+ "tool-use",
1961
+ "model.count-tokens",
1962
+ "model.download-remove",
1963
+ "model.info",
1964
+ "model.search"
1965
+ ];
1966
+ case "feature-extraction":
1967
+ case "sentence-similarity":
1968
+ return ["text.embedding", "model.download-remove", "model.info", "model.search"];
1969
+ case "text-classification":
1970
+ return ["text.classification", "model.download-remove", "model.info", "model.search"];
1971
+ case "token-classification":
1972
+ return ["text.ner", "model.download-remove", "model.info", "model.search"];
1973
+ case "fill-mask":
1974
+ return ["text.fill-mask", "model.download-remove", "model.info", "model.search"];
1975
+ case "translation":
1976
+ return ["text.translation", "model.download-remove", "model.info", "model.search"];
1977
+ case "summarization":
1978
+ return ["text.summary", "model.download-remove", "model.info", "model.search"];
1979
+ case "question-answering":
1980
+ return ["text.question-answering", "model.download-remove", "model.info", "model.search"];
1981
+ case "image-classification":
1982
+ return ["image.classification", "model.download-remove", "model.info", "model.search"];
1983
+ case "image-segmentation":
1984
+ return ["image.segmentation", "model.download-remove", "model.info", "model.search"];
1985
+ case "image-to-text":
1986
+ return ["image.to-text", "model.download-remove", "model.info", "model.search"];
1987
+ case "object-detection":
1988
+ return ["image.object-detection", "model.download-remove", "model.info", "model.search"];
1989
+ case "zero-shot-image-classification":
1990
+ return [
1991
+ "image.classification",
1992
+ "image.embedding",
1993
+ "model.download-remove",
1994
+ "model.info",
1995
+ "model.search"
1996
+ ];
1997
+ }
1998
+ const baseName = id.split("/").pop() ?? id;
1999
+ if (/embed|minilm|bge-|gte-|e5-/i.test(baseName)) {
2000
+ return ["text.embedding", "model.download-remove", "model.info", "model.search"];
2001
+ }
2002
+ if (/clip|siglip/i.test(baseName)) {
2003
+ return [
2004
+ "image.classification",
2005
+ "image.embedding",
2006
+ "model.download-remove",
2007
+ "model.info",
2008
+ "model.search"
2009
+ ];
2010
+ }
2011
+ if (/yolo|detr|owl/i.test(baseName)) {
2012
+ return ["image.object-detection", "model.download-remove", "model.info", "model.search"];
2013
+ }
2014
+ if (/sam|segformer|mask/i.test(baseName)) {
2015
+ return ["image.segmentation", "model.download-remove", "model.info", "model.search"];
2016
+ }
2017
+ if (/blip|llava|vision/i.test(baseName)) {
2018
+ return ["image.to-text", "model.download-remove", "model.info", "model.search"];
2019
+ }
2020
+ if (/llama|mistral|gemma|phi|qwen|tinyllama|smollm/i.test(baseName)) {
2021
+ return [
2022
+ "text.generation",
2023
+ "text.rewriter",
2024
+ "text.summary",
2025
+ "tool-use",
2026
+ "model.count-tokens",
2027
+ "model.download-remove",
2028
+ "model.info",
2029
+ "model.search"
2030
+ ];
2031
+ }
2032
+ return ["model.search", "model.info"];
2033
+ }
2034
+
2035
+ // src/ai/HuggingFaceTransformersQueuedProvider.ts
2191
2036
  init_HFT_Pipeline();
2192
2037
  var GPU_DEVICES = new Set(["webgpu", "gpu", "metal"]);
2193
2038
  var HFT_CPU_QUEUE_CONCURRENCY_PRODUCTION = 4;
@@ -2217,34 +2062,14 @@ class HuggingFaceTransformersQueuedProvider extends QueuedAiProvider {
2217
2062
  isLocal = true;
2218
2063
  supportsBrowser = true;
2219
2064
  cpuStrategy;
2220
- taskTypes = [
2221
- "AiChatTask",
2222
- "DownloadModelTask",
2223
- "UnloadModelTask",
2224
- "ModelInfoTask",
2225
- "CountTokensTask",
2226
- "TextEmbeddingTask",
2227
- "TextGenerationTask",
2228
- "TextQuestionAnswerTask",
2229
- "TextLanguageDetectionTask",
2230
- "TextClassificationTask",
2231
- "TextFillMaskTask",
2232
- "TextNamedEntityRecognitionTask",
2233
- "TextRewriterTask",
2234
- "TextSummaryTask",
2235
- "TextTranslationTask",
2236
- "ImageSegmentationTask",
2237
- "ImageToTextTask",
2238
- "BackgroundRemovalTask",
2239
- "ImageEmbeddingTask",
2240
- "ImageClassificationTask",
2241
- "ObjectDetectionTask",
2242
- "ToolCallingTask",
2243
- "StructuredGenerationTask",
2244
- "ModelSearchTask"
2245
- ];
2246
- constructor(tasks, streamTasks, previewTasks) {
2247
- super(tasks, streamTasks, previewTasks);
2065
+ constructor(promiseRunFns, previewTasks) {
2066
+ super(promiseRunFns, previewTasks);
2067
+ }
2068
+ inferCapabilities(model) {
2069
+ return inferHftCapabilities(model);
2070
+ }
2071
+ workerRunFnSpecs() {
2072
+ return hftWorkerRunFnSpecs();
2248
2073
  }
2249
2074
  createSession(_model) {
2250
2075
  return crypto.randomUUID();
@@ -2269,7 +2094,7 @@ class HuggingFaceTransformersQueuedProvider extends QueuedAiProvider {
2269
2094
  async function registerHuggingFaceTransformersInline(options) {
2270
2095
  const { env } = await loadTransformersSDK();
2271
2096
  env.backends.onnx.wasm.proxy = true;
2272
- const provider = new HuggingFaceTransformersQueuedProvider(HFT_TASKS, HFT_STREAM_TASKS, HFT_PREVIEW_TASKS);
2097
+ const provider = new HuggingFaceTransformersQueuedProvider(HFT_RUN_FNS, HFT_PREVIEW_TASKS);
2273
2098
  const baseDispose = provider.dispose.bind(provider);
2274
2099
  provider.dispose = async () => {
2275
2100
  await clearHftInlinePipelineCache();
@@ -2280,7 +2105,6 @@ async function registerHuggingFaceTransformersInline(options) {
2280
2105
 
2281
2106
  // src/ai/registerHuggingFaceTransformersWorker.ts
2282
2107
  import { registerProviderWorker } from "@workglow/ai/provider-utils";
2283
- init_HFT_Pipeline();
2284
2108
 
2285
2109
  // src/ai/HuggingFaceTransformersProvider.ts
2286
2110
  import { AiProvider } from "@workglow/ai/worker";
@@ -2291,34 +2115,14 @@ class HuggingFaceTransformersProvider extends AiProvider {
2291
2115
  displayName = "Hugging Face Transformers (ONNX)";
2292
2116
  isLocal = true;
2293
2117
  supportsBrowser = true;
2294
- taskTypes = [
2295
- "AiChatTask",
2296
- "DownloadModelTask",
2297
- "UnloadModelTask",
2298
- "ModelInfoTask",
2299
- "CountTokensTask",
2300
- "TextEmbeddingTask",
2301
- "TextGenerationTask",
2302
- "TextQuestionAnswerTask",
2303
- "TextLanguageDetectionTask",
2304
- "TextClassificationTask",
2305
- "TextFillMaskTask",
2306
- "TextNamedEntityRecognitionTask",
2307
- "TextRewriterTask",
2308
- "TextSummaryTask",
2309
- "TextTranslationTask",
2310
- "ImageSegmentationTask",
2311
- "ImageToTextTask",
2312
- "BackgroundRemovalTask",
2313
- "ImageEmbeddingTask",
2314
- "ImageClassificationTask",
2315
- "ObjectDetectionTask",
2316
- "ToolCallingTask",
2317
- "StructuredGenerationTask",
2318
- "ModelSearchTask"
2319
- ];
2320
- constructor(tasks, streamTasks, previewTasks) {
2321
- super(tasks, streamTasks, previewTasks);
2118
+ constructor(promiseRunFns, previewTasks) {
2119
+ super(promiseRunFns, previewTasks);
2120
+ }
2121
+ inferCapabilities(model) {
2122
+ return inferHftCapabilities(model);
2123
+ }
2124
+ workerRunFnSpecs() {
2125
+ return hftWorkerRunFnSpecs();
2322
2126
  }
2323
2127
  createSession(_model) {
2324
2128
  return crypto.randomUUID();
@@ -2329,14 +2133,16 @@ class HuggingFaceTransformersProvider extends AiProvider {
2329
2133
  }
2330
2134
 
2331
2135
  // src/ai/registerHuggingFaceTransformersWorker.ts
2136
+ init_HFT_Pipeline();
2332
2137
  async function registerHuggingFaceTransformersWorker() {
2333
2138
  const sdk = await loadTransformersSDK();
2334
2139
  globalThis.__HFT__ = sdk;
2335
2140
  const { env } = sdk;
2336
2141
  env.backends.onnx.wasm.proxy = true;
2337
- await registerProviderWorker((ws) => new HuggingFaceTransformersProvider(HFT_TASKS, HFT_STREAM_TASKS, HFT_PREVIEW_TASKS).registerOnWorkerServer(ws), "HuggingFaceTransformers");
2142
+ await registerProviderWorker((ws) => new HuggingFaceTransformersProvider(HFT_RUN_FNS, HFT_PREVIEW_TASKS).registerOnWorkerServer(ws), "HuggingFaceTransformers");
2338
2143
  }
2339
2144
  export {
2145
+ validateAndExtractRerankerScores,
2340
2146
  setHftSession,
2341
2147
  setHftCacheDir,
2342
2148
  removeCachedPipeline,
@@ -2362,7 +2168,8 @@ export {
2362
2168
  HF_TRANSFORMERS_ONNX_GPU,
2363
2169
  HF_TRANSFORMERS_ONNX_CPU,
2364
2170
  HF_TRANSFORMERS_ONNX,
2171
+ HFT_TextReranker,
2365
2172
  HFT_NULL_PROCESSOR_PREFIX
2366
2173
  };
2367
2174
 
2368
- //# debugId=ABFB8E008DDF9A1264756E2164756E21
2175
+ //# debugId=13B5D715B9C2AB4A64756E2164756E21