@workglow/huggingface-transformers 0.2.33 → 0.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/HuggingFaceTransformersProvider.d.ts +9 -8
- package/dist/ai/HuggingFaceTransformersProvider.d.ts.map +1 -1
- package/dist/ai/HuggingFaceTransformersQueuedProvider.d.ts +10 -8
- package/dist/ai/HuggingFaceTransformersQueuedProvider.d.ts.map +1 -1
- package/dist/ai/common/HFT_BackgroundRemoval.d.ts.map +1 -1
- package/dist/ai/common/HFT_Capabilities.d.ts +28 -0
- package/dist/ai/common/HFT_Capabilities.d.ts.map +1 -0
- package/dist/ai/common/HFT_CapabilitySets.d.ts +39 -0
- package/dist/ai/common/HFT_CapabilitySets.d.ts.map +1 -0
- package/dist/ai/common/HFT_Chat.d.ts +1 -2
- package/dist/ai/common/HFT_Chat.d.ts.map +1 -1
- package/dist/ai/common/HFT_CountTokens.d.ts.map +1 -1
- package/dist/ai/common/HFT_Download.d.ts +7 -2
- package/dist/ai/common/HFT_Download.d.ts.map +1 -1
- package/dist/ai/common/{HFT_Unload.d.ts → HFT_DownloadRemove.d.ts} +3 -3
- package/dist/ai/common/HFT_DownloadRemove.d.ts.map +1 -0
- package/dist/ai/common/HFT_ImageClassification.d.ts.map +1 -1
- package/dist/ai/common/HFT_ImageEmbedding.d.ts.map +1 -1
- package/dist/ai/common/HFT_ImageSegmentation.d.ts.map +1 -1
- package/dist/ai/common/HFT_ImageToText.d.ts.map +1 -1
- package/dist/ai/common/HFT_JobRunFns.d.ts +9 -9
- package/dist/ai/common/HFT_JobRunFns.d.ts.map +1 -1
- package/dist/ai/common/HFT_ModelInfo.d.ts.map +1 -1
- package/dist/ai/common/HFT_ModelSchema.d.ts +3 -3
- package/dist/ai/common/HFT_ObjectDetection.d.ts.map +1 -1
- package/dist/ai/common/HFT_Pipeline.d.ts +30 -4
- package/dist/ai/common/HFT_Pipeline.d.ts.map +1 -1
- package/dist/ai/common/HFT_Streaming.d.ts +5 -12
- package/dist/ai/common/HFT_Streaming.d.ts.map +1 -1
- package/dist/ai/common/HFT_StructuredGeneration.d.ts +1 -2
- package/dist/ai/common/HFT_StructuredGeneration.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextClassification.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextEmbedding.d.ts +4 -0
- package/dist/ai/common/HFT_TextEmbedding.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextFillMask.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextGeneration.d.ts +1 -6
- package/dist/ai/common/HFT_TextGeneration.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextLanguageDetection.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextNamedEntityRecognition.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextQuestionAnswer.d.ts +1 -6
- package/dist/ai/common/HFT_TextQuestionAnswer.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextRewriter.d.ts +1 -6
- package/dist/ai/common/HFT_TextRewriter.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextSummary.d.ts +1 -6
- package/dist/ai/common/HFT_TextSummary.d.ts.map +1 -1
- package/dist/ai/common/HFT_TextTranslation.d.ts +1 -6
- package/dist/ai/common/HFT_TextTranslation.d.ts.map +1 -1
- package/dist/ai/common/HFT_ToolCalling.d.ts +1 -2
- package/dist/ai/common/HFT_ToolCalling.d.ts.map +1 -1
- package/dist/ai/index.d.ts +53 -2
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/registerHuggingFaceTransformersInline.d.ts.map +1 -1
- package/dist/ai/registerHuggingFaceTransformersWorker.d.ts.map +1 -1
- package/dist/ai/runtime.d.ts.map +1 -1
- package/dist/ai-runtime.d.ts.map +1 -1
- package/dist/ai-runtime.js +602 -848
- package/dist/ai-runtime.js.map +37 -36
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +1383 -183
- package/dist/ai.js.map +37 -8
- package/package.json +12 -13
- package/dist/ai/common/HFT_Unload.d.ts.map +0 -1
package/dist/ai-runtime.js
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
283
|
-
|
|
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
|
-
|
|
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
|
|
311
|
-
|
|
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
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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) {
|
|
@@ -734,31 +728,66 @@ import { registerProviderInline } from "@workglow/ai/provider-utils";
|
|
|
734
728
|
// src/ai/common/HFT_InlineLifecycle.ts
|
|
735
729
|
async function clearHftInlinePipelineCache() {
|
|
736
730
|
const { clearPipelineCache: clearPipelineCache2 } = await Promise.resolve().then(() => (init_HFT_Pipeline(), exports_HFT_Pipeline));
|
|
737
|
-
clearPipelineCache2();
|
|
731
|
+
await clearPipelineCache2();
|
|
738
732
|
}
|
|
739
733
|
|
|
740
|
-
// src/ai/common/
|
|
741
|
-
|
|
742
|
-
var
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
734
|
+
// src/ai/common/HFT_CapabilitySets.ts
|
|
735
|
+
var HFT_TEXT_GENERATION = ["text.generation"];
|
|
736
|
+
var HFT_TOOL_USE = ["text.generation", "tool-use"];
|
|
737
|
+
var HFT_JSON_MODE = ["text.generation", "json-mode"];
|
|
738
|
+
var HFT_TEXT_REWRITER = ["text.rewriter"];
|
|
739
|
+
var HFT_TEXT_SUMMARY = ["text.summary"];
|
|
740
|
+
var HFT_TEXT_TRANSLATION = ["text.translation"];
|
|
741
|
+
var HFT_TEXT_QUESTION_ANSWERING = [
|
|
742
|
+
"text.question-answering"
|
|
743
|
+
];
|
|
744
|
+
var HFT_TEXT_EMBEDDING = ["text.embedding"];
|
|
745
|
+
var HFT_TEXT_CLASSIFICATION = ["text.classification"];
|
|
746
|
+
var HFT_TEXT_LANGUAGE_DETECTION = [
|
|
747
|
+
"text.language-detection"
|
|
748
|
+
];
|
|
749
|
+
var HFT_TEXT_FILL_MASK = ["text.fill-mask"];
|
|
750
|
+
var HFT_TEXT_NER = ["text.ner"];
|
|
751
|
+
var HFT_IMAGE_CLASSIFICATION = ["image.classification"];
|
|
752
|
+
var HFT_IMAGE_EMBEDDING = ["image.embedding"];
|
|
753
|
+
var HFT_IMAGE_SEGMENTATION = ["image.segmentation"];
|
|
754
|
+
var HFT_IMAGE_TO_TEXT = ["image.to-text"];
|
|
755
|
+
var HFT_IMAGE_BACKGROUND_REMOVAL = [
|
|
756
|
+
"image.background-removal"
|
|
757
|
+
];
|
|
758
|
+
var HFT_IMAGE_OBJECT_DETECTION = [
|
|
759
|
+
"image.object-detection"
|
|
760
|
+
];
|
|
761
|
+
var HFT_COUNT_TOKENS = ["model.count-tokens"];
|
|
762
|
+
var HFT_MODEL_DOWNLOAD_REMOVE = ["model.download-remove"];
|
|
763
|
+
var HFT_MODEL_DOWNLOAD = ["model.download"];
|
|
764
|
+
var HFT_MODEL_SEARCH = ["model.search"];
|
|
765
|
+
var HFT_MODEL_INFO = ["model.info"];
|
|
766
|
+
var HFT_CAPABILITY_SETS = [
|
|
767
|
+
HFT_TEXT_GENERATION,
|
|
768
|
+
HFT_TOOL_USE,
|
|
769
|
+
HFT_JSON_MODE,
|
|
770
|
+
HFT_TEXT_REWRITER,
|
|
771
|
+
HFT_TEXT_SUMMARY,
|
|
772
|
+
HFT_TEXT_TRANSLATION,
|
|
773
|
+
HFT_TEXT_QUESTION_ANSWERING,
|
|
774
|
+
HFT_TEXT_EMBEDDING,
|
|
775
|
+
HFT_TEXT_CLASSIFICATION,
|
|
776
|
+
HFT_TEXT_LANGUAGE_DETECTION,
|
|
777
|
+
HFT_TEXT_FILL_MASK,
|
|
778
|
+
HFT_TEXT_NER,
|
|
779
|
+
HFT_IMAGE_CLASSIFICATION,
|
|
780
|
+
HFT_IMAGE_EMBEDDING,
|
|
781
|
+
HFT_IMAGE_SEGMENTATION,
|
|
782
|
+
HFT_IMAGE_TO_TEXT,
|
|
783
|
+
HFT_IMAGE_BACKGROUND_REMOVAL,
|
|
784
|
+
HFT_IMAGE_OBJECT_DETECTION,
|
|
785
|
+
HFT_COUNT_TOKENS,
|
|
786
|
+
HFT_MODEL_DOWNLOAD_REMOVE,
|
|
787
|
+
HFT_MODEL_DOWNLOAD,
|
|
788
|
+
HFT_MODEL_SEARCH,
|
|
789
|
+
HFT_MODEL_INFO
|
|
790
|
+
];
|
|
762
791
|
|
|
763
792
|
// src/ai/common/HFT_BackgroundRemoval.ts
|
|
764
793
|
init_HFT_Pipeline();
|
|
@@ -770,15 +799,18 @@ function rawImageToBase64Png(image) {
|
|
|
770
799
|
}
|
|
771
800
|
return fn.call(image);
|
|
772
801
|
}
|
|
773
|
-
var HFT_BackgroundRemoval = async (input, model,
|
|
774
|
-
const remover = await getPipeline(model,
|
|
802
|
+
var HFT_BackgroundRemoval = async (input, model, signal, emit) => {
|
|
803
|
+
const remover = await getPipeline(model, emit, {}, signal);
|
|
775
804
|
const imageArg = await imageValueToBlob(input.image);
|
|
776
805
|
const result = await remover(imageArg);
|
|
777
806
|
const resultImage = Array.isArray(result) ? result[0] : result;
|
|
778
807
|
const dataUri = `data:image/png;base64,${rawImageToBase64Png(resultImage)}`;
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
808
|
+
emit({
|
|
809
|
+
type: "finish",
|
|
810
|
+
data: {
|
|
811
|
+
image: await dataUriToImageValue(dataUri)
|
|
812
|
+
}
|
|
813
|
+
});
|
|
782
814
|
};
|
|
783
815
|
|
|
784
816
|
// src/ai/common/HFT_Chat.ts
|
|
@@ -800,64 +832,11 @@ import {
|
|
|
800
832
|
} from "@workglow/ai/provider-utils";
|
|
801
833
|
|
|
802
834
|
// src/ai/common/HFT_Streaming.ts
|
|
803
|
-
function
|
|
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) {
|
|
835
|
+
function createStreamingTextStreamer(tokenizer, onText, textStreamer) {
|
|
855
836
|
return new textStreamer(tokenizer, {
|
|
856
837
|
skip_prompt: true,
|
|
857
838
|
decode_kwargs: { skip_special_tokens: true },
|
|
858
|
-
callback_function:
|
|
859
|
-
queue.push({ type: "text-delta", port: "text", textDelta: text });
|
|
860
|
-
}
|
|
839
|
+
callback_function: onText
|
|
861
840
|
});
|
|
862
841
|
}
|
|
863
842
|
function createTextStreamer(tokenizer, updateProgress, textStreamer) {
|
|
@@ -1025,76 +1004,19 @@ function buildPromptAndPrefix(tokenizer, input, modelFamily) {
|
|
|
1025
1004
|
responsePrefix
|
|
1026
1005
|
};
|
|
1027
1006
|
}
|
|
1028
|
-
var HFT_ToolCalling = async (input, model,
|
|
1029
|
-
const generateText = await getPipeline(model,
|
|
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);
|
|
1007
|
+
var HFT_ToolCalling = async (input, model, signal, emit, _outputSchema, sessionId) => {
|
|
1008
|
+
const generateText = await getPipeline(model, emit, {}, signal);
|
|
1092
1009
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1093
1010
|
const modelFamily = detectModelFamilyFromConfig(model);
|
|
1094
1011
|
const { prompt, responsePrefix } = buildPromptAndPrefix(generateText.tokenizer, input, modelFamily);
|
|
1095
|
-
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1012
|
+
let fullText = "";
|
|
1013
|
+
const filter = createToolCallMarkupFilter((text) => {
|
|
1014
|
+
emit({ type: "text-delta", port: "text", textDelta: text });
|
|
1015
|
+
});
|
|
1016
|
+
const streamer = createStreamingTextStreamer(generateText.tokenizer, (text) => {
|
|
1017
|
+
fullText += text;
|
|
1018
|
+
filter.feed(text);
|
|
1019
|
+
}, TextStreamer);
|
|
1098
1020
|
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
1099
1021
|
if (signal) {
|
|
1100
1022
|
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
@@ -1130,57 +1052,33 @@ var HFT_ToolCalling_Stream = async function* (input, model, signal, _outputSchem
|
|
|
1130
1052
|
const { DynamicCache } = await loadTransformersSDK();
|
|
1131
1053
|
past_key_values = new DynamicCache(session.baseEntries);
|
|
1132
1054
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
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) => {
|
|
1055
|
+
try {
|
|
1056
|
+
await generateText(prompt, {
|
|
1057
|
+
max_new_tokens: input.maxTokens ?? 1024,
|
|
1058
|
+
temperature: input.temperature ?? undefined,
|
|
1059
|
+
return_full_text: false,
|
|
1060
|
+
streamer,
|
|
1061
|
+
stopping_criteria: [stopping_criteria],
|
|
1062
|
+
...past_key_values ? { past_key_values } : {}
|
|
1063
|
+
});
|
|
1064
|
+
} finally {
|
|
1155
1065
|
filter.flush();
|
|
1156
|
-
|
|
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;
|
|
1066
|
+
}
|
|
1169
1067
|
const parseableFullText = responsePrefix ? `${responsePrefix}${fullText}` : fullText;
|
|
1170
1068
|
const { text: cleanedText, toolCalls } = adaptParserResult(parseToolCalls(parseableFullText, { parser: modelFamily }));
|
|
1171
1069
|
const validToolCalls = filterValidToolCalls(normalizeParsedToolCalls(input, toolCalls), input.tools);
|
|
1172
1070
|
if (validToolCalls.length > 0) {
|
|
1173
|
-
|
|
1071
|
+
emit({ type: "object-delta", port: "toolCalls", objectDelta: [...validToolCalls] });
|
|
1174
1072
|
}
|
|
1175
|
-
|
|
1073
|
+
emit({
|
|
1176
1074
|
type: "finish",
|
|
1177
1075
|
data: { text: cleanedText, toolCalls: validToolCalls }
|
|
1178
|
-
};
|
|
1076
|
+
});
|
|
1179
1077
|
};
|
|
1180
1078
|
|
|
1181
1079
|
// src/ai/common/HFT_Chat.ts
|
|
1182
|
-
async function generateTurn(input, model, sessionId,
|
|
1183
|
-
const generateText = await getPipeline(model,
|
|
1080
|
+
async function generateTurn(input, model, sessionId, emit, signal, onDelta) {
|
|
1081
|
+
const generateText = await getPipeline(model, emit, {}, signal);
|
|
1184
1082
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1185
1083
|
const hfTokenizer = generateText.tokenizer;
|
|
1186
1084
|
const hfModel = generateText.model;
|
|
@@ -1205,16 +1103,12 @@ async function generateTurn(input, model, sessionId, onProgress, signal, onDelta
|
|
|
1205
1103
|
let accumulated = "";
|
|
1206
1104
|
let streamer;
|
|
1207
1105
|
if (onDelta) {
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
accumulated += event.textDelta;
|
|
1213
|
-
onDelta(event.textDelta);
|
|
1214
|
-
}
|
|
1215
|
-
};
|
|
1106
|
+
streamer = createStreamingTextStreamer(hfTokenizer, (text) => {
|
|
1107
|
+
accumulated += text;
|
|
1108
|
+
onDelta(text);
|
|
1109
|
+
}, TextStreamer);
|
|
1216
1110
|
} else {
|
|
1217
|
-
streamer = createTextStreamer(hfTokenizer,
|
|
1111
|
+
streamer = createTextStreamer(hfTokenizer, (progress, message) => emit({ type: "phase", message: message ?? "", progress }), TextStreamer);
|
|
1218
1112
|
}
|
|
1219
1113
|
const output = await hfModel.generate({
|
|
1220
1114
|
...inputs,
|
|
@@ -1252,112 +1146,140 @@ async function generateTurn(input, model, sessionId, onProgress, signal, onDelta
|
|
|
1252
1146
|
}
|
|
1253
1147
|
return accumulated;
|
|
1254
1148
|
}
|
|
1255
|
-
var HFT_Chat = async (input, model,
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
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: {} };
|
|
1149
|
+
var HFT_Chat = async (input, model, signal, emit, _outputSchema, sessionId) => {
|
|
1150
|
+
await generateTurn(input, model, sessionId, emit, signal, (piece) => {
|
|
1151
|
+
emit({ type: "text-delta", port: "text", textDelta: piece });
|
|
1152
|
+
});
|
|
1153
|
+
emit({ type: "finish", data: {} });
|
|
1288
1154
|
};
|
|
1289
1155
|
|
|
1290
1156
|
// src/ai/common/HFT_CountTokens.ts
|
|
1291
1157
|
init_HFT_Pipeline();
|
|
1292
|
-
|
|
1158
|
+
async function countTokens(input, model) {
|
|
1293
1159
|
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
|
-
});
|
|
1160
|
+
const tokenizer = await AutoTokenizer.from_pretrained(model.provider_config.model_path, {});
|
|
1297
1161
|
const tokenIds = tokenizer.encode(input.text);
|
|
1298
1162
|
return { count: tokenIds.length };
|
|
1163
|
+
}
|
|
1164
|
+
var HFT_CountTokens = async (input, model, _signal, emit) => {
|
|
1165
|
+
const data = await countTokens(input, model);
|
|
1166
|
+
emit({ type: "finish", data });
|
|
1299
1167
|
};
|
|
1300
1168
|
var HFT_CountTokens_Preview = async (input, model) => {
|
|
1301
|
-
return
|
|
1169
|
+
return countTokens(input, model);
|
|
1302
1170
|
};
|
|
1303
1171
|
|
|
1304
1172
|
// src/ai/common/HFT_Download.ts
|
|
1305
1173
|
init_HFT_Pipeline();
|
|
1306
1174
|
import { getLogger as getLogger2 } from "@workglow/util/worker";
|
|
1307
|
-
var HFT_Download = async (input, model,
|
|
1175
|
+
var HFT_Download = async (input, model, signal, emit) => {
|
|
1308
1176
|
const logger = getLogger2();
|
|
1309
1177
|
const timerLabel = `hft:Download:${model?.provider_config.model_path}`;
|
|
1310
1178
|
logger.time(timerLabel, { model: model?.provider_config.model_path });
|
|
1311
|
-
await getPipeline(model,
|
|
1179
|
+
await getPipeline(model, emit, {}, signal, 100);
|
|
1312
1180
|
logger.timeEnd(timerLabel, { model: model?.provider_config.model_path });
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1181
|
+
emit({ type: "finish", data: { model: input.model } });
|
|
1182
|
+
};
|
|
1183
|
+
|
|
1184
|
+
// src/ai/common/HFT_DownloadRemove.ts
|
|
1185
|
+
init_HFT_Pipeline();
|
|
1186
|
+
function hasBrowserCacheStorage() {
|
|
1187
|
+
return typeof globalThis !== "undefined" && "caches" in globalThis && typeof globalThis.caches?.open === "function";
|
|
1188
|
+
}
|
|
1189
|
+
async function deleteModelCacheFromBrowser(model_path) {
|
|
1190
|
+
const cachesApi = globalThis.caches;
|
|
1191
|
+
const cache = await cachesApi.open(HTF_CACHE_NAME);
|
|
1192
|
+
const keys = await cache.keys();
|
|
1193
|
+
const prefix = `/${model_path}/`;
|
|
1194
|
+
const requestsToDelete = [];
|
|
1195
|
+
for (const request of keys) {
|
|
1196
|
+
const url = new URL(request.url);
|
|
1197
|
+
if (url.pathname.startsWith(prefix)) {
|
|
1198
|
+
requestsToDelete.push(request);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
for (const request of requestsToDelete) {
|
|
1202
|
+
try {
|
|
1203
|
+
const deleted = await cache.delete(request);
|
|
1204
|
+
if (!deleted) {
|
|
1205
|
+
const deletedByUrl = await cache.delete(request.url);
|
|
1206
|
+
if (!deletedByUrl) {}
|
|
1207
|
+
}
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
console.error(`Failed to delete cache entry: ${request.url}`, error);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
async function deleteModelCacheFromFilesystem(model) {
|
|
1214
|
+
const { ModelRegistry } = await loadTransformersSDK();
|
|
1215
|
+
const { pipeline: pipelineType, model_path, dtype } = model.provider_config;
|
|
1216
|
+
await ModelRegistry.clear_pipeline_cache(pipelineType, model_path, {
|
|
1217
|
+
...dtype ? { dtype } : {}
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
var HFT_DownloadRemove = async (input, model, _signal, emit) => {
|
|
1221
|
+
const cacheKey = getPipelineCacheKey(model);
|
|
1222
|
+
await removeCachedPipeline(cacheKey);
|
|
1223
|
+
const model_path = model.provider_config.model_path;
|
|
1224
|
+
disposeHftSessionsForModel(model_path);
|
|
1225
|
+
if (hasBrowserCacheStorage()) {
|
|
1226
|
+
await deleteModelCacheFromBrowser(model_path);
|
|
1227
|
+
} else {
|
|
1228
|
+
await deleteModelCacheFromFilesystem(model);
|
|
1229
|
+
}
|
|
1230
|
+
emit({ type: "finish", data: { model: input.model } });
|
|
1316
1231
|
};
|
|
1317
1232
|
|
|
1318
1233
|
// src/ai/common/HFT_ImageClassification.ts
|
|
1319
1234
|
init_HFT_Pipeline();
|
|
1320
1235
|
import { imageValueToBlob as imageValueToBlob2 } from "@workglow/ai/provider-utils";
|
|
1321
|
-
var HFT_ImageClassification = async (input, model,
|
|
1236
|
+
var HFT_ImageClassification = async (input, model, signal, emit) => {
|
|
1322
1237
|
if (model?.provider_config?.pipeline === "zero-shot-image-classification") {
|
|
1323
1238
|
if (!input.categories || !Array.isArray(input.categories) || input.categories.length === 0) {
|
|
1324
1239
|
console.warn("Zero-shot image classification requires categories", input);
|
|
1325
1240
|
throw new Error("Zero-shot image classification requires categories");
|
|
1326
1241
|
}
|
|
1327
|
-
const zeroShotClassifier = await getPipeline(model,
|
|
1242
|
+
const zeroShotClassifier = await getPipeline(model, emit, {}, signal);
|
|
1328
1243
|
const imageArg2 = await imageValueToBlob2(input.image);
|
|
1329
1244
|
const result2 = await zeroShotClassifier(imageArg2, input.categories, {});
|
|
1330
1245
|
const results2 = Array.isArray(result2) ? result2 : [result2];
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1246
|
+
emit({
|
|
1247
|
+
type: "finish",
|
|
1248
|
+
data: {
|
|
1249
|
+
categories: results2.map((r) => ({
|
|
1250
|
+
label: r.label,
|
|
1251
|
+
score: r.score
|
|
1252
|
+
}))
|
|
1253
|
+
}
|
|
1254
|
+
});
|
|
1255
|
+
return;
|
|
1337
1256
|
}
|
|
1338
|
-
const classifier = await getPipeline(model,
|
|
1257
|
+
const classifier = await getPipeline(model, emit, {}, signal);
|
|
1339
1258
|
const imageArg = await imageValueToBlob2(input.image);
|
|
1340
1259
|
const result = await classifier(imageArg, {
|
|
1341
1260
|
top_k: input.maxCategories
|
|
1342
1261
|
});
|
|
1343
1262
|
const results = Array.isArray(result) ? result : [result];
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1263
|
+
emit({
|
|
1264
|
+
type: "finish",
|
|
1265
|
+
data: {
|
|
1266
|
+
categories: results.map((r) => ({
|
|
1267
|
+
label: r.label,
|
|
1268
|
+
score: r.score
|
|
1269
|
+
}))
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1350
1272
|
};
|
|
1351
1273
|
|
|
1352
1274
|
// src/ai/common/HFT_ImageEmbedding.ts
|
|
1353
1275
|
init_HFT_Pipeline();
|
|
1354
1276
|
import { getLogger as getLogger3 } from "@workglow/util/worker";
|
|
1355
1277
|
import { imageValueToBlob as imageValueToBlob3 } from "@workglow/ai/provider-utils";
|
|
1356
|
-
var HFT_ImageEmbedding = async (input, model,
|
|
1278
|
+
var HFT_ImageEmbedding = async (input, model, signal, emit) => {
|
|
1357
1279
|
const logger = getLogger3();
|
|
1358
1280
|
const timerLabel = `hft:ImageEmbedding:${model?.provider_config.model_path}`;
|
|
1359
1281
|
logger.time(timerLabel, { model: model?.provider_config.model_path });
|
|
1360
|
-
const embedder = await getPipeline(model,
|
|
1282
|
+
const embedder = await getPipeline(model, emit, {}, signal);
|
|
1361
1283
|
logger.debug("HFT ImageEmbedding: pipeline ready, generating embedding", {
|
|
1362
1284
|
model: model?.provider_config.model_path
|
|
1363
1285
|
});
|
|
@@ -1369,21 +1291,23 @@ var HFT_ImageEmbedding = async (input, model, onProgress, signal) => {
|
|
|
1369
1291
|
vectors.push(result2.data);
|
|
1370
1292
|
}
|
|
1371
1293
|
logger.timeEnd(timerLabel, { count: vectors.length });
|
|
1372
|
-
|
|
1294
|
+
emit({ type: "finish", data: { vector: vectors } });
|
|
1295
|
+
return;
|
|
1373
1296
|
}
|
|
1374
1297
|
const imageArg = await imageValueToBlob3(input.image);
|
|
1375
1298
|
const result = await embedder(imageArg);
|
|
1376
1299
|
logger.timeEnd(timerLabel, { dimensions: result?.data?.length });
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1300
|
+
emit({
|
|
1301
|
+
type: "finish",
|
|
1302
|
+
data: { vector: result.data }
|
|
1303
|
+
});
|
|
1380
1304
|
};
|
|
1381
1305
|
|
|
1382
1306
|
// src/ai/common/HFT_ImageSegmentation.ts
|
|
1383
1307
|
init_HFT_Pipeline();
|
|
1384
1308
|
import { imageValueToBlob as imageValueToBlob4 } from "@workglow/ai/provider-utils";
|
|
1385
|
-
var HFT_ImageSegmentation = async (input, model,
|
|
1386
|
-
const segmenter = await getPipeline(model,
|
|
1309
|
+
var HFT_ImageSegmentation = async (input, model, signal, emit) => {
|
|
1310
|
+
const segmenter = await getPipeline(model, emit, {}, signal);
|
|
1387
1311
|
const imageArg = await imageValueToBlob4(input.image);
|
|
1388
1312
|
const result = await segmenter(imageArg, {
|
|
1389
1313
|
threshold: input.threshold,
|
|
@@ -1395,30 +1319,36 @@ var HFT_ImageSegmentation = async (input, model, onProgress, signal) => {
|
|
|
1395
1319
|
score: mask.score || 0,
|
|
1396
1320
|
mask: {}
|
|
1397
1321
|
})));
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1322
|
+
emit({
|
|
1323
|
+
type: "finish",
|
|
1324
|
+
data: {
|
|
1325
|
+
masks: processedMasks
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1401
1328
|
};
|
|
1402
1329
|
|
|
1403
1330
|
// src/ai/common/HFT_ImageToText.ts
|
|
1404
1331
|
init_HFT_Pipeline();
|
|
1405
1332
|
import { imageValueToBlob as imageValueToBlob5 } from "@workglow/ai/provider-utils";
|
|
1406
|
-
var HFT_ImageToText = async (input, model,
|
|
1407
|
-
const captioner = await getPipeline(model,
|
|
1333
|
+
var HFT_ImageToText = async (input, model, signal, emit) => {
|
|
1334
|
+
const captioner = await getPipeline(model, emit, {}, signal);
|
|
1408
1335
|
const imageArg = await imageValueToBlob5(input.image);
|
|
1409
1336
|
const result = await captioner(imageArg, {
|
|
1410
1337
|
max_new_tokens: input.maxTokens
|
|
1411
1338
|
});
|
|
1412
1339
|
const text = Array.isArray(result[0]) ? result[0][0]?.generated_text : result[0]?.generated_text;
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1340
|
+
emit({
|
|
1341
|
+
type: "finish",
|
|
1342
|
+
data: {
|
|
1343
|
+
text: text || ""
|
|
1344
|
+
}
|
|
1345
|
+
});
|
|
1416
1346
|
};
|
|
1417
1347
|
|
|
1418
1348
|
// src/ai/common/HFT_ModelInfo.ts
|
|
1419
1349
|
import { getLogger as getLogger4 } from "@workglow/util/worker";
|
|
1420
1350
|
init_HFT_Pipeline();
|
|
1421
|
-
var HFT_ModelInfo = async (input, model) => {
|
|
1351
|
+
var HFT_ModelInfo = async (input, model, _signal, emit) => {
|
|
1422
1352
|
if (input.detail === "dimensions") {
|
|
1423
1353
|
if (!model)
|
|
1424
1354
|
throw new Error("Model config is required for ModelInfoTask.");
|
|
@@ -1436,18 +1366,22 @@ var HFT_ModelInfo = async (input, model) => {
|
|
|
1436
1366
|
}
|
|
1437
1367
|
} catch {}
|
|
1438
1368
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1369
|
+
emit({
|
|
1370
|
+
type: "finish",
|
|
1371
|
+
data: {
|
|
1372
|
+
model: input.model,
|
|
1373
|
+
is_local: true,
|
|
1374
|
+
is_remote: false,
|
|
1375
|
+
supports_browser: true,
|
|
1376
|
+
supports_node: true,
|
|
1377
|
+
is_cached: false,
|
|
1378
|
+
is_loaded: false,
|
|
1379
|
+
file_sizes: null,
|
|
1380
|
+
...native_dimensions !== undefined ? { native_dimensions } : {},
|
|
1381
|
+
...mrl ? { mrl } : {}
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
1384
|
+
return;
|
|
1451
1385
|
}
|
|
1452
1386
|
const logger = getLogger4();
|
|
1453
1387
|
const { ModelRegistry } = await loadTransformersSDK();
|
|
@@ -1494,79 +1428,90 @@ var HFT_ModelInfo = async (input, model) => {
|
|
|
1494
1428
|
}
|
|
1495
1429
|
}
|
|
1496
1430
|
logger.timeEnd(timerLabel, { model: model?.provider_config.model_path });
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1431
|
+
emit({
|
|
1432
|
+
type: "finish",
|
|
1433
|
+
data: {
|
|
1434
|
+
model: input.model,
|
|
1435
|
+
is_local: true,
|
|
1436
|
+
is_remote: false,
|
|
1437
|
+
supports_browser: true,
|
|
1438
|
+
supports_node: true,
|
|
1439
|
+
is_cached,
|
|
1440
|
+
is_loaded,
|
|
1441
|
+
file_sizes,
|
|
1442
|
+
...quantizations ? { quantizations } : {}
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
// src/ai/common/HFT_ModelSearch.ts
|
|
1448
|
+
import { searchHfModels, mapHfModelResult } from "@workglow/ai/provider-utils";
|
|
1449
|
+
var HFT_ModelSearch = async (input, _model, signal, emit) => {
|
|
1450
|
+
const entries = await searchHfModels(input.query?.trim() ?? "", { filter: "onnx" }, ["siblings"], signal);
|
|
1451
|
+
const results = entries.map((entry) => {
|
|
1452
|
+
const item = mapHfModelResult(entry, HF_TRANSFORMERS_ONNX);
|
|
1453
|
+
if (entry.siblings && entry.siblings.length > 0) {
|
|
1454
|
+
const filePaths = entry.siblings.map((s) => s.rfilename);
|
|
1455
|
+
const quantizations = parseOnnxQuantizations({ filePaths });
|
|
1456
|
+
if (quantizations.length > 0) {
|
|
1457
|
+
const record = item.record;
|
|
1458
|
+
const providerConfig = record.provider_config ?? {};
|
|
1459
|
+
providerConfig.quantizations = quantizations;
|
|
1460
|
+
record.provider_config = providerConfig;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
const raw = item.raw;
|
|
1464
|
+
delete raw.siblings;
|
|
1465
|
+
return item;
|
|
1466
|
+
});
|
|
1467
|
+
emit({ type: "finish", data: { results } });
|
|
1508
1468
|
};
|
|
1509
1469
|
|
|
1510
1470
|
// src/ai/common/HFT_ObjectDetection.ts
|
|
1511
1471
|
init_HFT_Pipeline();
|
|
1512
1472
|
import { imageValueToBlob as imageValueToBlob6 } from "@workglow/ai/provider-utils";
|
|
1513
|
-
var HFT_ObjectDetection = async (input, model,
|
|
1473
|
+
var HFT_ObjectDetection = async (input, model, signal, emit) => {
|
|
1514
1474
|
if (model?.provider_config?.pipeline === "zero-shot-object-detection") {
|
|
1515
1475
|
if (!input.labels || !Array.isArray(input.labels) || input.labels.length === 0) {
|
|
1516
1476
|
throw new Error("Zero-shot object detection requires labels");
|
|
1517
1477
|
}
|
|
1518
|
-
const zeroShotDetector = await getPipeline(model,
|
|
1478
|
+
const zeroShotDetector = await getPipeline(model, emit, {}, signal);
|
|
1519
1479
|
const imageArg2 = await imageValueToBlob6(input.image);
|
|
1520
1480
|
const result = await zeroShotDetector(imageArg2, Array.from(input.labels), {
|
|
1521
1481
|
threshold: input.threshold
|
|
1522
1482
|
});
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1483
|
+
emit({
|
|
1484
|
+
type: "finish",
|
|
1485
|
+
data: {
|
|
1486
|
+
detections: result.map((d) => ({
|
|
1487
|
+
label: d.label,
|
|
1488
|
+
score: d.score,
|
|
1489
|
+
box: d.box
|
|
1490
|
+
}))
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
return;
|
|
1530
1494
|
}
|
|
1531
|
-
const detector = await getPipeline(model,
|
|
1495
|
+
const detector = await getPipeline(model, emit, {}, signal);
|
|
1532
1496
|
const imageArg = await imageValueToBlob6(input.image);
|
|
1533
1497
|
const detections = await detector(imageArg, {
|
|
1534
1498
|
threshold: input.threshold
|
|
1535
1499
|
});
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1500
|
+
emit({
|
|
1501
|
+
type: "finish",
|
|
1502
|
+
data: {
|
|
1503
|
+
detections: detections.map((d) => ({
|
|
1504
|
+
label: d.label,
|
|
1505
|
+
score: d.score,
|
|
1506
|
+
box: d.box
|
|
1507
|
+
}))
|
|
1508
|
+
}
|
|
1509
|
+
});
|
|
1543
1510
|
};
|
|
1544
1511
|
|
|
1545
1512
|
// src/ai/common/HFT_StructuredGeneration.ts
|
|
1546
1513
|
init_HFT_Pipeline();
|
|
1547
1514
|
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
1515
|
function buildStructuredGenerationPrompt(input) {
|
|
1571
1516
|
const schemaStr = JSON.stringify(input.outputSchema, null, 2);
|
|
1572
1517
|
return `${input.prompt}
|
|
@@ -1595,8 +1540,8 @@ function extractJsonFromText(text) {
|
|
|
1595
1540
|
return {};
|
|
1596
1541
|
}
|
|
1597
1542
|
}
|
|
1598
|
-
var HFT_StructuredGeneration = async (input, model,
|
|
1599
|
-
const generateText = await getPipeline(model,
|
|
1543
|
+
var HFT_StructuredGeneration = async (input, model, signal, emit) => {
|
|
1544
|
+
const generateText = await getPipeline(model, emit, {}, signal);
|
|
1600
1545
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1601
1546
|
const prompt = buildStructuredGenerationPrompt(input);
|
|
1602
1547
|
const messages = [{ role: "user", content: prompt }];
|
|
@@ -1604,139 +1549,105 @@ var HFT_StructuredGeneration = async (input, model, onProgress, signal) => {
|
|
|
1604
1549
|
tokenize: false,
|
|
1605
1550
|
add_generation_prompt: true
|
|
1606
1551
|
});
|
|
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);
|
|
1629
|
-
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1630
|
-
const prompt = buildStructuredGenerationPrompt(input);
|
|
1631
|
-
const messages = [{ role: "user", content: prompt }];
|
|
1632
|
-
const formattedPrompt = generateText.tokenizer.apply_chat_template(messages, {
|
|
1633
|
-
tokenize: false,
|
|
1634
|
-
add_generation_prompt: true
|
|
1635
|
-
});
|
|
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
1552
|
let fullText = "";
|
|
1643
1553
|
let cleanedText = "";
|
|
1644
1554
|
let inThinkBlock = false;
|
|
1645
1555
|
let jsonStart = -1;
|
|
1646
|
-
const
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
if (closeIdx !== -1) {
|
|
1656
|
-
inThinkBlock = false;
|
|
1657
|
-
remaining = remaining.slice(closeIdx + "</think>".length);
|
|
1658
|
-
} else {
|
|
1659
|
-
remaining = "";
|
|
1660
|
-
}
|
|
1556
|
+
const streamer = createStreamingTextStreamer(generateText.tokenizer, (delta) => {
|
|
1557
|
+
fullText += delta;
|
|
1558
|
+
let remaining = delta;
|
|
1559
|
+
while (remaining.length > 0) {
|
|
1560
|
+
if (inThinkBlock) {
|
|
1561
|
+
const closeIdx = remaining.indexOf("</think>");
|
|
1562
|
+
if (closeIdx !== -1) {
|
|
1563
|
+
inThinkBlock = false;
|
|
1564
|
+
remaining = remaining.slice(closeIdx + "</think>".length);
|
|
1661
1565
|
} else {
|
|
1662
|
-
|
|
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
|
-
}
|
|
1566
|
+
remaining = "";
|
|
1671
1567
|
}
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
port: "object",
|
|
1682
|
-
objectDelta: partial
|
|
1683
|
-
});
|
|
1684
|
-
return;
|
|
1568
|
+
} else {
|
|
1569
|
+
const openIdx = remaining.indexOf("<think>");
|
|
1570
|
+
if (openIdx !== -1) {
|
|
1571
|
+
cleanedText += remaining.slice(0, openIdx).replace(/<\|[a-z_]+\|>/g, "");
|
|
1572
|
+
inThinkBlock = true;
|
|
1573
|
+
remaining = remaining.slice(openIdx + "<think>".length);
|
|
1574
|
+
} else {
|
|
1575
|
+
cleanedText += remaining.replace(/<\|[a-z_]+\|>/g, "");
|
|
1576
|
+
remaining = "";
|
|
1685
1577
|
}
|
|
1686
1578
|
}
|
|
1687
1579
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1580
|
+
if (jsonStart === -1) {
|
|
1581
|
+
jsonStart = cleanedText.indexOf("{");
|
|
1582
|
+
}
|
|
1583
|
+
if (jsonStart !== -1) {
|
|
1584
|
+
const partial = parsePartialJson(cleanedText.slice(jsonStart));
|
|
1585
|
+
if (partial !== undefined) {
|
|
1586
|
+
emit({ type: "object-delta", port: "object", objectDelta: partial });
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
emit({ type: "text-delta", port: "text", textDelta: delta });
|
|
1591
|
+
}, TextStreamer);
|
|
1592
|
+
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
1593
|
+
if (signal) {
|
|
1594
|
+
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
1595
|
+
}
|
|
1596
|
+
await generateText(formattedPrompt, {
|
|
1691
1597
|
max_new_tokens: input.maxTokens ?? 1024,
|
|
1692
1598
|
temperature: input.temperature ?? undefined,
|
|
1693
1599
|
return_full_text: false,
|
|
1694
1600
|
streamer,
|
|
1695
1601
|
stopping_criteria: [stopping_criteria]
|
|
1696
|
-
})
|
|
1697
|
-
yield* queue.iterable;
|
|
1698
|
-
await pipelinePromise;
|
|
1602
|
+
});
|
|
1699
1603
|
const object = extractJsonFromText(fullText);
|
|
1700
|
-
|
|
1604
|
+
emit({ type: "finish", data: { object } });
|
|
1701
1605
|
};
|
|
1702
1606
|
|
|
1703
1607
|
// src/ai/common/HFT_TextClassification.ts
|
|
1704
1608
|
init_HFT_Pipeline();
|
|
1705
|
-
var HFT_TextClassification = async (input, model,
|
|
1609
|
+
var HFT_TextClassification = async (input, model, signal, emit) => {
|
|
1706
1610
|
if (model?.provider_config?.pipeline === "zero-shot-classification") {
|
|
1707
1611
|
if (!input.candidateLabels || !Array.isArray(input.candidateLabels) || input.candidateLabels.length === 0) {
|
|
1708
1612
|
throw new Error("Zero-shot text classification requires candidate labels");
|
|
1709
1613
|
}
|
|
1710
|
-
const zeroShotClassifier = await getPipeline(model,
|
|
1614
|
+
const zeroShotClassifier = await getPipeline(model, emit, {}, signal);
|
|
1711
1615
|
const result2 = await zeroShotClassifier(input.text, input.candidateLabels, {});
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1616
|
+
emit({
|
|
1617
|
+
type: "finish",
|
|
1618
|
+
data: {
|
|
1619
|
+
categories: result2.labels.map((label, idx) => ({
|
|
1620
|
+
label,
|
|
1621
|
+
score: result2.scores[idx]
|
|
1622
|
+
}))
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
return;
|
|
1718
1626
|
}
|
|
1719
|
-
const TextClassification = await getPipeline(model,
|
|
1627
|
+
const TextClassification = await getPipeline(model, emit, {}, signal);
|
|
1720
1628
|
const result = await TextClassification(input.text, {
|
|
1721
1629
|
top_k: input.maxCategories || undefined
|
|
1722
1630
|
});
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1631
|
+
emit({
|
|
1632
|
+
type: "finish",
|
|
1633
|
+
data: {
|
|
1634
|
+
categories: result.map((category) => ({
|
|
1635
|
+
label: category.label,
|
|
1636
|
+
score: category.score
|
|
1637
|
+
}))
|
|
1638
|
+
}
|
|
1639
|
+
});
|
|
1729
1640
|
};
|
|
1730
1641
|
|
|
1731
1642
|
// src/ai/common/HFT_TextEmbedding.ts
|
|
1732
1643
|
init_HFT_Pipeline();
|
|
1733
1644
|
import { getLogger as getLogger5 } from "@workglow/util/worker";
|
|
1734
|
-
var HFT_TextEmbedding = async (input, model,
|
|
1645
|
+
var HFT_TextEmbedding = async (input, model, signal, emit) => {
|
|
1735
1646
|
const logger = getLogger5();
|
|
1736
1647
|
const uuid = crypto.randomUUID();
|
|
1737
1648
|
const timerLabel = `hft:TextEmbedding:${model?.provider_config.model_path}:${uuid}`;
|
|
1738
1649
|
logger.time(timerLabel, { model: model?.provider_config.model_path });
|
|
1739
|
-
const generateEmbedding = await getPipeline(model,
|
|
1650
|
+
const generateEmbedding = await getPipeline(model, emit, {}, signal);
|
|
1740
1651
|
logger.debug("HFT TextEmbedding: pipeline ready, generating embedding", {
|
|
1741
1652
|
model: model?.provider_config.model_path,
|
|
1742
1653
|
inputLength: Array.isArray(input.text) ? input.text.length : input.text?.length
|
|
@@ -1757,7 +1668,8 @@ var HFT_TextEmbedding = async (input, model, onProgress, signal) => {
|
|
|
1757
1668
|
}
|
|
1758
1669
|
const vectors = Array.from({ length: numTexts }, (_, i) => hfVector[i].data.slice());
|
|
1759
1670
|
logger.timeEnd(timerLabel, { batchSize: numTexts, dimensions: vectorDim });
|
|
1760
|
-
|
|
1671
|
+
emit({ type: "finish", data: { vector: vectors } });
|
|
1672
|
+
return;
|
|
1761
1673
|
}
|
|
1762
1674
|
if (hfVector.size !== embeddingDim) {
|
|
1763
1675
|
logger.timeEnd(timerLabel, { status: "error", reason: "dimension mismatch" });
|
|
@@ -1765,38 +1677,32 @@ var HFT_TextEmbedding = async (input, model, onProgress, signal) => {
|
|
|
1765
1677
|
throw new Error(`HuggingFace Embedding vector length does not match model dimensions v${hfVector.size} != m${embeddingDim}`);
|
|
1766
1678
|
}
|
|
1767
1679
|
logger.timeEnd(timerLabel, { dimensions: hfVector.size });
|
|
1768
|
-
|
|
1680
|
+
emit({ type: "finish", data: { vector: hfVector.data } });
|
|
1769
1681
|
};
|
|
1770
1682
|
|
|
1771
1683
|
// src/ai/common/HFT_TextFillMask.ts
|
|
1772
1684
|
init_HFT_Pipeline();
|
|
1773
|
-
var HFT_TextFillMask = async (input, model,
|
|
1774
|
-
const unmasker = await getPipeline(model,
|
|
1685
|
+
var HFT_TextFillMask = async (input, model, signal, emit) => {
|
|
1686
|
+
const unmasker = await getPipeline(model, emit, {}, signal);
|
|
1775
1687
|
const predictions = await unmasker(input.text);
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1688
|
+
emit({
|
|
1689
|
+
type: "finish",
|
|
1690
|
+
data: {
|
|
1691
|
+
predictions: predictions.map((prediction) => ({
|
|
1692
|
+
entity: prediction.token_str,
|
|
1693
|
+
score: prediction.score,
|
|
1694
|
+
sequence: prediction.sequence
|
|
1695
|
+
}))
|
|
1696
|
+
}
|
|
1697
|
+
});
|
|
1783
1698
|
};
|
|
1784
1699
|
|
|
1785
1700
|
// src/ai/common/HFT_TextGeneration.ts
|
|
1786
1701
|
init_HFT_Pipeline();
|
|
1787
|
-
|
|
1788
|
-
|
|
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);
|
|
1702
|
+
var HFT_TextGeneration = async (input, model, signal, emit, _outputSchema, sessionId) => {
|
|
1703
|
+
const generateText = await getPipeline(model, emit, {}, signal);
|
|
1794
1704
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1795
|
-
|
|
1796
|
-
model: model?.provider_config.model_path,
|
|
1797
|
-
promptLength: input.prompt?.length
|
|
1798
|
-
});
|
|
1799
|
-
const streamer = createTextStreamer(generateText.tokenizer, onProgress, TextStreamer);
|
|
1705
|
+
const streamer = createStreamingTextStreamer(generateText.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
|
|
1800
1706
|
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
1801
1707
|
if (signal) {
|
|
1802
1708
|
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
@@ -1819,366 +1725,160 @@ var HFT_TextGeneration = async (input, model, onProgress, signal, _outputSchema,
|
|
|
1819
1725
|
past_key_values = session.cache;
|
|
1820
1726
|
}
|
|
1821
1727
|
const messages = [{ role: "user", content: input.prompt }];
|
|
1822
|
-
|
|
1728
|
+
await generateText(messages, {
|
|
1823
1729
|
streamer,
|
|
1824
1730
|
do_sample: false,
|
|
1825
1731
|
max_new_tokens: input.maxTokens ?? 4 * 1024,
|
|
1826
1732
|
stopping_criteria: [stopping_criteria],
|
|
1827
1733
|
...past_key_values ? { past_key_values } : {}
|
|
1828
1734
|
});
|
|
1829
|
-
|
|
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: {} };
|
|
1735
|
+
emit({ type: "finish", data: {} });
|
|
1876
1736
|
};
|
|
1877
1737
|
|
|
1878
1738
|
// src/ai/common/HFT_TextLanguageDetection.ts
|
|
1879
1739
|
init_HFT_Pipeline();
|
|
1880
|
-
var HFT_TextLanguageDetection = async (input, model,
|
|
1881
|
-
const TextClassification = await getPipeline(model,
|
|
1740
|
+
var HFT_TextLanguageDetection = async (input, model, signal, emit) => {
|
|
1741
|
+
const TextClassification = await getPipeline(model, emit, {}, signal);
|
|
1882
1742
|
const result = await TextClassification(input.text, {
|
|
1883
1743
|
top_k: input.maxLanguages || undefined
|
|
1884
1744
|
});
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1745
|
+
emit({
|
|
1746
|
+
type: "finish",
|
|
1747
|
+
data: {
|
|
1748
|
+
languages: result.map((category) => ({
|
|
1749
|
+
language: category.label,
|
|
1750
|
+
score: category.score
|
|
1751
|
+
}))
|
|
1752
|
+
}
|
|
1753
|
+
});
|
|
1891
1754
|
};
|
|
1892
1755
|
|
|
1893
1756
|
// src/ai/common/HFT_TextNamedEntityRecognition.ts
|
|
1894
1757
|
init_HFT_Pipeline();
|
|
1895
|
-
var HFT_TextNamedEntityRecognition = async (input, model,
|
|
1896
|
-
const textNamedEntityRecognition = await getPipeline(model,
|
|
1758
|
+
var HFT_TextNamedEntityRecognition = async (input, model, signal, emit) => {
|
|
1759
|
+
const textNamedEntityRecognition = await getPipeline(model, emit, {}, signal);
|
|
1897
1760
|
const results = await textNamedEntityRecognition(input.text, {
|
|
1898
1761
|
ignore_labels: input.blockList
|
|
1899
1762
|
});
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1763
|
+
emit({
|
|
1764
|
+
type: "finish",
|
|
1765
|
+
data: {
|
|
1766
|
+
entities: results.map((entity) => ({
|
|
1767
|
+
entity: entity.entity,
|
|
1768
|
+
score: entity.score,
|
|
1769
|
+
word: entity.word
|
|
1770
|
+
}))
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1907
1773
|
};
|
|
1908
1774
|
|
|
1909
1775
|
// src/ai/common/HFT_TextQuestionAnswer.ts
|
|
1910
1776
|
init_HFT_Pipeline();
|
|
1911
|
-
var HFT_TextQuestionAnswer = async (input, model,
|
|
1912
|
-
const generateAnswer = await getPipeline(model,
|
|
1777
|
+
var HFT_TextQuestionAnswer = async (input, model, signal, emit) => {
|
|
1778
|
+
const generateAnswer = await getPipeline(model, emit, {}, signal);
|
|
1913
1779
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1914
|
-
const streamer =
|
|
1780
|
+
const streamer = createStreamingTextStreamer(generateAnswer.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
|
|
1915
1781
|
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
1916
1782
|
if (signal) {
|
|
1917
1783
|
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
1918
1784
|
}
|
|
1919
|
-
const
|
|
1785
|
+
const pipelineResult = await generateAnswer(input.question, input.context, {
|
|
1920
1786
|
streamer,
|
|
1921
1787
|
stopping_criteria: [stopping_criteria]
|
|
1922
1788
|
});
|
|
1923
|
-
const answerText =
|
|
1924
|
-
|
|
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 } };
|
|
1789
|
+
const answerText = Array.isArray(pipelineResult) ? pipelineResult[0]?.answer ?? "" : pipelineResult?.answer ?? "";
|
|
1790
|
+
emit({ type: "finish", data: { text: answerText } });
|
|
1955
1791
|
};
|
|
1956
1792
|
|
|
1957
1793
|
// src/ai/common/HFT_TextRewriter.ts
|
|
1958
1794
|
init_HFT_Pipeline();
|
|
1959
|
-
var HFT_TextRewriter = async (input, model,
|
|
1960
|
-
const generateText = await getPipeline(model,
|
|
1795
|
+
var HFT_TextRewriter = async (input, model, signal, emit) => {
|
|
1796
|
+
const generateText = await getPipeline(model, emit, {}, signal);
|
|
1961
1797
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
1962
|
-
const streamer =
|
|
1798
|
+
const streamer = createStreamingTextStreamer(generateText.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
|
|
1963
1799
|
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
1964
1800
|
if (signal) {
|
|
1965
1801
|
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
1966
1802
|
}
|
|
1967
1803
|
const promptedText = (input.prompt ? input.prompt + `
|
|
1968
1804
|
` : "") + input.text;
|
|
1969
|
-
|
|
1805
|
+
await generateText(promptedText, {
|
|
1970
1806
|
streamer,
|
|
1971
1807
|
stopping_criteria: [stopping_criteria]
|
|
1972
1808
|
});
|
|
1973
|
-
|
|
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: {} };
|
|
1809
|
+
emit({ type: "finish", data: {} });
|
|
2003
1810
|
};
|
|
2004
1811
|
|
|
2005
1812
|
// src/ai/common/HFT_TextSummary.ts
|
|
2006
1813
|
init_HFT_Pipeline();
|
|
2007
|
-
var HFT_TextSummary = async (input, model,
|
|
2008
|
-
const generateSummary = await getPipeline(model,
|
|
1814
|
+
var HFT_TextSummary = async (input, model, signal, emit) => {
|
|
1815
|
+
const generateSummary = await getPipeline(model, emit, {}, signal);
|
|
2009
1816
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
2010
|
-
const streamer =
|
|
1817
|
+
const streamer = createStreamingTextStreamer(generateSummary.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
|
|
2011
1818
|
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
2012
1819
|
if (signal) {
|
|
2013
1820
|
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
2014
1821
|
}
|
|
2015
|
-
|
|
1822
|
+
await generateSummary(input.text, {
|
|
2016
1823
|
streamer,
|
|
2017
1824
|
stopping_criteria: [stopping_criteria]
|
|
2018
1825
|
});
|
|
2019
|
-
|
|
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: {} };
|
|
1826
|
+
emit({ type: "finish", data: {} });
|
|
2046
1827
|
};
|
|
2047
1828
|
|
|
2048
1829
|
// src/ai/common/HFT_TextTranslation.ts
|
|
2049
1830
|
init_HFT_Pipeline();
|
|
2050
|
-
var HFT_TextTranslation = async (input, model,
|
|
2051
|
-
const translate = await getPipeline(model,
|
|
1831
|
+
var HFT_TextTranslation = async (input, model, signal, emit) => {
|
|
1832
|
+
const translate = await getPipeline(model, emit, {}, signal);
|
|
2052
1833
|
const { TextStreamer, InterruptableStoppingCriteria } = await loadTransformersSDK();
|
|
2053
|
-
const streamer =
|
|
1834
|
+
const streamer = createStreamingTextStreamer(translate.tokenizer, (text) => emit({ type: "text-delta", port: "text", textDelta: text }), TextStreamer);
|
|
2054
1835
|
const stopping_criteria = new InterruptableStoppingCriteria;
|
|
2055
1836
|
if (signal) {
|
|
2056
1837
|
signal.addEventListener("abort", () => stopping_criteria.interrupt(), { once: true });
|
|
2057
1838
|
}
|
|
2058
|
-
|
|
1839
|
+
await translate(input.text, {
|
|
2059
1840
|
src_lang: input.source_lang,
|
|
2060
1841
|
tgt_lang: input.target_lang,
|
|
2061
1842
|
streamer,
|
|
2062
1843
|
stopping_criteria: [stopping_criteria]
|
|
2063
1844
|
});
|
|
2064
|
-
|
|
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 } };
|
|
1845
|
+
emit({ type: "finish", data: { target_lang: input.target_lang } });
|
|
2089
1846
|
};
|
|
2090
1847
|
|
|
2091
|
-
// src/ai/common/
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
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);
|
|
1848
|
+
// src/ai/common/HFT_JobRunFns.ts
|
|
1849
|
+
var HFT_TextGeneration_Unified = async (input, model, signal, emit, outputSchema, sessionId) => {
|
|
1850
|
+
const maybeMessages = input.messages;
|
|
1851
|
+
if (Array.isArray(maybeMessages) && maybeMessages.length > 0) {
|
|
1852
|
+
await HFT_Chat(input, model, signal, emit, outputSchema, sessionId);
|
|
2136
1853
|
} else {
|
|
2137
|
-
await
|
|
1854
|
+
await HFT_TextGeneration(input, model, signal, emit, outputSchema, sessionId);
|
|
2138
1855
|
}
|
|
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
1856
|
};
|
|
1857
|
+
var HFT_RUN_FNS = [
|
|
1858
|
+
{ serves: HFT_TEXT_GENERATION, runFn: HFT_TextGeneration_Unified },
|
|
1859
|
+
{ serves: HFT_TOOL_USE, runFn: HFT_ToolCalling },
|
|
1860
|
+
{ serves: HFT_JSON_MODE, runFn: HFT_StructuredGeneration },
|
|
1861
|
+
{ serves: HFT_TEXT_REWRITER, runFn: HFT_TextRewriter },
|
|
1862
|
+
{ serves: HFT_TEXT_SUMMARY, runFn: HFT_TextSummary },
|
|
1863
|
+
{ serves: HFT_TEXT_TRANSLATION, runFn: HFT_TextTranslation },
|
|
1864
|
+
{ serves: HFT_TEXT_QUESTION_ANSWERING, runFn: HFT_TextQuestionAnswer },
|
|
1865
|
+
{ serves: HFT_TEXT_EMBEDDING, runFn: HFT_TextEmbedding },
|
|
1866
|
+
{ serves: HFT_TEXT_CLASSIFICATION, runFn: HFT_TextClassification },
|
|
1867
|
+
{ serves: HFT_TEXT_LANGUAGE_DETECTION, runFn: HFT_TextLanguageDetection },
|
|
1868
|
+
{ serves: HFT_TEXT_FILL_MASK, runFn: HFT_TextFillMask },
|
|
1869
|
+
{ serves: HFT_TEXT_NER, runFn: HFT_TextNamedEntityRecognition },
|
|
1870
|
+
{ serves: HFT_IMAGE_CLASSIFICATION, runFn: HFT_ImageClassification },
|
|
1871
|
+
{ serves: HFT_IMAGE_EMBEDDING, runFn: HFT_ImageEmbedding },
|
|
1872
|
+
{ serves: HFT_IMAGE_SEGMENTATION, runFn: HFT_ImageSegmentation },
|
|
1873
|
+
{ serves: HFT_IMAGE_TO_TEXT, runFn: HFT_ImageToText },
|
|
1874
|
+
{ serves: HFT_IMAGE_BACKGROUND_REMOVAL, runFn: HFT_BackgroundRemoval },
|
|
1875
|
+
{ serves: HFT_IMAGE_OBJECT_DETECTION, runFn: HFT_ObjectDetection },
|
|
1876
|
+
{ serves: HFT_COUNT_TOKENS, runFn: HFT_CountTokens },
|
|
1877
|
+
{ serves: HFT_MODEL_DOWNLOAD_REMOVE, runFn: HFT_DownloadRemove },
|
|
1878
|
+
{ serves: HFT_MODEL_DOWNLOAD, runFn: HFT_Download },
|
|
1879
|
+
{ serves: HFT_MODEL_SEARCH, runFn: HFT_ModelSearch },
|
|
1880
|
+
{ serves: HFT_MODEL_INFO, runFn: HFT_ModelInfo }
|
|
1881
|
+
];
|
|
2182
1882
|
var HFT_PREVIEW_TASKS = {
|
|
2183
1883
|
CountTokensTask: HFT_CountTokens_Preview
|
|
2184
1884
|
};
|
|
@@ -2188,6 +1888,100 @@ init_HFT_Pipeline();
|
|
|
2188
1888
|
|
|
2189
1889
|
// src/ai/HuggingFaceTransformersQueuedProvider.ts
|
|
2190
1890
|
import { QueuedAiProvider } from "@workglow/ai";
|
|
1891
|
+
|
|
1892
|
+
// src/ai/common/HFT_Capabilities.ts
|
|
1893
|
+
var HFT_RUN_FN_SPECS = HFT_CAPABILITY_SETS.map((serves) => ({ serves }));
|
|
1894
|
+
function hftWorkerRunFnSpecs() {
|
|
1895
|
+
return HFT_RUN_FN_SPECS;
|
|
1896
|
+
}
|
|
1897
|
+
function inferHftCapabilities(model) {
|
|
1898
|
+
const declared = model.capabilities ?? [];
|
|
1899
|
+
if (declared.length > 0)
|
|
1900
|
+
return declared;
|
|
1901
|
+
const id = String(model.model_id ?? model.provider_config?.model_path ?? model.provider_config?.model_name ?? "");
|
|
1902
|
+
const pipelineTask = model.provider_config?.pipeline_task ?? "";
|
|
1903
|
+
switch (pipelineTask) {
|
|
1904
|
+
case "text-generation":
|
|
1905
|
+
return [
|
|
1906
|
+
"text.generation",
|
|
1907
|
+
"text.rewriter",
|
|
1908
|
+
"text.summary",
|
|
1909
|
+
"tool-use",
|
|
1910
|
+
"model.count-tokens",
|
|
1911
|
+
"model.download-remove",
|
|
1912
|
+
"model.info",
|
|
1913
|
+
"model.search"
|
|
1914
|
+
];
|
|
1915
|
+
case "feature-extraction":
|
|
1916
|
+
case "sentence-similarity":
|
|
1917
|
+
return ["text.embedding", "model.download-remove", "model.info", "model.search"];
|
|
1918
|
+
case "text-classification":
|
|
1919
|
+
return ["text.classification", "model.download-remove", "model.info", "model.search"];
|
|
1920
|
+
case "token-classification":
|
|
1921
|
+
return ["text.ner", "model.download-remove", "model.info", "model.search"];
|
|
1922
|
+
case "fill-mask":
|
|
1923
|
+
return ["text.fill-mask", "model.download-remove", "model.info", "model.search"];
|
|
1924
|
+
case "translation":
|
|
1925
|
+
return ["text.translation", "model.download-remove", "model.info", "model.search"];
|
|
1926
|
+
case "summarization":
|
|
1927
|
+
return ["text.summary", "model.download-remove", "model.info", "model.search"];
|
|
1928
|
+
case "question-answering":
|
|
1929
|
+
return ["text.question-answering", "model.download-remove", "model.info", "model.search"];
|
|
1930
|
+
case "image-classification":
|
|
1931
|
+
return ["image.classification", "model.download-remove", "model.info", "model.search"];
|
|
1932
|
+
case "image-segmentation":
|
|
1933
|
+
return ["image.segmentation", "model.download-remove", "model.info", "model.search"];
|
|
1934
|
+
case "image-to-text":
|
|
1935
|
+
return ["image.to-text", "model.download-remove", "model.info", "model.search"];
|
|
1936
|
+
case "object-detection":
|
|
1937
|
+
return ["image.object-detection", "model.download-remove", "model.info", "model.search"];
|
|
1938
|
+
case "zero-shot-image-classification":
|
|
1939
|
+
return [
|
|
1940
|
+
"image.classification",
|
|
1941
|
+
"image.embedding",
|
|
1942
|
+
"model.download-remove",
|
|
1943
|
+
"model.info",
|
|
1944
|
+
"model.search"
|
|
1945
|
+
];
|
|
1946
|
+
}
|
|
1947
|
+
const baseName = id.split("/").pop() ?? id;
|
|
1948
|
+
if (/embed|minilm|bge-|gte-|e5-/i.test(baseName)) {
|
|
1949
|
+
return ["text.embedding", "model.download-remove", "model.info", "model.search"];
|
|
1950
|
+
}
|
|
1951
|
+
if (/clip|siglip/i.test(baseName)) {
|
|
1952
|
+
return [
|
|
1953
|
+
"image.classification",
|
|
1954
|
+
"image.embedding",
|
|
1955
|
+
"model.download-remove",
|
|
1956
|
+
"model.info",
|
|
1957
|
+
"model.search"
|
|
1958
|
+
];
|
|
1959
|
+
}
|
|
1960
|
+
if (/yolo|detr|owl/i.test(baseName)) {
|
|
1961
|
+
return ["image.object-detection", "model.download-remove", "model.info", "model.search"];
|
|
1962
|
+
}
|
|
1963
|
+
if (/sam|segformer|mask/i.test(baseName)) {
|
|
1964
|
+
return ["image.segmentation", "model.download-remove", "model.info", "model.search"];
|
|
1965
|
+
}
|
|
1966
|
+
if (/blip|llava|vision/i.test(baseName)) {
|
|
1967
|
+
return ["image.to-text", "model.download-remove", "model.info", "model.search"];
|
|
1968
|
+
}
|
|
1969
|
+
if (/llama|mistral|gemma|phi|qwen|tinyllama|smollm/i.test(baseName)) {
|
|
1970
|
+
return [
|
|
1971
|
+
"text.generation",
|
|
1972
|
+
"text.rewriter",
|
|
1973
|
+
"text.summary",
|
|
1974
|
+
"tool-use",
|
|
1975
|
+
"model.count-tokens",
|
|
1976
|
+
"model.download-remove",
|
|
1977
|
+
"model.info",
|
|
1978
|
+
"model.search"
|
|
1979
|
+
];
|
|
1980
|
+
}
|
|
1981
|
+
return ["model.search", "model.info"];
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
// src/ai/HuggingFaceTransformersQueuedProvider.ts
|
|
2191
1985
|
init_HFT_Pipeline();
|
|
2192
1986
|
var GPU_DEVICES = new Set(["webgpu", "gpu", "metal"]);
|
|
2193
1987
|
var HFT_CPU_QUEUE_CONCURRENCY_PRODUCTION = 4;
|
|
@@ -2217,34 +2011,14 @@ class HuggingFaceTransformersQueuedProvider extends QueuedAiProvider {
|
|
|
2217
2011
|
isLocal = true;
|
|
2218
2012
|
supportsBrowser = true;
|
|
2219
2013
|
cpuStrategy;
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
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);
|
|
2014
|
+
constructor(promiseRunFns, previewTasks) {
|
|
2015
|
+
super(promiseRunFns, previewTasks);
|
|
2016
|
+
}
|
|
2017
|
+
inferCapabilities(model) {
|
|
2018
|
+
return inferHftCapabilities(model);
|
|
2019
|
+
}
|
|
2020
|
+
workerRunFnSpecs() {
|
|
2021
|
+
return hftWorkerRunFnSpecs();
|
|
2248
2022
|
}
|
|
2249
2023
|
createSession(_model) {
|
|
2250
2024
|
return crypto.randomUUID();
|
|
@@ -2269,7 +2043,7 @@ class HuggingFaceTransformersQueuedProvider extends QueuedAiProvider {
|
|
|
2269
2043
|
async function registerHuggingFaceTransformersInline(options) {
|
|
2270
2044
|
const { env } = await loadTransformersSDK();
|
|
2271
2045
|
env.backends.onnx.wasm.proxy = true;
|
|
2272
|
-
const provider = new HuggingFaceTransformersQueuedProvider(
|
|
2046
|
+
const provider = new HuggingFaceTransformersQueuedProvider(HFT_RUN_FNS, HFT_PREVIEW_TASKS);
|
|
2273
2047
|
const baseDispose = provider.dispose.bind(provider);
|
|
2274
2048
|
provider.dispose = async () => {
|
|
2275
2049
|
await clearHftInlinePipelineCache();
|
|
@@ -2280,7 +2054,6 @@ async function registerHuggingFaceTransformersInline(options) {
|
|
|
2280
2054
|
|
|
2281
2055
|
// src/ai/registerHuggingFaceTransformersWorker.ts
|
|
2282
2056
|
import { registerProviderWorker } from "@workglow/ai/provider-utils";
|
|
2283
|
-
init_HFT_Pipeline();
|
|
2284
2057
|
|
|
2285
2058
|
// src/ai/HuggingFaceTransformersProvider.ts
|
|
2286
2059
|
import { AiProvider } from "@workglow/ai/worker";
|
|
@@ -2291,34 +2064,14 @@ class HuggingFaceTransformersProvider extends AiProvider {
|
|
|
2291
2064
|
displayName = "Hugging Face Transformers (ONNX)";
|
|
2292
2065
|
isLocal = true;
|
|
2293
2066
|
supportsBrowser = true;
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
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);
|
|
2067
|
+
constructor(promiseRunFns, previewTasks) {
|
|
2068
|
+
super(promiseRunFns, previewTasks);
|
|
2069
|
+
}
|
|
2070
|
+
inferCapabilities(model) {
|
|
2071
|
+
return inferHftCapabilities(model);
|
|
2072
|
+
}
|
|
2073
|
+
workerRunFnSpecs() {
|
|
2074
|
+
return hftWorkerRunFnSpecs();
|
|
2322
2075
|
}
|
|
2323
2076
|
createSession(_model) {
|
|
2324
2077
|
return crypto.randomUUID();
|
|
@@ -2329,12 +2082,13 @@ class HuggingFaceTransformersProvider extends AiProvider {
|
|
|
2329
2082
|
}
|
|
2330
2083
|
|
|
2331
2084
|
// src/ai/registerHuggingFaceTransformersWorker.ts
|
|
2085
|
+
init_HFT_Pipeline();
|
|
2332
2086
|
async function registerHuggingFaceTransformersWorker() {
|
|
2333
2087
|
const sdk = await loadTransformersSDK();
|
|
2334
2088
|
globalThis.__HFT__ = sdk;
|
|
2335
2089
|
const { env } = sdk;
|
|
2336
2090
|
env.backends.onnx.wasm.proxy = true;
|
|
2337
|
-
await registerProviderWorker((ws) => new HuggingFaceTransformersProvider(
|
|
2091
|
+
await registerProviderWorker((ws) => new HuggingFaceTransformersProvider(HFT_RUN_FNS, HFT_PREVIEW_TASKS).registerOnWorkerServer(ws), "HuggingFaceTransformers");
|
|
2338
2092
|
}
|
|
2339
2093
|
export {
|
|
2340
2094
|
setHftSession,
|
|
@@ -2365,4 +2119,4 @@ export {
|
|
|
2365
2119
|
HFT_NULL_PROCESSOR_PREFIX
|
|
2366
2120
|
};
|
|
2367
2121
|
|
|
2368
|
-
//# debugId=
|
|
2122
|
+
//# debugId=93CB8C37EE02941864756E2164756E21
|