@huggingface/inference 4.0.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/dist/commonjs/package.d.ts +1 -1
- package/dist/commonjs/package.js +1 -1
- 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/utils/request.js +2 -2
- package/dist/esm/package.d.ts +1 -1
- package/dist/esm/package.js +1 -1
- 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/utils/request.js +2 -2
- package/package.json +1 -1
- package/src/package.ts +1 -1
- package/src/snippets/getInferenceSnippets.ts +69 -7
- package/src/utils/request.ts +2 -2
package/dist/commonjs/package.js
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PACKAGE_NAME = exports.PACKAGE_VERSION = void 0;
|
|
4
4
|
// Generated file from package.json. Issues importing JSON directly when publishing on commonjs/ESM - see https://github.com/microsoft/TypeScript/issues/51783
|
|
5
|
-
exports.PACKAGE_VERSION = "4.0.
|
|
5
|
+
exports.PACKAGE_VERSION = "4.0.1";
|
|
6
6
|
exports.PACKAGE_NAME = "@huggingface/inference";
|
|
@@ -4,6 +4,7 @@ import type { InferenceProviderOrPolicy } from "../types.js";
|
|
|
4
4
|
export type InferenceSnippetOptions = {
|
|
5
5
|
streaming?: boolean;
|
|
6
6
|
billTo?: string;
|
|
7
|
+
accessToken?: string;
|
|
7
8
|
} & Record<string, unknown>;
|
|
8
|
-
export declare function getInferenceSnippets(model: ModelDataMinimal,
|
|
9
|
+
export declare function getInferenceSnippets(model: ModelDataMinimal, provider: InferenceProviderOrPolicy, inferenceProviderMapping?: InferenceProviderModelMapping, opts?: Record<string, unknown>): InferenceSnippet[];
|
|
9
10
|
//# sourceMappingURL=getInferenceSnippets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getInferenceSnippets.d.ts","sourceRoot":"","sources":["../../../src/snippets/getInferenceSnippets.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAG3F,OAAO,KAAK,EAAE,yBAAyB,EAA8B,MAAM,aAAa,CAAC;AAGzF,MAAM,MAAM,uBAAuB,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"getInferenceSnippets.d.ts","sourceRoot":"","sources":["../../../src/snippets/getInferenceSnippets.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAG3F,OAAO,KAAK,EAAE,yBAAyB,EAA8B,MAAM,aAAa,CAAC;AAGzF,MAAM,MAAM,uBAAuB,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAC5G,MAAM,EACN,OAAO,CACP,CAAC;AA0UF,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,yBAAyB,EACnC,wBAAwB,CAAC,EAAE,6BAA6B,EACxD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,gBAAgB,EAAE,CAIpB"}
|
|
@@ -76,9 +76,10 @@ const HF_JS_METHODS = {
|
|
|
76
76
|
"text-to-speech": "textToSpeech",
|
|
77
77
|
translation: "translation",
|
|
78
78
|
};
|
|
79
|
+
const ACCESS_TOKEN_PLACEHOLDER = "<ACCESS_TOKEN>"; // Placeholder to replace with env variable in snippets
|
|
79
80
|
// Snippet generators
|
|
80
81
|
const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
81
|
-
return (model,
|
|
82
|
+
return (model, provider, inferenceProviderMapping, opts) => {
|
|
82
83
|
const providerModelId = inferenceProviderMapping?.providerId ?? model.id;
|
|
83
84
|
/// Hacky: hard-code conversational templates here
|
|
84
85
|
let task = model.pipeline_tag;
|
|
@@ -97,10 +98,11 @@ const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
|
97
98
|
console.error(`Failed to get provider helper for ${provider} (${task})`, e);
|
|
98
99
|
return [];
|
|
99
100
|
}
|
|
101
|
+
const accessTokenOrPlaceholder = opts?.accessToken ?? ACCESS_TOKEN_PLACEHOLDER;
|
|
100
102
|
/// Prepare inputs + make request
|
|
101
103
|
const inputs = inputPreparationFn ? inputPreparationFn(model, opts) : { inputs: (0, tasks_1.getModelInputSnippet)(model) };
|
|
102
104
|
const request = (0, makeRequestOptions_js_1.makeRequestOptionsFromResolvedModel)(providerModelId, providerHelper, {
|
|
103
|
-
accessToken,
|
|
105
|
+
accessToken: accessTokenOrPlaceholder,
|
|
104
106
|
provider,
|
|
105
107
|
...inputs,
|
|
106
108
|
}, inferenceProviderMapping, {
|
|
@@ -121,7 +123,7 @@ const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
|
121
123
|
}
|
|
122
124
|
/// Prepare template injection data
|
|
123
125
|
const params = {
|
|
124
|
-
accessToken,
|
|
126
|
+
accessToken: accessTokenOrPlaceholder,
|
|
125
127
|
authorizationHeader: request.info.headers?.Authorization,
|
|
126
128
|
baseUrl: removeSuffix(request.url, "/chat/completions"),
|
|
127
129
|
fullUrl: request.url,
|
|
@@ -185,6 +187,10 @@ const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
|
185
187
|
});
|
|
186
188
|
snippet = `${importSection}\n\n${snippet}`;
|
|
187
189
|
}
|
|
190
|
+
/// Replace access token placeholder
|
|
191
|
+
if (snippet.includes(ACCESS_TOKEN_PLACEHOLDER)) {
|
|
192
|
+
snippet = replaceAccessTokenPlaceholder(snippet, language, provider);
|
|
193
|
+
}
|
|
188
194
|
/// Snippet is ready!
|
|
189
195
|
return { language, client: client, content: snippet };
|
|
190
196
|
})
|
|
@@ -247,9 +253,9 @@ const snippets = {
|
|
|
247
253
|
"zero-shot-classification": snippetGenerator("zeroShotClassification"),
|
|
248
254
|
"zero-shot-image-classification": snippetGenerator("zeroShotImageClassification"),
|
|
249
255
|
};
|
|
250
|
-
function getInferenceSnippets(model,
|
|
256
|
+
function getInferenceSnippets(model, provider, inferenceProviderMapping, opts) {
|
|
251
257
|
return model.pipeline_tag && model.pipeline_tag in snippets
|
|
252
|
-
? snippets[model.pipeline_tag]?.(model,
|
|
258
|
+
? snippets[model.pipeline_tag]?.(model, provider, inferenceProviderMapping, opts) ?? []
|
|
253
259
|
: [];
|
|
254
260
|
}
|
|
255
261
|
// String manipulation helpers
|
|
@@ -310,3 +316,36 @@ function indentString(str) {
|
|
|
310
316
|
function removeSuffix(str, suffix) {
|
|
311
317
|
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
|
|
312
318
|
}
|
|
319
|
+
function replaceAccessTokenPlaceholder(snippet, language, provider) {
|
|
320
|
+
// If "opts.accessToken" is not set, the snippets are generated with a placeholder.
|
|
321
|
+
// Once snippets are rendered, we replace the placeholder with code to fetch the access token from an environment variable.
|
|
322
|
+
// Determine if HF_TOKEN or specific provider token should be used
|
|
323
|
+
const accessTokenEnvVar = !snippet.includes("https://") || // no URL provided => using a client => use $HF_TOKEN
|
|
324
|
+
snippet.includes("https://router.huggingface.co") || // explicit routed request => use $HF_TOKEN
|
|
325
|
+
provider == "hf-inference" // hf-inference provider => use $HF_TOKEN
|
|
326
|
+
? "HF_TOKEN"
|
|
327
|
+
: provider.toUpperCase().replace("-", "_") + "_API_KEY"; // e.g. "REPLICATE_API_KEY"
|
|
328
|
+
// Replace the placeholder with the env variable
|
|
329
|
+
if (language === "sh") {
|
|
330
|
+
snippet = snippet.replace(`'Authorization: Bearer ${ACCESS_TOKEN_PLACEHOLDER}'`, `"Authorization: Bearer $${accessTokenEnvVar}"` // e.g. "Authorization: Bearer $HF_TOKEN"
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
else if (language === "python") {
|
|
334
|
+
snippet = "import os\n" + snippet;
|
|
335
|
+
snippet = snippet.replace(`"${ACCESS_TOKEN_PLACEHOLDER}"`, `os.environ["${accessTokenEnvVar}"]` // e.g. os.environ["HF_TOKEN")
|
|
336
|
+
);
|
|
337
|
+
snippet = snippet.replace(`"Bearer ${ACCESS_TOKEN_PLACEHOLDER}"`, `f"Bearer {os.environ['${accessTokenEnvVar}']}"` // e.g. f"Bearer {os.environ['HF_TOKEN']}"
|
|
338
|
+
);
|
|
339
|
+
snippet = snippet.replace(`"Key ${ACCESS_TOKEN_PLACEHOLDER}"`, `f"Key {os.environ['${accessTokenEnvVar}']}"` // e.g. f"Key {os.environ['FAL_AI_API_KEY']}"
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
else if (language === "js") {
|
|
343
|
+
snippet = snippet.replace(`"${ACCESS_TOKEN_PLACEHOLDER}"`, `process.env.${accessTokenEnvVar}` // e.g. process.env.HF_TOKEN
|
|
344
|
+
);
|
|
345
|
+
snippet = snippet.replace(`Authorization: "Bearer ${ACCESS_TOKEN_PLACEHOLDER}",`, `Authorization: \`Bearer $\{process.env.${accessTokenEnvVar}}\`,` // e.g. Authorization: `Bearer ${process.env.HF_TOKEN}`,
|
|
346
|
+
);
|
|
347
|
+
snippet = snippet.replace(`Authorization: "Key ${ACCESS_TOKEN_PLACEHOLDER}",`, `Authorization: \`Key $\{process.env.${accessTokenEnvVar}}\`,` // e.g. Authorization: `Key ${process.env.FAL_AI_API_KEY}`,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return snippet;
|
|
351
|
+
}
|
|
@@ -35,8 +35,8 @@ async function innerRequest(args, providerHelper, options) {
|
|
|
35
35
|
body: requestArgsToJson(args),
|
|
36
36
|
}, { requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output });
|
|
37
37
|
}
|
|
38
|
-
if (typeof output.error === "string" || typeof output.detail === "string") {
|
|
39
|
-
throw new errors_js_1.InferenceClientProviderApiError(`Failed to perform inference: ${output.error ?? output.detail}`, {
|
|
38
|
+
if (typeof output.error === "string" || typeof output.detail === "string" || typeof output.message === "string") {
|
|
39
|
+
throw new errors_js_1.InferenceClientProviderApiError(`Failed to perform inference: ${output.error ?? output.detail ?? output.message}`, {
|
|
40
40
|
url,
|
|
41
41
|
method: info.method ?? "GET",
|
|
42
42
|
headers: info.headers,
|
package/dist/esm/package.d.ts
CHANGED
package/dist/esm/package.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Generated file from package.json. Issues importing JSON directly when publishing on commonjs/ESM - see https://github.com/microsoft/TypeScript/issues/51783
|
|
2
|
-
export const PACKAGE_VERSION = "4.0.
|
|
2
|
+
export const PACKAGE_VERSION = "4.0.1";
|
|
3
3
|
export const PACKAGE_NAME = "@huggingface/inference";
|
|
@@ -4,6 +4,7 @@ import type { InferenceProviderOrPolicy } from "../types.js";
|
|
|
4
4
|
export type InferenceSnippetOptions = {
|
|
5
5
|
streaming?: boolean;
|
|
6
6
|
billTo?: string;
|
|
7
|
+
accessToken?: string;
|
|
7
8
|
} & Record<string, unknown>;
|
|
8
|
-
export declare function getInferenceSnippets(model: ModelDataMinimal,
|
|
9
|
+
export declare function getInferenceSnippets(model: ModelDataMinimal, provider: InferenceProviderOrPolicy, inferenceProviderMapping?: InferenceProviderModelMapping, opts?: Record<string, unknown>): InferenceSnippet[];
|
|
9
10
|
//# sourceMappingURL=getInferenceSnippets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getInferenceSnippets.d.ts","sourceRoot":"","sources":["../../../src/snippets/getInferenceSnippets.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAG3F,OAAO,KAAK,EAAE,yBAAyB,EAA8B,MAAM,aAAa,CAAC;AAGzF,MAAM,MAAM,uBAAuB,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"getInferenceSnippets.d.ts","sourceRoot":"","sources":["../../../src/snippets/getInferenceSnippets.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAG3F,OAAO,KAAK,EAAE,yBAAyB,EAA8B,MAAM,aAAa,CAAC;AAGzF,MAAM,MAAM,uBAAuB,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAC5G,MAAM,EACN,OAAO,CACP,CAAC;AA0UF,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,yBAAyB,EACnC,wBAAwB,CAAC,EAAE,6BAA6B,EACxD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,gBAAgB,EAAE,CAIpB"}
|
|
@@ -73,9 +73,10 @@ const HF_JS_METHODS = {
|
|
|
73
73
|
"text-to-speech": "textToSpeech",
|
|
74
74
|
translation: "translation",
|
|
75
75
|
};
|
|
76
|
+
const ACCESS_TOKEN_PLACEHOLDER = "<ACCESS_TOKEN>"; // Placeholder to replace with env variable in snippets
|
|
76
77
|
// Snippet generators
|
|
77
78
|
const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
78
|
-
return (model,
|
|
79
|
+
return (model, provider, inferenceProviderMapping, opts) => {
|
|
79
80
|
const providerModelId = inferenceProviderMapping?.providerId ?? model.id;
|
|
80
81
|
/// Hacky: hard-code conversational templates here
|
|
81
82
|
let task = model.pipeline_tag;
|
|
@@ -94,10 +95,11 @@ const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
|
94
95
|
console.error(`Failed to get provider helper for ${provider} (${task})`, e);
|
|
95
96
|
return [];
|
|
96
97
|
}
|
|
98
|
+
const accessTokenOrPlaceholder = opts?.accessToken ?? ACCESS_TOKEN_PLACEHOLDER;
|
|
97
99
|
/// Prepare inputs + make request
|
|
98
100
|
const inputs = inputPreparationFn ? inputPreparationFn(model, opts) : { inputs: getModelInputSnippet(model) };
|
|
99
101
|
const request = makeRequestOptionsFromResolvedModel(providerModelId, providerHelper, {
|
|
100
|
-
accessToken,
|
|
102
|
+
accessToken: accessTokenOrPlaceholder,
|
|
101
103
|
provider,
|
|
102
104
|
...inputs,
|
|
103
105
|
}, inferenceProviderMapping, {
|
|
@@ -118,7 +120,7 @@ const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
|
118
120
|
}
|
|
119
121
|
/// Prepare template injection data
|
|
120
122
|
const params = {
|
|
121
|
-
accessToken,
|
|
123
|
+
accessToken: accessTokenOrPlaceholder,
|
|
122
124
|
authorizationHeader: request.info.headers?.Authorization,
|
|
123
125
|
baseUrl: removeSuffix(request.url, "/chat/completions"),
|
|
124
126
|
fullUrl: request.url,
|
|
@@ -182,6 +184,10 @@ const snippetGenerator = (templateName, inputPreparationFn) => {
|
|
|
182
184
|
});
|
|
183
185
|
snippet = `${importSection}\n\n${snippet}`;
|
|
184
186
|
}
|
|
187
|
+
/// Replace access token placeholder
|
|
188
|
+
if (snippet.includes(ACCESS_TOKEN_PLACEHOLDER)) {
|
|
189
|
+
snippet = replaceAccessTokenPlaceholder(snippet, language, provider);
|
|
190
|
+
}
|
|
185
191
|
/// Snippet is ready!
|
|
186
192
|
return { language, client: client, content: snippet };
|
|
187
193
|
})
|
|
@@ -244,9 +250,9 @@ const snippets = {
|
|
|
244
250
|
"zero-shot-classification": snippetGenerator("zeroShotClassification"),
|
|
245
251
|
"zero-shot-image-classification": snippetGenerator("zeroShotImageClassification"),
|
|
246
252
|
};
|
|
247
|
-
export function getInferenceSnippets(model,
|
|
253
|
+
export function getInferenceSnippets(model, provider, inferenceProviderMapping, opts) {
|
|
248
254
|
return model.pipeline_tag && model.pipeline_tag in snippets
|
|
249
|
-
? snippets[model.pipeline_tag]?.(model,
|
|
255
|
+
? snippets[model.pipeline_tag]?.(model, provider, inferenceProviderMapping, opts) ?? []
|
|
250
256
|
: [];
|
|
251
257
|
}
|
|
252
258
|
// String manipulation helpers
|
|
@@ -307,3 +313,36 @@ function indentString(str) {
|
|
|
307
313
|
function removeSuffix(str, suffix) {
|
|
308
314
|
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
|
|
309
315
|
}
|
|
316
|
+
function replaceAccessTokenPlaceholder(snippet, language, provider) {
|
|
317
|
+
// If "opts.accessToken" is not set, the snippets are generated with a placeholder.
|
|
318
|
+
// Once snippets are rendered, we replace the placeholder with code to fetch the access token from an environment variable.
|
|
319
|
+
// Determine if HF_TOKEN or specific provider token should be used
|
|
320
|
+
const accessTokenEnvVar = !snippet.includes("https://") || // no URL provided => using a client => use $HF_TOKEN
|
|
321
|
+
snippet.includes("https://router.huggingface.co") || // explicit routed request => use $HF_TOKEN
|
|
322
|
+
provider == "hf-inference" // hf-inference provider => use $HF_TOKEN
|
|
323
|
+
? "HF_TOKEN"
|
|
324
|
+
: provider.toUpperCase().replace("-", "_") + "_API_KEY"; // e.g. "REPLICATE_API_KEY"
|
|
325
|
+
// Replace the placeholder with the env variable
|
|
326
|
+
if (language === "sh") {
|
|
327
|
+
snippet = snippet.replace(`'Authorization: Bearer ${ACCESS_TOKEN_PLACEHOLDER}'`, `"Authorization: Bearer $${accessTokenEnvVar}"` // e.g. "Authorization: Bearer $HF_TOKEN"
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
else if (language === "python") {
|
|
331
|
+
snippet = "import os\n" + snippet;
|
|
332
|
+
snippet = snippet.replace(`"${ACCESS_TOKEN_PLACEHOLDER}"`, `os.environ["${accessTokenEnvVar}"]` // e.g. os.environ["HF_TOKEN")
|
|
333
|
+
);
|
|
334
|
+
snippet = snippet.replace(`"Bearer ${ACCESS_TOKEN_PLACEHOLDER}"`, `f"Bearer {os.environ['${accessTokenEnvVar}']}"` // e.g. f"Bearer {os.environ['HF_TOKEN']}"
|
|
335
|
+
);
|
|
336
|
+
snippet = snippet.replace(`"Key ${ACCESS_TOKEN_PLACEHOLDER}"`, `f"Key {os.environ['${accessTokenEnvVar}']}"` // e.g. f"Key {os.environ['FAL_AI_API_KEY']}"
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
else if (language === "js") {
|
|
340
|
+
snippet = snippet.replace(`"${ACCESS_TOKEN_PLACEHOLDER}"`, `process.env.${accessTokenEnvVar}` // e.g. process.env.HF_TOKEN
|
|
341
|
+
);
|
|
342
|
+
snippet = snippet.replace(`Authorization: "Bearer ${ACCESS_TOKEN_PLACEHOLDER}",`, `Authorization: \`Bearer $\{process.env.${accessTokenEnvVar}}\`,` // e.g. Authorization: `Bearer ${process.env.HF_TOKEN}`,
|
|
343
|
+
);
|
|
344
|
+
snippet = snippet.replace(`Authorization: "Key ${ACCESS_TOKEN_PLACEHOLDER}",`, `Authorization: \`Key $\{process.env.${accessTokenEnvVar}}\`,` // e.g. Authorization: `Key ${process.env.FAL_AI_API_KEY}`,
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
return snippet;
|
|
348
|
+
}
|
|
@@ -31,8 +31,8 @@ export async function innerRequest(args, providerHelper, options) {
|
|
|
31
31
|
body: requestArgsToJson(args),
|
|
32
32
|
}, { requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output });
|
|
33
33
|
}
|
|
34
|
-
if (typeof output.error === "string" || typeof output.detail === "string") {
|
|
35
|
-
throw new InferenceClientProviderApiError(`Failed to perform inference: ${output.error ?? output.detail}`, {
|
|
34
|
+
if (typeof output.error === "string" || typeof output.detail === "string" || typeof output.message === "string") {
|
|
35
|
+
throw new InferenceClientProviderApiError(`Failed to perform inference: ${output.error ?? output.detail ?? output.message}`, {
|
|
36
36
|
url,
|
|
37
37
|
method: info.method ?? "GET",
|
|
38
38
|
headers: info.headers,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huggingface/inference",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Hugging Face and Tim Mikeladze <tim.mikeladze@gmail.com>",
|
|
6
6
|
"description": "Typescript client for the Hugging Face Inference Providers and Inference Endpoints",
|
package/src/package.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Generated file from package.json. Issues importing JSON directly when publishing on commonjs/ESM - see https://github.com/microsoft/TypeScript/issues/51783
|
|
2
|
-
export const PACKAGE_VERSION = "4.0.
|
|
2
|
+
export const PACKAGE_VERSION = "4.0.1";
|
|
3
3
|
export const PACKAGE_NAME = "@huggingface/inference";
|
|
@@ -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
|
+
}
|
package/src/utils/request.ts
CHANGED
|
@@ -65,9 +65,9 @@ export async function innerRequest<T>(
|
|
|
65
65
|
{ requestId: response.headers.get("x-request-id") ?? "", status: response.status, body: output }
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
|
-
if (typeof output.error === "string" || typeof output.detail === "string") {
|
|
68
|
+
if (typeof output.error === "string" || typeof output.detail === "string" || typeof output.message === "string") {
|
|
69
69
|
throw new InferenceClientProviderApiError(
|
|
70
|
-
`Failed to perform inference: ${output.error ?? output.detail}`,
|
|
70
|
+
`Failed to perform inference: ${output.error ?? output.detail ?? output.message}`,
|
|
71
71
|
{
|
|
72
72
|
url,
|
|
73
73
|
method: info.method ?? "GET",
|