@wityai/root2-cli
Version:
Command-line interface for Root2 vector memory layer
272 lines ⢠12.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.queryCommand = queryCommand;
const chalk_1 = __importDefault(require("chalk"));
const inquirer_1 = __importDefault(require("inquirer"));
const root2_api_client_1 = require("@wityai/root2-api-client");
const config_1 = require("../utils/config");
const formatting_1 = require("../utils/formatting");
const spinner_1 = require("../utils/spinner");
function queryCommand(program) {
program
.command('query')
.alias('q')
.description('Query information from your Root2 knowledge base')
.argument('<query>', 'The query to search for')
.option('-f, --format <format>', 'Output format (structured|text)', 'text')
.option('-n, --max-results <number>', 'Maximum results to return', '10')
.option('-m, --include-metadata', 'Include metadata in results')
.option('--filters <filters>', 'JSON string of filters to apply')
.option('-i, --interactive', 'Interactive query mode')
.option('--output <format>', 'Display format (json|table|text)', 'text')
.action(async (query, options) => {
try {
const config = await (0, config_1.validateConfig)();
const apiClient = new root2_api_client_1.Root2Api({
clientId: config.clientId,
apiKey: config.apiKey,
apiHost: config.apiHost,
enableLogging: config.verbose || false
});
if (options.interactive) {
await interactiveQuery(apiClient);
return;
}
await executeQuery(apiClient, query, options);
}
catch (error) {
console.error(formatting_1.format.error(error instanceof Error ? error.message : 'Unknown error'));
process.exit(1);
}
});
program
.command('ask')
.description('Start interactive query session')
.option('--format <format>', 'Output format (structured|text)', 'text')
.option('--max-results <number>', 'Maximum results to return', '10')
.option('--include-metadata', 'Include metadata in results')
.action(async (options) => {
try {
const config = await (0, config_1.validateConfig)();
const apiClient = new root2_api_client_1.Root2Api({
clientId: config.clientId,
apiKey: config.apiKey,
apiHost: config.apiHost,
enableLogging: config.verbose || false
});
await interactiveQuery(apiClient, options);
}
catch (error) {
console.error(formatting_1.format.error(error instanceof Error ? error.message : 'Unknown error'));
process.exit(1);
}
});
}
async function executeQuery(apiClient, query, options) {
const queryOptions = {
outputFormat: options.format,
maxResults: parseInt(options.maxResults),
includeMetadata: options.includeMetadata
};
if (options.filters) {
try {
queryOptions.filters = JSON.parse(options.filters);
}
catch (error) {
throw new Error('Invalid filters JSON format');
}
}
console.log(chalk_1.default.blue(`š Searching for: "${query}"`));
const result = await (0, spinner_1.withSpinner)('Querying Root2 knowledge base...', () => apiClient.queryInfo(query, queryOptions), {
successText: 'Query completed successfully',
errorText: 'Query failed'
});
if (result.success && result.data) {
console.log(chalk_1.default.green(`\nā
Found ${result.data.length} result(s):\n`));
const formattedOutput = formatting_1.OutputFormatter.formatQueryResults(result.data, options.output, options.includeMetadata);
console.log(formattedOutput);
}
else {
console.log(formatting_1.format.warning('No results found for your query.'));
console.log(chalk_1.default.gray('\nTips:'));
console.log(chalk_1.default.gray('⢠Try rephrasing your question'));
console.log(chalk_1.default.gray('⢠Use more specific keywords'));
console.log(chalk_1.default.gray('⢠Check if content has been imported to your knowledge base'));
console.log(chalk_1.default.gray('⢠Try using broader search terms'));
}
}
async function interactiveQuery(apiClient, initialOptions = {}) {
console.log(chalk_1.default.cyan('\nš¤ Root2 Interactive Query Session\n'));
console.log(chalk_1.default.gray('Type your questions and get answers from your knowledge base.'));
console.log(chalk_1.default.gray('Type "exit", "quit", or press Ctrl+C to end the session.\n'));
const sessionOptions = {
format: initialOptions.format || 'text',
maxResults: parseInt(initialOptions.maxResults || '10'),
includeMetadata: initialOptions.includeMetadata || false,
output: initialOptions.output || 'text'
};
let queryCount = 0;
while (true) {
try {
const { query, continueSession } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'query',
message: `${chalk_1.default.cyan('Query')} ${chalk_1.default.gray(`#${queryCount + 1}`)}:`,
validate: (input) => {
const trimmed = input.trim().toLowerCase();
if (trimmed === 'exit' || trimmed === 'quit') {
return true;
}
if (!input.trim()) {
return 'Please enter a query';
}
return true;
}
}
]);
const trimmedQuery = query.trim().toLowerCase();
if (trimmedQuery === 'exit' || trimmedQuery === 'quit') {
break;
}
if (trimmedQuery === 'help') {
showInteractiveHelp();
continue;
}
if (trimmedQuery === 'config') {
await showSessionConfig(sessionOptions);
continue;
}
if (trimmedQuery.startsWith('set ')) {
await updateSessionConfig(sessionOptions, trimmedQuery);
continue;
}
queryCount++;
console.log();
await executeQuery(apiClient, query, sessionOptions);
const { shouldContinue } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'shouldContinue',
message: 'Continue with another query?',
default: true
}
]);
if (!shouldContinue) {
break;
}
console.log(chalk_1.default.gray('ā'.repeat(50)));
}
catch (error) {
if (error instanceof Error && error.message.includes('User force closed')) {
break;
}
console.error(formatting_1.format.error(error instanceof Error ? error.message : 'Unknown error'));
const { shouldContinue } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'shouldContinue',
message: 'An error occurred. Continue anyway?',
default: true
}
]);
if (!shouldContinue) {
break;
}
}
}
console.log(formatting_1.format.info('\nš Interactive session ended.'));
if (queryCount > 0) {
console.log(formatting_1.format.success(`Processed ${queryCount} queries. Thank you for using Root2!`));
}
}
function showInteractiveHelp() {
console.log(chalk_1.default.cyan('\nš Interactive Query Help\n'));
console.log('Available commands:');
console.log(` ${chalk_1.default.yellow('help')} - Show this help message`);
console.log(` ${chalk_1.default.yellow('config')} - Show current session configuration`);
console.log(` ${chalk_1.default.yellow('set <option>')} - Update session options`);
console.log(` ${chalk_1.default.yellow('exit/quit')} - End the session`);
console.log('\nSet commands:');
console.log(` ${chalk_1.default.gray('set format structured')} - Use structured output format`);
console.log(` ${chalk_1.default.gray('set format text')} - Use text output format`);
console.log(` ${chalk_1.default.gray('set max-results 5')} - Set maximum results to 5`);
console.log(` ${chalk_1.default.gray('set metadata on/off')} - Toggle metadata inclusion`);
console.log(` ${chalk_1.default.gray('set output json')} - Set display format to JSON`);
console.log('\nTips:');
console.log(chalk_1.default.gray('⢠Ask specific questions for better results'));
console.log(chalk_1.default.gray('⢠Use natural language - no need for special syntax'));
console.log(chalk_1.default.gray('⢠Reference documents, topics, or concepts in your knowledge base'));
console.log('');
}
async function showSessionConfig(options) {
console.log(chalk_1.default.cyan('\nāļø Current Session Configuration\n'));
console.log(` ${chalk_1.default.blue('Format'.padEnd(12))}: ${options.format}`);
console.log(` ${chalk_1.default.blue('Max Results'.padEnd(12))}: ${options.maxResults}`);
console.log(` ${chalk_1.default.blue('Metadata'.padEnd(12))}: ${options.includeMetadata ? 'enabled' : 'disabled'}`);
console.log(` ${chalk_1.default.blue('Output'.padEnd(12))}: ${options.output}`);
console.log('');
}
async function updateSessionConfig(options, command) {
const parts = command.split(' ');
if (parts.length < 3) {
console.log(formatting_1.format.warning('Invalid set command. Use "help" to see available options.'));
return;
}
const setting = parts[1];
const value = parts.slice(2).join(' ');
try {
switch (setting) {
case 'format':
if (['structured', 'text'].includes(value)) {
options.format = value;
console.log(formatting_1.format.success(`Format set to: ${value}`));
}
else {
console.log(formatting_1.format.warning('Format must be "structured" or "text"'));
}
break;
case 'max-results':
const maxResults = parseInt(value);
if (isNaN(maxResults) || maxResults < 1 || maxResults > 100) {
console.log(formatting_1.format.warning('Max results must be a number between 1 and 100'));
}
else {
options.maxResults = maxResults;
console.log(formatting_1.format.success(`Max results set to: ${maxResults}`));
}
break;
case 'metadata':
if (['on', 'true', 'enabled'].includes(value.toLowerCase())) {
options.includeMetadata = true;
console.log(formatting_1.format.success('Metadata inclusion enabled'));
}
else if (['off', 'false', 'disabled'].includes(value.toLowerCase())) {
options.includeMetadata = false;
console.log(formatting_1.format.success('Metadata inclusion disabled'));
}
else {
console.log(formatting_1.format.warning('Metadata must be "on" or "off"'));
}
break;
case 'output':
if (['json', 'table', 'text'].includes(value)) {
options.output = value;
console.log(formatting_1.format.success(`Output format set to: ${value}`));
}
else {
console.log(formatting_1.format.warning('Output format must be "json", "table", or "text"'));
}
break;
default:
console.log(formatting_1.format.warning(`Unknown setting: ${setting}. Use "help" to see available options.`));
}
}
catch (error) {
console.log(formatting_1.format.error('Failed to update configuration'));
}
}
//# sourceMappingURL=query.js.map