@huggingface/inference 3.3.3 → 3.3.5
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/README.md +4 -0
- package/dist/index.cjs +131 -53
- package/dist/index.js +131 -53
- package/dist/src/lib/makeRequestOptions.d.ts +0 -2
- package/dist/src/lib/makeRequestOptions.d.ts.map +1 -1
- package/dist/src/providers/black-forest-labs.d.ts +18 -0
- package/dist/src/providers/black-forest-labs.d.ts.map +1 -0
- package/dist/src/providers/consts.d.ts.map +1 -1
- package/dist/src/providers/hyperbolic.d.ts +18 -0
- package/dist/src/providers/hyperbolic.d.ts.map +1 -0
- package/dist/src/providers/novita.d.ts +18 -0
- package/dist/src/providers/novita.d.ts.map +1 -0
- package/dist/src/tasks/cv/textToImage.d.ts +10 -1
- package/dist/src/tasks/cv/textToImage.d.ts.map +1 -1
- package/dist/src/tasks/nlp/featureExtraction.d.ts.map +1 -1
- package/dist/src/tasks/nlp/sentenceSimilarity.d.ts.map +1 -1
- package/dist/src/tasks/nlp/textGeneration.d.ts.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/delay.d.ts +2 -0
- package/dist/src/utils/delay.d.ts.map +1 -0
- package/dist/test/HfInference.spec.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/lib/makeRequestOptions.ts +51 -16
- package/src/providers/black-forest-labs.ts +18 -0
- package/src/providers/consts.ts +3 -0
- package/src/providers/hyperbolic.ts +18 -0
- package/src/providers/novita.ts +18 -0
- package/src/tasks/cv/textToImage.ts +95 -6
- package/src/tasks/nlp/featureExtraction.ts +0 -4
- package/src/tasks/nlp/sentenceSimilarity.ts +0 -3
- package/src/tasks/nlp/textGeneration.ts +31 -0
- package/src/types.ts +5 -1
- package/src/utils/delay.ts +5 -0
package/README.md
CHANGED
|
@@ -49,10 +49,13 @@ You can send inference requests to third-party providers with the inference clie
|
|
|
49
49
|
Currently, we support the following providers:
|
|
50
50
|
- [Fal.ai](https://fal.ai)
|
|
51
51
|
- [Fireworks AI](https://fireworks.ai)
|
|
52
|
+
- [Hyperbolic](https://hyperbolic.xyz)
|
|
52
53
|
- [Nebius](https://studio.nebius.ai)
|
|
54
|
+
- [Novita](https://novita.ai/?utm_source=github_huggingface&utm_medium=github_readme&utm_campaign=link)
|
|
53
55
|
- [Replicate](https://replicate.com)
|
|
54
56
|
- [Sambanova](https://sambanova.ai)
|
|
55
57
|
- [Together](https://together.xyz)
|
|
58
|
+
- [Blackforestlabs](https://blackforestlabs.ai)
|
|
56
59
|
|
|
57
60
|
To send requests to a third-party provider, you have to pass the `provider` parameter to the inference function. Make sure your request is authenticated with an access token.
|
|
58
61
|
```ts
|
|
@@ -72,6 +75,7 @@ When authenticated with a third-party provider key, the request is made directly
|
|
|
72
75
|
Only a subset of models are supported when requesting third-party providers. You can check the list of supported models per pipeline tasks here:
|
|
73
76
|
- [Fal.ai supported models](https://huggingface.co/api/partners/fal-ai/models)
|
|
74
77
|
- [Fireworks AI supported models](https://huggingface.co/api/partners/fireworks-ai/models)
|
|
78
|
+
- [Hyperbolic supported models](https://huggingface.co/api/partners/hyperbolic/models)
|
|
75
79
|
- [Nebius supported models](https://huggingface.co/api/partners/nebius/models)
|
|
76
80
|
- [Replicate supported models](https://huggingface.co/api/partners/replicate/models)
|
|
77
81
|
- [Sambanova supported models](https://huggingface.co/api/partners/sambanova/models)
|
package/dist/index.cjs
CHANGED
|
@@ -115,9 +115,18 @@ var SAMBANOVA_API_BASE_URL = "https://api.sambanova.ai";
|
|
|
115
115
|
// src/providers/together.ts
|
|
116
116
|
var TOGETHER_API_BASE_URL = "https://api.together.xyz";
|
|
117
117
|
|
|
118
|
+
// src/providers/novita.ts
|
|
119
|
+
var NOVITA_API_BASE_URL = "https://api.novita.ai/v3/openai";
|
|
120
|
+
|
|
118
121
|
// src/providers/fireworks-ai.ts
|
|
119
122
|
var FIREWORKS_AI_API_BASE_URL = "https://api.fireworks.ai/inference";
|
|
120
123
|
|
|
124
|
+
// src/providers/hyperbolic.ts
|
|
125
|
+
var HYPERBOLIC_API_BASE_URL = "https://api.hyperbolic.xyz";
|
|
126
|
+
|
|
127
|
+
// src/providers/black-forest-labs.ts
|
|
128
|
+
var BLACKFORESTLABS_AI_API_BASE_URL = "https://api.us1.bfl.ai/v1";
|
|
129
|
+
|
|
121
130
|
// src/lib/isUrl.ts
|
|
122
131
|
function isUrl(modelOrUrl) {
|
|
123
132
|
return /^http(s?):/.test(modelOrUrl) || modelOrUrl.startsWith("/");
|
|
@@ -125,7 +134,7 @@ function isUrl(modelOrUrl) {
|
|
|
125
134
|
|
|
126
135
|
// package.json
|
|
127
136
|
var name = "@huggingface/inference";
|
|
128
|
-
var version = "3.3.
|
|
137
|
+
var version = "3.3.5";
|
|
129
138
|
|
|
130
139
|
// src/providers/consts.ts
|
|
131
140
|
var HARDCODED_MODEL_ID_MAPPING = {
|
|
@@ -135,13 +144,16 @@ var HARDCODED_MODEL_ID_MAPPING = {
|
|
|
135
144
|
* Example:
|
|
136
145
|
* "Qwen/Qwen2.5-Coder-32B-Instruct": "Qwen2.5-Coder-32B-Instruct",
|
|
137
146
|
*/
|
|
147
|
+
"black-forest-labs": {},
|
|
138
148
|
"fal-ai": {},
|
|
139
149
|
"fireworks-ai": {},
|
|
140
150
|
"hf-inference": {},
|
|
151
|
+
hyperbolic: {},
|
|
141
152
|
nebius: {},
|
|
142
153
|
replicate: {},
|
|
143
154
|
sambanova: {},
|
|
144
|
-
together: {}
|
|
155
|
+
together: {},
|
|
156
|
+
novita: {}
|
|
145
157
|
};
|
|
146
158
|
|
|
147
159
|
// src/lib/getProviderModelId.ts
|
|
@@ -195,13 +207,10 @@ async function makeRequestOptions(args, options) {
|
|
|
195
207
|
const { accessToken, endpointUrl, provider: maybeProvider, model: maybeModel, ...remainingArgs } = args;
|
|
196
208
|
let otherArgs = remainingArgs;
|
|
197
209
|
const provider = maybeProvider ?? "hf-inference";
|
|
198
|
-
const {
|
|
210
|
+
const { includeCredentials, taskHint, chatCompletion: chatCompletion2 } = options ?? {};
|
|
199
211
|
if (endpointUrl && provider !== "hf-inference") {
|
|
200
212
|
throw new Error(`Cannot use endpointUrl with a third-party provider.`);
|
|
201
213
|
}
|
|
202
|
-
if (forceTask && provider !== "hf-inference") {
|
|
203
|
-
throw new Error(`Cannot use forceTask with a third-party provider.`);
|
|
204
|
-
}
|
|
205
214
|
if (maybeModel && isUrl(maybeModel)) {
|
|
206
215
|
throw new Error(`Model URLs are no longer supported. Use endpointUrl instead.`);
|
|
207
216
|
}
|
|
@@ -218,14 +227,19 @@ async function makeRequestOptions(args, options) {
|
|
|
218
227
|
const url = endpointUrl ? chatCompletion2 ? endpointUrl + `/v1/chat/completions` : endpointUrl : makeUrl({
|
|
219
228
|
authMethod,
|
|
220
229
|
chatCompletion: chatCompletion2 ?? false,
|
|
221
|
-
forceTask,
|
|
222
230
|
model,
|
|
223
231
|
provider: provider ?? "hf-inference",
|
|
224
232
|
taskHint
|
|
225
233
|
});
|
|
226
234
|
const headers = {};
|
|
227
235
|
if (accessToken) {
|
|
228
|
-
|
|
236
|
+
if (provider === "fal-ai" && authMethod === "provider-key") {
|
|
237
|
+
headers["Authorization"] = `Key ${accessToken}`;
|
|
238
|
+
} else if (provider === "black-forest-labs" && authMethod === "provider-key") {
|
|
239
|
+
headers["X-Key"] = accessToken;
|
|
240
|
+
} else {
|
|
241
|
+
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
242
|
+
}
|
|
229
243
|
}
|
|
230
244
|
const ownUserAgent = `${name}/${version}`;
|
|
231
245
|
headers["User-Agent"] = [ownUserAgent, typeof navigator !== "undefined" ? navigator.userAgent : void 0].filter((x) => x !== void 0).join(" ");
|
|
@@ -251,7 +265,7 @@ async function makeRequestOptions(args, options) {
|
|
|
251
265
|
method: "POST",
|
|
252
266
|
body: binary ? args.data : JSON.stringify({
|
|
253
267
|
...otherArgs,
|
|
254
|
-
...chatCompletion2 || provider === "together" || provider === "nebius" ? { model } : void 0
|
|
268
|
+
...taskHint === "text-to-image" && provider === "hyperbolic" ? { model_name: model } : chatCompletion2 || provider === "together" || provider === "nebius" || provider === "hyperbolic" ? { model } : void 0
|
|
255
269
|
}),
|
|
256
270
|
...credentials ? { credentials } : void 0,
|
|
257
271
|
signal: options?.signal
|
|
@@ -264,6 +278,10 @@ function makeUrl(params) {
|
|
|
264
278
|
}
|
|
265
279
|
const shouldProxy = params.provider !== "hf-inference" && params.authMethod !== "provider-key";
|
|
266
280
|
switch (params.provider) {
|
|
281
|
+
case "black-forest-labs": {
|
|
282
|
+
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : BLACKFORESTLABS_AI_API_BASE_URL;
|
|
283
|
+
return `${baseUrl}/${params.model}`;
|
|
284
|
+
}
|
|
267
285
|
case "fal-ai": {
|
|
268
286
|
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : FAL_AI_API_BASE_URL;
|
|
269
287
|
return `${baseUrl}/${params.model}`;
|
|
@@ -315,13 +333,32 @@ function makeUrl(params) {
|
|
|
315
333
|
}
|
|
316
334
|
return baseUrl;
|
|
317
335
|
}
|
|
336
|
+
case "hyperbolic": {
|
|
337
|
+
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : HYPERBOLIC_API_BASE_URL;
|
|
338
|
+
if (params.taskHint === "text-to-image") {
|
|
339
|
+
return `${baseUrl}/v1/images/generations`;
|
|
340
|
+
}
|
|
341
|
+
return `${baseUrl}/v1/chat/completions`;
|
|
342
|
+
}
|
|
343
|
+
case "novita": {
|
|
344
|
+
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : NOVITA_API_BASE_URL;
|
|
345
|
+
if (params.taskHint === "text-generation") {
|
|
346
|
+
if (params.chatCompletion) {
|
|
347
|
+
return `${baseUrl}/chat/completions`;
|
|
348
|
+
}
|
|
349
|
+
return `${baseUrl}/completions`;
|
|
350
|
+
}
|
|
351
|
+
return baseUrl;
|
|
352
|
+
}
|
|
318
353
|
default: {
|
|
319
354
|
const baseUrl = HF_HUB_INFERENCE_PROXY_TEMPLATE.replaceAll("{{PROVIDER}}", "hf-inference");
|
|
320
|
-
|
|
355
|
+
if (params.taskHint && ["feature-extraction", "sentence-similarity"].includes(params.taskHint)) {
|
|
356
|
+
return `${baseUrl}/pipeline/${params.taskHint}/${params.model}`;
|
|
357
|
+
}
|
|
321
358
|
if (params.taskHint === "text-generation" && params.chatCompletion) {
|
|
322
|
-
return
|
|
359
|
+
return `${baseUrl}/models/${params.model}/v1/chat/completions`;
|
|
323
360
|
}
|
|
324
|
-
return
|
|
361
|
+
return `${baseUrl}/models/${params.model}`;
|
|
325
362
|
}
|
|
326
363
|
}
|
|
327
364
|
}
|
|
@@ -768,6 +805,13 @@ async function objectDetection(args, options) {
|
|
|
768
805
|
return res;
|
|
769
806
|
}
|
|
770
807
|
|
|
808
|
+
// src/utils/delay.ts
|
|
809
|
+
function delay(ms) {
|
|
810
|
+
return new Promise((resolve) => {
|
|
811
|
+
setTimeout(() => resolve(), ms);
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
|
|
771
815
|
// src/tasks/cv/textToImage.ts
|
|
772
816
|
function getResponseFormatArg(provider) {
|
|
773
817
|
switch (provider) {
|
|
@@ -795,17 +839,36 @@ async function textToImage(args, options) {
|
|
|
795
839
|
taskHint: "text-to-image"
|
|
796
840
|
});
|
|
797
841
|
if (res && typeof res === "object") {
|
|
842
|
+
if (args.provider === "black-forest-labs" && "polling_url" in res && typeof res.polling_url === "string") {
|
|
843
|
+
return await pollBflResponse(res.polling_url, options?.outputType);
|
|
844
|
+
}
|
|
798
845
|
if (args.provider === "fal-ai" && "images" in res && Array.isArray(res.images) && res.images[0].url) {
|
|
799
|
-
|
|
800
|
-
|
|
846
|
+
if (options?.outputType === "url") {
|
|
847
|
+
return res.images[0].url;
|
|
848
|
+
} else {
|
|
849
|
+
const image = await fetch(res.images[0].url);
|
|
850
|
+
return await image.blob();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
if (args.provider === "hyperbolic" && "images" in res && Array.isArray(res.images) && res.images[0] && typeof res.images[0].image === "string") {
|
|
854
|
+
if (options?.outputType === "url") {
|
|
855
|
+
return `data:image/jpeg;base64,${res.images[0].image}`;
|
|
856
|
+
}
|
|
857
|
+
const base64Response = await fetch(`data:image/jpeg;base64,${res.images[0].image}`);
|
|
858
|
+
return await base64Response.blob();
|
|
801
859
|
}
|
|
802
860
|
if ("data" in res && Array.isArray(res.data) && res.data[0].b64_json) {
|
|
803
861
|
const base64Data = res.data[0].b64_json;
|
|
862
|
+
if (options?.outputType === "url") {
|
|
863
|
+
return `data:image/jpeg;base64,${base64Data}`;
|
|
864
|
+
}
|
|
804
865
|
const base64Response = await fetch(`data:image/jpeg;base64,${base64Data}`);
|
|
805
|
-
|
|
806
|
-
return blob;
|
|
866
|
+
return await base64Response.blob();
|
|
807
867
|
}
|
|
808
868
|
if ("output" in res && Array.isArray(res.output)) {
|
|
869
|
+
if (options?.outputType === "url") {
|
|
870
|
+
return res.output[0];
|
|
871
|
+
}
|
|
809
872
|
const urlResponse = await fetch(res.output[0]);
|
|
810
873
|
const blob = await urlResponse.blob();
|
|
811
874
|
return blob;
|
|
@@ -815,8 +878,33 @@ async function textToImage(args, options) {
|
|
|
815
878
|
if (!isValidOutput) {
|
|
816
879
|
throw new InferenceOutputError("Expected Blob");
|
|
817
880
|
}
|
|
881
|
+
if (options?.outputType === "url") {
|
|
882
|
+
const b64 = await res.arrayBuffer().then((buf) => Buffer.from(buf).toString("base64"));
|
|
883
|
+
return `data:image/jpeg;base64,${b64}`;
|
|
884
|
+
}
|
|
818
885
|
return res;
|
|
819
886
|
}
|
|
887
|
+
async function pollBflResponse(url, outputType) {
|
|
888
|
+
const urlObj = new URL(url);
|
|
889
|
+
for (let step = 0; step < 5; step++) {
|
|
890
|
+
await delay(1e3);
|
|
891
|
+
console.debug(`Polling Black Forest Labs API for the result... ${step + 1}/5`);
|
|
892
|
+
urlObj.searchParams.set("attempt", step.toString(10));
|
|
893
|
+
const resp = await fetch(urlObj, { headers: { "Content-Type": "application/json" } });
|
|
894
|
+
if (!resp.ok) {
|
|
895
|
+
throw new InferenceOutputError("Failed to fetch result from black forest labs API");
|
|
896
|
+
}
|
|
897
|
+
const payload = await resp.json();
|
|
898
|
+
if (typeof payload === "object" && payload && "status" in payload && typeof payload.status === "string" && payload.status === "Ready" && "result" in payload && typeof payload.result === "object" && payload.result && "sample" in payload.result && typeof payload.result.sample === "string") {
|
|
899
|
+
if (outputType === "url") {
|
|
900
|
+
return payload.result.sample;
|
|
901
|
+
}
|
|
902
|
+
const image = await fetch(payload.result.sample);
|
|
903
|
+
return await image.blob();
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
throw new InferenceOutputError("Failed to fetch result from black forest labs API");
|
|
907
|
+
}
|
|
820
908
|
|
|
821
909
|
// src/tasks/cv/imageToImage.ts
|
|
822
910
|
async function imageToImage(args, options) {
|
|
@@ -911,43 +999,11 @@ async function textToVideo(args, options) {
|
|
|
911
999
|
}
|
|
912
1000
|
}
|
|
913
1001
|
|
|
914
|
-
// src/lib/getDefaultTask.ts
|
|
915
|
-
var taskCache = /* @__PURE__ */ new Map();
|
|
916
|
-
var CACHE_DURATION = 10 * 60 * 1e3;
|
|
917
|
-
var MAX_CACHE_ITEMS = 1e3;
|
|
918
|
-
async function getDefaultTask(model, accessToken, options) {
|
|
919
|
-
if (isUrl(model)) {
|
|
920
|
-
return null;
|
|
921
|
-
}
|
|
922
|
-
const key = `${model}:${accessToken}`;
|
|
923
|
-
let cachedTask = taskCache.get(key);
|
|
924
|
-
if (cachedTask && cachedTask.date < new Date(Date.now() - CACHE_DURATION)) {
|
|
925
|
-
taskCache.delete(key);
|
|
926
|
-
cachedTask = void 0;
|
|
927
|
-
}
|
|
928
|
-
if (cachedTask === void 0) {
|
|
929
|
-
const modelTask = await (options?.fetch ?? fetch)(`${HF_HUB_URL}/api/models/${model}?expand[]=pipeline_tag`, {
|
|
930
|
-
headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
|
|
931
|
-
}).then((resp) => resp.json()).then((json) => json.pipeline_tag).catch(() => null);
|
|
932
|
-
if (!modelTask) {
|
|
933
|
-
return null;
|
|
934
|
-
}
|
|
935
|
-
cachedTask = { task: modelTask, date: /* @__PURE__ */ new Date() };
|
|
936
|
-
taskCache.set(key, { task: modelTask, date: /* @__PURE__ */ new Date() });
|
|
937
|
-
if (taskCache.size > MAX_CACHE_ITEMS) {
|
|
938
|
-
taskCache.delete(taskCache.keys().next().value);
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
return cachedTask.task;
|
|
942
|
-
}
|
|
943
|
-
|
|
944
1002
|
// src/tasks/nlp/featureExtraction.ts
|
|
945
1003
|
async function featureExtraction(args, options) {
|
|
946
|
-
const defaultTask = args.model ? await getDefaultTask(args.model, args.accessToken, options) : void 0;
|
|
947
1004
|
const res = await request(args, {
|
|
948
1005
|
...options,
|
|
949
|
-
taskHint: "feature-extraction"
|
|
950
|
-
...defaultTask === "sentence-similarity" && { forceTask: "feature-extraction" }
|
|
1006
|
+
taskHint: "feature-extraction"
|
|
951
1007
|
});
|
|
952
1008
|
let isValidOutput = true;
|
|
953
1009
|
const isNumArrayRec = (arr, maxDepth, curDepth = 0) => {
|
|
@@ -1000,11 +1056,9 @@ async function questionAnswering(args, options) {
|
|
|
1000
1056
|
|
|
1001
1057
|
// src/tasks/nlp/sentenceSimilarity.ts
|
|
1002
1058
|
async function sentenceSimilarity(args, options) {
|
|
1003
|
-
const defaultTask = args.model ? await getDefaultTask(args.model, args.accessToken, options) : void 0;
|
|
1004
1059
|
const res = await request(prepareInput(args), {
|
|
1005
1060
|
...options,
|
|
1006
|
-
taskHint: "sentence-similarity"
|
|
1007
|
-
...defaultTask === "feature-extraction" && { forceTask: "sentence-similarity" }
|
|
1061
|
+
taskHint: "sentence-similarity"
|
|
1008
1062
|
});
|
|
1009
1063
|
const isValidOutput = Array.isArray(res) && res.every((x) => typeof x === "number");
|
|
1010
1064
|
if (!isValidOutput) {
|
|
@@ -1090,6 +1144,27 @@ async function textGeneration(args, options) {
|
|
|
1090
1144
|
return {
|
|
1091
1145
|
generated_text: completion.text
|
|
1092
1146
|
};
|
|
1147
|
+
} else if (args.provider === "hyperbolic") {
|
|
1148
|
+
const payload = {
|
|
1149
|
+
messages: [{ content: args.inputs, role: "user" }],
|
|
1150
|
+
...args.parameters ? {
|
|
1151
|
+
max_tokens: args.parameters.max_new_tokens,
|
|
1152
|
+
...omit(args.parameters, "max_new_tokens")
|
|
1153
|
+
} : void 0,
|
|
1154
|
+
...omit(args, ["inputs", "parameters"])
|
|
1155
|
+
};
|
|
1156
|
+
const raw = await request(payload, {
|
|
1157
|
+
...options,
|
|
1158
|
+
taskHint: "text-generation"
|
|
1159
|
+
});
|
|
1160
|
+
const isValidOutput = typeof raw === "object" && "choices" in raw && Array.isArray(raw?.choices) && typeof raw?.model === "string";
|
|
1161
|
+
if (!isValidOutput) {
|
|
1162
|
+
throw new InferenceOutputError("Expected ChatCompletionOutput");
|
|
1163
|
+
}
|
|
1164
|
+
const completion = raw.choices[0];
|
|
1165
|
+
return {
|
|
1166
|
+
generated_text: completion.message.content
|
|
1167
|
+
};
|
|
1093
1168
|
} else {
|
|
1094
1169
|
const res = toArray(
|
|
1095
1170
|
await request(args, {
|
|
@@ -1302,10 +1377,13 @@ var HfInferenceEndpoint = class {
|
|
|
1302
1377
|
|
|
1303
1378
|
// src/types.ts
|
|
1304
1379
|
var INFERENCE_PROVIDERS = [
|
|
1380
|
+
"black-forest-labs",
|
|
1305
1381
|
"fal-ai",
|
|
1306
1382
|
"fireworks-ai",
|
|
1307
|
-
"nebius",
|
|
1308
1383
|
"hf-inference",
|
|
1384
|
+
"hyperbolic",
|
|
1385
|
+
"nebius",
|
|
1386
|
+
"novita",
|
|
1309
1387
|
"replicate",
|
|
1310
1388
|
"sambanova",
|
|
1311
1389
|
"together"
|
package/dist/index.js
CHANGED
|
@@ -60,9 +60,18 @@ var SAMBANOVA_API_BASE_URL = "https://api.sambanova.ai";
|
|
|
60
60
|
// src/providers/together.ts
|
|
61
61
|
var TOGETHER_API_BASE_URL = "https://api.together.xyz";
|
|
62
62
|
|
|
63
|
+
// src/providers/novita.ts
|
|
64
|
+
var NOVITA_API_BASE_URL = "https://api.novita.ai/v3/openai";
|
|
65
|
+
|
|
63
66
|
// src/providers/fireworks-ai.ts
|
|
64
67
|
var FIREWORKS_AI_API_BASE_URL = "https://api.fireworks.ai/inference";
|
|
65
68
|
|
|
69
|
+
// src/providers/hyperbolic.ts
|
|
70
|
+
var HYPERBOLIC_API_BASE_URL = "https://api.hyperbolic.xyz";
|
|
71
|
+
|
|
72
|
+
// src/providers/black-forest-labs.ts
|
|
73
|
+
var BLACKFORESTLABS_AI_API_BASE_URL = "https://api.us1.bfl.ai/v1";
|
|
74
|
+
|
|
66
75
|
// src/lib/isUrl.ts
|
|
67
76
|
function isUrl(modelOrUrl) {
|
|
68
77
|
return /^http(s?):/.test(modelOrUrl) || modelOrUrl.startsWith("/");
|
|
@@ -70,7 +79,7 @@ function isUrl(modelOrUrl) {
|
|
|
70
79
|
|
|
71
80
|
// package.json
|
|
72
81
|
var name = "@huggingface/inference";
|
|
73
|
-
var version = "3.3.
|
|
82
|
+
var version = "3.3.5";
|
|
74
83
|
|
|
75
84
|
// src/providers/consts.ts
|
|
76
85
|
var HARDCODED_MODEL_ID_MAPPING = {
|
|
@@ -80,13 +89,16 @@ var HARDCODED_MODEL_ID_MAPPING = {
|
|
|
80
89
|
* Example:
|
|
81
90
|
* "Qwen/Qwen2.5-Coder-32B-Instruct": "Qwen2.5-Coder-32B-Instruct",
|
|
82
91
|
*/
|
|
92
|
+
"black-forest-labs": {},
|
|
83
93
|
"fal-ai": {},
|
|
84
94
|
"fireworks-ai": {},
|
|
85
95
|
"hf-inference": {},
|
|
96
|
+
hyperbolic: {},
|
|
86
97
|
nebius: {},
|
|
87
98
|
replicate: {},
|
|
88
99
|
sambanova: {},
|
|
89
|
-
together: {}
|
|
100
|
+
together: {},
|
|
101
|
+
novita: {}
|
|
90
102
|
};
|
|
91
103
|
|
|
92
104
|
// src/lib/getProviderModelId.ts
|
|
@@ -140,13 +152,10 @@ async function makeRequestOptions(args, options) {
|
|
|
140
152
|
const { accessToken, endpointUrl, provider: maybeProvider, model: maybeModel, ...remainingArgs } = args;
|
|
141
153
|
let otherArgs = remainingArgs;
|
|
142
154
|
const provider = maybeProvider ?? "hf-inference";
|
|
143
|
-
const {
|
|
155
|
+
const { includeCredentials, taskHint, chatCompletion: chatCompletion2 } = options ?? {};
|
|
144
156
|
if (endpointUrl && provider !== "hf-inference") {
|
|
145
157
|
throw new Error(`Cannot use endpointUrl with a third-party provider.`);
|
|
146
158
|
}
|
|
147
|
-
if (forceTask && provider !== "hf-inference") {
|
|
148
|
-
throw new Error(`Cannot use forceTask with a third-party provider.`);
|
|
149
|
-
}
|
|
150
159
|
if (maybeModel && isUrl(maybeModel)) {
|
|
151
160
|
throw new Error(`Model URLs are no longer supported. Use endpointUrl instead.`);
|
|
152
161
|
}
|
|
@@ -163,14 +172,19 @@ async function makeRequestOptions(args, options) {
|
|
|
163
172
|
const url = endpointUrl ? chatCompletion2 ? endpointUrl + `/v1/chat/completions` : endpointUrl : makeUrl({
|
|
164
173
|
authMethod,
|
|
165
174
|
chatCompletion: chatCompletion2 ?? false,
|
|
166
|
-
forceTask,
|
|
167
175
|
model,
|
|
168
176
|
provider: provider ?? "hf-inference",
|
|
169
177
|
taskHint
|
|
170
178
|
});
|
|
171
179
|
const headers = {};
|
|
172
180
|
if (accessToken) {
|
|
173
|
-
|
|
181
|
+
if (provider === "fal-ai" && authMethod === "provider-key") {
|
|
182
|
+
headers["Authorization"] = `Key ${accessToken}`;
|
|
183
|
+
} else if (provider === "black-forest-labs" && authMethod === "provider-key") {
|
|
184
|
+
headers["X-Key"] = accessToken;
|
|
185
|
+
} else {
|
|
186
|
+
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
187
|
+
}
|
|
174
188
|
}
|
|
175
189
|
const ownUserAgent = `${name}/${version}`;
|
|
176
190
|
headers["User-Agent"] = [ownUserAgent, typeof navigator !== "undefined" ? navigator.userAgent : void 0].filter((x) => x !== void 0).join(" ");
|
|
@@ -196,7 +210,7 @@ async function makeRequestOptions(args, options) {
|
|
|
196
210
|
method: "POST",
|
|
197
211
|
body: binary ? args.data : JSON.stringify({
|
|
198
212
|
...otherArgs,
|
|
199
|
-
...chatCompletion2 || provider === "together" || provider === "nebius" ? { model } : void 0
|
|
213
|
+
...taskHint === "text-to-image" && provider === "hyperbolic" ? { model_name: model } : chatCompletion2 || provider === "together" || provider === "nebius" || provider === "hyperbolic" ? { model } : void 0
|
|
200
214
|
}),
|
|
201
215
|
...credentials ? { credentials } : void 0,
|
|
202
216
|
signal: options?.signal
|
|
@@ -209,6 +223,10 @@ function makeUrl(params) {
|
|
|
209
223
|
}
|
|
210
224
|
const shouldProxy = params.provider !== "hf-inference" && params.authMethod !== "provider-key";
|
|
211
225
|
switch (params.provider) {
|
|
226
|
+
case "black-forest-labs": {
|
|
227
|
+
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : BLACKFORESTLABS_AI_API_BASE_URL;
|
|
228
|
+
return `${baseUrl}/${params.model}`;
|
|
229
|
+
}
|
|
212
230
|
case "fal-ai": {
|
|
213
231
|
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : FAL_AI_API_BASE_URL;
|
|
214
232
|
return `${baseUrl}/${params.model}`;
|
|
@@ -260,13 +278,32 @@ function makeUrl(params) {
|
|
|
260
278
|
}
|
|
261
279
|
return baseUrl;
|
|
262
280
|
}
|
|
281
|
+
case "hyperbolic": {
|
|
282
|
+
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : HYPERBOLIC_API_BASE_URL;
|
|
283
|
+
if (params.taskHint === "text-to-image") {
|
|
284
|
+
return `${baseUrl}/v1/images/generations`;
|
|
285
|
+
}
|
|
286
|
+
return `${baseUrl}/v1/chat/completions`;
|
|
287
|
+
}
|
|
288
|
+
case "novita": {
|
|
289
|
+
const baseUrl = shouldProxy ? HF_HUB_INFERENCE_PROXY_TEMPLATE.replace("{{PROVIDER}}", params.provider) : NOVITA_API_BASE_URL;
|
|
290
|
+
if (params.taskHint === "text-generation") {
|
|
291
|
+
if (params.chatCompletion) {
|
|
292
|
+
return `${baseUrl}/chat/completions`;
|
|
293
|
+
}
|
|
294
|
+
return `${baseUrl}/completions`;
|
|
295
|
+
}
|
|
296
|
+
return baseUrl;
|
|
297
|
+
}
|
|
263
298
|
default: {
|
|
264
299
|
const baseUrl = HF_HUB_INFERENCE_PROXY_TEMPLATE.replaceAll("{{PROVIDER}}", "hf-inference");
|
|
265
|
-
|
|
300
|
+
if (params.taskHint && ["feature-extraction", "sentence-similarity"].includes(params.taskHint)) {
|
|
301
|
+
return `${baseUrl}/pipeline/${params.taskHint}/${params.model}`;
|
|
302
|
+
}
|
|
266
303
|
if (params.taskHint === "text-generation" && params.chatCompletion) {
|
|
267
|
-
return
|
|
304
|
+
return `${baseUrl}/models/${params.model}/v1/chat/completions`;
|
|
268
305
|
}
|
|
269
|
-
return
|
|
306
|
+
return `${baseUrl}/models/${params.model}`;
|
|
270
307
|
}
|
|
271
308
|
}
|
|
272
309
|
}
|
|
@@ -713,6 +750,13 @@ async function objectDetection(args, options) {
|
|
|
713
750
|
return res;
|
|
714
751
|
}
|
|
715
752
|
|
|
753
|
+
// src/utils/delay.ts
|
|
754
|
+
function delay(ms) {
|
|
755
|
+
return new Promise((resolve) => {
|
|
756
|
+
setTimeout(() => resolve(), ms);
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
|
|
716
760
|
// src/tasks/cv/textToImage.ts
|
|
717
761
|
function getResponseFormatArg(provider) {
|
|
718
762
|
switch (provider) {
|
|
@@ -740,17 +784,36 @@ async function textToImage(args, options) {
|
|
|
740
784
|
taskHint: "text-to-image"
|
|
741
785
|
});
|
|
742
786
|
if (res && typeof res === "object") {
|
|
787
|
+
if (args.provider === "black-forest-labs" && "polling_url" in res && typeof res.polling_url === "string") {
|
|
788
|
+
return await pollBflResponse(res.polling_url, options?.outputType);
|
|
789
|
+
}
|
|
743
790
|
if (args.provider === "fal-ai" && "images" in res && Array.isArray(res.images) && res.images[0].url) {
|
|
744
|
-
|
|
745
|
-
|
|
791
|
+
if (options?.outputType === "url") {
|
|
792
|
+
return res.images[0].url;
|
|
793
|
+
} else {
|
|
794
|
+
const image = await fetch(res.images[0].url);
|
|
795
|
+
return await image.blob();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (args.provider === "hyperbolic" && "images" in res && Array.isArray(res.images) && res.images[0] && typeof res.images[0].image === "string") {
|
|
799
|
+
if (options?.outputType === "url") {
|
|
800
|
+
return `data:image/jpeg;base64,${res.images[0].image}`;
|
|
801
|
+
}
|
|
802
|
+
const base64Response = await fetch(`data:image/jpeg;base64,${res.images[0].image}`);
|
|
803
|
+
return await base64Response.blob();
|
|
746
804
|
}
|
|
747
805
|
if ("data" in res && Array.isArray(res.data) && res.data[0].b64_json) {
|
|
748
806
|
const base64Data = res.data[0].b64_json;
|
|
807
|
+
if (options?.outputType === "url") {
|
|
808
|
+
return `data:image/jpeg;base64,${base64Data}`;
|
|
809
|
+
}
|
|
749
810
|
const base64Response = await fetch(`data:image/jpeg;base64,${base64Data}`);
|
|
750
|
-
|
|
751
|
-
return blob;
|
|
811
|
+
return await base64Response.blob();
|
|
752
812
|
}
|
|
753
813
|
if ("output" in res && Array.isArray(res.output)) {
|
|
814
|
+
if (options?.outputType === "url") {
|
|
815
|
+
return res.output[0];
|
|
816
|
+
}
|
|
754
817
|
const urlResponse = await fetch(res.output[0]);
|
|
755
818
|
const blob = await urlResponse.blob();
|
|
756
819
|
return blob;
|
|
@@ -760,8 +823,33 @@ async function textToImage(args, options) {
|
|
|
760
823
|
if (!isValidOutput) {
|
|
761
824
|
throw new InferenceOutputError("Expected Blob");
|
|
762
825
|
}
|
|
826
|
+
if (options?.outputType === "url") {
|
|
827
|
+
const b64 = await res.arrayBuffer().then((buf) => Buffer.from(buf).toString("base64"));
|
|
828
|
+
return `data:image/jpeg;base64,${b64}`;
|
|
829
|
+
}
|
|
763
830
|
return res;
|
|
764
831
|
}
|
|
832
|
+
async function pollBflResponse(url, outputType) {
|
|
833
|
+
const urlObj = new URL(url);
|
|
834
|
+
for (let step = 0; step < 5; step++) {
|
|
835
|
+
await delay(1e3);
|
|
836
|
+
console.debug(`Polling Black Forest Labs API for the result... ${step + 1}/5`);
|
|
837
|
+
urlObj.searchParams.set("attempt", step.toString(10));
|
|
838
|
+
const resp = await fetch(urlObj, { headers: { "Content-Type": "application/json" } });
|
|
839
|
+
if (!resp.ok) {
|
|
840
|
+
throw new InferenceOutputError("Failed to fetch result from black forest labs API");
|
|
841
|
+
}
|
|
842
|
+
const payload = await resp.json();
|
|
843
|
+
if (typeof payload === "object" && payload && "status" in payload && typeof payload.status === "string" && payload.status === "Ready" && "result" in payload && typeof payload.result === "object" && payload.result && "sample" in payload.result && typeof payload.result.sample === "string") {
|
|
844
|
+
if (outputType === "url") {
|
|
845
|
+
return payload.result.sample;
|
|
846
|
+
}
|
|
847
|
+
const image = await fetch(payload.result.sample);
|
|
848
|
+
return await image.blob();
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
throw new InferenceOutputError("Failed to fetch result from black forest labs API");
|
|
852
|
+
}
|
|
765
853
|
|
|
766
854
|
// src/tasks/cv/imageToImage.ts
|
|
767
855
|
async function imageToImage(args, options) {
|
|
@@ -856,43 +944,11 @@ async function textToVideo(args, options) {
|
|
|
856
944
|
}
|
|
857
945
|
}
|
|
858
946
|
|
|
859
|
-
// src/lib/getDefaultTask.ts
|
|
860
|
-
var taskCache = /* @__PURE__ */ new Map();
|
|
861
|
-
var CACHE_DURATION = 10 * 60 * 1e3;
|
|
862
|
-
var MAX_CACHE_ITEMS = 1e3;
|
|
863
|
-
async function getDefaultTask(model, accessToken, options) {
|
|
864
|
-
if (isUrl(model)) {
|
|
865
|
-
return null;
|
|
866
|
-
}
|
|
867
|
-
const key = `${model}:${accessToken}`;
|
|
868
|
-
let cachedTask = taskCache.get(key);
|
|
869
|
-
if (cachedTask && cachedTask.date < new Date(Date.now() - CACHE_DURATION)) {
|
|
870
|
-
taskCache.delete(key);
|
|
871
|
-
cachedTask = void 0;
|
|
872
|
-
}
|
|
873
|
-
if (cachedTask === void 0) {
|
|
874
|
-
const modelTask = await (options?.fetch ?? fetch)(`${HF_HUB_URL}/api/models/${model}?expand[]=pipeline_tag`, {
|
|
875
|
-
headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
|
|
876
|
-
}).then((resp) => resp.json()).then((json) => json.pipeline_tag).catch(() => null);
|
|
877
|
-
if (!modelTask) {
|
|
878
|
-
return null;
|
|
879
|
-
}
|
|
880
|
-
cachedTask = { task: modelTask, date: /* @__PURE__ */ new Date() };
|
|
881
|
-
taskCache.set(key, { task: modelTask, date: /* @__PURE__ */ new Date() });
|
|
882
|
-
if (taskCache.size > MAX_CACHE_ITEMS) {
|
|
883
|
-
taskCache.delete(taskCache.keys().next().value);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
return cachedTask.task;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
947
|
// src/tasks/nlp/featureExtraction.ts
|
|
890
948
|
async function featureExtraction(args, options) {
|
|
891
|
-
const defaultTask = args.model ? await getDefaultTask(args.model, args.accessToken, options) : void 0;
|
|
892
949
|
const res = await request(args, {
|
|
893
950
|
...options,
|
|
894
|
-
taskHint: "feature-extraction"
|
|
895
|
-
...defaultTask === "sentence-similarity" && { forceTask: "feature-extraction" }
|
|
951
|
+
taskHint: "feature-extraction"
|
|
896
952
|
});
|
|
897
953
|
let isValidOutput = true;
|
|
898
954
|
const isNumArrayRec = (arr, maxDepth, curDepth = 0) => {
|
|
@@ -945,11 +1001,9 @@ async function questionAnswering(args, options) {
|
|
|
945
1001
|
|
|
946
1002
|
// src/tasks/nlp/sentenceSimilarity.ts
|
|
947
1003
|
async function sentenceSimilarity(args, options) {
|
|
948
|
-
const defaultTask = args.model ? await getDefaultTask(args.model, args.accessToken, options) : void 0;
|
|
949
1004
|
const res = await request(prepareInput(args), {
|
|
950
1005
|
...options,
|
|
951
|
-
taskHint: "sentence-similarity"
|
|
952
|
-
...defaultTask === "feature-extraction" && { forceTask: "sentence-similarity" }
|
|
1006
|
+
taskHint: "sentence-similarity"
|
|
953
1007
|
});
|
|
954
1008
|
const isValidOutput = Array.isArray(res) && res.every((x) => typeof x === "number");
|
|
955
1009
|
if (!isValidOutput) {
|
|
@@ -1035,6 +1089,27 @@ async function textGeneration(args, options) {
|
|
|
1035
1089
|
return {
|
|
1036
1090
|
generated_text: completion.text
|
|
1037
1091
|
};
|
|
1092
|
+
} else if (args.provider === "hyperbolic") {
|
|
1093
|
+
const payload = {
|
|
1094
|
+
messages: [{ content: args.inputs, role: "user" }],
|
|
1095
|
+
...args.parameters ? {
|
|
1096
|
+
max_tokens: args.parameters.max_new_tokens,
|
|
1097
|
+
...omit(args.parameters, "max_new_tokens")
|
|
1098
|
+
} : void 0,
|
|
1099
|
+
...omit(args, ["inputs", "parameters"])
|
|
1100
|
+
};
|
|
1101
|
+
const raw = await request(payload, {
|
|
1102
|
+
...options,
|
|
1103
|
+
taskHint: "text-generation"
|
|
1104
|
+
});
|
|
1105
|
+
const isValidOutput = typeof raw === "object" && "choices" in raw && Array.isArray(raw?.choices) && typeof raw?.model === "string";
|
|
1106
|
+
if (!isValidOutput) {
|
|
1107
|
+
throw new InferenceOutputError("Expected ChatCompletionOutput");
|
|
1108
|
+
}
|
|
1109
|
+
const completion = raw.choices[0];
|
|
1110
|
+
return {
|
|
1111
|
+
generated_text: completion.message.content
|
|
1112
|
+
};
|
|
1038
1113
|
} else {
|
|
1039
1114
|
const res = toArray(
|
|
1040
1115
|
await request(args, {
|
|
@@ -1247,10 +1322,13 @@ var HfInferenceEndpoint = class {
|
|
|
1247
1322
|
|
|
1248
1323
|
// src/types.ts
|
|
1249
1324
|
var INFERENCE_PROVIDERS = [
|
|
1325
|
+
"black-forest-labs",
|
|
1250
1326
|
"fal-ai",
|
|
1251
1327
|
"fireworks-ai",
|
|
1252
|
-
"nebius",
|
|
1253
1328
|
"hf-inference",
|
|
1329
|
+
"hyperbolic",
|
|
1330
|
+
"nebius",
|
|
1331
|
+
"novita",
|
|
1254
1332
|
"replicate",
|
|
1255
1333
|
"sambanova",
|
|
1256
1334
|
"together"
|
|
@@ -6,8 +6,6 @@ export declare function makeRequestOptions(args: RequestArgs & {
|
|
|
6
6
|
data?: Blob | ArrayBuffer;
|
|
7
7
|
stream?: boolean;
|
|
8
8
|
}, options?: Options & {
|
|
9
|
-
/** When a model can be used for multiple tasks, and we want to run a non-default task */
|
|
10
|
-
forceTask?: string | InferenceTask;
|
|
11
9
|
/** To load default model if needed */
|
|
12
10
|
taskHint?: InferenceTask;
|
|
13
11
|
chatCompletion?: boolean;
|