UNPKG

ragvault

Version:

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

195 lines (194 loc) 9.66 kB
import inquirer from "inquirer"; import { LLM } from "../../types/index.js"; import { getCollection } from "../../utils/chroma-client.js"; import { saveUsers } from "../../utils/user-transactions.js"; import { SettingsCommands } from "../../inquirer-commands/nested-commands/settings.js"; import { SettingsActions } from "./settings-actions.js"; import { answerQuestionOpenAI } from "../../helpers/gpt.js"; import { answerQuestionClaude } from "../../helpers/claude.js"; import { saveConversationHistory } from "../../helpers/history.js"; import { answerQuestionGemini } from "../../helpers/gemini.js"; import { promptAuthenticatedUser } from "../../inquirer-commands/ask-authenticated.js"; import { handleAuthenticatedAction } from "../ask-authenticated-action.js"; export const QuestionActions = async (action, username, users, session) => { switch (action) { case "Using Local LLM": try { let conversationHistory = []; let continueAsking = true; while (continueAsking) { const { question } = await inquirer.prompt([ { type: "input", name: "question", message: conversationHistory.length === 0 ? "What question would you like to ask?" : "Ask a follow-up question (or type 'exit' to end):", }, ]); if (question.toLowerCase() === "exit") { continueAsking = false; break; } const collection = await getCollection(username + "-ragvault"); const historyString = conversationHistory .map((h) => `Question: ${h.question}\nAnswer: ${h.response}`) .join("\n\n"); const chunks = await collection.query({ queryTexts: [historyString, question], nResults: 2, }); const response = chunks.documents .flat() .filter((doc) => doc !== null) .join("\n"); console.log("\n" + response + "\n"); conversationHistory.push({ question, response, }); const { continue: shouldContinue } = await inquirer.prompt([ { type: "confirm", name: "continue", message: "Would you like to ask a follow-up question?", default: true, }, ]); continueAsking = shouldContinue; } if (conversationHistory.length > 0) { await saveConversationHistory(conversationHistory, username); console.log("\nConversation History:"); conversationHistory.forEach((entry, index) => { console.log(`\n--- Question ${index + 1} ---`); console.log(`Q: ${entry.question}`); console.log(`A: ${entry.response}`); }); } } catch (error) { console.error("\nSomething went wrong\n"); } break; case "Using Remote LLM": try { const sessionLLM = session.answerLLM; if (!sessionLLM) { console.log("No remote LLM selected. Please select one in the settings."); const action = await SettingsCommands(); await SettingsActions(action, session, username, users); return; } let conversationHistory = []; let continueAsking = true; while (continueAsking) { const { question } = await inquirer.prompt([ { type: "input", name: "question", message: conversationHistory.length === 0 ? "What question would you like to ask?" : "Ask a follow-up/similar question (or type 'exit' to end):", }, ]); if (question.toLowerCase() === "exit") { continueAsking = false; break; } let response; switch (sessionLLM) { case LLM.OPENAI: if (!users[username].openAIKey) { console.log("OpenAI key not found"); const { openAIKey } = await inquirer.prompt([ { type: "input", name: "openAIKey", message: "Enter your OpenAI API key", }, ]); users[username].openAIKey = openAIKey; await saveUsers(users); } response = await answerQuestionOpenAI(users[username].openAIKey, username, question, conversationHistory); break; case LLM.CLAUDE: if (!users[username].claudeKey) { console.log("Claude key not found"); const { claudeKey } = await inquirer.prompt([ { type: "input", name: "claudeKey", message: "Enter your Claude API key", }, ]); users[username].claudeKey = claudeKey; await saveUsers(users); } response = await answerQuestionClaude(users[username].claudeKey, username, question, conversationHistory); break; case LLM.GEMINI: if (!users[username].geminiKey) { console.log("Gemini key not found"); const { geminiKey } = await inquirer.prompt([ { type: "input", name: "geminiKey", message: "Enter your Gemini API key", }, ]); users[username].geminiKey = geminiKey; await saveUsers(users); } response = await answerQuestionGemini(users[username].geminiKey, username, question, conversationHistory); break; default: console.log("Invalid LLM selected."); continue; } if (response) { conversationHistory.push({ question: question, response: response, }); const { nextAction } = await inquirer.prompt([ { type: "list", name: "nextAction", message: "What would you like to do next?", choices: [ "Ask a follow-up question", "Ask a similar question", "Finish conversation and checkout", ], }, ]); if (nextAction === "Finish conversation and checkout") { continueAsking = false; } } else { console.log("Did not get a response from the LLM."); } } if (conversationHistory.length > 0) { await saveConversationHistory(conversationHistory, username); console.log("\nConversation History:"); conversationHistory.forEach((entry, index) => { console.log(`\n--- Question ${index + 1} ---`); console.log(`Q: ${entry.question}`); console.log(`A: ${entry.response}`); }); } } catch (error) { console.error("\nSomething went wrong with remote LLM questioning.\n", error); } break; case "Back": const newAction = await promptAuthenticatedUser(username); await handleAuthenticatedAction(newAction, username, session, users); break; } };