// ---- OR Personas ----
const OR_PRESETS = {
architect: { role: 'architect', model_id: 'anthropic/claude-sonnet-4-5', description: 'Strategy, systems design, tradeoffs, roadmaps', tier: 'frontier' },
builder: { role: 'builder', model_id: 'deepseek/deepseek-v3-0324', description: 'Code, automation, implementation, debugging', tier: 'balanced' },
researcher:{ role: 'researcher',model_id: 'google/gemini-2.5-flash', description: 'Source gathering, synthesis, validation', tier: 'fast' },
critic: { role: 'critic', model_id: 'deepseek/deepseek-r1', description: 'Review, red-team, gap finding, quality control', tier: 'balanced' },
operator: { role: 'operator', model_id: 'google/gemini-2.5-flash', description: 'SOPs, documentation, execution flow', tier: 'fast' },
};
const TIER_COLORS = { frontier: 'text-purple-400', balanced: 'text-blue-400', fast: 'text-green-400', local: 'text-yellow-400' };
const TIER_LABELS = { frontier: ' Frontier', balanced: ' Balanced', fast: ' Fast', local: ' Local' };
async function loadORPersonas() {
try {
const r = await fetch('/api/or-personas'); const d = await r.json();
const grid = document.getElementById('or-persona-grid');
const personas = d.personas || {};
if (Object.keys(personas).length === 0) {
grid.innerHTML = '
No personas configured. Use Quick Presets below or add one manually.
';
return;
}
grid.innerHTML = Object.entries(personas).map(([role, p]) => {
const tc = TIER_COLORS[p.tier] || 'text-slate-400';
const tl = TIER_LABELS[p.tier] || p.tier;
return `
${role}
${tl}
${p.model_id}
${p.description || ''}
`;
}).join('');
} catch(e) { console.error('OR personas load error:', e); }
}
function showORForm(data) {
const f = document.getElementById('or-form');
f.classList.remove('hidden');
if (data) {
document.getElementById('or-role').value = data.role || '';
document.getElementById('or-model').value = data.model_id || '';
document.getElementById('or-desc').value = data.description || '';
document.getElementById('or-tier').value = data.tier || 'balanced';
} else {
document.getElementById('or-role').value = '';
document.getElementById('or-model').value = '';
document.getElementById('or-desc').value = '';
document.getElementById('or-tier').value = 'balanced';
}
}
async function saveORPersona() {
const body = {
role: document.getElementById('or-role').value.trim(),
model_id: document.getElementById('or-model').value.trim(),
description: document.getElementById('or-desc').value.trim(),
tier: document.getElementById('or-tier').value
};
if (!body.role || !body.model_id) { alert('Role and Model ID required'); return; }
await fetch('/api/or-personas', { method:'POST', headers:{'Content-Type':'application/json','Authorization':'Bearer '+apiKey}, body:JSON.stringify(body) });
document.getElementById('or-form').classList.add('hidden');
loadORPersonas();
}
async function deleteORPersona(role) {
if (!confirm('Delete persona: ' + role + '?')) return;
await fetch('/api/or-personas/' + role, { method:'DELETE', headers:{'Authorization':'Bearer '+apiKey} });
loadORPersonas();
}
function loadPreset(name) {
const p = OR_PRESETS[name]; if (!p) return;
showORForm(p);
}
async function loadAllPresets() {
if (!confirm('Load all 5 default Pantheon OS personas? This will overwrite existing ones with the same role name.')) return;
for (const p of Object.values(OR_PRESETS)) {
await fetch('/api/or-personas', { method:'POST', headers:{'Content-Type':'application/json','Authorization':'Bearer '+apiKey}, body:JSON.stringify(p) });
}
loadORPersonas();
}
const origSwitchTab = switchTab;
switchTab = function(name) {
origSwitchTab(name);
if (name === 'or-personas') loadORPersonas();
};
⚡ Pantheon OS
Hermes Management Dashboard
Gateway
—
PID: —
Uptime: —
CPU: —
RAM: —
Model Assignments
Auxiliary (vision / compression)
—
Recent Activity (agent.log tail)
Agent Personas
Each profile has its own SOUL.md identity loaded by Hermes.
config.yaml
/root/.hermes/config.yaml — YAML validated on save
OpenRouter Role Personas
Assign specific OpenRouter models to each role. Hermes will route tasks to the right model based on the active persona.
QUICK PRESETS