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:
parent
6f86964f4b
commit
7fb34a0b1d
6 changed files with 124 additions and 13 deletions
104
bin/brainy.js
104
bin/brainy.js
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.'))
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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']
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue