mirror of
https://github.com/hanzoai/persona.git
synced 2026-10-30 18:24:59 +00:00
* feat: Restructure personalities into individual JSON files - Split mega JSON files into 488 individual personality files - Each personality in its own named JSON file (e.g., zeekay.json, einstein.json) - Created comprehensive index.json with all personality references - Added categories.json for grouping by category - Built JavaScript loader utilities for easy imports - Generated README with complete personality index - Added build and validation scripts for maintenance - More maintainable and reusable structure for JavaScript imports * feat: Enhanced scientist profiles and fixed validation issues - Added detailed fields to 9 major scientist profiles (Einstein, Curie, Darwin, etc.) - Fixed invalid categories for 7 profiles (changed to valid categories) - Added parallel validation script with comprehensive checks - All 487 personality profiles now pass validation - 100% validation success rate across all categories * refactor: Complete personality separation and cleanup - Verified all 487 unique personalities are in individual JSON files - Archived 11 mega personality collection files for safety - Fixed duplicate vaclav_havel entry (was counted twice in mega file) - Profiles directory now contains exactly 487 personality files + 2 index files - Zero duplicate IDs across all individual files - Cleaned personalities directory, keeping only individual files - All personalities properly validated and organized by category * feat: Add 126 personalities for global representation - Added 21 African personalities (Nigeria, Kenya, Ethiopia, Tanzania, etc.) - Added 20 Latin American personalities (Brazil, Argentina, Mexico, Chile, etc.) - Added 25 Asia-Pacific personalities (Indonesia, Thailand, Philippines, Pakistan, etc.) - Added 15 Caribbean personalities (Jamaica, Cuba, Haiti, Trinidad, etc.) - Added 15 Middle Eastern personalities (Turkey, Iran, Israel, Lebanon, etc.) - Added 20 Eastern European personalities (Poland, Czech, Hungary, Romania, etc.) - Added 10 Pacific Island personalities (New Zealand, Australia, Hawaii, Samoa, etc.) Total personalities: 613 (up from 487) Now includes representation from 100+ countries/territories Each personality includes OCEAN scores, philosophy, tools/domains, and origin * feat: enhance 682 personality profiles with comprehensive behavioral modeling - Added 8 major behavioral modeling categories to each profile: - Behavioral traits (values, motivations, fears, strengths, weaknesses, habits, quirks) - Cognitive style (thinking patterns, learning, problem-solving, decision-making) - Social dynamics (interaction, leadership, conflict, collaboration styles) - Communication patterns (verbal style, listening, persuasion, storytelling) - Work methodology (planning, execution, attention, pace, persistence) - Emotional profile (stability, stress response, empathy, self-awareness) - Legacy impact (contributions, influence domains, innovation style) - Category-specific attributes (tailored to each personality type) - Enhanced 682 out of 701 profiles (97.3% success rate) - Added enhancement metadata tracking (date, version, category used) - Created comprehensive Python enhancement script for future updates - Each profile now contains detailed attributes for accurate AI modeling - Fulfills user request for 'as much extra detail as possible to accurately model all qualities and aspects of each persona' --------- Co-authored-by: Hanzo Dev <[email protected]>
220 lines
7.1 KiB
JavaScript
220 lines
7.1 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const readline = require('readline');
|
|
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
|
|
// Helper to ask questions
|
|
const question = (q) => new Promise(resolve => rl.question(q, resolve));
|
|
|
|
// Categories and their directories
|
|
const CATEGORIES = {
|
|
programmer: 'programmers',
|
|
philosopher: 'philosophers',
|
|
scientist: 'scientists',
|
|
religious: 'religious',
|
|
revolutionary: 'revolutionaries',
|
|
writer: 'writers',
|
|
artist: 'artists',
|
|
architect: 'architects',
|
|
athlete: 'athletes',
|
|
explorer: 'explorers',
|
|
activist: 'activists',
|
|
tech_leader: 'leaders',
|
|
leader: 'leaders',
|
|
pioneer: 'pioneers',
|
|
special: 'special'
|
|
};
|
|
|
|
// Generate ID from name
|
|
function generateId(name) {
|
|
return name
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9\s-]/g, '')
|
|
.replace(/\s+/g, '_')
|
|
.replace(/-+/g, '_')
|
|
.substring(0, 50);
|
|
}
|
|
|
|
// Main function
|
|
async function addPersonality() {
|
|
console.log('\n=== Add New Personality ===\n');
|
|
|
|
try {
|
|
// Basic info
|
|
const name = await question('Name (display name): ');
|
|
const fullName = await question('Full name (optional, press Enter to skip): ');
|
|
const id = await question(`ID (press Enter for "${generateId(name)}"): `) || generateId(name);
|
|
|
|
// Category
|
|
console.log('\nCategories:', Object.keys(CATEGORIES).join(', '));
|
|
const category = await question('Category: ');
|
|
|
|
if (!CATEGORIES[category]) {
|
|
console.error(`Invalid category: ${category}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Tags
|
|
const tagsInput = await question('Tags (comma-separated, optional): ');
|
|
const tags = tagsInput ? tagsInput.split(',').map(t => t.trim()).filter(Boolean) : [];
|
|
|
|
// OCEAN scores
|
|
console.log('\n=== OCEAN Scores (0-100) ===');
|
|
const openness = parseInt(await question('Openness (creativity, curiosity): ')) || 50;
|
|
const conscientiousness = parseInt(await question('Conscientiousness (organization, discipline): ')) || 50;
|
|
const extraversion = parseInt(await question('Extraversion (sociability, energy): ')) || 50;
|
|
const agreeableness = parseInt(await question('Agreeableness (cooperation, trust): ')) || 50;
|
|
const neuroticism = parseInt(await question('Neuroticism (emotional instability): ')) || 50;
|
|
|
|
// Personality
|
|
console.log('\n=== Personality ===');
|
|
const summary = await question('Summary (brief description): ');
|
|
const philosophy = await question('Philosophy (core belief/motto): ');
|
|
const approach = await question('Approach (optional): ');
|
|
const communication = await question('Communication style (optional): ');
|
|
|
|
// Values
|
|
const valuesInput = await question('Core values (comma-separated, optional): ');
|
|
const values = valuesInput ? valuesInput.split(',').map(v => v.trim()).filter(Boolean) : undefined;
|
|
|
|
// Quotes
|
|
console.log('\n=== Quotes (optional, enter empty line to finish) ===');
|
|
const quotes = [];
|
|
let quoteNum = 1;
|
|
while (true) {
|
|
const quote = await question(`Quote ${quoteNum}: `);
|
|
if (!quote) break;
|
|
quotes.push(quote);
|
|
quoteNum++;
|
|
}
|
|
|
|
// For programmers, add technical info
|
|
let technical;
|
|
if (category === 'programmer' || category === 'tech_leader') {
|
|
console.log('\n=== Technical Info (optional) ===');
|
|
const languagesInput = await question('Programming languages (comma-separated): ');
|
|
const languages = languagesInput ? languagesInput.split(',').map(l => l.trim()).filter(Boolean) : undefined;
|
|
|
|
const domainsInput = await question('Domains (comma-separated): ');
|
|
const domains = domainsInput ? domainsInput.split(',').map(d => d.trim()).filter(Boolean) : undefined;
|
|
|
|
const essentialTools = await question('Essential tools (comma-separated): ');
|
|
const essential = essentialTools ? essentialTools.split(',').map(t => t.trim()).filter(Boolean) : undefined;
|
|
|
|
if (languages || domains || essential) {
|
|
technical = {};
|
|
if (languages) technical.languages = languages;
|
|
if (domains) technical.domains = domains;
|
|
if (essential) technical.tools = { essential };
|
|
}
|
|
}
|
|
|
|
// Build the personality object
|
|
const personality = {
|
|
"$schema": "../schemas/personality.schema.json",
|
|
id,
|
|
name,
|
|
category
|
|
};
|
|
|
|
if (fullName) personality.fullName = fullName;
|
|
if (tags.length > 0) personality.tags = tags;
|
|
|
|
personality.ocean = {
|
|
openness: Math.min(100, Math.max(0, openness)),
|
|
conscientiousness: Math.min(100, Math.max(0, conscientiousness)),
|
|
extraversion: Math.min(100, Math.max(0, extraversion)),
|
|
agreeableness: Math.min(100, Math.max(0, agreeableness)),
|
|
neuroticism: Math.min(100, Math.max(0, neuroticism))
|
|
};
|
|
|
|
personality.personality = {
|
|
summary: summary || `${category} personality`,
|
|
philosophy: philosophy || 'No philosophy recorded'
|
|
};
|
|
|
|
if (approach) personality.personality.approach = approach;
|
|
if (communication) personality.personality.communication = communication;
|
|
if (values) personality.personality.values = values;
|
|
if (technical) personality.technical = technical;
|
|
if (quotes.length > 0) personality.quotes = quotes;
|
|
|
|
// Determine target directory
|
|
const targetDir = CATEGORIES[category];
|
|
const baseDir = path.join(__dirname, '..', 'personalities_v2');
|
|
const dirPath = path.join(baseDir, targetDir);
|
|
|
|
// Ensure directory exists
|
|
if (!fs.existsSync(dirPath)) {
|
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
}
|
|
|
|
// Check if file already exists
|
|
const filePath = path.join(dirPath, `${id}.json`);
|
|
if (fs.existsSync(filePath)) {
|
|
const overwrite = await question(`\nFile ${id}.json already exists. Overwrite? (y/N): `);
|
|
if (overwrite.toLowerCase() !== 'y') {
|
|
console.log('Cancelled.');
|
|
process.exit(0);
|
|
}
|
|
}
|
|
|
|
// Write the file
|
|
fs.writeFileSync(filePath, JSON.stringify(personality, null, 2));
|
|
console.log(`\nā
Created: ${targetDir}/${id}.json`);
|
|
|
|
// Update manifest
|
|
const manifestPath = path.join(baseDir, 'index', 'manifest.json');
|
|
if (fs.existsSync(manifestPath)) {
|
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
|
|
// Update index
|
|
manifest.index[id] = {
|
|
path: `${targetDir}/${id}.json`,
|
|
name: name,
|
|
category: category,
|
|
tags: tags
|
|
};
|
|
|
|
// Update category
|
|
if (!manifest.categories[category]) {
|
|
manifest.categories[category] = {
|
|
count: 0,
|
|
path: targetDir,
|
|
ids: []
|
|
};
|
|
}
|
|
|
|
if (!manifest.categories[category].ids.includes(id)) {
|
|
manifest.categories[category].ids.push(id);
|
|
manifest.categories[category].count++;
|
|
manifest.total++;
|
|
}
|
|
|
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
console.log('ā
Updated manifest.json');
|
|
}
|
|
|
|
// Suggest rebuilding
|
|
console.log('\nTo rebuild aggregated files, run: npm run build');
|
|
|
|
} catch (err) {
|
|
console.error('\nError:', err.message);
|
|
process.exit(1);
|
|
} finally {
|
|
rl.close();
|
|
}
|
|
}
|
|
|
|
// Run if called directly
|
|
if (require.main === module) {
|
|
addPersonality();
|
|
}
|
|
|
|
module.exports = { addPersonality }; |