async function renderErrors() {
const content = document.getElementById('pageContent');
content.innerHTML = `
Circuit Breaker Status
`;
await Promise.all([refreshErrors(), loadCircuitBreaker()]);
}
async function refreshErrors() {
const container = document.getElementById('errorList');
if (!container) return;
const category = document.getElementById('errorCategoryFilter')?.value || '';
try {
const data = await api.getErrors(100, category);
const errors = data.errors || [];
const totalEl = document.getElementById('errorTotalCount');
if (totalEl) totalEl.textContent = errors.length;
const agentErrors = errors.filter(e => e.category === 'agent').length;
const skillErrors = errors.filter(e => e.category === 'skill').length;
const circuitErrors = errors.filter(e => e.category === 'circuit').length;
const aEl = document.getElementById('errorAgentCount');
if (aEl) aEl.textContent = agentErrors;
const sEl = document.getElementById('errorSkillCount');
if (sEl) sEl.textContent = skillErrors;
const cEl = document.getElementById('errorCircuitCount');
if (cEl) cEl.textContent = circuitErrors;
const badge = document.getElementById('errorCountBadge');
if (badge) {
if (errors.length > 0) { badge.style.display = 'inline'; badge.textContent = errors.length + ' issues'; }
else { badge.style.display = 'none'; }
}
if (errors.length === 0) {
container.innerHTML = '✅
No errors
System is running smoothly
';
return;
}
container.innerHTML = `
| Time | Category | Source | Message | ID |
${errors.slice().reverse().map(e => `
| ${formatDate(e.timestamp)} |
${escapeHtml(e.category)} |
${escapeHtml(e.source)} |
${escapeHtml(e.message)} |
${e.id || ''} |
`).join('')}
${errors.length} error${errors.length !== 1 ? 's' : ''}
`;
} catch (err) {
if (container) container.innerHTML = `âš
${escapeHtml(err.message)}
`;
}
}
async function clearAllErrors() {
if (!confirm('Clear all error logs?')) return;
try {
await api.clearErrors();
showToast('Error log cleared', 'success');
refreshErrors();
} catch (err) {
showToast('Error: ' + err.message, 'error');
}
}
async function loadCircuitBreaker() {
const container = document.getElementById('circuitBreakerCards');
if (!container) return;
try {
const data = await api.getCircuitBreaker();
const agents = data.agents || {};
const agentNames = Object.keys(agents);
if (agentNames.length === 0) {
container.innerHTML = '🔌
No circuit breaker data
';
return;
}
const agentIcons = { opencode: '🔧', hermes: '⚡', gemini: '🧠' };
container.innerHTML = agentNames.map(a => {
const cb = agents[a] || {};
const isOpen = cb.state === 'open';
return `
${agentIcons[a] || '🤖'}
${escapeHtml(a)}
${cb.state || 'closed'}
Failures: ${cb.failures || 0}
Threshold: ${data.threshold || 3}
${isOpen ? `
` : ''}
`;
}).join('');
} catch {
container.innerHTML = 'âš
Failed to load circuit breaker
';
}
}
async function resetCircuit(agent) {
try {
await api.resetCircuitBreaker(agent);
showToast(`Circuit breaker reset for ${agent}`, 'success');
loadCircuitBreaker();
} catch (err) {
showToast('Error: ' + err.message, 'error');
}
}