diff --git a/packages/inference/.gitignore b/packages/inference/.gitignore new file mode 100644 index 0000000000..08c5ac1e7a --- /dev/null +++ b/packages/inference/.gitignore @@ -0,0 +1 @@ +src/snippets/templates.exported.ts \ No newline at end of file diff --git a/packages/inference/package.json b/packages/inference/package.json index 448f82d8f2..4fb1e6c92a 100644 --- a/packages/inference/package.json +++ b/packages/inference/package.json @@ -26,27 +26,21 @@ }, "files": [ "dist", - "src" + "src", + "!src/snippets/templates/**/*.jinja" ], "source": "src/index.ts", "types": "./dist/src/index.d.ts", "main": "./dist/index.cjs", "module": "./dist/index.js", "exports": { - ".": { - "types": "./dist/src/index.d.ts", - "require": "./dist/index.cjs", - "import": "./dist/index.js" - } - }, - "browser": { - "./src/snippets/index.js": false, - "./dist/index.js": "./dist/browser/index.js", - "./dist/index.mjs": "./dist/browser/index.mjs" + "types": "./dist/src/index.d.ts", + "require": "./dist/index.cjs", + "import": "./dist/index.js" }, "type": "module", "scripts": { - "build": "tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration", + "build": "pnpm run export-templates && tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration", "dts": "tsx scripts/generate-dts.ts && tsc --noEmit dist/index.d.ts", "lint": "eslint --quiet --fix --ext .cjs,.ts .", "lint:check": "eslint --ext .cjs,.ts .", @@ -57,7 +51,8 @@ "test": "vitest run --config vitest.config.mts", "test:browser": "vitest run --browser.name=chrome --browser.headless --config vitest.config.mts", "check": "tsc", - "dev": "tsup src/index.ts --format cjs,esm --watch" + "dev": "pnpm run export-templates && tsup src/index.ts --format cjs,esm --watch", + "export-templates": "tsx scripts/export-templates.ts" }, "dependencies": { "@huggingface/tasks": "workspace:^", diff --git a/packages/inference/scripts/export-templates.ts b/packages/inference/scripts/export-templates.ts new file mode 100644 index 0000000000..cd22362a91 --- /dev/null +++ b/packages/inference/scripts/export-templates.ts @@ -0,0 +1,54 @@ +/* Script that export all jinja files from packages/inference/src/snippets/templates into a TS module. + +Templates are exported in packages/inference/src/snippets/templates.exported.ts. +*/ +import { readFileSync, writeFileSync, readdirSync } from "node:fs"; +import path from "node:path"; + +const TEMPLATES_DIR = path.join(process.cwd(), "src", "snippets", "templates"); + +function exportTemplatesAsCode(): string { + /// language -> client -> templateName -> templateContent + const templates: Record>> = {}; + + // Read all language directories + const languages = readdirSync(TEMPLATES_DIR); + for (const language of languages) { + const languagePath = path.join(TEMPLATES_DIR, language); + if (!readdirSync(languagePath).length) continue; + + templates[language] = {}; + + // Read all client directories + const clients = readdirSync(languagePath); + for (const client of clients) { + const clientPath = path.join(languagePath, client); + if (!readdirSync(clientPath).length) continue; + + templates[language][client] = {}; + + // Read all template files + const files = readdirSync(clientPath); + for (const file of files) { + if (!file.endsWith(".jinja")) continue; + + const templatePath = path.join(clientPath, file); + const templateContent = readFileSync(templatePath, "utf8"); + const templateName = path.basename(file, ".jinja"); + + templates[language][client][templateName] = templateContent; + } + } + } + + const templatesJson = JSON.stringify(templates, null, 2); + return `// Generated file - do not edit directly +export const templates: Record>> = ${templatesJson} as const; +`; +} + +// Generate and write the templates file +const output = exportTemplatesAsCode(); +const outputPath = path.join(process.cwd(), "src", "snippets", "templates.exported.ts"); +writeFileSync(outputPath, output); +console.log("Templates exported successfully! 🚀"); diff --git a/packages/inference/src/snippets/getInferenceSnippets.ts b/packages/inference/src/snippets/getInferenceSnippets.ts index 377869709f..6e126c3aaa 100644 --- a/packages/inference/src/snippets/getInferenceSnippets.ts +++ b/packages/inference/src/snippets/getInferenceSnippets.ts @@ -10,9 +10,7 @@ import { import type { InferenceProvider, InferenceTask, RequestArgs } from "../types"; import { Template } from "@huggingface/jinja"; import { makeRequestOptionsFromResolvedModel } from "../lib/makeRequestOptions"; -import fs from "fs"; -import path from "path"; -import { existsSync as pathExists } from "node:fs"; +import { templates } from "./templates.exported"; const PYTHON_CLIENTS = ["huggingface_hub", "fal_client", "requests", "openai"] as const; const JS_CLIENTS = ["fetch", "huggingface.js", "openai"] as const; @@ -44,34 +42,18 @@ interface TemplateParams { // Helpers to find + load templates -const rootDirFinder = (): string => { - let currentPath = - typeof import.meta !== "undefined" && import.meta.url - ? path.normalize(new URL(import.meta.url).pathname) /// for ESM - : __dirname; /// for CJS - - while (currentPath !== "/") { - if (pathExists(path.join(currentPath, "package.json"))) { - return currentPath; - } - - currentPath = path.normalize(path.join(currentPath, "..")); - } - - return "/"; -}; - -const templatePath = (language: InferenceSnippetLanguage, client: Client, templateName: string): string => - path.join(rootDirFinder(), "src", "snippets", "templates", language, client, `${templateName}.jinja`); const hasTemplate = (language: InferenceSnippetLanguage, client: Client, templateName: string): boolean => - pathExists(templatePath(language, client, templateName)); + templates[language]?.[client]?.[templateName] !== undefined; const loadTemplate = ( language: InferenceSnippetLanguage, client: Client, templateName: string ): ((data: TemplateParams) => string) => { - const template = fs.readFileSync(templatePath(language, client, templateName), "utf8"); + const template = templates[language]?.[client]?.[templateName]; + if (!template) { + throw new Error(`Template not found: ${language}/${client}/${templateName}`); + } return (data: TemplateParams) => new Template(template).render({ ...data }); }; diff --git a/packages/inference/tsup.config.ts b/packages/inference/tsup.config.ts deleted file mode 100644 index 6be4e128a6..0000000000 --- a/packages/inference/tsup.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -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", - target: "es2018", - splitting: true, - outDir: "dist/browser", -}; - -export default [nodeConfig, browserConfig];