@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
201 lines ⢠8.13 kB
JavaScript
import chalk from "chalk";
import ora from "ora";
import inquirer from "inquirer";
import { logger } from "../../lib/utils/logger.js";
import { updateEnvFile as writeEnvFile, displayEnvUpdateSummary, } from "../utils/envManager.js";
/**
* Validates Hugging Face API key format
* Must start with "hf_" prefix
*/
function validateHuggingFaceApiKey(apiKey) {
return (typeof apiKey === "string" && apiKey.startsWith("hf_") && apiKey.length > 10);
}
/**
* Check current Hugging Face configuration
*/
function checkHuggingFaceConfig() {
const apiKey = process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
const model = process.env.HUGGINGFACE_MODEL;
const hasApiKey = !!apiKey;
const hasModel = !!model;
const isValid = hasApiKey && validateHuggingFaceApiKey(apiKey);
return {
hasApiKey,
hasModel,
apiKey: apiKey ? `hf_${"*".repeat(6)}` : undefined,
model,
isValid,
};
}
export const handleHuggingFaceSetup = async (argv) => {
const spinner = ora();
try {
spinner.start("Checking Hugging Face configuration...");
const config = checkHuggingFaceConfig();
spinner.stop();
// Display current status
logger.always(chalk.bold.blue("\nš¤ Hugging Face Configuration Status\n"));
logger.always(`${config.hasApiKey ? "ā
" : "ā"} API Key: ${config.apiKey || "Not set"}`);
logger.always(`${config.hasModel ? "ā
" : "ā ļø"} Model: ${config.model || "Not set (will use default)"}`);
if (config.isValid) {
logger.always(chalk.green("\nā
Hugging Face is properly configured!"));
if (argv.check) {
return;
}
const { shouldReconfigure } = await inquirer.prompt([
{
type: "confirm",
name: "shouldReconfigure",
message: "Configuration looks good. Do you want to reconfigure anyway?",
default: false,
},
]);
if (!shouldReconfigure) {
logger.always(chalk.green("ā
Keeping existing configuration."));
return;
}
}
else {
logger.always(chalk.yellow("\nā ļø Hugging Face configuration needs setup."));
if (argv.check) {
throw new Error("Hugging Face configuration is incomplete");
}
}
if (argv["non-interactive"]) {
logger.always(chalk.yellow("Non-interactive mode: Skipping configuration setup."));
logger.always(chalk.blue("Please set HUGGINGFACE_API_KEY manually."));
return;
}
// Interactive setup
logger.always(chalk.blue("\nš ļø Let's configure Hugging Face!\n"));
// Step 1: API Key
const { apiKey } = await inquirer.prompt([
{
type: "password",
name: "apiKey",
message: "Enter your Hugging Face API token:",
mask: "*",
validate: (input) => {
if (!input.trim()) {
return "API token is required";
}
if (!validateHuggingFaceApiKey(input.trim())) {
return "Invalid API token format. Must start with 'hf_'";
}
return true;
},
},
]);
// Step 2: Model Selection
const { modelChoice } = await inquirer.prompt([
{
type: "select",
name: "modelChoice",
message: "Select a Hugging Face model:",
choices: [
{
name: "Skip - use default (microsoft/DialoGPT-large)",
value: "default",
},
{
name: "microsoft/DialoGPT-large (Conversational AI - Recommended)",
value: "microsoft/DialoGPT-large",
},
{
name: "microsoft/DialoGPT-medium (Faster, smaller)",
value: "microsoft/DialoGPT-medium",
},
{
name: "facebook/blenderbot-400M-distill (General purpose)",
value: "facebook/blenderbot-400M-distill",
},
{
name: "microsoft/DialoGPT-small (Fastest)",
value: "microsoft/DialoGPT-small",
},
{
name: "Custom model name",
value: "custom",
},
],
default: "default",
},
]);
let selectedModel;
if (modelChoice === "custom") {
const { customModel } = await inquirer.prompt([
{
type: "input",
name: "customModel",
message: "Enter custom model name:",
validate: (input) => {
const trimmed = input.trim();
if (!trimmed) {
return "Model name is required";
}
if (!trimmed.includes("/")) {
return "Model name should include organization (e.g., 'microsoft/DialoGPT-large')";
}
return true;
},
},
]);
selectedModel = customModel.trim();
}
else if (modelChoice !== "default") {
selectedModel = modelChoice;
}
// If modelChoice === "default", selectedModel remains undefined
// Save configuration
spinner.start("Saving configuration...");
const updates = {
HUGGINGFACE_API_KEY: apiKey.trim(),
};
// Only set model if user didn't choose default
if (selectedModel) {
updates.HUGGINGFACE_MODEL = selectedModel;
}
try {
const result = writeEnvFile(updates);
spinner.stop();
// Display update summary
displayEnvUpdateSummary(result, false);
logger.always(chalk.green("\nā
Hugging Face configuration saved successfully!"));
}
catch (envError) {
spinner.stop();
throw new Error(`Failed to save configuration: ${envError instanceof Error ? envError.message : String(envError)}`, { cause: envError });
}
logger.always(chalk.blue("\nš Usage examples:"));
logger.always(chalk.gray(' neurolink generate "Hello, how are you?" --provider huggingface'));
if (selectedModel) {
logger.always(chalk.gray(` neurolink generate "Tell me a story" --provider huggingface --model ${selectedModel}`));
}
else {
logger.always(chalk.gray(' neurolink generate "Tell me a story" --provider huggingface'));
logger.always(chalk.gray(' neurolink generate "Explain AI" --provider huggingface --model microsoft/DialoGPT-medium'));
}
logger.always(chalk.blue("\nš Resources:"));
logger.always(chalk.gray(" ⢠Hugging Face Models: https://huggingface.co/models"));
logger.always(chalk.gray(" ⢠API Documentation: https://huggingface.co/docs/api-inference"));
logger.always(chalk.gray(" ⢠Get API Token: https://huggingface.co/settings/tokens"));
}
catch (error) {
spinner.stop();
logger.error("Hugging Face setup failed", error);
throw error;
}
};
export const setupHuggingFaceBuilder = {
check: {
type: "boolean",
describe: "Only check existing configuration without prompting",
default: false,
},
"non-interactive": {
type: "boolean",
describe: "Skip interactive prompts",
default: false,
},
};
//# sourceMappingURL=setup-huggingface.js.map