feat(chat): add Brainy Chat foundation and documentation

- Add initial BrainyChat class implementation with context management
- Update BRAINY-CHAT.md with comprehensive documentation
- Update README.md to include Brainy Chat preview feature
- Foundation for natural language interaction with vector data
This commit is contained in:
David Snelling 2025-08-07 14:25:35 -07:00
parent 57a0caba88
commit 0c1c1e901c
3 changed files with 348 additions and 129 deletions

View file

@ -1,85 +1,125 @@
# Brainy Chat - Talk to Your Data (Coming Soon!) 🧠💬
**Transform your Brainy database into an intelligent conversational AI** that understands and reasons about your data using RAG (Retrieval-Augmented Generation).
**Transform your Brainy database into an intelligent conversational AI** with the simplest API imaginable - just one method, one optional parameter!
## 🚀 Zero to Smart in One Line
## 🚀 The Simplest AI Chat API Ever Created
```javascript
// Coming in v0.56!
// Coming in v0.56 - Just ONE line, ONE method!
import { BrainyChat } from '@soulcraft/brainy/chat'
const chat = await BrainyChat.create(brainy)
const chat = new BrainyChat(brainy) // That's literally it!
const response = await chat.ask("What are the trends in our customer data?")
```
## 🎯 Key Features
## 🎯 The Beauty of Simplicity: One Optional Parameter
### **1. Talk to Your Data**
```javascript
// Natural language queries over your entire knowledge base
const answer = await chat.ask("Which customers are most similar to John?")
// → "Based on purchase patterns and interactions, customers Sarah (0.92 similarity),
// Mike (0.89), and Lisa (0.87) are most similar to John. They share interests in
// technology products and have similar engagement patterns..."
```
// WITHOUT LLM - Works instantly with template-based responses
const chat = new BrainyChat(brainy)
await chat.ask("Find similar customers to John")
// → Uses smart templates to format your data meaningfully
### **2. Graph-Aware Responses**
```javascript
// Understands relationships, not just similarity
const answer = await chat.ask("How is Project Alpha connected to our team?")
// → "Project Alpha has 6 direct connections:
// - Led by: John (since 2024-01)
// - Team members: Sarah, Mike (developers), Lisa (designer)
// - Depends on: Project Beta (data pipeline)
// - Influences: 3 downstream projects..."
```
### **3. Zero Additional Dependencies**
```javascript
// Uses the same Transformers.js models already loaded!
const chat = await BrainyChat.create(brainy, {
model: 'existing', // Reuses your embedding model
mode: 'lightweight' // No extra models needed
// WITH LLM - Same API, smarter responses
const smartChat = new BrainyChat(brainy, {
llm: 'Xenova/LaMini-Flan-T5-77M' // Just add this one parameter!
})
await smartChat.ask("Find similar customers to John")
// → Uses LLM to generate natural, insightful responses
// That's it. No complex configuration. No multiple interfaces.
// Just: new BrainyChat(brainy, { llm?: string })
```
## 🏗️ Architecture Options
### **Option 1: Embedding-Based Q&A** (No Extra Models!)
Uses your existing embedding model for semantic understanding:
## 🎯 Why This API Design is Revolutionary
### **1. Progressive Enhancement Done Right**
```javascript
const chat = await BrainyChat.create(brainy, {
mode: 'embedding-qa' // Zero additional size!
// Start simple - works immediately
const chat = new BrainyChat(brainy)
await chat.ask("Which customers are most similar to John?")
// → Returns formatted results using smart templates
// Enhance when needed - same exact API!
const betterChat = new BrainyChat(brainy, { llm: 'gpt-4o-mini' })
await betterChat.ask("Which customers are most similar to John?")
// → Returns natural language insights with deeper analysis
```
### **2. Zero Learning Curve**
```javascript
// The ENTIRE API in 3 lines:
const chat = new BrainyChat(brainy, { llm?: string }) // Constructor
await chat.ask(question: string) // Ask questions
await chat.chat() // Interactive mode
// That's it. Nothing else to learn.
```
### **3. Works Everywhere, Scales Anywhere**
```javascript
// Development - No LLM needed
const devChat = new BrainyChat(brainy)
// Staging - Small local LLM
const stagingChat = new BrainyChat(brainy, {
llm: 'Xenova/LaMini-Flan-T5-77M' // 77MB model
})
// How it works:
// 1. Embed user question
// 2. Find similar content via vector search
// 3. Extract relevant passages
// 4. Synthesize answer from passages
// Production - Premium LLM
const prodChat = new BrainyChat(brainy, {
llm: 'claude-3-5-sonnet' // Or any model you want
})
// ALL THREE USE THE EXACT SAME CODE!
```
### **Option 2: Small Local LLM** (Optional, 500MB-2GB)
Add a tiny language model for natural responses:
## 🏗️ How It Works Under the Hood
### **Without LLM (Default) - Smart Templates**
```javascript
const chat = await BrainyChat.create(brainy, {
mode: 'local-llm',
model: '@huggingface/Phi-3-mini' // 1.3GB, runs on CPU
})
const chat = new BrainyChat(brainy) // No config needed!
// When you ask a question:
await chat.ask("What are the main product categories?")
// Brainy Chat:
// 1. Searches your data using embeddings
// 2. Analyzes the question type (list, comparison, count, etc.)
// 3. Formats results with intelligent templates
// 4. Returns: "Found 5 main categories: Electronics, Books, Clothing, Home, Sports"
```
### **Option 3: API-Powered** (Optional, Zero Size)
Use external LLMs with YOUR data as context:
### **With LLM - Natural Language Generation**
```javascript
const chat = await BrainyChat.create(brainy, {
mode: 'api',
provider: 'openai',
apiKey: process.env.OPENAI_KEY,
model: 'gpt-4o-mini' // Fast & cheap
})
const chat = new BrainyChat(brainy, { llm: 'Xenova/LaMini-Flan-T5-77M' })
// Same question:
await chat.ask("What are the main product categories?")
// Brainy Chat:
// 1. Searches your data (same as before)
// 2. Passes context to the LLM
// 3. LLM generates natural response
// 4. Returns: "Your store features 5 primary product categories. Electronics
// leads with 45% of inventory, followed by Books at 23%. Clothing, Home
// goods, and Sports equipment round out your offerings, with seasonal
// variations in the Sports category showing 3x growth in summer months."
```
### **The Magic: Same Code, Different Intelligence Levels**
```javascript
// Your code never changes:
async function analyzeData(brainy, useLLM = false) {
const chat = new BrainyChat(brainy,
useLLM ? { llm: 'gpt-4o-mini' } : {}
)
return await chat.ask("Analyze customer satisfaction trends")
}
// Works in development (no LLM)
// Works in production (with LLM)
// Same function, progressive enhancement!
```
## 💡 Intelligent Features
@ -112,19 +152,92 @@ const response = await chat.ask("What's our refund policy?", {
// }
```
## 🚀 Complete API Reference (Yes, This Is Everything!)
```javascript
import { BrainyData, BrainyChat } from '@soulcraft/brainy'
// Setup
const brainy = new BrainyData()
await brainy.init()
// Create chat - THE ONLY CONSTRUCTOR
const chat = new BrainyChat(
brainy, // Required: Your Brainy instance
{ // Optional: Configuration
llm?: string, // Optional: LLM model name
sources?: bool // Optional: Include source references (default: false)
}
)
// Ask questions - THE ONLY METHOD YOU NEED
const answer = await chat.ask("Your question here")
// Interactive mode - BONUS METHOD
await chat.chat() // Starts interactive REPL
// That's it. That's the entire API.
// No configuration hell. No complex setup.
// Just: new BrainyChat(brainy, { llm?: string })
```
## 🎉 Examples: From Zero to AI in Seconds
```javascript
// Example 1: Customer Support Bot (No LLM)
const supportBot = new BrainyChat(brainy)
await supportBot.ask("How do I reset my password?")
// Returns: "Based on 'password-reset-guide': Click Settings > Security > Reset"
// Example 2: Smart Analytics (With LLM)
const analyst = new BrainyChat(brainy, { llm: 'gpt-4o-mini' })
await analyst.ask("What patterns exist in user churn?")
// Returns: "Analysis reveals three key churn indicators: users who haven't
// logged in for 30+ days show 73% churn probability..."
// Example 3: Development vs Production
const chat = new BrainyChat(brainy, {
llm: process.env.LLM_MODEL // undefined in dev, defined in prod
})
// Works perfectly in both environments!
```
## 📝 Use Cases
### **Customer Support Bot**
```javascript
const supportBot = new BrainyChat(brainy)
await supportBot.ask("How do I reset my password?")
// Searches docs, tickets, and FAQs to provide accurate answer
```
### **Data Analyst Assistant**
```javascript
const analyst = new BrainyChat(brainy, { llm: 'gpt-4o-mini' })
await analyst.ask("What patterns do you see in user churn?")
// Analyzes vector similarities and relationships to identify patterns
```
### **Code Documentation Helper**
```javascript
const docHelper = new BrainyChat(brainy)
await docHelper.ask("How does the authentication system work?")
// Searches all auth-related code and docs to explain
```
## 🛠️ Implementation Strategy
### **Phase 1: Embedding-Based Q&A** (v0.56)
### **Phase 1: Template-Based Q&A** (v0.56)
- Zero additional dependencies
- Uses existing embedding model
- Template-based responses
- ~50KB additional code
- Smart template responses
- ~150 lines of code total
### **Phase 2: Small LLM Integration** (v0.57)
- Optional Phi-3 or Gemma model
- Lazy loading (only if used)
### **Phase 2: Optional LLM Enhancement** (v0.57)
- Lazy-loaded Hugging Face models
- Natural language generation
- +1-2GB optional download
- Same simple API
- Progressive enhancement
### **Phase 3: Advanced Features** (v0.58)
- Multi-turn conversations
@ -132,73 +245,21 @@ const response = await chat.ask("What's our refund policy?", {
- Analytical reports
- Custom fine-tuning
## 📝 Example Use Cases
### **Customer Support Bot**
```javascript
const supportBot = await BrainyChat.create(brainy, {
systemPrompt: "You are a helpful support agent with access to all product docs and tickets"
})
await supportBot.ask("How do I reset my password?")
// Searches docs, tickets, and FAQs to provide accurate answer
```
### **Data Analyst Assistant**
```javascript
const analyst = await BrainyChat.create(brainy, {
systemPrompt: "You are a data analyst. Provide insights and patterns."
})
await analyst.ask("What patterns do you see in user churn?")
// Analyzes vector similarities and relationships to identify patterns
```
### **Code Documentation Helper**
```javascript
const docHelper = await BrainyChat.create(brainy, {
systemPrompt: "Explain code and architecture based on the codebase"
})
await docHelper.ask("How does the authentication system work?")
// Searches all auth-related code and docs to explain
```
## 🚀 Quick Start (When Released)
```javascript
import { BrainyData, BrainyChat } from '@soulcraft/brainy'
// Your existing Brainy setup
const brainy = new BrainyData()
await brainy.init()
// Add chat capabilities with ZERO config
const chat = await BrainyChat.create(brainy)
// Start talking to your data!
const response = await chat.ask("What do you know about quantum computing?")
console.log(response)
// Interactive mode
await chat.interactive() // Starts REPL chat interface
```
## 🎯 Why This Is Revolutionary
1. **Your Data, Not Generic** - Responses based on YOUR specific knowledge
2. **No External Services** - Runs entirely locally (optional API mode)
3. **Zero to Smart** - One line to add AI chat to any Brainy database
4. **Tiny Footprint** - Reuses existing embeddings, adds minimal code
5. **Graph + Vector** - Understands both similarity AND relationships
1. **Simplest API Ever** - One constructor, one method, one optional parameter
2. **Progressive Enhancement** - Works without LLM, better with it
3. **Your Data, Not Generic** - Responses based on YOUR specific knowledge
4. **Zero to Smart** - Literally one line to add AI chat to any Brainy database
5. **Tiny Footprint** - Just ~150 lines of code, reuses existing embeddings
## 🔜 Coming in v0.56
This feature is under active development. The initial release will include:
- Embedding-based Q&A (zero additional models)
- Simple chat interface
- Simple BrainyChat class with just `ask()` method
- Template-based responses (no LLM required)
- Optional LLM parameter for enhanced responses
- Source attribution
- Context window management
- Template-based natural responses
- Interactive chat mode
Stay tuned for the most exciting Brainy feature yet - the ability to literally talk to your data! 🚀
**The future of data interaction: One line of code, infinite possibilities!** 🚀

View file

@ -15,16 +15,23 @@
# 🆕 Coming Soon: Talk to Your Data with Brainy Chat!
**Transform your database into an AI that understands your data:**
**Transform your database into an AI that understands your data - with just ONE simple method:**
```javascript
// Coming in v0.56!
const chat = await BrainyChat.create(brainy)
// Coming in v0.56 - Impossibly simple API!
const chat = new BrainyChat(brainy) // That's it!
const answer = await chat.ask("What patterns do you see in customer behavior?")
// → AI analyzes YOUR data and relationships to provide insights
// → Works instantly with zero config!
// Want smarter responses? Just add an optional LLM:
const smartChat = new BrainyChat(brainy, { llm: 'Xenova/LaMini-Flan-T5-77M' })
const smartAnswer = await smartChat.ask("Analyze our Q4 performance")
// → Same simple API, but now with LLM-powered insights!
```
[📖 **Learn More About Brainy Chat**](BRAINY-CHAT.md) | **Zero extra dependencies** | **Uses existing embeddings**
**🎯 One interface. Optional LLM. Zero complexity.**
[📖 **Learn More About Brainy Chat**](BRAINY-CHAT.md) | **Zero extra dependencies** | **Works without LLM, better with it**
---

151
src/chat/brainyChat.ts Normal file
View file

@ -0,0 +1,151 @@
/**
* Brainy Chat - Talk to Your Data
*
* Simple, powerful conversational AI for your Brainy database.
* Works with zero configuration, optionally enhanced with LLM.
*/
import { BrainyData } from '../brainyData.js'
import { SearchResult } from '../coreTypes.js'
export interface ChatOptions {
/** Optional LLM model name (e.g., 'Xenova/LaMini-Flan-T5-77M') */
llm?: string
/** Include source references in responses */
sources?: boolean
}
export class BrainyChat {
private brainy: BrainyData
private llm?: any
private history: string[] = []
constructor(brainy: BrainyData, options: ChatOptions = {}) {
this.brainy = brainy
// Load LLM if specified (lazy-loaded on first use)
if (options.llm) {
this.loadLLM(options.llm)
}
}
/**
* Ask a question - works with or without LLM
*/
async ask(question: string): Promise<string> {
// Find relevant context
const context = await this.brainy.search(question, 5)
// Generate response
const answer = this.llm
? await this.generateWithLLM(question, context)
: this.generateWithTemplate(question, context)
// Track history
this.history.push(question, answer)
if (this.history.length > 20) {
this.history = this.history.slice(-20)
}
return answer
}
/**
* Load LLM model (lazy, only when needed)
*/
private async loadLLM(model: string): Promise<void> {
try {
const { pipeline } = await import('@huggingface/transformers')
this.llm = await pipeline('text2text-generation', model, { quantized: true })
} catch (error) {
console.log('LLM not available, using templates')
}
}
/**
* Generate response with LLM
*/
private async generateWithLLM(question: string, context: SearchResult[]): Promise<string> {
const contextText = context
.map(c => `${c.id}: ${JSON.stringify(c.metadata || {})}`)
.join('\n')
const prompt = `Context:\n${contextText}\n\nQuestion: ${question}\nAnswer:`
try {
const result = await this.llm(prompt, { max_new_tokens: 150 })
return result[0].generated_text.trim()
} catch {
return this.generateWithTemplate(question, context)
}
}
/**
* Generate response with templates (no LLM needed)
*/
private generateWithTemplate(question: string, context: SearchResult[]): string {
if (context.length === 0) {
return "I couldn't find relevant information to answer that."
}
const q = question.toLowerCase()
// Quantitative questions
if (q.includes('how many') || q.includes('count')) {
return `I found ${context.length} relevant items. The top matches are: ${
context.slice(0, 3).map(c => c.id).join(', ')
}.`
}
// Comparison questions
if (q.includes('compare') || q.includes('difference')) {
if (context.length < 2) return "I need at least two items to compare."
return `Comparing ${context[0].id} (${(context[0].score * 100).toFixed(0)}% match) with ${
context[1].id} (${(context[1].score * 100).toFixed(0)}% match).`
}
// List questions
if (q.includes('list') || q.includes('what are')) {
return `Here are the top results:\n${
context.slice(0, 5).map((c, i) => `${i+1}. ${c.id}`).join('\n')
}`
}
// General response
const top = context[0]
const metadata = top.metadata ?
Object.entries(top.metadata).slice(0, 3)
.map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(', ') :
'no details'
return `Based on "${top.id}" (${(top.score * 100).toFixed(0)}% relevant): ${metadata}`
}
/**
* Interactive chat mode
*/
async chat(): Promise<void> {
const readline = await import('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
console.log('\n🧠 Chat with your data (type "exit" to quit)\n')
const prompt = () => {
rl.question('You: ', async (question) => {
if (question === 'exit') {
rl.close()
return
}
const answer = await this.ask(question)
console.log(`\nAI: ${answer}\n`)
prompt()
})
}
prompt()
}
}