From 1a78b1601ad8249f6c7b71f1b9c02d0326ad32d3 Mon Sep 17 00:00:00 2001 From: Wauplin Date: Fri, 7 Mar 2025 15:11:44 +0100 Subject: [PATCH 1/9] Raise in snippet templating if not using nodejs --- packages/inference/src/snippets/python.ts | 5 +++++ packages/inference/src/utils/environment.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 packages/inference/src/utils/environment.ts diff --git a/packages/inference/src/snippets/python.ts b/packages/inference/src/snippets/python.ts index 2db55df8d0..e789713408 100644 --- a/packages/inference/src/snippets/python.ts +++ b/packages/inference/src/snippets/python.ts @@ -13,6 +13,7 @@ import { Template } from "@huggingface/jinja"; import fs from "fs"; import path from "path"; import { existsSync as pathExists } from "node:fs"; +import { isNode, SnippetEnvironmentError } from "../utils/environment"; const TOOLS = ["huggingface_hub", "requests", "fal_client", "openai"]; @@ -234,6 +235,10 @@ export function getPythonInferenceSnippet( providerModelId?: string, opts?: Record ): InferenceSnippet[] { + if (!isNode()) { + throw new SnippetEnvironmentError("Python snippet generation is only available in Node.js environment"); + } + const snippets = model.tags.includes("conversational") ? snippetConversational(model, accessToken, provider, providerModelId, opts) : model.pipeline_tag && model.pipeline_tag in pythonSnippets diff --git a/packages/inference/src/utils/environment.ts b/packages/inference/src/utils/environment.ts new file mode 100644 index 0000000000..20286e3a2f --- /dev/null +++ b/packages/inference/src/utils/environment.ts @@ -0,0 +1,16 @@ +/** + * Checks if code is running in Node.js environment (for snippet generation) + */ +export function isNode(): boolean { + return typeof process !== "undefined" && process.versions != null && process.versions.node != null; +} + +/** + * Error thrown when trying to use snippet generation in unsupported environment + */ +export class SnippetEnvironmentError extends Error { + constructor(message: string) { + super(message); + this.name = "SnippetEnvironmentError"; + } +} From 06429f0cd419685dc15950aa8293bc57ac4f3a2d Mon Sep 17 00:00:00 2001 From: Wauplin Date: Fri, 7 Mar 2025 15:29:39 +0100 Subject: [PATCH 2/9] refacto --- packages/inference/src/snippets/python.ts | 37 +++++++++++++++------ packages/inference/src/utils/environment.ts | 16 --------- 2 files changed, 26 insertions(+), 27 deletions(-) delete mode 100644 packages/inference/src/utils/environment.ts diff --git a/packages/inference/src/snippets/python.ts b/packages/inference/src/snippets/python.ts index e789713408..1c334e62a7 100644 --- a/packages/inference/src/snippets/python.ts +++ b/packages/inference/src/snippets/python.ts @@ -10,10 +10,6 @@ import { } from "@huggingface/tasks"; import type { InferenceProvider } from "../types"; import { Template } from "@huggingface/jinja"; -import fs from "fs"; -import path from "path"; -import { existsSync as pathExists } from "node:fs"; -import { isNode, SnippetEnvironmentError } from "../utils/environment"; const TOOLS = ["huggingface_hub", "requests", "fal_client", "openai"]; @@ -30,8 +26,25 @@ interface TemplateParams { } // Helpers to find + load templates +function isNode(): boolean { + return typeof process !== "undefined" && process.versions != null && process.versions.node != null; +} + +function loadNodeModules() { + if (!isNode()) { + throw new Error("Inference snippet generation is only available in Node.js environment"); + } + // eslint-disable-next-line @typescript-eslint/no-var-requires + const fs = require("fs"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const path = require("path"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const pathExists = require("fs").existsSync; + return { fs, path, pathExists }; +} const rootDirFinder = (): string => { + const { path, pathExists } = loadNodeModules(); let currentPath = path.normalize(import.meta.url).replace("file:", ""); while (currentPath !== "/") { @@ -45,11 +58,17 @@ const rootDirFinder = (): string => { return "/"; }; -const templatePath = (tool: string, templateName: string): string => - path.join(rootDirFinder(), "src", "snippets", "templates", "python", tool, `${templateName}.jinja`); -const hasTemplate = (tool: string, templateName: string): boolean => pathExists(templatePath(tool, templateName)); +const templatePath = (tool: string, templateName: string): string => { + const { path } = loadNodeModules(); + return path.join(rootDirFinder(), "src", "snippets", "templates", "python", tool, `${templateName}.jinja`); +}; +const hasTemplate = (tool: string, templateName: string): boolean => { + const { pathExists } = loadNodeModules(); + return pathExists(templatePath(tool, templateName)); +}; const loadTemplate = (tool: string, templateName: string): ((data: TemplateParams) => string) => { + const { fs } = loadNodeModules(); const template = fs.readFileSync(templatePath(tool, templateName), "utf8"); return (data: TemplateParams) => new Template(template).render({ ...data }); }; @@ -235,10 +254,6 @@ export function getPythonInferenceSnippet( providerModelId?: string, opts?: Record ): InferenceSnippet[] { - if (!isNode()) { - throw new SnippetEnvironmentError("Python snippet generation is only available in Node.js environment"); - } - const snippets = model.tags.includes("conversational") ? snippetConversational(model, accessToken, provider, providerModelId, opts) : model.pipeline_tag && model.pipeline_tag in pythonSnippets diff --git a/packages/inference/src/utils/environment.ts b/packages/inference/src/utils/environment.ts deleted file mode 100644 index 20286e3a2f..0000000000 --- a/packages/inference/src/utils/environment.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Checks if code is running in Node.js environment (for snippet generation) - */ -export function isNode(): boolean { - return typeof process !== "undefined" && process.versions != null && process.versions.node != null; -} - -/** - * Error thrown when trying to use snippet generation in unsupported environment - */ -export class SnippetEnvironmentError extends Error { - constructor(message: string) { - super(message); - this.name = "SnippetEnvironmentError"; - } -} From 24042d797ffc3215a61c3d8a649013c462ebbb69 Mon Sep 17 00:00:00 2001 From: Wauplin Date: Mon, 10 Mar 2025 17:11:39 +0100 Subject: [PATCH 3/9] do not bundle snippets code if browser mode --- packages/inference/package.json | 13 ++++++--- packages/inference/src/snippets/python.ts | 33 +++++------------------ 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/packages/inference/package.json b/packages/inference/package.json index ee6fa68381..6895b13df7 100644 --- a/packages/inference/package.json +++ b/packages/inference/package.json @@ -33,9 +33,16 @@ "main": "./dist/index.cjs", "module": "./dist/index.js", "exports": { - "types": "./dist/src/index.d.ts", - "require": "./dist/index.cjs", - "import": "./dist/index.js" + ".": { + "types": "./dist/src/index.d.ts", + "require": "./dist/index.cjs", + "import": "./dist/index.js" + } + }, + "browser": { + "./src/snippets": false, + "./dist/index.js": "./dist/browser/index.js", + "./dist/index.mjs": "./dist/browser/index.mjs" }, "type": "module", "scripts": { diff --git a/packages/inference/src/snippets/python.ts b/packages/inference/src/snippets/python.ts index 1c334e62a7..a5aa074fb1 100644 --- a/packages/inference/src/snippets/python.ts +++ b/packages/inference/src/snippets/python.ts @@ -10,6 +10,9 @@ import { } from "@huggingface/tasks"; import type { InferenceProvider } from "../types"; import { Template } from "@huggingface/jinja"; +import fs from "fs"; +import path from "path"; +import { existsSync as pathExists } from "node:fs"; const TOOLS = ["huggingface_hub", "requests", "fal_client", "openai"]; @@ -26,25 +29,7 @@ interface TemplateParams { } // Helpers to find + load templates -function isNode(): boolean { - return typeof process !== "undefined" && process.versions != null && process.versions.node != null; -} - -function loadNodeModules() { - if (!isNode()) { - throw new Error("Inference snippet generation is only available in Node.js environment"); - } - // eslint-disable-next-line @typescript-eslint/no-var-requires - const fs = require("fs"); - // eslint-disable-next-line @typescript-eslint/no-var-requires - const path = require("path"); - // eslint-disable-next-line @typescript-eslint/no-var-requires - const pathExists = require("fs").existsSync; - return { fs, path, pathExists }; -} - const rootDirFinder = (): string => { - const { path, pathExists } = loadNodeModules(); let currentPath = path.normalize(import.meta.url).replace("file:", ""); while (currentPath !== "/") { @@ -58,17 +43,11 @@ const rootDirFinder = (): string => { return "/"; }; -const templatePath = (tool: string, templateName: string): string => { - const { path } = loadNodeModules(); - return path.join(rootDirFinder(), "src", "snippets", "templates", "python", tool, `${templateName}.jinja`); -}; -const hasTemplate = (tool: string, templateName: string): boolean => { - const { pathExists } = loadNodeModules(); - return pathExists(templatePath(tool, templateName)); -}; +const templatePath = (tool: string, templateName: string): string => + path.join(rootDirFinder(), "src", "snippets", "templates", "python", tool, `${templateName}.jinja`); +const hasTemplate = (tool: string, templateName: string): boolean => pathExists(templatePath(tool, templateName)); const loadTemplate = (tool: string, templateName: string): ((data: TemplateParams) => string) => { - const { fs } = loadNodeModules(); const template = fs.readFileSync(templatePath(tool, templateName), "utf8"); return (data: TemplateParams) => new Template(template).render({ ...data }); }; From 23fd3577f5d633938e33c12b6378e242955af062 Mon Sep 17 00:00:00 2001 From: Wauplin Date: Mon, 10 Mar 2025 17:11:58 +0100 Subject: [PATCH 4/9] add tsup config --- packages/inference/tsup.config.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/inference/tsup.config.ts diff --git a/packages/inference/tsup.config.ts b/packages/inference/tsup.config.ts new file mode 100644 index 0000000000..b3b40c89e3 --- /dev/null +++ b/packages/inference/tsup.config.ts @@ -0,0 +1,22 @@ +import type { Options } from "tsup"; + +const baseConfig: Options = { + entry: ["./index.ts"], + format: ["cjs", "esm"], + outDir: "dist", + clean: true, +}; + +const nodeConfig: Options = { + ...baseConfig, + platform: "node", +}; + +const browserConfig: Options = { + ...baseConfig, + platform: "browser", + splitting: true, + outDir: "dist/browser", +}; + +export default [nodeConfig, browserConfig]; From ec58abf32958d988a6a258b1ab9296c5e7bb0f01 Mon Sep 17 00:00:00 2001 From: Wauplin Date: Mon, 10 Mar 2025 18:40:54 +0100 Subject: [PATCH 5/9] test --- packages/inference/package.json | 5 +++++ packages/inference/src/index.ts | 5 ++++- packages/inference/src/snippets/index.ts | 2 +- packages/inference/tsup.config.ts | 1 + packages/tasks-gen/scripts/generate-snippets-fixtures.ts | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/inference/package.json b/packages/inference/package.json index 6895b13df7..06565e95b8 100644 --- a/packages/inference/package.json +++ b/packages/inference/package.json @@ -37,6 +37,11 @@ "types": "./dist/src/index.d.ts", "require": "./dist/index.cjs", "import": "./dist/index.js" + }, + "./snippets": { + "types": "./dist/snippets/index.d.ts", + "require": "./dist/snippets/index.cjs", + "import": "./dist/snippets/index.js" } }, "browser": { diff --git a/packages/inference/src/index.ts b/packages/inference/src/index.ts index b21526a5ea..1c7fa246db 100644 --- a/packages/inference/src/index.ts +++ b/packages/inference/src/index.ts @@ -3,5 +3,8 @@ export { InferenceOutputError } from "./lib/InferenceOutputError"; export * from "./types"; export * from "./tasks"; -import * as snippets from "./snippets/index.js"; +let snippets = {}; +if (typeof window === "undefined") { + snippets = import("./snippets").then((mod) => mod.default); +} export { snippets }; diff --git a/packages/inference/src/snippets/index.ts b/packages/inference/src/snippets/index.ts index 142c965642..922fda1b07 100644 --- a/packages/inference/src/snippets/index.ts +++ b/packages/inference/src/snippets/index.ts @@ -2,4 +2,4 @@ import * as curl from "./curl.js"; import * as python from "./python.js"; import * as js from "./js.js"; -export { curl, python, js }; +export default { curl, python, js }; diff --git a/packages/inference/tsup.config.ts b/packages/inference/tsup.config.ts index b3b40c89e3..6be4e128a6 100644 --- a/packages/inference/tsup.config.ts +++ b/packages/inference/tsup.config.ts @@ -15,6 +15,7 @@ const nodeConfig: Options = { const browserConfig: Options = { ...baseConfig, platform: "browser", + target: "es2018", splitting: true, outDir: "dist/browser", }; diff --git a/packages/tasks-gen/scripts/generate-snippets-fixtures.ts b/packages/tasks-gen/scripts/generate-snippets-fixtures.ts index c9051a2c57..17a3d4ae9e 100644 --- a/packages/tasks-gen/scripts/generate-snippets-fixtures.ts +++ b/packages/tasks-gen/scripts/generate-snippets-fixtures.ts @@ -19,7 +19,7 @@ import { existsSync as pathExists } from "node:fs"; import * as fs from "node:fs/promises"; import * as path from "node:path/posix"; -import { snippets } from "@huggingface/inference"; +import { snippets } from "@huggingface/inference/snippets"; import type { SnippetInferenceProvider, InferenceSnippet, ModelDataMinimal } from "@huggingface/tasks"; type LANGUAGE = "sh" | "js" | "py"; From 3848abeb6810f4b75474263eb5e58fa4d0720051 Mon Sep 17 00:00:00 2001 From: Wauplin Date: Mon, 10 Mar 2025 18:52:28 +0100 Subject: [PATCH 6/9] remove for now --- packages/inference/package.json | 5 ----- packages/tasks-gen/scripts/generate-snippets-fixtures.ts | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/inference/package.json b/packages/inference/package.json index 06565e95b8..6895b13df7 100644 --- a/packages/inference/package.json +++ b/packages/inference/package.json @@ -37,11 +37,6 @@ "types": "./dist/src/index.d.ts", "require": "./dist/index.cjs", "import": "./dist/index.js" - }, - "./snippets": { - "types": "./dist/snippets/index.d.ts", - "require": "./dist/snippets/index.cjs", - "import": "./dist/snippets/index.js" } }, "browser": { diff --git a/packages/tasks-gen/scripts/generate-snippets-fixtures.ts b/packages/tasks-gen/scripts/generate-snippets-fixtures.ts index 17a3d4ae9e..c9051a2c57 100644 --- a/packages/tasks-gen/scripts/generate-snippets-fixtures.ts +++ b/packages/tasks-gen/scripts/generate-snippets-fixtures.ts @@ -19,7 +19,7 @@ import { existsSync as pathExists } from "node:fs"; import * as fs from "node:fs/promises"; import * as path from "node:path/posix"; -import { snippets } from "@huggingface/inference/snippets"; +import { snippets } from "@huggingface/inference"; import type { SnippetInferenceProvider, InferenceSnippet, ModelDataMinimal } from "@huggingface/tasks"; type LANGUAGE = "sh" | "js" | "py"; From be6074a4bc2183ed64a6d6f2ffc4517cffc96dc5 Mon Sep 17 00:00:00 2001 From: Wauplin Date: Mon, 10 Mar 2025 18:54:43 +0100 Subject: [PATCH 7/9] nit --- packages/inference/src/snippets/python.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/inference/src/snippets/python.ts b/packages/inference/src/snippets/python.ts index a5aa074fb1..2db55df8d0 100644 --- a/packages/inference/src/snippets/python.ts +++ b/packages/inference/src/snippets/python.ts @@ -29,6 +29,7 @@ interface TemplateParams { } // Helpers to find + load templates + const rootDirFinder = (): string => { let currentPath = path.normalize(import.meta.url).replace("file:", ""); From 9584aeaf5c9934c6459bb2a627116713ff6db840 Mon Sep 17 00:00:00 2001 From: coyotte508 Date: Mon, 10 Mar 2025 23:58:13 +0100 Subject: [PATCH 8/9] revert custom import --- packages/inference/src/index.ts | 5 +---- packages/inference/src/snippets/index.ts | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/inference/src/index.ts b/packages/inference/src/index.ts index 1c7fa246db..aa16be8e63 100644 --- a/packages/inference/src/index.ts +++ b/packages/inference/src/index.ts @@ -2,9 +2,6 @@ export { InferenceClient, InferenceClientEndpoint, HfInference } from "./Inferen export { InferenceOutputError } from "./lib/InferenceOutputError"; export * from "./types"; export * from "./tasks"; +import * as snippets from "./snippets/index.js"; -let snippets = {}; -if (typeof window === "undefined") { - snippets = import("./snippets").then((mod) => mod.default); -} export { snippets }; diff --git a/packages/inference/src/snippets/index.ts b/packages/inference/src/snippets/index.ts index 922fda1b07..142c965642 100644 --- a/packages/inference/src/snippets/index.ts +++ b/packages/inference/src/snippets/index.ts @@ -2,4 +2,4 @@ import * as curl from "./curl.js"; import * as python from "./python.js"; import * as js from "./js.js"; -export default { curl, python, js }; +export { curl, python, js }; From 722b9027b0c59c1ff5212b34451d36d3e6171bf0 Mon Sep 17 00:00:00 2001 From: coyotte508 Date: Tue, 11 Mar 2025 00:11:50 +0100 Subject: [PATCH 9/9] fix package.json definition --- packages/inference/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/inference/package.json b/packages/inference/package.json index 6895b13df7..dfe93e8d64 100644 --- a/packages/inference/package.json +++ b/packages/inference/package.json @@ -40,7 +40,7 @@ } }, "browser": { - "./src/snippets": false, + "./src/snippets/index.js": false, "./dist/index.js": "./dist/browser/index.js", "./dist/index.mjs": "./dist/browser/index.mjs" },