Voice commands now create activities directly via API
- Replace navigation to pre-filled forms with direct API activity creation - Fetch children from family and use first child (can be enhanced for name matching) - Show success/error messages with proper feedback - Auto-close dialog after successful save - Add test endpoint /api/v1/voice/test-classify for easy testing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
148
test-voice-commands.js
Executable file
148
test-voice-commands.js
Executable file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Voice Command Testing Script
|
||||
* Tests the voice classification API with various baby care commands
|
||||
*/
|
||||
|
||||
const API_URL = process.env.API_URL || 'http://localhost:3020';
|
||||
const ENDPOINT = '/api/v1/voice/test-classify'; // Using public test endpoint
|
||||
|
||||
// ANSI color codes
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
red: '\x1b[31m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
cyan: '\x1b[36m',
|
||||
};
|
||||
|
||||
// Test commands
|
||||
const commands = [
|
||||
'Change wet diaper',
|
||||
'Baby ate 150ml formula',
|
||||
'Baby slept for 1 hour',
|
||||
'Alice slept for 30 min',
|
||||
'Alice ate 3 pcs of broccoli at 11:00 AM',
|
||||
'Dirty diaper change',
|
||||
'Fed baby 120ml',
|
||||
'Baby napped for 45 minutes',
|
||||
'Changed diaper, it was wet',
|
||||
'Gave baby vitamin D drops',
|
||||
];
|
||||
|
||||
async function testCommand(command, testNum) {
|
||||
console.log(`${colors.yellow}Test #${testNum}: "${command}"${colors.reset}`);
|
||||
console.log('---');
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}${ENDPOINT}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
text: command,
|
||||
language: 'en',
|
||||
childName: 'Alice',
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok || !data.success) {
|
||||
console.log(`${colors.red}✗ API returned error${colors.reset}`);
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
console.log('');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract classification details
|
||||
const { type = 'unknown', confidence = 0, details = {}, timestamp = null } = data.classification || {};
|
||||
|
||||
// Color-code based on type
|
||||
let typeColor;
|
||||
switch (type) {
|
||||
case 'feeding':
|
||||
typeColor = colors.green;
|
||||
break;
|
||||
case 'sleep':
|
||||
typeColor = colors.blue;
|
||||
break;
|
||||
case 'diaper':
|
||||
typeColor = colors.yellow;
|
||||
break;
|
||||
case 'medicine':
|
||||
typeColor = colors.cyan;
|
||||
break;
|
||||
case 'milestone':
|
||||
typeColor = colors.green;
|
||||
break;
|
||||
default:
|
||||
typeColor = colors.red;
|
||||
}
|
||||
|
||||
// Display results
|
||||
console.log(`Type: ${typeColor}${type}${colors.reset}`);
|
||||
console.log(`Confidence: ${confidence}`);
|
||||
console.log(`Timestamp: ${timestamp || 'null'}`);
|
||||
console.log('Details:');
|
||||
console.log(JSON.stringify(details, null, 2));
|
||||
|
||||
// Validate confidence threshold
|
||||
const passed = type !== 'unknown' && confidence >= 0.3;
|
||||
|
||||
if (passed) {
|
||||
console.log(`${colors.green}✓ Command successfully classified${colors.reset}\n`);
|
||||
return true;
|
||||
} else {
|
||||
console.log(`${colors.red}✗ Low confidence or unknown type${colors.reset}\n`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`${colors.red}✗ Request failed: ${error.message}${colors.reset}\n`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function runTests() {
|
||||
console.log(`${colors.blue}========================================${colors.reset}`);
|
||||
console.log(`${colors.blue}Voice Command Testing Suite${colors.reset}`);
|
||||
console.log(`${colors.blue}========================================${colors.reset}\n`);
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
for (let i = 0; i < commands.length; i++) {
|
||||
const result = await testCommand(commands[i], i + 1);
|
||||
if (result) {
|
||||
passed++;
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Summary
|
||||
console.log(`${colors.blue}========================================${colors.reset}`);
|
||||
console.log(`${colors.blue}Test Summary${colors.reset}`);
|
||||
console.log(`${colors.blue}========================================${colors.reset}`);
|
||||
console.log(`Total: ${commands.length}`);
|
||||
console.log(`${colors.green}Passed: ${passed}${colors.reset}`);
|
||||
console.log(`${colors.red}Failed: ${failed}${colors.reset}`);
|
||||
console.log('');
|
||||
|
||||
if (failed === 0) {
|
||||
console.log(`${colors.green}All tests passed! 🎉${colors.reset}`);
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log(`${colors.red}Some tests failed. Check the output above.${colors.reset}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Run tests
|
||||
runTests().catch(error => {
|
||||
console.error(`${colors.red}Fatal error: ${error.message}${colors.reset}`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user