const AgentsUI = {
agents: [],
avatarColors: [
'#6366f1',
'#8b5cf6',
'#ec4899',
'#f59e0b',
'#10b981',
'#3b82f6',
'#ef4444',
'#14b8a6',
],
async load() {
try {
AgentsUI.agents = await API.agents.list();
AgentsUI.render();
} catch (err) {
Toast.error(`Erro ao carregar agentes: ${err.message}`);
}
},
render() {
const grid = document.getElementById('agents-grid');
const empty = document.getElementById('agents-empty-state');
if (!grid) return;
if (AgentsUI.agents.length === 0) {
if (empty) empty.style.display = 'flex';
return;
}
if (empty) empty.style.display = 'none';
const existingCards = grid.querySelectorAll('.agent-card');
existingCards.forEach((c) => c.remove());
const fragment = document.createDocumentFragment();
AgentsUI.agents.forEach((agent) => {
const wrapper = document.createElement('div');
wrapper.innerHTML = AgentsUI.renderCard(agent);
fragment.appendChild(wrapper.firstElementChild);
});
grid.appendChild(fragment);
if (window.lucide) lucide.createIcons({ nodes: [grid] });
},
renderCard(agent) {
const name = agent.agent_name || agent.name || 'Sem nome';
const color = AgentsUI.getAvatarColor(name);
const initials = AgentsUI.getInitials(name);
const statusLabel = agent.status === 'active' ? 'Ativo' : 'Inativo';
const statusClass = agent.status === 'active' ? 'badge-active' : 'badge-inactive';
const model = (agent.config && agent.config.model) || agent.model || 'claude-sonnet-4-6';
const updatedAt = AgentsUI.formatDate(agent.updated_at || agent.updatedAt || agent.created_at || agent.createdAt);
return `
${initials}
${name}
${statusLabel}
${agent.description ? `
${agent.description}
` : ''}
${model}
${updatedAt}
`;
},
openCreateModal() {
const form = document.getElementById('agent-form');
if (form) form.reset();
const idField = document.getElementById('agent-form-id');
if (idField) idField.value = '';
const titleEl = document.getElementById('agent-modal-title');
if (titleEl) titleEl.textContent = 'Novo Agente';
const toggle = document.getElementById('agent-status-toggle');
if (toggle) toggle.checked = true;
const tagsHidden = document.getElementById('agent-tags');
if (tagsHidden) tagsHidden.value = '[]';
const tagsChips = document.getElementById('agent-tags-chips');
if (tagsChips) tagsChips.innerHTML = '';
Modal.open('agent-modal-overlay');
},
async openEditModal(agentId) {
try {
const agent = await API.agents.get(agentId);
const titleEl = document.getElementById('agent-modal-title');
if (titleEl) titleEl.textContent = 'Editar Agente';
const fields = {
'agent-form-id': agent.id,
'agent-name': agent.agent_name || agent.name || '',
'agent-description': agent.description || '',
'agent-system-prompt': (agent.config && agent.config.systemPrompt) || '',
'agent-model': (agent.config && agent.config.model) || 'claude-sonnet-4-6',
'agent-workdir': (agent.config && agent.config.workingDirectory) || '',
};
for (const [fieldId, value] of Object.entries(fields)) {
const el = document.getElementById(fieldId);
if (el) el.value = value;
}
const toggle = document.getElementById('agent-status-toggle');
if (toggle) toggle.checked = agent.status === 'active';
const tags = Array.isArray(agent.tags) ? agent.tags : [];
const tagsHidden = document.getElementById('agent-tags');
if (tagsHidden) tagsHidden.value = JSON.stringify(tags);
const tagsChips = document.getElementById('agent-tags-chips');
if (tagsChips) {
tagsChips.innerHTML = tags.map((t) =>
`${t}`
).join('');
}
Modal.open('agent-modal-overlay');
} catch (err) {
Toast.error(`Erro ao carregar agente: ${err.message}`);
}
},
async save() {
const idEl = document.getElementById('agent-form-id');
const id = idEl ? idEl.value.trim() : '';
const nameEl = document.getElementById('agent-name');
if (!nameEl || !nameEl.value.trim()) {
Toast.warning('Nome do agente é obrigatório');
return;
}
const tagsHidden = document.getElementById('agent-tags');
let tags = [];
try {
tags = JSON.parse(tagsHidden?.value || '[]');
} catch {
tags = [];
}
const toggle = document.getElementById('agent-status-toggle');
const data = {
agent_name: nameEl.value.trim(),
description: document.getElementById('agent-description')?.value.trim() || '',
status: toggle && toggle.checked ? 'active' : 'inactive',
config: {
systemPrompt: document.getElementById('agent-system-prompt')?.value.trim() || '',
model: document.getElementById('agent-model')?.value || 'claude-sonnet-4-6',
workingDirectory: document.getElementById('agent-workdir')?.value.trim() || '',
},
};
try {
if (id) {
await API.agents.update(id, data);
Toast.success('Agente atualizado com sucesso');
} else {
await API.agents.create(data);
Toast.success('Agente criado com sucesso');
}
Modal.close('agent-modal-overlay');
await AgentsUI.load();
} catch (err) {
Toast.error(`Erro ao salvar agente: ${err.message}`);
}
},
async delete(agentId) {
const confirmed = await Modal.confirm(
'Excluir agente',
'Tem certeza que deseja excluir este agente? Esta ação não pode ser desfeita.'
);
if (!confirmed) return;
try {
await API.agents.delete(agentId);
Toast.success('Agente excluído com sucesso');
await AgentsUI.load();
} catch (err) {
Toast.error(`Erro ao excluir agente: ${err.message}`);
}
},
async execute(agentId) {
const agent = AgentsUI.agents.find((a) => a.id === agentId);
try {
const allAgents = AgentsUI.agents.length > 0 ? AgentsUI.agents : await API.agents.list();
const selectEl = document.getElementById('execute-agent-select');
if (selectEl) {
selectEl.innerHTML = '' +
allAgents
.filter((a) => a.status === 'active')
.map((a) => ``)
.join('');
selectEl.value = agentId;
}
const hiddenId = document.getElementById('execute-agent-id');
if (hiddenId) hiddenId.value = agentId;
const taskEl = document.getElementById('execute-task-desc');
if (taskEl) taskEl.value = '';
const instructionsEl = document.getElementById('execute-instructions');
if (instructionsEl) instructionsEl.value = '';
Modal.open('execute-modal-overlay');
} catch (err) {
Toast.error(`Erro ao abrir modal de execução: ${err.message}`);
}
},
async export(agentId) {
try {
const data = await API.agents.export(agentId);
const jsonEl = document.getElementById('export-code-content');
if (jsonEl) jsonEl.textContent = JSON.stringify(data, null, 2);
Modal.open('export-modal-overlay');
} catch (err) {
Toast.error(`Erro ao exportar agente: ${err.message}`);
}
},
getAvatarColor(name) {
let hash = 0;
for (let i = 0; i < name.length; i++) {
hash = name.charCodeAt(i) + ((hash << 5) - hash);
}
const index = Math.abs(hash) % AgentsUI.avatarColors.length;
return AgentsUI.avatarColors[index];
},
getInitials(name) {
return name
.split(' ')
.slice(0, 2)
.map((w) => w[0])
.join('')
.toUpperCase();
},
formatDate(isoString) {
if (!isoString) return '—';
const date = new Date(isoString);
return date.toLocaleDateString('pt-BR', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
},
};
window.AgentsUI = AgentsUI;