brainy/tests/zero-config-models.test.ts
David Snelling 26c7d61185 CHECKPOINT: Brainy 2.0 API refactor - pre-fixes state
Current state:
- Unified augmentation system to BrainyAugmentation interface
- Changed methods to specific noun/verb naming (addNoun, getNoun, etc)
- Made old methods private
- Combined getNouns into single unified method
- Neural API exists and is complete
- Triple Intelligence uses correct Brainy operators (not MongoDB)

Issues identified:
- Documentation incorrectly shows MongoDB operators (code is correct)
- Need to ensure all features are properly exposed
- Need to verify nothing was lost in simplification

This commit serves as a rollback point before applying fixes.
2025-08-25 09:52:32 -07:00

249 lines
No EOL
7.8 KiB
TypeScript

/**
* Zero-Config Model Loading Tests
*
* Verifies that Brainy works WITHOUT ANY configuration
* No environment variables, no setup, just works!
*
* CRITICAL: Uses REAL transformer models - NO MOCKING
*/
import { describe, it, expect } from 'vitest'
import { BrainyData } from '../src/brainyData.js'
describe('Zero-Config Model Loading', () => {
it('should work without ANY configuration - just new BrainyData()', async () => {
// This is how a developer would use Brainy - ZERO CONFIG!
const brain = new BrainyData()
await brain.init()
// Should just work - add some content
const id1 = await brain.addNoun('JavaScript is a programming language')
const id2 = await brain.addNoun('TypeScript adds static types to JavaScript')
const id3 = await brain.addNoun('Pizza is a delicious Italian food')
expect(id1).toBeTruthy()
expect(id2).toBeTruthy()
expect(id3).toBeTruthy()
// Search should work with real embeddings
const results = await brain.search('programming languages')
expect(results).toBeDefined()
expect(results.length).toBeGreaterThan(0)
// Programming content should rank higher than pizza
const programmingIndex = results.findIndex(r =>
r.metadata?.data?.includes('JavaScript') ||
r.metadata?.data?.includes('TypeScript')
)
const pizzaIndex = results.findIndex(r =>
r.metadata?.data?.includes('Pizza')
)
if (programmingIndex !== -1 && pizzaIndex !== -1) {
expect(programmingIndex).toBeLessThan(pizzaIndex)
}
await brain.cleanup?.()
}, { timeout: 30000 }) // Allow time for model download if needed
it('should automatically download models on first use if not cached', async () => {
// Even with no models downloaded, it should work
const brain = new BrainyData()
await brain.init()
// First embedding creation triggers model download if needed
const id = await brain.addNoun('Test content that triggers model loading')
expect(id).toBeTruthy()
// Subsequent operations should be fast (models cached)
const startTime = Date.now()
await brain.addNoun('Second item should be fast')
const duration = Date.now() - startTime
expect(duration).toBeLessThan(1000) // Should be fast with cached model
await brain.cleanup?.()
}, { timeout: 60000 }) // Allow more time for potential model download
it('should work in different storage modes without config', async () => {
// Memory storage - zero config
const memoryBrain = new BrainyData({
storage: { forceMemoryStorage: true }
})
await memoryBrain.init()
await memoryBrain.addNoun('Memory storage test')
expect(memoryBrain).toBeDefined()
await memoryBrain.cleanup?.()
// FileSystem storage - zero config (default)
const fsBrain = new BrainyData()
await fsBrain.init()
await fsBrain.addNoun('FileSystem storage test')
expect(fsBrain).toBeDefined()
await fsBrain.cleanup?.()
})
it('should handle the model loading cascade transparently', async () => {
// User doesn't need to know about the cascade
// It just works: Local → CDN → GitHub → HuggingFace
const brain = new BrainyData()
await brain.init()
// Should work regardless of where models come from
const content = 'The model loading cascade is transparent to users'
const id = await brain.addNoun(content)
expect(id).toBeTruthy()
// Verify embeddings are working (384 dimensions)
const results = await brain.search(content)
expect(results).toBeDefined()
expect(results.length).toBeGreaterThan(0)
await brain.cleanup?.()
})
it('should work with natural language queries out of the box', async () => {
const brain = new BrainyData()
await brain.init()
// Add various content
await brain.addNoun('React is a JavaScript library for building UIs', 'content', {
type: 'technology',
category: 'frontend'
})
await brain.addNoun('Node.js is a JavaScript runtime for servers', 'content', {
type: 'technology',
category: 'backend'
})
await brain.addNoun('MongoDB is a NoSQL database', 'content', {
type: 'database',
category: 'backend'
})
// Natural language search should just work
const results = await brain.find({
like: 'backend technologies for web development'
})
expect(results).toBeDefined()
expect(results.some(r => r.metadata?.category === 'backend')).toBe(true)
await brain.cleanup?.()
})
it('should handle errors gracefully with zero config', async () => {
const brain = new BrainyData()
await brain.init()
// Even with invalid inputs, should handle gracefully
const result = await brain.search('')
expect(result).toBeDefined()
expect(Array.isArray(result)).toBe(true)
// Should handle non-existent IDs gracefully
const notFound = await brain.getNoun('non-existent-id')
expect(notFound).toBeNull()
await brain.cleanup?.()
})
describe('Developer Experience', () => {
it('should provide helpful error messages without config', async () => {
const brain = new BrainyData()
await brain.init()
try {
// Try to add invalid data
await brain.addNoun(null as any)
} catch (error) {
// Should have a helpful error message
expect(error).toBeDefined()
expect((error as Error).message).toBeTruthy()
}
await brain.cleanup?.()
})
it('should work in both Node.js and browser environments', async () => {
// This test runs in Node.js
const brain = new BrainyData()
await brain.init()
// Check environment detection works
expect(brain).toBeDefined()
// Should auto-detect and use appropriate storage
const id = await brain.addNoun('Cross-platform content')
expect(id).toBeTruthy()
await brain.cleanup?.()
})
it('should not require any model management from developer', async () => {
// Developer never needs to:
// - Download models manually
// - Set model paths
// - Configure model sources
// - Handle model errors
const brain = new BrainyData()
await brain.init()
// Just use it!
const operations = await Promise.all([
brain.addNoun('Concurrent operation 1'),
brain.addNoun('Concurrent operation 2'),
brain.addNoun('Concurrent operation 3')
])
expect(operations.every(id => id)).toBe(true)
await brain.cleanup?.()
})
})
describe('Production Readiness', () => {
it('should handle high load without configuration', async () => {
const brain = new BrainyData()
await brain.init()
// Add many items rapidly
const promises = []
for (let i = 0; i < 10; i++) {
promises.push(brain.addNoun(`Item ${i}: ${Math.random()}`))
}
const results = await Promise.all(promises)
expect(results.every(id => id)).toBe(true)
// Search should still work under load
const searchResults = await brain.search('Item')
expect(searchResults.length).toBeGreaterThan(0)
await brain.cleanup?.()
})
it('should recover from transient failures automatically', async () => {
const brain = new BrainyData()
await brain.init()
// Even if model loading has transient issues, should recover
const id = await brain.addNoun('Resilient content handling')
expect(id).toBeTruthy()
// Operations should continue working
const moreIds = await Promise.all([
brain.addNoun('More content 1'),
brain.addNoun('More content 2')
])
expect(moreIds.every(id => id)).toBe(true)
await brain.cleanup?.()
})
})
})