Aurum GPU • připraveno
A
Finance Agent
8 specializovaných finančních agentů — Claude + GPU. Credit, AML, M&A, Cashflow, Fraud, Insurance, Valuace a Leady. Zadej konkrétní případ nebo analýzu.
Credit scoring
AML screening
DCF valuace
Cashflow forecast
`; // Push to server → get public URL try { const res = await fetch(`${ROUTER}/v1/report/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title, content: html, report_type: options.type || 'analysis' }) }); const data = await res.json(); console.log('[REPORT] Generated:', data.url); return { status: 'ok', url: data.url, filename: data.filename, html }; } catch(e) { console.error('[REPORT] Error:', e); // Fallback: open as data URL const blob = new Blob([html], { type: 'text/html' }); const url = URL.createObjectURL(blob); return { status: 'local', url, html }; } } // Konvertuje HTML report URL do PDF přes Playwright async function reportToPdf(reportUrl) { console.log('[PDF] Converting:', reportUrl); try { const res = await fetch(`${ROUTER}/v1/playwright/pdf`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': 'demo-key-123' }, body: JSON.stringify({ url: reportUrl }) }); const data = await res.json(); if (data.pdf_base64) { // Auto-download PDF const link = document.createElement('a'); link.href = 'data:application/pdf;base64,' + data.pdf_base64; link.download = 'CzechAI_Report_' + new Date().toISOString().slice(0,10) + '.pdf'; link.click(); return { status: 'ok', downloaded: true }; } return data; } catch(e) { console.error('[PDF] Error:', e); return { error: e.message, hint: 'Otevřete report URL a použijte Ctrl+P pro tisk do PDF' }; } } // ─── KOMPLEXNÍ REPORT: Nemovitost (cena + AML + market) ─── async function fullPropertyReport(typ, mesto, plocha, cena, vlastnik = null) { console.log('[FULL-REPORT] Building...'); const sections = []; // 1. Cenový odhad (4 mapy) const price = await priceEstimate(typ, mesto, plocha, cena); if (price.konsenzus) { const k = price.konsenzus; const dtagClass = k.dtag === 'D30' ? 'dtag-d30' : k.dtag === 'D20' ? 'dtag-d20' : k.dtag === 'D15' ? 'dtag-d15' : 'dtag-fair'; const fmt = n => n ? n.toLocaleString('cs-CZ') : '—'; sections.push({ icon: '📊', title: 'Cenový odhad nemovitosti', html: `
Typ
${typ}
Lokalita
${mesto}
Plocha
${plocha} m²
Nabídková cena
${fmt(cena)} Kč
Tržní odhad (medián)
${fmt(k.cena)} Kč
Odchylka
${k.rozdil_pct > 0 ? '−' : '+'}${Math.abs(k.rozdil_pct)} % ${k.dtag}

Detaily jednotlivých zdrojů

ZdrojOdhad celkemKč/m²Confidence
Super-Ensemble v2.3${fmt(price.zdroje.super_ensemble?.cena)} Kč${fmt(price.zdroje.super_ensemble?.cena_m2)}${price.zdroje.super_ensemble?.confidence || '—'}
Oceňovač KNN (145K)${fmt(price.zdroje.ocenovac?.cena)} Kč${fmt(price.zdroje.ocenovac?.cena_m2)}${price.zdroje.ocenovac?.confidence || '—'}
Smart Engine V5${fmt(price.zdroje.smart?.cena)} Kč${fmt(price.zdroje.smart?.cena_m2)}${price.zdroje.smart?.confidence || '—'}
Prodeje V4 (reálné)${fmt(price.zdroje.prodeje?.cena)} Kč${fmt(price.zdroje.prodeje?.cena_m2)}${price.zdroje.prodeje?.confidence || '—'}
MEDIÁN (${k.metoda})${fmt(k.cena)} Kč${fmt(k.cena_m2)}

${k.verdikt}

Odhad vychází z mediánu ${price.zdroju} nezávislých cenových zdrojů. Maximální podhodnocení capováno na 30 %.

` }); } // 2. AML screening (pokud je vlastník) if (vlastnik) { const names = vlastnik.split(' '); const firstName = names[0] || ''; const lastName = names.slice(1).join(' ') || ''; const aml = await amlScreen(firstName, lastName); if (aml.status === 'ok') { const riskColor = aml.risk_score < 20 ? 'green' : aml.risk_score < 50 ? 'amber' : 'red'; sections.push({ icon: '🛡️', title: `AML Screening — ${vlastnik}`, html: `
Risk Score
${aml.risk_score}/100
Risk Level
${aml.risk_level}
Modulů celkem
${aml.modulu_celkem}
Čistých / Nálezů
${aml.modulu_ok} / ${aml.modulu_alert}
${aml.modulu_alert > 0 ? '

⚠️ Nálezy

' : '

✅ Žádné negativní nálezy v žádném z 18 modulů.

'}

Prověřené moduly

${aml.ciste.join(', ')}

` }); } } // 3. Market Intel try { const market = await marketIntel(mesto, typ); if (market && !market.error) { sections.push({ icon: '📈', title: `Tržní kontext — ${mesto}`, html: `

${JSON.stringify(market).substring(0, 500)}...

Data z Market Intelligence API (port 5400)

` }); } } catch(e) {} // Build and publish const title = `Analýza nemovitosti — ${typ} ${plocha}m², ${mesto}`; const report = await buildReport(title, sections, { subtitle: `${typ} ${plocha} m² | ${mesto} | Nabídka: ${cena?.toLocaleString('cs-CZ')} Kč`, method: `Medián ${price?.zdroju || 4} cenových map + AML 18 modulů`, type: 'property-analysis' }); // Try PDF conversion if (report.url) { const pdf = await reportToPdf(report.url); report.pdf = pdf; } return report; } // ─── Export poslední AI zprávy jako PDF report ─── async function exportLastAsPdf() { const conv = conversations.find(c => c.id === activeConvId); if (!conv || conv.messages.length < 2) { alert('Žádná konverzace k exportu'); return; } // Get last AI message const lastAi = [...conv.messages].reverse().find(m => m.role === 'assistant'); if (!lastAi) { alert('Žádná AI odpověď k exportu'); return; } const title = conv.title || 'CzechAI Report'; const sections = [{ icon: '📋', title: 'Analýza', html: marked.parse(lastAi.content.replace(/[\s\S]*?<\/think>/g, '')) }]; const statusEl = document.createElement('div'); statusEl.style.cssText = 'position:fixed;bottom:80px;right:32px;background:#161b22;border:1px solid #f59e0b;padding:12px 20px;border-radius:8px;color:#f59e0b;font-size:13px;z-index:999;animation:slideUp .3s'; statusEl.textContent = '📄 Generuji PDF report...'; document.body.appendChild(statusEl); const report = await buildReport(title, sections, { type: 'chat-export' }); if (report.url) { statusEl.textContent = '📄 Konvertuji do PDF...'; const pdf = await reportToPdf(report.url); if (pdf.downloaded) { statusEl.textContent = '✅ PDF stažen!'; } else { statusEl.innerHTML = '📄 Report: ' + report.url + ''; } } else { statusEl.textContent = '⚠️ Report vytvořen lokálně'; window.open(report.url); } setTimeout(() => statusEl.remove(), 5000); } // ═══════════════════════════════════════════════════════ // INIT // ═══════════════════════════════════════════════════════ renderConvList(); if (activeConvId && conversations.find(c => c.id === activeConvId)) { loadConversation(activeConvId); } else { showWelcome(); } // ═══════════════════════════════════════════════════════ // FINANCE PANEL // ═══════════════════════════════════════════════════════ const FINANCE_API = 'https://router.czechai.io'; // přes nginx // Fallback přímý endpoint na server const FIN_BASE = 'https://router.czechai.io/v1/trading'; let fpCurrentTab = 'stocks'; let fpStocksData = null; function toggleFinancePanel() { const panel = document.getElementById('financePanel'); panel.classList.toggle('hidden'); if (!panel.classList.contains('hidden') && !fpStocksData) { fpLoadStocks(); } } function fpTab(tab) { fpCurrentTab = tab; document.querySelectorAll('.fp-tab').forEach((t, i) => { t.classList.toggle('active', ['stocks','search','ta'][i] === tab); }); const body = document.getElementById('fpBody'); if (tab === 'stocks') { if (fpStocksData) fpRenderStocks(fpStocksData); else fpLoadStocks(); } else if (tab === 'search') { fpRenderSearch(); } else if (tab === 'ta') { fpRenderTA(); } } async function fpLoadStocks() { document.getElementById('fpBody').innerHTML = '
⏳ Načítám české akcie z PSE...
'; try { const res = await fetch(`${FIN_BASE}/agents/finance/czech-stocks`); const data = await res.json(); fpStocksData = data.stocks || []; fpRenderStocks(fpStocksData); } catch (e) { document.getElementById('fpBody').innerHTML = `
❌ Chyba: ${e.message}
`; } } function fpRenderStocks(stocks) { const body = document.getElementById('fpBody'); body.innerHTML = `
PSE • ${stocks.length} akcií • Klikni → vloží do chatu
${stocks.map(s => `
${s.symbol}
${s.name || ''}
${s.sector || ''} ${s.currency || 'CZK'}
${s.isin || ''}
`).join('')}
`; } function fpRenderSearch() { document.getElementById('fpBody').innerHTML = `
Zadej dotaz výše...
`; } async function fpDoSearch() { const q = document.getElementById('fpSearchInput')?.value?.trim(); if (!q) return; document.getElementById('fpSearchResults').innerHTML = '
⏳ Hledám...
'; try { const res = await fetch(`${FIN_BASE}/agents/finance/search`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({query: q, limit: 12}) }); const data = await res.json(); const results = data.results || []; if (!results.length) { document.getElementById('fpSearchResults').innerHTML = '
Nic nenalezeno.
'; return; } document.getElementById('fpSearchResults').innerHTML = `
${results.length} výsledků
${results.map(s => `
${s.symbol || s.Symbol || '?'}
${s.name || s.longName || ''}
${s.country || ''} ${s.exchange || ''}
`).join('')}
`; } catch (e) { document.getElementById('fpSearchResults').innerHTML = `
Chyba: ${e.message}
`; } } function fpRenderTA() { document.getElementById('fpBody').innerHTML = `
Vlož pole cen (čárkou oddělená čísla) pro výpočet RSI, MACD, Bollinger Bands:
`; } async function fpRunTA() { const raw = document.getElementById('fpPricesInput')?.value || ''; const prices = raw.split(/[\s,;]+/).map(Number).filter(n => !isNaN(n) && n > 0); if (prices.length < 5) { document.getElementById('fpTAResults').innerHTML = '
Potřebuji min. 5 cen.
'; return; } document.getElementById('fpTAResults').innerHTML = '
⏳ Počítám...
'; try { const res = await fetch(`${FIN_BASE}/agents/finance/technical`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({prices}) }); const d = await res.json(); const rsi = d.rsi_14; const rsiColor = rsi === null ? 'neutral' : rsi > 70 ? 'bear' : rsi < 30 ? 'bull' : 'neutral'; const macd = d.macd || {}; const macdColor = macd.histogram > 0 ? 'bull' : macd.histogram < 0 ? 'bear' : 'neutral'; const bb = d.bollinger_bands || {}; const signal = d.signal || 'N/A'; const signalColor = signal.includes('BULL') || signal.includes('OVERSOLD') ? 'bull' : signal.includes('BEAR') || signal.includes('OVERBOUGHT') ? 'bear' : 'neutral'; document.getElementById('fpTAResults').innerHTML = `
${prices.length} datapointů
${fpIndicator('RSI (14)', rsi !== null ? rsi : 'N/A', rsiColor)} ${fpIndicator('MACD', macd.macd !== null ? macd.macd : 'N/A', macdColor)} ${fpIndicator('MACD Signal', macd.signal !== null ? macd.signal : 'N/A', 'neutral')} ${fpIndicator('MACD Histogram', macd.histogram !== null ? macd.histogram : 'N/A', macdColor)} ${fpIndicator('BB Upper', bb.upper !== null ? bb.upper : 'N/A', 'neutral')} ${fpIndicator('BB Middle (SMA20)', bb.middle !== null ? bb.middle : 'N/A', 'neutral')} ${fpIndicator('BB Lower', bb.lower !== null ? bb.lower : 'N/A', 'neutral')} ${fpIndicator('BB Bandwidth %', bb.bandwidth !== null ? bb.bandwidth + '%' : 'N/A', 'neutral')} ${fpIndicator('SMA 20', d.sma_20 !== null ? d.sma_20 : 'N/A', 'neutral')} ${fpIndicator('SMA 50', d.sma_50 !== null ? d.sma_50 : 'N/A', 'neutral')} ${fpIndicator('EMA 20', d.ema_20 !== null ? d.ema_20 : 'N/A', 'neutral')} ${fpIndicator('EMA 50', d.ema_50 !== null ? d.ema_50 : 'N/A', 'neutral')}
📡 Signál ${signal}
`; } catch (e) { document.getElementById('fpTAResults').innerHTML = `
Chyba: ${e.message}
`; } } function fpIndicator(label, val, cls) { return `
${label}${val}
`; } function fpInjectStock(symbol, name) { const ta = `Proveď finanční analýzu akcie ${symbol} (${name}). Použij dostupná data z PSE, fundamentální ukazatele, historický vývoj a sektory. Vrať: fair value odhad, výhled, rizika a doporučení BUY/HOLD/SELL.`; fillPrompt(ta); toggleFinancePanel(); } function fpInjectTA(data) { const summary = `Technická analýza výsledky: - RSI(14): ${data.rsi_14 ?? 'N/A'} - MACD: ${data.macd?.macd ?? 'N/A'} | Signal: ${data.macd?.signal ?? 'N/A'} | Histogram: ${data.macd?.histogram ?? 'N/A'} - Bollinger Bands: Upper ${data.bollinger_bands?.upper ?? 'N/A'} | Middle ${data.bollinger_bands?.middle ?? 'N/A'} | Lower ${data.bollinger_bands?.lower ?? 'N/A'} - SMA20: ${data.sma_20 ?? 'N/A'} | SMA50: ${data.sma_50 ?? 'N/A'} - EMA20: ${data.ema_20 ?? 'N/A'} | EMA50: ${data.ema_50 ?? 'N/A'} - Signál: ${data.signal ?? 'N/A'} Interpretuj tato data, identifikuj klíčové patterny a dej obchodní doporučení.`; fillPrompt(summary); toggleFinancePanel(); }