UNPKG

@masuidrive/bloom-local-rag

Version:

RAG (Retrieval-Augmented Generation) system for local directories - Index and search your documents with AI-powered answers

101 lines (98 loc) 4.66 kB
#!/usr/bin/env node // Suppress LanceDB debug logs unless explicitly enabled if (!process.env.RUST_LOG) { // Set general log level to error and specifically disable lance_encoding TRACE logs process.env.RUST_LOG = 'error,lance_encoding=off,lance_file=off,lance=warn'; } // Also try LanceDB-specific environment variables if (!process.env.LANCE_LOG) { process.env.LANCE_LOG = 'error'; } if (!process.env.LANCEDB_LOG) { process.env.LANCEDB_LOG = 'error'; } // Note: Node.js cannot directly redirect file descriptor 2 (stderr) that native modules use // The Rust-based LanceDB writes directly to fd 2, bypassing Node.js's process.stderr // The only reliable way to suppress these logs is at the shell level: // bloom-local-rag command 2>/dev/null // bloom-local-rag command 2> >(grep -v "[TRACE\|DEBUG" >&2) import { Command } from 'commander'; import { readFileSync } from 'fs'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; import { config as dotenvConfig } from 'dotenv'; import { initCommand } from './commands/init.js'; import { queryCommand } from './commands/query.js'; import { reindexCommand } from './commands/reindex.js'; import { statusCommand } from './commands/status.js'; // Load environment variables from .env file dotenvConfig(); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Read package.json for version const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')); const program = new Command(); program .name('bloom-local-rag') .description(`RAG (Retrieval-Augmented Generation) system for local directories. This tool enables semantic search across your local documents with AI-powered answers. It creates a vector database from your files and uses LLMs to provide contextual answers. Key features: • Index multiple file types (Markdown, code, YAML, etc.) • Semantic search using vector embeddings • AI-generated answers based on your documents • Supports both Gemini and OpenAI models • No daemon process required Quick start: 1. Set up API key: export GOOGLE_API_KEY=your-key 2. Initialize: npx @masuidrive/bloom-local-rag --init 3. Search: npx @masuidrive/bloom-local-rag "your question"`) .version(packageJson.version) .argument('[query]', 'search query (default mode)') .option('-d, --dir <path>', 'target directory (default: current directory)', (value, previous) => value) .option('--directory <path>', 'target directory (default: current directory)', (value, previous) => value) .option('--init', 'initialize RAG system in directory') .option('--reindex', 'update the vector index with file changes') .option('--status', 'display information about indexed documents') .option('-l, --limit <n>', 'number of results (query mode)', parseInt, 5) .option('--no-context', 'skip LLM answer generation (query mode)') .option('--json', 'output as JSON (query mode)') .option('--temperature <value>', 'LLM temperature (query mode)', parseFloat) .option('-v, --verbose', 'show detailed information') .option('--force', 'force reindex all files (reindex mode)') .option('-e, --extensions <exts...>', 'file extensions to index (init mode)', ['.md', '.mdx', '.txt', '.js', '.ts', '.jsx', '.tsx', '.yaml', '.yml']) .option('--chunk-size <size>', 'text chunk size (init mode)', parseInt, 1000) .option('--chunk-overlap <size>', 'chunk overlap size (init mode)', parseInt, 200) .option('--embedding-provider <provider>', 'embedding provider (init mode)', 'gemini') .option('--embedding-model <model>', 'embedding model (init mode)') .option('--llm-provider <provider>', 'LLM provider (init mode)', 'gemini') .option('--llm-model <model>', 'LLM model (init mode)') .option('--exclude <patterns...>', 'additional exclude patterns (init mode)', []) .action(async (query, options) => { // Merge directory options const mergedOptions = { ...options, directory: options.directory || options.dir }; // Determine which mode to run if (options.init) { await initCommand(mergedOptions); } else if (options.reindex) { await reindexCommand(mergedOptions); } else if (options.status) { await statusCommand(mergedOptions); } else if (query) { // Default query mode await queryCommand(query, mergedOptions); } else { // No query provided and no mode specified program.outputHelp(); } }); // Parse command line arguments program.parse(process.argv); //# sourceMappingURL=cli.js.map