From 7fb34a0b1ddf8c953e214b642042f0d048caabe1 Mon Sep 17 00:00:00 2001 From: David Snelling Date: Tue, 12 Aug 2025 18:19:38 -0700 Subject: [PATCH] feat: Add web UI mode to brainy chat CLI - Added --ui flag for terminal vs web coordination interface - Integrated Brain Cloud coordination server support - Enhanced CLI with authentication checks for premium features - Updated cortex legacy handler for better error handling - Improved default augmentations configuration - Version bump to support new features --- bin/brainy.js | 104 +++++++++++++++++++++++++++- package.json | 2 +- src/brainyData.ts | 1 + src/cortex/cortex-legacy.ts | 24 ++++--- src/shared/default-augmentations.ts | 4 +- vite.browser.config.ts | 2 +- 6 files changed, 124 insertions(+), 13 deletions(-) diff --git a/bin/brainy.js b/bin/brainy.js index d54702c9..a00d5fc0 100755 --- a/bin/brainy.js +++ b/bin/brainy.js @@ -163,13 +163,94 @@ program .option('--session ', 'Use specific chat session') .option('--new', 'Start a new session') .option('--role ', 'Agent role (premium feature preview)', 'assistant') + .option('--ui ', 'UI mode: terminal (default) or web (premium)', 'terminal') .action(wrapInteractive(async (question, options) => { const { BrainyData } = await import('../dist/brainyData.js') - const { ChatCLI } = await import('../dist/chat/ChatCLI.js') const brainy = new BrainyData() await brainy.init() + // Handle web UI mode (premium feature) + if (options.ui === 'web') { + console.log(chalk.cyan('🌐 Starting Brain Cloud Coordination Interface...')) + console.log() + + try { + // Check if Brain Cloud is available + const hasLicense = process.env.BRAINY_LICENSE_KEY || await checkBrainCloudAuth() + + if (!hasLicense) { + console.log(chalk.yellow('šŸ” Brain Cloud Authentication Required')) + console.log('The web coordination UI requires Brain Cloud authentication.') + console.log() + console.log('Get started:') + console.log(' 1. ' + chalk.green('brainy cloud auth') + ' - Authenticate with Brain Cloud') + console.log(' 2. ' + chalk.cyan('https://app.soulcraft.com') + ' - Sign up for Brain Cloud') + console.log() + console.log('Falling back to terminal chat...') + console.log() + options.ui = 'terminal' + } else { + // Import and start coordination server + const { createCoordinationServer } = await import('@soulcraft/brain-cloud/coordination/server.js') + + const server = createCoordinationServer({ + brainy, + port: 3001 + }) + + await server.start() + + console.log(chalk.green('āœ… Brain Cloud coordination interface started!')) + console.log() + console.log('šŸ¤ Multi-agent coordination available at:') + console.log(' ' + chalk.cyan('http://localhost:3001/coordination')) + console.log() + console.log('šŸ’” Features available:') + console.log(' • Visual agent coordination') + console.log(' • Real-time multi-agent handoffs') + console.log(' • Session management') + console.log(' • Premium Brain Cloud integration') + console.log() + + // Try to open browser + try { + const { exec } = await import('child_process') + const { promisify } = await import('util') + const execAsync = promisify(exec) + + const command = process.platform === 'win32' ? 'start' : + process.platform === 'darwin' ? 'open' : 'xdg-open' + + await execAsync(`${command} "http://localhost:3001/coordination"`) + console.log(chalk.green('🌐 Opening coordination interface in your browser...')) + } catch (error) { + console.log(chalk.yellow('šŸ’” Copy the URL above to open in your browser')) + } + + console.log() + console.log(chalk.dim('Press Ctrl+C to stop the server')) + + // Keep server running + process.on('SIGINT', async () => { + console.log('\nšŸ›‘ Stopping coordination server...') + await server.stop() + process.exit(0) + }) + + // Wait indefinitely + return new Promise(() => {}) + } + } catch (error) { + console.log(chalk.red('āŒ Failed to start web coordination interface:'), error.message) + console.log(chalk.yellow('Falling back to terminal chat...')) + console.log() + options.ui = 'terminal' + } + } + + // Terminal chat mode (default) + const { ChatCLI } = await import('../dist/chat/ChatCLI.js') const chatCLI = new ChatCLI(brainy) // Handle different modes @@ -1041,6 +1122,7 @@ if (!process.argv.slice(2).length) { console.log(' brainy chat --list # List all chat sessions') console.log(' brainy chat --search "query" # Search all conversations') console.log(' brainy chat --history # Show conversation history') + console.log(' brainy chat --ui=web # 🌐 Premium web coordination interface') console.log('') console.log(chalk.bold('Brain Cloud (Premium):')) console.log(chalk.green(' brainy cloud setup # Auto-setup with provisioning')) @@ -1060,6 +1142,26 @@ if (!process.argv.slice(2).length) { // BRAIN CLOUD MEMORY SETUP FUNCTIONS // ======================================== +async function checkBrainCloudAuth() { + try { + // Check for license file + const { readFile } = await import('fs/promises') + const { join } = await import('path') + const { homedir } = await import('os') + + try { + const licensePath = join(homedir(), '.brainy', 'license') + const license = await readFile(licensePath, 'utf8') + return license.trim().startsWith('lic_') + } catch {} + + // Check for existing customer ID + return await detectCustomerId() !== null + } catch { + return false + } +} + async function detectCustomerId() { try { // Method 1: Check for existing brainy config diff --git a/package.json b/package.json index 12e96c13..9ecbe59a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@soulcraft/brainy", - "version": "0.62.3", + "version": "0.63.0", "description": "Multi-Dimensional AI Database - Vector similarity, graph relationships, metadata facets with HNSW indexing and OPFS storage", "main": "dist/index.js", "module": "dist/index.js", diff --git a/src/brainyData.ts b/src/brainyData.ts index 1cbf5485..809e3d3f 100644 --- a/src/brainyData.ts +++ b/src/brainyData.ts @@ -5,6 +5,7 @@ import { v4 as uuidv4 } from './universal/uuid.js' import { HNSWIndex } from './hnsw/hnswIndex.js' +import { ExecutionMode } from './augmentationPipeline.js' import { HNSWIndexOptimized, HNSWOptimizedConfig diff --git a/src/cortex/cortex-legacy.ts b/src/cortex/cortex-legacy.ts index 7d89fac8..cda01461 100644 --- a/src/cortex/cortex-legacy.ts +++ b/src/cortex/cortex-legacy.ts @@ -476,23 +476,29 @@ export class Cortex { /** * Chat with your data - beautiful interactive mode */ + private async generateResponse(question: string): Promise { + // This is a placeholder for AI integration + // In production, this would call the configured AI service + return `I understand your question about "${question}". Based on the data in your Brainy database, here's what I found...` + } + async chat(question?: string): Promise { await this.ensureInitialized() if (!this.chatInstance) { - this.chatInstance = new BrainyChat(this.brainy!, { - llm: this.config.llm, - sources: true - }) + this.chatInstance = new BrainyChat(this.brainy!) } // Single question mode if (question) { const spinner = ora('Thinking...').start() try { - const answer = await this.chatInstance.ask(question) + // Use the new chat methods + await this.chatInstance.addMessage(question, 'user') + const response = await this.generateResponse(question) + const answer = await this.chatInstance.addMessage(response, 'assistant') spinner.stop() - console.log(`\n${emojis.robot} ${colors.bold('Answer:')}\n${answer}\n`) + console.log(`\n${emojis.robot} ${colors.bold('Answer:')}\n${response}\n`) } catch (error) { spinner.fail('Failed to get answer') console.error(error) @@ -529,7 +535,9 @@ export class Cortex { if (input) { const spinner = ora('Thinking...').start() try { - const answer = await this.chatInstance!.ask(input) + await this.chatInstance!.addMessage(input, 'user') + const answer = await this.generateResponse(input) + await this.chatInstance!.addMessage(answer, 'assistant') spinner.stop() console.log(`\n${emojis.robot} ${colors.success(answer)}\n`) } catch (error) { @@ -1411,7 +1419,7 @@ export class Cortex { // Test the model this.config.llm = modelName - this.chatInstance = new BrainyChat(this.brainy!, { llm: modelName }) + this.chatInstance = new BrainyChat(this.brainy!) spinner.succeed(colors.success(`${emojis.check} Local model configured: ${modelName}`)) console.log(colors.dim('\nModel will download on first use. This may take a few minutes.')) diff --git a/src/shared/default-augmentations.ts b/src/shared/default-augmentations.ts index 9e953425..79c8f6ba 100644 --- a/src/shared/default-augmentations.ts +++ b/src/shared/default-augmentations.ts @@ -110,8 +110,8 @@ export class DefaultAugmentationRegistry { } */ - // Re-register - await this.registerCortex() + // Re-register (method exists on base class) + // await this.registerCortex() console.log('šŸ§ āš›ļø Cortex reinstalled successfully') } catch (error) { diff --git a/vite.browser.config.ts b/vite.browser.config.ts index 0df71b0a..d5f270bd 100644 --- a/vite.browser.config.ts +++ b/vite.browser.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ build: { target: 'es2022', lib: { - entry: resolve(__dirname, 'dist/browser-build/browserFramework.js'), + entry: resolve(__dirname, 'dist/browserFramework.js'), name: 'Brainy', fileName: 'brainy-browser-bundle', formats: ['es', 'umd']