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
This commit is contained in:
David Snelling 2025-08-12 18:19:38 -07:00
parent 6f86964f4b
commit 7fb34a0b1d
6 changed files with 124 additions and 13 deletions

View file

@ -163,13 +163,94 @@ program
.option('--session <id>', 'Use specific chat session')
.option('--new', 'Start a new session')
.option('--role <name>', 'Agent role (premium feature preview)', 'assistant')
.option('--ui <mode>', '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

View file

@ -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",

View file

@ -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

View file

@ -476,23 +476,29 @@ export class Cortex {
/**
* Chat with your data - beautiful interactive mode
*/
private async generateResponse(question: string): Promise<string> {
// 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<void> {
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.'))

View file

@ -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) {

View file

@ -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']