@huggingface/inference 3.15.0 → 4.0.1
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 +102 -0
- package/dist/commonjs/errors.d.ts +46 -0
- package/dist/commonjs/errors.d.ts.map +1 -0
- package/dist/commonjs/errors.js +70 -0
- package/dist/commonjs/index.d.ts +1 -1
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +2 -3
- package/dist/commonjs/lib/getInferenceProviderMapping.d.ts.map +1 -1
- package/dist/commonjs/lib/getInferenceProviderMapping.js +27 -16
- package/dist/commonjs/lib/getProviderHelper.d.ts.map +1 -1
- package/dist/commonjs/lib/getProviderHelper.js +4 -3
- package/dist/commonjs/lib/makeRequestOptions.d.ts.map +1 -1
- package/dist/commonjs/lib/makeRequestOptions.js +12 -11
- package/dist/commonjs/package.d.ts +1 -1
- package/dist/commonjs/package.d.ts.map +1 -1
- package/dist/commonjs/package.js +1 -1
- package/dist/commonjs/providers/black-forest-labs.d.ts.map +1 -1
- package/dist/commonjs/providers/black-forest-labs.js +4 -4
- package/dist/commonjs/providers/fal-ai.d.ts.map +1 -1
- package/dist/commonjs/providers/fal-ai.js +29 -17
- package/dist/commonjs/providers/featherless-ai.d.ts.map +1 -1
- package/dist/commonjs/providers/featherless-ai.js +2 -2
- package/dist/commonjs/providers/hf-inference.d.ts.map +1 -1
- package/dist/commonjs/providers/hf-inference.js +27 -30
- package/dist/commonjs/providers/hyperbolic.d.ts.map +1 -1
- package/dist/commonjs/providers/hyperbolic.js +3 -3
- package/dist/commonjs/providers/nebius.d.ts.map +1 -1
- package/dist/commonjs/providers/nebius.js +2 -2
- package/dist/commonjs/providers/novita.d.ts.map +1 -1
- package/dist/commonjs/providers/novita.js +12 -8
- package/dist/commonjs/providers/nscale.d.ts.map +1 -1
- package/dist/commonjs/providers/nscale.js +2 -2
- package/dist/commonjs/providers/ovhcloud.d.ts.map +1 -1
- package/dist/commonjs/providers/ovhcloud.js +2 -2
- package/dist/commonjs/providers/providerHelper.js +3 -3
- package/dist/commonjs/providers/replicate.js +4 -4
- package/dist/commonjs/providers/sambanova.d.ts +16 -0
- package/dist/commonjs/providers/sambanova.d.ts.map +1 -1
- package/dist/commonjs/providers/sambanova.js +2 -18
- package/dist/commonjs/providers/together.d.ts.map +1 -1
- package/dist/commonjs/providers/together.js +3 -3
- package/dist/commonjs/snippets/getInferenceSnippets.d.ts +2 -1
- package/dist/commonjs/snippets/getInferenceSnippets.d.ts.map +1 -1
- package/dist/commonjs/snippets/getInferenceSnippets.js +44 -5
- package/dist/commonjs/tasks/audio/automaticSpeechRecognition.d.ts.map +1 -1
- package/dist/commonjs/tasks/audio/automaticSpeechRecognition.js +2 -2
- package/dist/commonjs/utils/request.d.ts.map +1 -1
- package/dist/commonjs/utils/request.js +77 -12
- package/dist/commonjs/vendor/type-fest/basic.d.ts +33 -0
- package/dist/commonjs/vendor/type-fest/basic.d.ts.map +1 -0
- package/dist/commonjs/vendor/type-fest/basic.js +2 -0
- package/dist/esm/errors.d.ts +46 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +62 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/lib/getInferenceProviderMapping.d.ts.map +1 -1
- package/dist/esm/lib/getInferenceProviderMapping.js +27 -16
- package/dist/esm/lib/getProviderHelper.d.ts.map +1 -1
- package/dist/esm/lib/getProviderHelper.js +4 -3
- package/dist/esm/lib/makeRequestOptions.d.ts.map +1 -1
- package/dist/esm/lib/makeRequestOptions.js +12 -11
- package/dist/esm/package.d.ts +1 -1
- package/dist/esm/package.d.ts.map +1 -1
- package/dist/esm/package.js +1 -1
- package/dist/esm/providers/black-forest-labs.d.ts.map +1 -1
- package/dist/esm/providers/black-forest-labs.js +4 -4
- package/dist/esm/providers/fal-ai.d.ts.map +1 -1
- package/dist/esm/providers/fal-ai.js +29 -17
- package/dist/esm/providers/featherless-ai.d.ts.map +1 -1
- package/dist/esm/providers/featherless-ai.js +2 -2
- package/dist/esm/providers/hf-inference.d.ts.map +1 -1
- package/dist/esm/providers/hf-inference.js +27 -30
- package/dist/esm/providers/hyperbolic.d.ts.map +1 -1
- package/dist/esm/providers/hyperbolic.js +3 -3
- package/dist/esm/providers/nebius.d.ts.map +1 -1
- package/dist/esm/providers/nebius.js +2 -2
- package/dist/esm/providers/novita.d.ts.map +1 -1
- package/dist/esm/providers/novita.js +12 -8
- package/dist/esm/providers/nscale.d.ts.map +1 -1
- package/dist/esm/providers/nscale.js +2 -2
- package/dist/esm/providers/ovhcloud.d.ts.map +1 -1
- package/dist/esm/providers/ovhcloud.js +2 -2
- package/dist/esm/providers/providerHelper.js +3 -3
- package/dist/esm/providers/replicate.js +4 -4
- package/dist/esm/providers/sambanova.d.ts +16 -0
- package/dist/esm/providers/sambanova.d.ts.map +1 -1
- package/dist/esm/providers/sambanova.js +2 -18
- package/dist/esm/providers/together.d.ts.map +1 -1
- package/dist/esm/providers/together.js +3 -3
- package/dist/esm/snippets/getInferenceSnippets.d.ts +2 -1
- package/dist/esm/snippets/getInferenceSnippets.d.ts.map +1 -1
- package/dist/esm/snippets/getInferenceSnippets.js +44 -5
- package/dist/esm/tasks/audio/automaticSpeechRecognition.d.ts.map +1 -1
- package/dist/esm/tasks/audio/automaticSpeechRecognition.js +2 -2
- package/dist/esm/utils/request.d.ts.map +1 -1
- package/dist/esm/utils/request.js +77 -12
- package/dist/esm/vendor/type-fest/basic.d.ts +33 -0
- package/dist/esm/vendor/type-fest/basic.d.ts.map +1 -0
- package/dist/esm/vendor/type-fest/basic.js +1 -0
- package/package.json +2 -2
- package/src/errors.ts +82 -0
- package/src/index.ts +1 -1
- package/src/lib/getInferenceProviderMapping.ts +42 -22
- package/src/lib/getProviderHelper.ts +8 -3
- package/src/lib/makeRequestOptions.ts +20 -11
- package/src/package.ts +1 -1
- package/src/providers/black-forest-labs.ts +14 -4
- package/src/providers/fal-ai.ts +59 -23
- package/src/providers/featherless-ai.ts +2 -2
- package/src/providers/hf-inference.ts +75 -34
- package/src/providers/hyperbolic.ts +3 -4
- package/src/providers/nebius.ts +2 -2
- package/src/providers/novita.ts +30 -8
- package/src/providers/nscale.ts +2 -2
- package/src/providers/ovhcloud.ts +2 -2
- package/src/providers/providerHelper.ts +3 -3
- package/src/providers/replicate.ts +4 -4
- package/src/providers/sambanova.ts +3 -4
- package/src/providers/together.ts +3 -3
- package/src/snippets/getInferenceSnippets.ts +69 -7
- package/src/tasks/audio/automaticSpeechRecognition.ts +2 -2
- package/src/utils/request.ts +127 -14
- package/src/vendor/type-fest/basic.ts +31 -0
- package/src/vendor/type-fest/license-cc0 +121 -0
- package/src/vendor/type-fest/license-mit +9 -0
- package/dist/commonjs/lib/InferenceOutputError.d.ts +0 -4
- package/dist/commonjs/lib/InferenceOutputError.d.ts.map +0 -1
- package/dist/commonjs/lib/InferenceOutputError.js +0 -10
- package/dist/esm/lib/InferenceOutputError.d.ts +0 -4
- package/dist/esm/lib/InferenceOutputError.d.ts.map +0 -1
- package/dist/esm/lib/InferenceOutputError.js +0 -6
- package/src/lib/InferenceOutputError.ts +0 -8
package/src/providers/nscale.ts
CHANGED
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
* Thanks!
|
|
16
16
|
*/
|
|
17
17
|
import type { TextToImageInput } from "@huggingface/tasks";
|
|
18
|
-
import { InferenceOutputError } from "../lib/InferenceOutputError.js";
|
|
19
18
|
import type { BodyParams } from "../types.js";
|
|
20
19
|
import { omit } from "../utils/omit.js";
|
|
21
20
|
import { BaseConversationalTask, TaskProviderHelper, type TextToImageTaskHelper } from "./providerHelper.js";
|
|
21
|
+
import { InferenceClientProviderOutputError } from "../errors.js";
|
|
22
22
|
|
|
23
23
|
const NSCALE_API_BASE_URL = "https://inference.api.nscale.com";
|
|
24
24
|
|
|
@@ -74,6 +74,6 @@ export class NscaleTextToImageTask extends TaskProviderHelper implements TextToI
|
|
|
74
74
|
return fetch(`data:image/jpeg;base64,${base64Data}`).then((res) => res.blob());
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
throw new
|
|
77
|
+
throw new InferenceClientProviderOutputError("Received malformed response from Nscale text-to-image API");
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
import { BaseConversationalTask, BaseTextGenerationTask } from "./providerHelper.js";
|
|
19
19
|
import type { ChatCompletionOutput, TextGenerationOutput, TextGenerationOutputFinishReason } from "@huggingface/tasks";
|
|
20
|
-
import { InferenceOutputError } from "../lib/InferenceOutputError.js";
|
|
21
20
|
import type { BodyParams } from "../types.js";
|
|
22
21
|
import { omit } from "../utils/omit.js";
|
|
23
22
|
import type { TextGenerationInput } from "@huggingface/tasks";
|
|
23
|
+
import { InferenceClientProviderOutputError } from "../errors.js";
|
|
24
24
|
|
|
25
25
|
const OVHCLOUD_API_BASE_URL = "https://oai.endpoints.kepler.ai.cloud.ovh.net";
|
|
26
26
|
|
|
@@ -70,6 +70,6 @@ export class OvhCloudTextGenerationTask extends BaseTextGenerationTask {
|
|
|
70
70
|
generated_text: completion.text,
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
-
throw new
|
|
73
|
+
throw new InferenceClientProviderOutputError("Received malformed response from OVHcloud text generation API");
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -46,7 +46,7 @@ import type {
|
|
|
46
46
|
ZeroShotImageClassificationOutput,
|
|
47
47
|
} from "@huggingface/tasks";
|
|
48
48
|
import { HF_ROUTER_URL } from "../config.js";
|
|
49
|
-
import {
|
|
49
|
+
import { InferenceClientProviderOutputError } from "../errors.js";
|
|
50
50
|
import type { AudioToAudioOutput } from "../tasks/audio/audioToAudio.js";
|
|
51
51
|
import type { BaseArgs, BodyParams, HeaderParams, InferenceProvider, RequestArgs, UrlParams } from "../types.js";
|
|
52
52
|
import { toArray } from "../utils/toArray.js";
|
|
@@ -320,7 +320,7 @@ export class BaseConversationalTask extends TaskProviderHelper implements Conver
|
|
|
320
320
|
return response;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
throw new
|
|
323
|
+
throw new InferenceClientProviderOutputError("Expected ChatCompletionOutput");
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
|
|
@@ -353,6 +353,6 @@ export class BaseTextGenerationTask extends TaskProviderHelper implements TextGe
|
|
|
353
353
|
return res[0];
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
throw new
|
|
356
|
+
throw new InferenceClientProviderOutputError("Expected Array<{generated_text: string}>");
|
|
357
357
|
}
|
|
358
358
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* Thanks!
|
|
16
16
|
*/
|
|
17
|
-
import {
|
|
17
|
+
import { InferenceClientProviderOutputError } from "../errors.js";
|
|
18
18
|
import { isUrl } from "../lib/isUrl.js";
|
|
19
19
|
import type { BodyParams, HeaderParams, UrlParams } from "../types.js";
|
|
20
20
|
import { omit } from "../utils/omit.js";
|
|
@@ -99,7 +99,7 @@ export class ReplicateTextToImageTask extends ReplicateTask implements TextToIma
|
|
|
99
99
|
return await urlResponse.blob();
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
throw new
|
|
102
|
+
throw new InferenceClientProviderOutputError("Received malformed response from Replicate text-to-image API");
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -132,7 +132,7 @@ export class ReplicateTextToSpeechTask extends ReplicateTask {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
throw new
|
|
135
|
+
throw new InferenceClientProviderOutputError("Received malformed response from Replicate text-to-speech API");
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
@@ -149,6 +149,6 @@ export class ReplicateTextToVideoTask extends ReplicateTask implements TextToVid
|
|
|
149
149
|
return await urlResponse.blob();
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
throw new
|
|
152
|
+
throw new InferenceClientProviderOutputError("Received malformed response from Replicate text-to-video API");
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -14,12 +14,11 @@
|
|
|
14
14
|
*
|
|
15
15
|
* Thanks!
|
|
16
16
|
*/
|
|
17
|
-
import { InferenceOutputError } from "../lib/InferenceOutputError.js";
|
|
18
|
-
|
|
19
17
|
import type { FeatureExtractionOutput } from "@huggingface/tasks";
|
|
20
18
|
import type { BodyParams } from "../types.js";
|
|
21
19
|
import type { FeatureExtractionTaskHelper } from "./providerHelper.js";
|
|
22
20
|
import { BaseConversationalTask, TaskProviderHelper } from "./providerHelper.js";
|
|
21
|
+
import { InferenceClientProviderOutputError } from "../errors.js";
|
|
23
22
|
|
|
24
23
|
export class SambanovaConversationalTask extends BaseConversationalTask {
|
|
25
24
|
constructor() {
|
|
@@ -40,8 +39,8 @@ export class SambanovaFeatureExtractionTask extends TaskProviderHelper implement
|
|
|
40
39
|
if (typeof response === "object" && "data" in response && Array.isArray(response.data)) {
|
|
41
40
|
return response.data.map((item) => item.embedding);
|
|
42
41
|
}
|
|
43
|
-
throw new
|
|
44
|
-
"
|
|
42
|
+
throw new InferenceClientProviderOutputError(
|
|
43
|
+
"Received malformed response from Sambanova feature-extraction (embeddings) API"
|
|
45
44
|
);
|
|
46
45
|
}
|
|
47
46
|
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
* Thanks!
|
|
16
16
|
*/
|
|
17
17
|
import type { ChatCompletionOutput, TextGenerationOutput, TextGenerationOutputFinishReason } from "@huggingface/tasks";
|
|
18
|
-
import { InferenceOutputError } from "../lib/InferenceOutputError.js";
|
|
19
18
|
import type { BodyParams } from "../types.js";
|
|
20
19
|
import { omit } from "../utils/omit.js";
|
|
21
20
|
import {
|
|
@@ -24,6 +23,7 @@ import {
|
|
|
24
23
|
TaskProviderHelper,
|
|
25
24
|
type TextToImageTaskHelper,
|
|
26
25
|
} from "./providerHelper.js";
|
|
26
|
+
import { InferenceClientProviderOutputError } from "../errors.js";
|
|
27
27
|
|
|
28
28
|
const TOGETHER_API_BASE_URL = "https://api.together.xyz";
|
|
29
29
|
|
|
@@ -74,7 +74,7 @@ export class TogetherTextGenerationTask extends BaseTextGenerationTask {
|
|
|
74
74
|
generated_text: completion.text,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
throw new
|
|
77
|
+
throw new InferenceClientProviderOutputError("Received malformed response from Together text generation API");
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -113,6 +113,6 @@ export class TogetherTextToImageTask extends TaskProviderHelper implements TextT
|
|
|
113
113
|
return fetch(`data:image/jpeg;base64,${base64Data}`).then((res) => res.blob());
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
throw new
|
|
116
|
+
throw new InferenceClientProviderOutputError("Received malformed response from Together text-to-image API");
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -14,7 +14,10 @@ import { makeRequestOptionsFromResolvedModel } from "../lib/makeRequestOptions.j
|
|
|
14
14
|
import type { InferenceProviderOrPolicy, InferenceTask, RequestArgs } from "../types.js";
|
|
15
15
|
import { templates } from "./templates.exported.js";
|
|
16
16
|
|
|
17
|
-
export type InferenceSnippetOptions = { streaming?: boolean; billTo?: string } & Record<
|
|
17
|
+
export type InferenceSnippetOptions = { streaming?: boolean; billTo?: string; accessToken?: string } & Record<
|
|
18
|
+
string,
|
|
19
|
+
unknown
|
|
20
|
+
>;
|
|
18
21
|
|
|
19
22
|
const PYTHON_CLIENTS = ["huggingface_hub", "fal_client", "requests", "openai"] as const;
|
|
20
23
|
const JS_CLIENTS = ["fetch", "huggingface.js", "openai"] as const;
|
|
@@ -121,11 +124,12 @@ const HF_JS_METHODS: Partial<Record<WidgetType, string>> = {
|
|
|
121
124
|
translation: "translation",
|
|
122
125
|
};
|
|
123
126
|
|
|
127
|
+
const ACCESS_TOKEN_PLACEHOLDER = "<ACCESS_TOKEN>"; // Placeholder to replace with env variable in snippets
|
|
128
|
+
|
|
124
129
|
// Snippet generators
|
|
125
130
|
const snippetGenerator = (templateName: string, inputPreparationFn?: InputPreparationFn) => {
|
|
126
131
|
return (
|
|
127
132
|
model: ModelDataMinimal,
|
|
128
|
-
accessToken: string,
|
|
129
133
|
provider: InferenceProviderOrPolicy,
|
|
130
134
|
inferenceProviderMapping?: InferenceProviderModelMapping,
|
|
131
135
|
opts?: InferenceSnippetOptions
|
|
@@ -149,13 +153,15 @@ const snippetGenerator = (templateName: string, inputPreparationFn?: InputPrepar
|
|
|
149
153
|
console.error(`Failed to get provider helper for ${provider} (${task})`, e);
|
|
150
154
|
return [];
|
|
151
155
|
}
|
|
156
|
+
const accessTokenOrPlaceholder = opts?.accessToken ?? ACCESS_TOKEN_PLACEHOLDER;
|
|
157
|
+
|
|
152
158
|
/// Prepare inputs + make request
|
|
153
159
|
const inputs = inputPreparationFn ? inputPreparationFn(model, opts) : { inputs: getModelInputSnippet(model) };
|
|
154
160
|
const request = makeRequestOptionsFromResolvedModel(
|
|
155
161
|
providerModelId,
|
|
156
162
|
providerHelper,
|
|
157
163
|
{
|
|
158
|
-
accessToken,
|
|
164
|
+
accessToken: accessTokenOrPlaceholder,
|
|
159
165
|
provider,
|
|
160
166
|
...inputs,
|
|
161
167
|
} as RequestArgs,
|
|
@@ -180,7 +186,7 @@ const snippetGenerator = (templateName: string, inputPreparationFn?: InputPrepar
|
|
|
180
186
|
|
|
181
187
|
/// Prepare template injection data
|
|
182
188
|
const params: TemplateParams = {
|
|
183
|
-
accessToken,
|
|
189
|
+
accessToken: accessTokenOrPlaceholder,
|
|
184
190
|
authorizationHeader: (request.info.headers as Record<string, string>)?.Authorization,
|
|
185
191
|
baseUrl: removeSuffix(request.url, "/chat/completions"),
|
|
186
192
|
fullUrl: request.url,
|
|
@@ -248,6 +254,11 @@ const snippetGenerator = (templateName: string, inputPreparationFn?: InputPrepar
|
|
|
248
254
|
snippet = `${importSection}\n\n${snippet}`;
|
|
249
255
|
}
|
|
250
256
|
|
|
257
|
+
/// Replace access token placeholder
|
|
258
|
+
if (snippet.includes(ACCESS_TOKEN_PLACEHOLDER)) {
|
|
259
|
+
snippet = replaceAccessTokenPlaceholder(snippet, language, provider);
|
|
260
|
+
}
|
|
261
|
+
|
|
251
262
|
/// Snippet is ready!
|
|
252
263
|
return { language, client: client as string, content: snippet };
|
|
253
264
|
})
|
|
@@ -299,7 +310,6 @@ const snippets: Partial<
|
|
|
299
310
|
PipelineType,
|
|
300
311
|
(
|
|
301
312
|
model: ModelDataMinimal,
|
|
302
|
-
accessToken: string,
|
|
303
313
|
provider: InferenceProviderOrPolicy,
|
|
304
314
|
inferenceProviderMapping?: InferenceProviderModelMapping,
|
|
305
315
|
opts?: InferenceSnippetOptions
|
|
@@ -339,13 +349,12 @@ const snippets: Partial<
|
|
|
339
349
|
|
|
340
350
|
export function getInferenceSnippets(
|
|
341
351
|
model: ModelDataMinimal,
|
|
342
|
-
accessToken: string,
|
|
343
352
|
provider: InferenceProviderOrPolicy,
|
|
344
353
|
inferenceProviderMapping?: InferenceProviderModelMapping,
|
|
345
354
|
opts?: Record<string, unknown>
|
|
346
355
|
): InferenceSnippet[] {
|
|
347
356
|
return model.pipeline_tag && model.pipeline_tag in snippets
|
|
348
|
-
? snippets[model.pipeline_tag]?.(model,
|
|
357
|
+
? snippets[model.pipeline_tag]?.(model, provider, inferenceProviderMapping, opts) ?? []
|
|
349
358
|
: [];
|
|
350
359
|
}
|
|
351
360
|
|
|
@@ -420,3 +429,56 @@ function indentString(str: string): string {
|
|
|
420
429
|
function removeSuffix(str: string, suffix: string) {
|
|
421
430
|
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
|
|
422
431
|
}
|
|
432
|
+
|
|
433
|
+
function replaceAccessTokenPlaceholder(
|
|
434
|
+
snippet: string,
|
|
435
|
+
language: InferenceSnippetLanguage,
|
|
436
|
+
provider: InferenceProviderOrPolicy
|
|
437
|
+
): string {
|
|
438
|
+
// If "opts.accessToken" is not set, the snippets are generated with a placeholder.
|
|
439
|
+
// Once snippets are rendered, we replace the placeholder with code to fetch the access token from an environment variable.
|
|
440
|
+
|
|
441
|
+
// Determine if HF_TOKEN or specific provider token should be used
|
|
442
|
+
const accessTokenEnvVar =
|
|
443
|
+
!snippet.includes("https://") || // no URL provided => using a client => use $HF_TOKEN
|
|
444
|
+
snippet.includes("https://router.huggingface.co") || // explicit routed request => use $HF_TOKEN
|
|
445
|
+
provider == "hf-inference" // hf-inference provider => use $HF_TOKEN
|
|
446
|
+
? "HF_TOKEN"
|
|
447
|
+
: provider.toUpperCase().replace("-", "_") + "_API_KEY"; // e.g. "REPLICATE_API_KEY"
|
|
448
|
+
|
|
449
|
+
// Replace the placeholder with the env variable
|
|
450
|
+
if (language === "sh") {
|
|
451
|
+
snippet = snippet.replace(
|
|
452
|
+
`'Authorization: Bearer ${ACCESS_TOKEN_PLACEHOLDER}'`,
|
|
453
|
+
`"Authorization: Bearer $${accessTokenEnvVar}"` // e.g. "Authorization: Bearer $HF_TOKEN"
|
|
454
|
+
);
|
|
455
|
+
} else if (language === "python") {
|
|
456
|
+
snippet = "import os\n" + snippet;
|
|
457
|
+
snippet = snippet.replace(
|
|
458
|
+
`"${ACCESS_TOKEN_PLACEHOLDER}"`,
|
|
459
|
+
`os.environ["${accessTokenEnvVar}"]` // e.g. os.environ["HF_TOKEN")
|
|
460
|
+
);
|
|
461
|
+
snippet = snippet.replace(
|
|
462
|
+
`"Bearer ${ACCESS_TOKEN_PLACEHOLDER}"`,
|
|
463
|
+
`f"Bearer {os.environ['${accessTokenEnvVar}']}"` // e.g. f"Bearer {os.environ['HF_TOKEN']}"
|
|
464
|
+
);
|
|
465
|
+
snippet = snippet.replace(
|
|
466
|
+
`"Key ${ACCESS_TOKEN_PLACEHOLDER}"`,
|
|
467
|
+
`f"Key {os.environ['${accessTokenEnvVar}']}"` // e.g. f"Key {os.environ['FAL_AI_API_KEY']}"
|
|
468
|
+
);
|
|
469
|
+
} else if (language === "js") {
|
|
470
|
+
snippet = snippet.replace(
|
|
471
|
+
`"${ACCESS_TOKEN_PLACEHOLDER}"`,
|
|
472
|
+
`process.env.${accessTokenEnvVar}` // e.g. process.env.HF_TOKEN
|
|
473
|
+
);
|
|
474
|
+
snippet = snippet.replace(
|
|
475
|
+
`Authorization: "Bearer ${ACCESS_TOKEN_PLACEHOLDER}",`,
|
|
476
|
+
`Authorization: \`Bearer $\{process.env.${accessTokenEnvVar}}\`,` // e.g. Authorization: `Bearer ${process.env.HF_TOKEN}`,
|
|
477
|
+
);
|
|
478
|
+
snippet = snippet.replace(
|
|
479
|
+
`Authorization: "Key ${ACCESS_TOKEN_PLACEHOLDER}",`,
|
|
480
|
+
`Authorization: \`Key $\{process.env.${accessTokenEnvVar}}\`,` // e.g. Authorization: `Key ${process.env.FAL_AI_API_KEY}`,
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
return snippet;
|
|
484
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { AutomaticSpeechRecognitionInput, AutomaticSpeechRecognitionOutput } from "@huggingface/tasks";
|
|
2
2
|
import { resolveProvider } from "../../lib/getInferenceProviderMapping.js";
|
|
3
3
|
import { getProviderHelper } from "../../lib/getProviderHelper.js";
|
|
4
|
-
import { InferenceOutputError } from "../../lib/InferenceOutputError.js";
|
|
5
4
|
import type { BaseArgs, Options } from "../../types.js";
|
|
6
5
|
import { innerRequest } from "../../utils/request.js";
|
|
7
6
|
import type { LegacyAudioInput } from "./utils.js";
|
|
7
|
+
import { InferenceClientProviderOutputError } from "../../errors.js";
|
|
8
8
|
|
|
9
9
|
export type AutomaticSpeechRecognitionArgs = BaseArgs & (AutomaticSpeechRecognitionInput | LegacyAudioInput);
|
|
10
10
|
/**
|
|
@@ -24,7 +24,7 @@ export async function automaticSpeechRecognition(
|
|
|
24
24
|
});
|
|
25
25
|
const isValidOutput = typeof res?.text === "string";
|
|
26
26
|
if (!isValidOutput) {
|
|
27
|
-
throw new
|
|
27
|
+
throw new InferenceClientProviderOutputError("Received malformed response from automatic-speech-recognition API");
|
|
28
28
|
}
|
|
29
29
|
return providerHelper.getResponse(res);
|
|
30
30
|
}
|
package/src/utils/request.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { makeRequestOptions } from "../lib/makeRequestOptions.js";
|
|
|
3
3
|
import type { InferenceTask, Options, RequestArgs } from "../types.js";
|
|
4
4
|
import type { EventSourceMessage } from "../vendor/fetch-event-source/parse.js";
|
|
5
5
|
import { getLines, getMessages } from "../vendor/fetch-event-source/parse.js";
|
|
6
|
+
import { InferenceClientProviderApiError } from "../errors.js";
|
|
7
|
+
import type { JsonObject } from "../vendor/type-fest/basic.js";
|
|
6
8
|
|
|
7
9
|
export interface ResponseWrapper<T> {
|
|
8
10
|
data: T;
|
|
@@ -12,6 +14,17 @@ export interface ResponseWrapper<T> {
|
|
|
12
14
|
};
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
function requestArgsToJson(args: RequestArgs): JsonObject {
|
|
18
|
+
// Convert the entire args object to a JSON-serializable format
|
|
19
|
+
const argsWithData = args as RequestArgs & { data?: Blob | ArrayBuffer };
|
|
20
|
+
return JSON.parse(
|
|
21
|
+
JSON.stringify({
|
|
22
|
+
...argsWithData,
|
|
23
|
+
data: argsWithData.data ? "[Blob or ArrayBuffer]" : null,
|
|
24
|
+
})
|
|
25
|
+
) as JsonObject;
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
/**
|
|
16
29
|
* Primitive to make custom calls to the inference provider
|
|
17
30
|
*/
|
|
@@ -39,18 +52,54 @@ export async function innerRequest<T>(
|
|
|
39
52
|
if (["application/json", "application/problem+json"].some((ct) => contentType?.startsWith(ct))) {
|
|
40
53
|
const output = await response.json();
|
|
41
54
|
if ([400, 422, 404, 500].includes(response.status) && options?.chatCompletion) {
|
|
42
|
-
throw new
|
|
43
|
-
`
|
|
55
|
+
throw new InferenceClientProviderApiError(
|
|
56
|
+
`Provider ${args.provider} does not seem to support chat completion for model ${
|
|
57
|
+
args.model
|
|
58
|
+
} . Error: ${JSON.stringify(output.error)}`,
|
|
59
|
+
{
|
|
60
|
+
url,
|
|
61
|
+
method: info.method ?? "GET",
|
|
62
|
+
headers: info.headers as Record<string, string>,
|
|
63
|
+
body: requestArgsToJson(args),
|
|
64
|
+
},
|
|
65
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
44
66
|
);
|
|
45
67
|
}
|
|
46
|
-
if (output.error || output.detail) {
|
|
47
|
-
throw new
|
|
68
|
+
if (typeof output.error === "string" || typeof output.detail === "string" || typeof output.message === "string") {
|
|
69
|
+
throw new InferenceClientProviderApiError(
|
|
70
|
+
`Failed to perform inference: ${output.error ?? output.detail ?? output.message}`,
|
|
71
|
+
{
|
|
72
|
+
url,
|
|
73
|
+
method: info.method ?? "GET",
|
|
74
|
+
headers: info.headers as Record<string, string>,
|
|
75
|
+
body: requestArgsToJson(args),
|
|
76
|
+
},
|
|
77
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
78
|
+
);
|
|
48
79
|
} else {
|
|
49
|
-
throw new
|
|
80
|
+
throw new InferenceClientProviderApiError(
|
|
81
|
+
`Failed to perform inference: an HTTP error occurred when requesting the provider.`,
|
|
82
|
+
{
|
|
83
|
+
url,
|
|
84
|
+
method: info.method ?? "GET",
|
|
85
|
+
headers: info.headers as Record<string, string>,
|
|
86
|
+
body: requestArgsToJson(args),
|
|
87
|
+
},
|
|
88
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
89
|
+
);
|
|
50
90
|
}
|
|
51
91
|
}
|
|
52
92
|
const message = contentType?.startsWith("text/plain;") ? await response.text() : undefined;
|
|
53
|
-
throw new
|
|
93
|
+
throw new InferenceClientProviderApiError(
|
|
94
|
+
`Failed to perform inference: ${message ?? "an HTTP error occurred when requesting the provider"}`,
|
|
95
|
+
{
|
|
96
|
+
url,
|
|
97
|
+
method: info.method ?? "GET",
|
|
98
|
+
headers: info.headers as Record<string, string>,
|
|
99
|
+
body: requestArgsToJson(args),
|
|
100
|
+
},
|
|
101
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: message ?? "" }
|
|
102
|
+
);
|
|
54
103
|
}
|
|
55
104
|
|
|
56
105
|
if (response.headers.get("Content-Type")?.startsWith("application/json")) {
|
|
@@ -85,26 +134,81 @@ export async function* innerStreamingRequest<T>(
|
|
|
85
134
|
if (response.headers.get("Content-Type")?.startsWith("application/json")) {
|
|
86
135
|
const output = await response.json();
|
|
87
136
|
if ([400, 422, 404, 500].includes(response.status) && options?.chatCompletion) {
|
|
88
|
-
throw new
|
|
137
|
+
throw new InferenceClientProviderApiError(
|
|
138
|
+
`Provider ${args.provider} does not seem to support chat completion for model ${
|
|
139
|
+
args.model
|
|
140
|
+
} . Error: ${JSON.stringify(output.error)}`,
|
|
141
|
+
{
|
|
142
|
+
url,
|
|
143
|
+
method: info.method ?? "GET",
|
|
144
|
+
headers: info.headers as Record<string, string>,
|
|
145
|
+
body: requestArgsToJson(args),
|
|
146
|
+
},
|
|
147
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
148
|
+
);
|
|
89
149
|
}
|
|
90
150
|
if (typeof output.error === "string") {
|
|
91
|
-
throw new
|
|
151
|
+
throw new InferenceClientProviderApiError(
|
|
152
|
+
`Failed to perform inference: ${output.error}`,
|
|
153
|
+
{
|
|
154
|
+
url,
|
|
155
|
+
method: info.method ?? "GET",
|
|
156
|
+
headers: info.headers as Record<string, string>,
|
|
157
|
+
body: requestArgsToJson(args),
|
|
158
|
+
},
|
|
159
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
160
|
+
);
|
|
92
161
|
}
|
|
93
162
|
if (output.error && "message" in output.error && typeof output.error.message === "string") {
|
|
94
163
|
/// OpenAI errors
|
|
95
|
-
throw new
|
|
164
|
+
throw new InferenceClientProviderApiError(
|
|
165
|
+
`Failed to perform inference: ${output.error.message}`,
|
|
166
|
+
{
|
|
167
|
+
url,
|
|
168
|
+
method: info.method ?? "GET",
|
|
169
|
+
headers: info.headers as Record<string, string>,
|
|
170
|
+
body: requestArgsToJson(args),
|
|
171
|
+
},
|
|
172
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
173
|
+
);
|
|
96
174
|
}
|
|
97
175
|
// Sambanova errors
|
|
98
176
|
if (typeof output.message === "string") {
|
|
99
|
-
throw new
|
|
177
|
+
throw new InferenceClientProviderApiError(
|
|
178
|
+
`Failed to perform inference: ${output.message}`,
|
|
179
|
+
{
|
|
180
|
+
url,
|
|
181
|
+
method: info.method ?? "GET",
|
|
182
|
+
headers: info.headers as Record<string, string>,
|
|
183
|
+
body: requestArgsToJson(args),
|
|
184
|
+
},
|
|
185
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
186
|
+
);
|
|
100
187
|
}
|
|
101
188
|
}
|
|
102
189
|
|
|
103
|
-
throw new
|
|
190
|
+
throw new InferenceClientProviderApiError(
|
|
191
|
+
`Failed to perform inference: an HTTP error occurred when requesting the provider.`,
|
|
192
|
+
{
|
|
193
|
+
url,
|
|
194
|
+
method: info.method ?? "GET",
|
|
195
|
+
headers: info.headers as Record<string, string>,
|
|
196
|
+
body: requestArgsToJson(args),
|
|
197
|
+
},
|
|
198
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: "" }
|
|
199
|
+
);
|
|
104
200
|
}
|
|
105
201
|
if (!response.headers.get("content-type")?.startsWith("text/event-stream")) {
|
|
106
|
-
throw new
|
|
107
|
-
`
|
|
202
|
+
throw new InferenceClientProviderApiError(
|
|
203
|
+
`Failed to perform inference: server does not support event stream content type, it returned ` +
|
|
204
|
+
response.headers.get("content-type"),
|
|
205
|
+
{
|
|
206
|
+
url,
|
|
207
|
+
method: info.method ?? "GET",
|
|
208
|
+
headers: info.headers as Record<string, string>,
|
|
209
|
+
body: requestArgsToJson(args),
|
|
210
|
+
},
|
|
211
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: "" }
|
|
108
212
|
);
|
|
109
213
|
}
|
|
110
214
|
|
|
@@ -151,7 +255,16 @@ export async function* innerStreamingRequest<T>(
|
|
|
151
255
|
typeof data.error.message === "string"
|
|
152
256
|
? data.error.message
|
|
153
257
|
: JSON.stringify(data.error);
|
|
154
|
-
throw new
|
|
258
|
+
throw new InferenceClientProviderApiError(
|
|
259
|
+
`Failed to perform inference: an occurred while streaming the response: ${errorStr}`,
|
|
260
|
+
{
|
|
261
|
+
url,
|
|
262
|
+
method: info.method ?? "GET",
|
|
263
|
+
headers: info.headers as Record<string, string>,
|
|
264
|
+
body: requestArgsToJson(args),
|
|
265
|
+
},
|
|
266
|
+
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: data }
|
|
267
|
+
);
|
|
155
268
|
}
|
|
156
269
|
yield data as T;
|
|
157
270
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Matches a JSON object.
|
|
3
|
+
|
|
4
|
+
This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`.
|
|
5
|
+
|
|
6
|
+
@category JSON
|
|
7
|
+
*/
|
|
8
|
+
export type JsonObject = { [Key in string]: JsonValue } & { [Key in string]?: JsonValue | undefined };
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
Matches a JSON array.
|
|
12
|
+
|
|
13
|
+
@category JSON
|
|
14
|
+
*/
|
|
15
|
+
export type JsonArray = JsonValue[] | readonly JsonValue[];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
Matches any valid JSON primitive value.
|
|
19
|
+
|
|
20
|
+
@category JSON
|
|
21
|
+
*/
|
|
22
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
Matches any valid JSON value.
|
|
26
|
+
|
|
27
|
+
@see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`.
|
|
28
|
+
|
|
29
|
+
@category JSON
|
|
30
|
+
*/
|
|
31
|
+
export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|