Veritas-AI / patch_index.py
Aditya-Jadhav150
feat: AEGIS-AI Detection Engine Overhaul v2 — Multi-model ensemble, forensic artifact localization, audio detection, decision fusion, rich forensic reporting (Code Only)
ea107b5
Raw History Blame Contribute Delete
27.2 kB
import re
with open(r"d:\ANTIGRAVITY\templates\index.html", "r", encoding="utf-8") as f:
html = f.read()
css_addition = """
/* New Forensic Report Styles */
.risk-badge {
font-size: 0.75rem;
font-weight: 700;
padding: 4px 10px;
border-radius: 20px;
text-transform: uppercase;
letter-spacing: 1px;
margin-left: 10px;
display: inline-block;
}
.risk-high { background: rgba(255, 42, 85, 0.2); color: var(--danger); border: 1px solid var(--danger-glow); animation: pulse-risk 2s infinite; }
.risk-medium { background: rgba(255, 204, 0, 0.2); color: var(--warning); border: 1px solid rgba(255, 204, 0, 0.4); }
.risk-low { background: rgba(0, 255, 170, 0.2); color: #00ffaa; border: 1px solid rgba(0, 255, 170, 0.4); }
@keyframes pulse-risk {
0% { box-shadow: 0 0 0 0 var(--danger-glow); }
70% { box-shadow: 0 0 0 10px rgba(255, 42, 85, 0); }
100% { box-shadow: 0 0 0 0 rgba(255, 42, 85, 0); }
}
.report-section {
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 15px;
}
.report-section-title {
font-family: 'Space Grotesk', sans-serif;
font-size: 1.1rem;
font-weight: 600;
color: var(--accent);
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid rgba(255,255,255,0.05);
padding-bottom: 10px;
}
.evidence-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.evidence-list li {
display: flex; align-items: flex-start; gap: 10px; font-size: 0.85rem; color: var(--text-main);
}
.evidence-list li i { margin-top: 3px; color: var(--accent); }
.breakdown-table { display: flex; flex-direction: column; gap: 12px; }
.breakdown-row { display: flex; flex-direction: column; gap: 5px; }
.breakdown-meta { display: flex; justify-content: space-between; font-size: 0.85rem; }
.breakdown-bar-bg { width: 100%; height: 6px; background: rgba(255,255,255,0.05); border-radius: 3px; overflow: hidden; }
.breakdown-bar-fill { height: 100%; border-radius: 3px; transition: width 1s cubic-bezier(0.1, 0.8, 0.2, 1); width: 0%; }
/* Tab Styles */
.tabs { display: flex; gap: 10px; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 10px; flex-wrap: wrap; }
.tab-btn { background: none; border: none; color: var(--text-muted); font-family: inherit; font-size: 0.9rem; cursor: pointer; padding: 5px 10px; transition: all 0.3s; border-radius: 4px; }
.tab-btn:hover { color: var(--text-main); background: rgba(255,255,255,0.05); }
.tab-btn.active { color: var(--accent); background: rgba(0, 240, 255, 0.1); }
.tab-content { display: none; margin-top: 15px; }
.tab-content.active { display: block; }
.heatmap-img { width: 100%; border-radius: 8px; border: 1px solid var(--border-glow); }
.meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; }
.meta-item { display: flex; flex-direction: column; gap: 5px; }
.meta-label { font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.meta-val { font-size: 0.9rem; font-weight: 500; }
.pill-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.pill { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); padding: 4px 10px; border-radius: 12px; font-size: 0.75rem; color: var(--text-muted); }
.collapsible-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; padding: 15px; background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.05); border-radius: 8px; margin-top: 15px; }
.collapsible-header:hover { background: rgba(255,255,255,0.04); }
.collapsible-content { display: none; padding: 15px; border: 1px solid rgba(255,255,255,0.05); border-top: none; border-radius: 0 0 8px 8px; margin-top: -8px; background: rgba(0,0,0,0.2); }
.identity-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.identity-table th, .identity-table td { padding: 8px; text-align: left; border-bottom: 1px solid rgba(255,255,255,0.05); }
.identity-table th { color: var(--text-muted); font-weight: 500; }
.identity-table tr.flagged td { color: var(--danger); }
"""
html = html.replace('/* Admin float link */', css_addition + '\n /* Admin float link */')
html_structure = """
<!-- Verdict banner -->
<div class="verdict-banner" id="verdict-banner">
<div class="verdict-info">
<h4 id="verdict-title">DEEPFAKE DETECTED <span id="risk-badge" class="risk-badge risk-high">HIGH RISK</span></h4>
<p id="verdict-description">High probability of synthetic rendering detected.</p>
</div>
<div class="verdict-percentage" id="verdict-percentage">
97<span>%</span>
</div>
</div>
<!-- NEW: Evidence Summary Card -->
<div class="report-section" id="evidence-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-list-check"></i> Evidence Summary</div>
<ul class="evidence-list" id="evidence-list"></ul>
</div>
<!-- NEW: Confidence Breakdown Card -->
<div class="report-section" id="confidence-breakdown-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-chart-bar"></i> Confidence Breakdown</div>
<div class="breakdown-table" id="confidence-breakdown-list"></div>
</div>
<!-- Crops comparison -->
<div class="images-comparison">
<div class="img-box">
<img id="result-img-orig" src="" alt="Uploaded original" style="display: none;">
<video id="result-video-orig" src="" autoplay loop muted playsinline style="display: none; width: 100%; border-radius: 8px; border: 1px solid var(--border-glow); box-shadow: 0 0 20px var(--accent-glow);"></video>
<div class="img-box-label">Original Input</div>
</div>
<div class="img-box scan-line-active" id="aligned-box">
<img id="result-img-aligned" src="" alt="Aligned Face" style="display: none;">
<div class="img-box-label">Aligned Crop</div>
</div>
</div>
<!-- NEW: Heatmap Carousel -->
<div class="report-section" id="heatmap-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-layer-group"></i> Forensic Artifact Localization</div>
<div class="tabs" id="heatmap-tabs"></div>
<div id="heatmap-contents"></div>
</div>
<!-- NEW: Ensemble Breakdown Card -->
<div class="report-section" id="ensemble-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-network-wired"></i> Ensemble Breakdown</div>
<div class="breakdown-table" id="ensemble-breakdown-list"></div>
</div>
<!-- NEW: Metadata Card -->
<div class="report-section" id="metadata-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-camera"></i> Metadata Analysis</div>
<div class="meta-grid" id="metadata-grid"></div>
<div class="pill-list" id="metadata-flags"></div>
</div>
<!-- NEW: Audio Card -->
<div class="report-section" id="audio-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-waveform"></i> Audio Analysis</div>
<div class="meta-grid" id="audio-grid"></div>
</div>
<!-- NEW: Temporal Card -->
<div class="report-section" id="temporal-card" style="display: none;">
<div class="report-section-title"><i class="fa-solid fa-clock-rotate-left"></i> Temporal Analysis</div>
<div class="meta-grid" id="temporal-grid"></div>
<div id="temporal-identities" style="margin-top: 15px;"></div>
</div>
<!-- 9 Metrics breakdown -->
<div class="metrics-grid">
"""
start_str = """ <!-- Verdict banner -->"""
end_str = """ <!-- 9 Metrics breakdown -->
<div class="metrics-grid">"""
html = html.replace(html[html.find(start_str):html.find(end_str)+len(end_str)], html_structure)
js_addition = """
<!-- NEW: Processing Stats -->
<div id="stats-card" style="display: none;">
<div class="collapsible-header" onclick="toggleStats()">
<div style="font-weight: 600; font-size: 0.9rem;"><i class="fa-solid fa-terminal"></i> Show Debug Info (Processing Stats)</div>
<i class="fa-solid fa-chevron-down" id="stats-chevron"></i>
</div>
<div class="collapsible-content" id="stats-content">
<div class="meta-grid" id="stats-grid"></div>
</div>
</div>
</div>
<!-- Empty state results placeholder -->
"""
html = html.replace(""" </div>
<!-- Empty state results placeholder -->""", js_addition)
js_logic = """
function toggleStats() {
const content = document.getElementById('stats-content');
const chevron = document.getElementById('stats-chevron');
if (content.style.display === 'block') {
content.style.display = 'none';
chevron.className = 'fa-solid fa-chevron-down';
} else {
content.style.display = 'block';
chevron.className = 'fa-solid fa-chevron-up';
}
}
function renderForensicReport(data) {
resultsEmpty.style.display = 'none';
resultsContainer.style.display = 'flex';
// Trigger animation frame
setTimeout(() => {
resultsContainer.classList.add('visible');
}, 50);
// Populate media
if (data.is_video) {
resultImgOrig.style.display = 'none';
resultVideoOrig.style.display = 'block';
resultVideoOrig.src = data.image_url;
resultImgAligned.style.display = 'none';
} else {
resultVideoOrig.style.display = 'none';
resultImgOrig.style.display = 'block';
resultImgOrig.src = data.image_url;
resultImgAligned.style.display = 'block';
resultImgAligned.src = data.aligned_url || data.image_url;
}
// Aligned crop scan animation toggle
if (data.aligned_url) {
alignedBox.classList.add('scan-line-active');
} else {
alignedBox.classList.remove('scan-line-active');
}
// --- 1. Verdict Banner ---
let prediction = data.prediction;
let confidence = data.confidence;
let riskLevel = 'MEDIUM';
if (data.verdict) {
prediction = data.verdict.final_prediction;
confidence = data.verdict.final_confidence;
riskLevel = data.verdict.risk_level || 'MEDIUM';
}
const isFake = prediction === 'FAKE';
verdictBanner.className = 'verdict-banner ' + (isFake ? 'fake' : 'real');
const riskBadge = document.getElementById('risk-badge');
if (riskBadge) {
riskBadge.textContent = riskLevel + " RISK";
riskBadge.className = 'risk-badge ' + (riskLevel === 'HIGH' ? 'risk-high' : (riskLevel === 'LOW' ? 'risk-low' : 'risk-medium'));
}
let verdictTitleText, verdictDescText;
if (data.is_video) {
verdictTitleText = isFake ? 'Verdict: AI Generated Video' : 'Verdict: Real Video';
verdictDescText = isFake
? 'Temporal frame analysis identifies high-confidence markers of video deepfake manipulation.'
: 'Frame-by-frame forensic scan confirms temporal consistency consistent with organic footage.';
} else if (data.method === 'general_vit_detector') {
verdictTitleText = isFake ? 'Verdict: AI Generated Image' : 'Verdict: Real Image';
verdictDescText = isFake
? 'General AI image detector (no face found) identifies AI-synthesis artefacts.'
: 'General AI image analysis finds no synthetic generation markers.';
} else {
verdictTitleText = isFake ? 'Verdict: AI Generated' : 'Verdict: Real Image';
verdictDescText = isFake
? 'Decomposition scan identifies high-confidence markers of synthetic rendering / deepfake.'
: 'Microscopic texture analysis confirms organic, camera-sensor origins.';
}
let riskBadgeHtml = `<span id="risk-badge" class="risk-badge ${riskLevel === 'HIGH' ? 'risk-high' : (riskLevel === 'LOW' ? 'risk-low' : 'risk-medium')}">${riskLevel} RISK</span>`;
verdictTitle.innerHTML = `${verdictTitleText} ${riskBadgeHtml}`;
verdictDescription.textContent = verdictDescText;
verdictPercentage.innerHTML = `${Math.round(confidence)}<span>%</span>`;
if (data.note) {
verdictDescription.textContent += ' [' + data.note + ']';
}
// Helper to render breakdown bars
function createBreakdownBar(label, value, isSourceFake) {
const color = isSourceFake ? 'var(--danger)' : 'var(--accent)';
return `
<div class="breakdown-row">
<div class="breakdown-meta">
<span>${label}</span>
<span style="color: ${color}">${value.toFixed(1)}%</span>
</div>
<div class="breakdown-bar-bg">
<div class="breakdown-bar-fill" style="width: ${value}%; background: ${color}"></div>
</div>
</div>
`;
}
// --- 2. Evidence Summary Card ---
if (data.evidence_summary && data.evidence_summary.length > 0) {
document.getElementById('evidence-card').style.display = 'flex';
const ul = document.getElementById('evidence-list');
ul.innerHTML = '';
data.evidence_summary.forEach(ev => {
ul.innerHTML += `<li><i class="fa-solid fa-check"></i> <span>${ev}</span></li>`;
});
} else {
document.getElementById('evidence-card').style.display = 'none';
}
// --- 3. Confidence Breakdown Table ---
if (data.confidence_breakdown) {
document.getElementById('confidence-breakdown-card').style.display = 'flex';
const list = document.getElementById('confidence-breakdown-list');
let html = '';
const displayNames = {
'image_ensemble': 'Image Ensemble',
'frequency_analysis': 'Frequency Analysis',
'ela_analysis': 'Error Level Analysis',
'metadata_forensics': 'Metadata Forensics',
'temporal_consistency': 'Temporal Consistency',
'audio_analysis': 'Audio Analysis'
};
for (const [key, val] of Object.entries(data.confidence_breakdown)) {
const label = displayNames[key] || key;
const isFakeSource = val > 50;
html += createBreakdownBar(label, val, isFakeSource);
}
list.innerHTML = html;
setTimeout(() => {
document.querySelectorAll('#confidence-breakdown-list .breakdown-bar-fill').forEach(el => {
el.style.width = el.style.width; // Trigger reflow is implicitly handled if we set it in HTML but let's animate
});
}, 100);
} else {
document.getElementById('confidence-breakdown-card').style.display = 'none';
}
// --- 4. Heatmap Carousel ---
if (data.artifact_localization && (data.artifact_localization.ela_url || data.artifact_localization.freq_url || data.artifact_localization.attention_url)) {
document.getElementById('heatmap-card').style.display = 'flex';
const tabs = document.getElementById('heatmap-tabs');
const contents = document.getElementById('heatmap-contents');
tabs.innerHTML = '';
contents.innerHTML = '';
const loc = data.artifact_localization;
let first = true;
function addTab(id, label, url) {
if (!url) return;
tabs.innerHTML += `<button class="tab-btn ${first ? 'active' : ''}" onclick="switchTab('${id}')" id="btn-${id}">${label}</button>`;
contents.innerHTML += `
<div class="tab-content ${first ? 'active' : ''}" id="content-${id}">
<img src="${url}" class="heatmap-img">
</div>
`;
first = false;
}
addTab('ela', 'Error Level Analysis', loc.ela_url);
addTab('freq', 'Frequency Anomaly', loc.freq_url);
addTab('attn', 'ViT Attention', loc.attention_url);
window.switchTab = function(id) {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
document.getElementById('btn-' + id).classList.add('active');
document.getElementById('content-' + id).classList.add('active');
};
} else {
document.getElementById('heatmap-card').style.display = 'none';
}
// --- 5. Ensemble Breakdown Card ---
if (data.ensemble) {
document.getElementById('ensemble-card').style.display = 'flex';
const list = document.getElementById('ensemble-breakdown-list');
let html = '';
if(data.ensemble.primary_score !== undefined) html += createBreakdownBar('Primary ViT (Face)', data.ensemble.primary_score, data.ensemble.primary_score > 50);
if(data.ensemble.secondary_score !== undefined) html += createBreakdownBar('Secondary ViT (General)', data.ensemble.secondary_score, data.ensemble.secondary_score > 50);
if(data.ensemble.fused_score !== undefined) html += createBreakdownBar('Fused Ensemble', data.ensemble.fused_score, data.ensemble.fused_score > 50);
list.innerHTML = html;
} else {
document.getElementById('ensemble-card').style.display = 'none';
}
// --- 6. Metadata Analysis Card ---
if (data.metadata_analysis) {
document.getElementById('metadata-card').style.display = 'flex';
const grid = document.getElementById('metadata-grid');
const m = data.metadata_analysis;
grid.innerHTML = `
<div class="meta-item"><span class="meta-label">Camera</span><span class="meta-val">${m.camera_model || 'Unknown'}</span></div>
<div class="meta-item"><span class="meta-label">Lens</span><span class="meta-val">${m.lens_info || 'Unknown'}</span></div>
<div class="meta-item"><span class="meta-label">Software</span><span class="meta-val">${m.software_detected || 'None detected'}</span></div>
<div class="meta-item"><span class="meta-label">EXIF</span><span class="meta-val">${m.has_exif ? 'Present' : 'Absent'}</span></div>
<div class="meta-item"><span class="meta-label">C2PA Status</span><span class="meta-val">${m.c2pa_status || 'Absent'}</span></div>
`;
const flags = document.getElementById('metadata-flags');
if (m.flags && m.flags.length > 0) {
flags.innerHTML = m.flags.map(f => `<div class="pill">${f}</div>`).join('');
} else {
flags.innerHTML = `<div class="pill">No anomalies</div>`;
}
} else {
document.getElementById('metadata-card').style.display = 'none';
}
// --- 7. Audio Analysis Card ---
if (data.audio_analysis) {
document.getElementById('audio-card').style.display = 'flex';
const grid = document.getElementById('audio-grid');
const a = data.audio_analysis;
const audioIsFake = a.audio_prediction === 'FAKE';
grid.innerHTML = `
<div class="meta-item"><span class="meta-label">Audio Verdict</span><span class="meta-val" style="color: ${audioIsFake ? 'var(--danger)' : 'var(--accent)'}">${a.audio_prediction || 'N/A'}</span></div>
<div class="meta-item"><span class="meta-label">Confidence</span><span class="meta-val">${a.audio_confidence ? a.audio_confidence.toFixed(1) + '%' : 'N/A'}</span></div>
<div class="meta-item"><span class="meta-label">Segments</span><span class="meta-val">${a.segments_analyzed || 0}</span></div>
`;
} else {
document.getElementById('audio-card').style.display = 'none';
}
// --- 8. Temporal Analysis Card ---
if (data.temporal_analysis) {
document.getElementById('temporal-card').style.display = 'flex';
const grid = document.getElementById('temporal-grid');
const t = data.temporal_analysis;
grid.innerHTML = `
<div class="meta-item"><span class="meta-label">Variance</span><span class="meta-val">${t.confidence_variance !== undefined ? t.confidence_variance.toFixed(3) : 'N/A'}</span></div>
<div class="meta-item"><span class="meta-label">Drift</span><span class="meta-val">${t.confidence_drift !== undefined ? t.confidence_drift.toFixed(3) : 'N/A'}</span></div>
<div class="meta-item"><span class="meta-label">Entropy</span><span class="meta-val">${t.prediction_entropy !== undefined ? t.prediction_entropy.toFixed(3) : 'N/A'}</span></div>
<div class="meta-item"><span class="meta-label">Consistency</span><span class="meta-val">${t.temporal_consistency_score !== undefined ? t.temporal_consistency_score.toFixed(3) : 'N/A'}</span></div>
`;
const idTableContainer = document.getElementById('temporal-identities');
if (t.identities && t.identities.length > 0) {
let idHtml = `<table class="identity-table"><tr><th>ID</th><th>Frames</th><th>Fake Prob</th><th>Verdict</th></tr>`;
t.identities.forEach(id => {
const rowClass = id.flagged ? 'flagged' : '';
idHtml += `<tr class="${rowClass}">
<td>#${id.id || id.identity_id}</td>
<td>${id.frames || id.frames_seen}</td>
<td>${(id.mean_fake || id.mean_fake_prob).toFixed(1)}%</td>
<td>${id.prediction || (id.flagged ? 'FAKE' : 'REAL')}</td>
</tr>`;
});
idHtml += `</table>`;
idTableContainer.innerHTML = idHtml;
} else {
idTableContainer.innerHTML = '';
}
} else {
document.getElementById('temporal-card').style.display = 'none';
}
// --- 9. Processing Stats ---
if (data.processing_stats) {
document.getElementById('stats-card').style.display = 'block';
const grid = document.getElementById('stats-grid');
const s = data.processing_stats;
grid.innerHTML = `
<div class="meta-item"><span class="meta-label">Total Time</span><span class="meta-val">${s.total_analysis_ms || 0} ms</span></div>
<div class="meta-item"><span class="meta-label">Inference</span><span class="meta-val">${s.model_inference_ms || 0} ms</span></div>
<div class="meta-item"><span class="meta-label">Heatmaps</span><span class="meta-val">${s.heatmap_generation_ms || 0} ms</span></div>
<div class="meta-item"><span class="meta-label">Peak RAM</span><span class="meta-val">${s.peak_ram_mb || 0} MB</span></div>
`;
} else {
document.getElementById('stats-card').style.display = 'none';
}
// Populate forensic metrics (safe with defaults if keys are missing)
"""
start_logic = """ function renderForensicReport(data) {"""
end_logic = """ // Populate forensic metrics (safe with defaults if keys are missing)"""
html = html.replace(html[html.find(start_logic):html.find(end_logic)+len(end_logic)], js_logic)
with open(r"d:\ANTIGRAVITY\templates\index.html", "w", encoding="utf-8") as f:
f.write(html)