diff --git a/src/antigravity_provider/router/web/static/app.js b/src/antigravity_provider/router/web/static/app.js
index 9b42033..f9aaa42 100644
--- a/src/antigravity_provider/router/web/static/app.js
+++ b/src/antigravity_provider/router/web/static/app.js
@@ -955,1366 +955,280 @@ function renderOverviewView() {
// ═══════════════════════════════════════════════════════════════
// 2. ROUTING VIEW (P0-1, P0-2 Main Routing Control Center)
// ═══════════════════════════════════════════════════════════════
+
+function getProviderIcon(provider) {
+ const map = {
+ 'openai-codex': 'codex.png',
+ 'google-antigravity': 'антигравити.png',
+ 'opencode-go': 'opencode.png',
+ 'anthropic-claude': 'claude.png',
+ 'deepseek': 'deepseek.png',
+ 'grok': 'grok.jfif'
+ };
+ return map[provider] || 'llama.png';
+}
+
function renderRoutingView() {
- const container = document.getElementById('routing-pipelines-container');
- if (!container || !currentSnapshot) return;
+ const leftCol = document.getElementById('routing-roles-container');
+ const rightCol = document.getElementById('routing-available-container');
+ if (!leftCol || !rightCol || !currentSnapshot) return;
const routing = currentSnapshot.routing || {};
const agents = currentSnapshot.agents || [];
- let html = '';
+ const profiles = currentSnapshot.profiles || {};
+ // Render Left Column (Roles)
+ let rolesHtml = '';
for (const [roleId, pipeline] of Object.entries(routing)) {
- const nodes = pipeline.nodes || [];
+ const chain = pipeline.preferred_chain || [];
const agentInfo = agents.find((a) => a.role_id === roleId);
- const roleDesc = agentInfo?.role_description_ru || (CANONICAL_ROLE_DESCRIPTIONS[roleId] || '');
- const quotaLabel = agentInfo?.active_quota_label || '';
- const quotaStatus = agentInfo?.active_quota_status || 'healthy';
+
+ let isImportant = ['manager', 'developer-1', 'developer-2'].includes(roleId);
+ let badgeHtml = isImportant ? ` Важная роль` : '';
+ let roleDesc = CANONICAL_ROLE_DESCRIPTIONS[roleId] || '';
- html += `
-
-