new changes in the api

This commit is contained in:
2026-07-06 15:15:51 +05:30
parent c742ef0e53
commit 871981035a
43 changed files with 414 additions and 1975 deletions

View File

@@ -452,43 +452,6 @@
transform: scaleY(1.1)
}
/* ── STRATEGY SWITCHER ── */
.strategy-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: .5rem
}
.strategy-card {
padding: .75rem;
border: 1px solid var(--border);
border-radius: 2px;
cursor: pointer;
transition: all .15s;
}
.strategy-card:hover {
border-color: var(--border2)
}
.strategy-card.active {
border-color: var(--accent);
background: rgba(0, 212, 255, .06)
}
.strategy-name {
font-size: .75rem;
font-weight: 700;
letter-spacing: .05em;
margin-bottom: .2rem
}
.strategy-desc {
font-family: var(--mono);
font-size: .62rem;
color: var(--muted)
}
/* ── BADGE ── */
.badge {
display: inline-block;
@@ -718,11 +681,6 @@
<div class="stat-value v-accent" id="sMLParams">&mdash;</div>
<div class="stat-sub" id="sParamsSub">&mdash;</div>
</div>
<div class="stat-card">
<div class="stat-label">SLA Breaches</div>
<div class="stat-value" id="sSLA">&mdash;</div>
<div class="stat-sub">Recent window</div>
</div>
<div class="stat-card">
<div class="stat-label">Avg Latency</div>
<div class="stat-value" id="sLatency">&mdash;</div>
@@ -758,17 +716,8 @@
<div class="chart-wrap"><canvas id="importanceChart"></canvas></div>
</div>
<div class="panel">
<div class="panel-title">
Strategy Mode
<span class="badge badge-purple" id="activeStrategyBadge">&mdash;</span>
</div>
<div class="strategy-grid" id="strategyGrid">
<!-- injected -->
</div>
<div style="margin-top:1rem">
<div class="panel-title" style="margin-bottom:.5rem">Multi-Objective Pareto</div>
<div class="chart-wrap" style="height:120px"><canvas id="paretoChart"></canvas></div>
</div>
<div class="panel-title">Multi-Objective Pareto</div>
<div class="chart-wrap" style="height:120px"><canvas id="paretoChart"></canvas></div>
</div>
<div class="panel">
<div class="panel-title">
@@ -794,28 +743,6 @@
<div class="panel-title">Quality Distribution</div>
<div class="chart-wrap"><canvas id="histogramChart"></canvas></div>
</div>
<div class="panel">
<div class="panel-title">Strategy Comparison</div>
<div class="tbl-scroll">
<table class="ml-table" id="strategyTable">
<thead>
<tr>
<th>Strategy</th>
<th>Calls</th>
<th>Avg Q</th>
<th>Unassigned</th>
<th>Avg km</th>
</tr>
</thead>
<tbody id="strategyTableBody">
<tr>
<td colspan="5" style="color:var(--muted);text-align:center;padding:1.5rem">Loading...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- ROW 4: Zone stats + Top trials + Model health -->
@@ -830,13 +757,12 @@
<th>Zone</th>
<th>Calls</th>
<th>Avg Q</th>
<th>SLA Breaches</th>
<th>Avg km</th>
</tr>
</thead>
<tbody id="zoneTableBody">
<tr>
<td colspan="5" style="color:var(--muted);text-align:center;padding:1.5rem">Loading...
<td colspan="4" style="color:var(--muted);text-align:center;padding:1.5rem">Loading...
</td>
</tr>
</tbody>
@@ -900,14 +826,6 @@
<script>
const API = '/api/v1/ml';
let charts = {};
let activeStrategy = 'balanced';
const STRATEGIES = {
aggressive_speed: { name: 'Aggressive Speed', desc: 'Max completions, ignore balance', color: '#ff4466' },
fuel_saver: { name: 'Fuel Saver', desc: 'Minimize total route distance', color: '#00e57a' },
zone_strict: { name: 'Zone Strict', desc: 'Balance + local routes', color: '#7c3aed' },
balanced: { name: 'Balanced', desc: 'Even spread across all metrics', color: '#00d4ff' },
};
const PARAM_DESC = {
max_pickup_distance_km: 'Max distance a rider can be from kitchen for initial pickup',
@@ -951,10 +869,8 @@
renderLatencyChart(data.quality_trend || {});
renderModelHealth(data.model || {});
renderBehaviorRules(data.behavior || {});
renderStrategyGrid(data.config?.ml_strategy || 'balanced');
renderHeatmap(data.hourly_stats || []);
renderHistogram(data.quality_histogram || []);
renderStrategyTable(data.strategy_comparison || []);
renderZoneTable(data.zone_stats || []);
renderTrialsTable(data.model?.top_trials || []);
renderImportanceChart(data.model?.feature_importance || {});
@@ -1007,11 +923,6 @@
const latArr = trend.latency_series || [];
const avgLat = latArr.length ? (latArr.reduce((a, b) => a + b, 0) / latArr.length).toFixed(0) : '&mdash;';
set('sLatency', avgLat !== '&mdash;' ? avgLat + 'ms' : '&mdash;');
// SLA count from hourly stats
const slaCount = (data.hourly_stats || []).reduce((s, r) => s + (r.sla_breaches || 0), 0);
set('sSLA', slaCount);
el('sSLA').className = 'stat-value ' + (slaCount === 0 ? 'v-green' : slaCount < 5 ? 'v-amber' : 'v-red');
}
// ─────────────────────────── CONFIG ───────────────────────────
@@ -1271,7 +1182,7 @@
<div style="font-family:var(--mono);font-size:.55rem;color:rgba(255,255,255,.5)">${h}h</div>
<div style="font-family:var(--mono);font-size:.6rem;color:#fff;font-weight:500">${q ? q.toFixed(0) : '&mdash;'}</div>
`;
cell.title = `Hour ${h}: Q=${q.toFixed(1)}, SLA breaches=${d?.sla_breaches || 0}, calls=${d?.call_count || 0}`;
cell.title = `Hour ${h}: Q=${q.toFixed(1)}, calls=${d?.call_count || 0}`;
row.appendChild(cell);
}
container.appendChild(row);
@@ -1285,28 +1196,14 @@
}
// ─────────────────────────── TABLES ───────────────────────────
function renderStrategyTable(rows) {
const tbody = el('strategyTableBody');
if (!rows.length) { tbody.innerHTML = '<tr><td colspan="5" style="color:var(--muted);text-align:center;padding:1.5rem">No data yet</td></tr>'; return; }
tbody.innerHTML = rows.map(r => `
<tr>
<td><span class="badge badge-blue">${r.strategy}</span></td>
<td>${r.call_count}</td>
<td><span class="${r.avg_quality > 75 ? 'badge-green' : r.avg_quality > 50 ? 'badge-amber' : 'badge-red'} badge">${r.avg_quality}%</span></td>
<td>${r.avg_unassigned.toFixed(1)}</td>
<td>${r.avg_distance_km.toFixed(1)} km</td>
</tr>`).join('');
}
function renderZoneTable(rows) {
const tbody = el('zoneTableBody');
if (!rows.length) { tbody.innerHTML = '<tr><td colspan="5" style="color:var(--muted);text-align:center;padding:1.5rem">No zone data yet</td></tr>'; return; }
if (!rows.length) { tbody.innerHTML = '<tr><td colspan="4" style="color:var(--muted);text-align:center;padding:1.5rem">No zone data yet</td></tr>'; return; }
tbody.innerHTML = rows.map(r => `
<tr>
<td style="color:var(--accent)">${r.zone_id}</td>
<td>${r.call_count}</td>
<td><span class="${r.avg_quality > 75 ? 'badge-green' : r.avg_quality > 50 ? 'badge-amber' : 'badge-red'} badge">${r.avg_quality}%</span></td>
<td><span class="${r.sla_breaches === 0 ? 'badge-green' : r.sla_breaches < 3 ? 'badge-amber' : 'badge-red'} badge">${r.sla_breaches}</span></td>
<td>${r.avg_distance_km.toFixed(1)} km</td>
</tr>`).join('');
}
@@ -1410,35 +1307,6 @@
}).join('');
}
// ─────────────────────────── STRATEGY ───────────────────────────
function renderStrategyGrid(current) {
activeStrategy = current;
const badge = el('activeStrategyBadge');
badge.textContent = STRATEGIES[current]?.name || current;
const grid = el('strategyGrid');
grid.innerHTML = Object.entries(STRATEGIES).map(([key, s]) => `
<div class="strategy-card ${key === current ? 'active' : ''}" onclick="setStrategy('${key}')">
<div class="strategy-name" style="color:${s.color}">${s.name}</div>
<div class="strategy-desc">${s.desc}</div>
</div>
`).join('');
}
async function setStrategy(key) {
try {
await fetch(`${API}/config`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ml_strategy: key })
});
toast(`Strategy set: ${STRATEGIES[key].name}`);
await fullRefresh();
} catch (e) {
toast('Failed to set strategy', true);
}
}
// ─────────────────────────── ACTIONS ───────────────────────────
async function triggerTrain() {
const btn = el('btnTrain');