UNPKG

ragvault

Version:

Securely manage and query your private data using a local vector database. Your private RAG.

149 lines (148 loc) 6.46 kB
#!/usr/bin/env node import { loadUsers, saveUsers } from "./utils/user-transactions.js"; import { loadSession, saveSession } from "./utils/session.js"; import { ensureAppDir } from "./utils/cli-helpers.js"; import { promptAuthenticatedUser } from "./inquirer-commands/ask-authenticated.js"; import { promptUnauthenticatedUser } from "./inquirer-commands/ask-unauthenticated.js"; import { handleAuthenticatedAction } from "./actions-for-inquirers/ask-authenticated-action.js"; import { handleUnauthenticatedAction } from "./actions-for-inquirers/ask-unauthenticated-action.js"; import cfonts from "cfonts"; import { checkChromaDocker } from "./utils/check-chromadocker.js"; import { generateCollectionName } from "./utils/generate-collectionName.js"; import { exec } from 'child_process'; import { promisify } from 'util'; import fs from 'fs/promises'; import path from 'path'; const execAsync = promisify(exec); async function startChromaDocker() { try { // Check if Docker is available try { await execAsync('docker --version'); } catch (error) { console.error('Docker is not installed or not available in PATH.'); return false; } // Check if chromadb/chroma image is available try { await execAsync('docker image inspect chromadb/chroma:latest >/dev/null 2>&1'); } catch (error) { console.log('ChromaDB image not found locally. Pulling from Docker Hub...'); try { await execAsync('docker pull chromadb/chroma:latest'); console.log('ChromaDB image pulled successfully.'); } catch (pullError) { console.error('Failed to pull ChromaDB image:', pullError); return false; } } // Stop and remove existing container if it exists try { // These commands will throw an error if the container doesn't exist, // which is fine, so we wrap them in a try-catch. await execAsync('docker stop chromadb'); await execAsync('docker rm chromadb'); console.log('Stopped and removed existing ChromaDB container.'); } catch (error) { // Ignore errors, container might not exist. } // Create and start a new container await execAsync("docker run -d --name chromadb -p 8765:8000 -v ragvault-data:/chroma/chroma chromadb/chroma"); console.log("New ChromaDB Docker container started successfully"); return true; } catch (error) { console.error('Failed to start ChromaDB Docker container:', error); return false; } } async function ensureHistoryDir() { const historyDir = path.join(process.cwd(), "conversation-history"); try { await fs.mkdir(historyDir, { recursive: true }); } catch (error) { console.error("Error creating history directory:", error); } } export async function mainInq() { await ensureAppDir(); await ensureHistoryDir(); const users = await loadUsers(); let session = await loadSession(); let currentUserName = session.currentUser?.username; let isChromaDBRunning = await checkChromaDocker(); if (!isChromaDBRunning) { console.log('ChromaDB Docker is not running. Attempting to start it...'); const started = await startChromaDocker(); if (started) { // Wait a few seconds for the container to fully start await new Promise(resolve => setTimeout(resolve, 5000)); isChromaDBRunning = await checkChromaDocker(); } } if (!isChromaDBRunning) { cfonts.say("Error", { font: "block", align: "left", colors: ["red"], background: "transparent", letterSpacing: 1, lineHeight: 1, space: true, maxLength: "0", gradient: false, }); console.log("Unable to start ChromaDB Docker. Please make sure Docker is installed and running."); process.exit(1); } cfonts.say("RAGVAULT", { font: "block", // define the font face align: "left", // define text alignment colors: ["system"], // define all colors background: "transparent", // define the background color, you can also use `backgroundColor` here as key letterSpacing: 1, // define letter spacing lineHeight: 1, // define the line height space: true, // define if the output text should have empty lines on top and on the bottom maxLength: "0", // define how many character can be on one line gradient: false, // define your two gradient colors independentGradient: false, // define if you want to recalculate the gradient for each new line transitionGradient: false, // define if this is a transition between colors directly rawMode: false, // define if the line breaks should be CRLF (`\r\n`) over the default LF (`\n`) env: "node", // define the environment cfonts is being executed in }); while (true) { if (!currentUserName) { const action = await promptUnauthenticatedUser(); const user = await handleUnauthenticatedAction(action, users, session); if (user) { session.currentUser = user; await saveSession(session); currentUserName = user.username; } } else if (!users[currentUserName].collectionName) { const isCollectionNameSet = users[currentUserName].collectionName; if (!isCollectionNameSet) { const collectionName = await generateCollectionName(currentUserName); users[currentUserName].collectionName = collectionName.name; await saveUsers(users); } const action = await promptAuthenticatedUser(currentUserName); await handleAuthenticatedAction(action, currentUserName, session, users); if (!session.currentUser) currentUserName = undefined; } else { const action = await promptAuthenticatedUser(currentUserName); await handleAuthenticatedAction(action, currentUserName, session, users); if (!session.currentUser) currentUserName = undefined; } } } mainInq();