update augorWorker to use openRouter configuration and set llmModel in config

This commit is contained in:
ImBenji 2026-04-22 22:22:52 +01:00
parent f580e7f117
commit d972569e54
2 changed files with 131 additions and 20 deletions

View file

@ -401,6 +401,18 @@
</div> </div>
<!-- Intelligence detail modal -->
<div class="overlay" id="intelOverlay">
<div class="modal" style="width:740px">
<h2 id="intel-modal-title">Detail</h2>
<div id="intel-modal-meta" style="font-size:12px; color:#64748b; margin-bottom:16px; display:flex; gap:16px; flex-wrap:wrap"></div>
<div id="intel-modal-body" style="font-size:13px; line-height:1.7; white-space:pre-wrap; word-break:break-word; background:#141620; padding:14px; border-radius:6px; border:1px solid #2d3148"></div>
<div class="modal-footer">
<button id="intelCloseBtn">Close</button>
</div>
</div>
</div>
<!-- Article modal --> <!-- Article modal -->
<div class="overlay" id="articleOverlay"> <div class="overlay" id="articleOverlay">
<div class="modal"> <div class="modal">
@ -772,6 +784,7 @@ async function loadIntelligence() {
if (type) params.set('type', type); if (type) params.set('type', type);
const data = await api(`/admin/api/intelligence/knowledge?${params}`); const data = await api(`/admin/api/intelligence/knowledge?${params}`);
intelRows = data.rows;
document.getElementById('intel-thead').innerHTML = ` document.getElementById('intel-thead').innerHTML = `
<tr><th>ID</th><th>Company</th><th>Event</th><th>Type</th><th>Data</th><th>Created</th></tr>`; <tr><th>ID</th><th>Company</th><th>Event</th><th>Type</th><th>Data</th><th>Created</th></tr>`;
@ -780,12 +793,12 @@ async function loadIntelligence() {
let parsed = {}; let parsed = {};
try { parsed = JSON.parse(r.data); } catch (_) {} try { parsed = JSON.parse(r.data); } catch (_) {}
const summary = Object.values(parsed).filter(v => typeof v === 'string').join(' · ').slice(0, 120); const summary = Object.values(parsed).filter(v => typeof v === 'string').join(' · ').slice(0, 120);
return `<tr> return `<tr style="cursor:pointer" onclick="openIntelDetail(${r.id}, 'knowledge')">
<td style="color:#64748b">${r.id}</td> <td style="color:#64748b">${r.id}</td>
<td style="white-space:nowrap">${r.company_name}</td> <td style="white-space:nowrap">${r.company_name}</td>
<td style="color:#64748b">${r.event_id}</td> <td style="color:#64748b">${r.event_id}</td>
<td><span class="badge null">${r.type}</span></td> <td><span class="badge null">${r.type}</span></td>
<td><span class="truncate" style="max-width:360px" title="${r.data.replace(/"/g,'&quot;')}">${summary}</span></td> <td><span class="truncate" style="max-width:360px">${summary}</span></td>
<td style="color:#64748b; white-space:nowrap">${r.created_at ? r.created_at.slice(0,16) : '—'}</td> <td style="color:#64748b; white-space:nowrap">${r.created_at ? r.created_at.slice(0,16) : '—'}</td>
</tr>`; </tr>`;
}).join(''); }).join('');
@ -800,12 +813,13 @@ async function loadIntelligence() {
document.getElementById('i-type').parentElement.style.display = 'none'; document.getElementById('i-type').parentElement.style.display = 'none';
const data = await api(`/admin/api/intelligence/predictions?${params}`); const data = await api(`/admin/api/intelligence/predictions?${params}`);
intelRows = data.rows;
document.getElementById('intel-thead').innerHTML = ` document.getElementById('intel-thead').innerHTML = `
<tr><th>ID</th><th>Company</th><th>Event</th><th>Type</th><th>Direction</th><th>Magnitude</th><th>Timeframe</th><th>Rationale</th><th>Created</th></tr>`; <tr><th>ID</th><th>Company</th><th>Event</th><th>Type</th><th>Direction</th><th>Magnitude</th><th>Timeframe</th><th>Rationale</th><th>Created</th></tr>`;
document.getElementById('intel-tbody').innerHTML = data.rows.map(r => ` document.getElementById('intel-tbody').innerHTML = data.rows.map(r => `
<tr> <tr style="cursor:pointer" onclick="openIntelDetail(${r.id}, 'predictions')">
<td style="color:#64748b">${r.id}</td> <td style="color:#64748b">${r.id}</td>
<td style="white-space:nowrap">${r.company_name}</td> <td style="white-space:nowrap">${r.company_name}</td>
<td style="color:#64748b">${r.event_id}</td> <td style="color:#64748b">${r.event_id}</td>
@ -813,7 +827,7 @@ async function loadIntelligence() {
<td>${r.direction || '—'}</td> <td>${r.direction || '—'}</td>
<td>${r.magnitude || '—'}</td> <td>${r.magnitude || '—'}</td>
<td>${r.timeframe || '—'}</td> <td>${r.timeframe || '—'}</td>
<td><span class="truncate" style="max-width:300px" title="${(r.rationale||'').replace(/"/g,'&quot;')}">${r.rationale || '—'}</span></td> <td><span class="truncate" style="max-width:300px">${r.rationale || '—'}</span></td>
<td style="color:#64748b; white-space:nowrap">${r.created_at ? r.created_at.slice(0,16) : '—'}</td> <td style="color:#64748b; white-space:nowrap">${r.created_at ? r.created_at.slice(0,16) : '—'}</td>
</tr> </tr>
`).join(''); `).join('');
@ -831,6 +845,45 @@ document.getElementById('iNextBtn').onclick = () => { intelOffset += PAGE; loadI
document.getElementById('i-view').onchange = () => { intelOffset = 0; loadIntelligence(); }; document.getElementById('i-view').onchange = () => { intelOffset = 0; loadIntelligence(); };
let intelRows = [];
function openIntelDetail(id, view) {
const row = intelRows.find(r => r.id === id);
if (!row) return;
document.getElementById('intel-modal-title').textContent =
`${row.company_name} — Event ${row.event_id}`;
const meta = [`type: ${row.type || view}`, `created: ${row.created_at ? row.created_at.slice(0,16) : '—'}`];
document.getElementById('intel-modal-meta').innerHTML = meta.map(m => `<span>${m}</span>`).join('');
let body = '';
if (view === 'knowledge') {
try {
const parsed = JSON.parse(row.data);
body = Object.entries(parsed).map(([k, v]) => `${k}: ${v}`).join('\n');
} catch (_) { body = row.data; }
} else {
body = [
row.rationale,
'',
`direction: ${row.direction || '—'}`,
`magnitude: ${row.magnitude || '—'}`,
`timeframe: ${row.timeframe || '—'}`,
].join('\n');
}
document.getElementById('intel-modal-body').textContent = body;
document.getElementById('intelOverlay').classList.add('open');
}
document.getElementById('intelCloseBtn').onclick = () =>
document.getElementById('intelOverlay').classList.remove('open');
document.getElementById('intelOverlay').onclick = function(e) {
if (e.target === this) this.classList.remove('open');
};
// ── sql console ──────────────────────────────────────────────────────────── // ── sql console ────────────────────────────────────────────────────────────
async function runSql() { async function runSql() {
@ -899,18 +952,31 @@ const tabContents = {
sql: document.getElementById('tab-sql'), sql: document.getElementById('tab-sql'),
}; };
function switchTab(tab) {
if (!tabContents[tab]) tab = 'articles';
document.querySelectorAll('.tab-btn').forEach(b => {
b.classList.toggle('active', b.dataset.tab === tab);
});
Object.entries(tabContents).forEach(([k, el]) => {
el.style.display = k === tab ? '' : 'none';
});
location.hash = tab;
if (tab === 'events') loadEvents();
if (tab === 'stats') loadStats();
if (tab === 'intelligence') { intelOffset = 0; loadIntelligenceStats().then(ok => { if (ok) { loadIntelligenceCompanies(); loadIntelligence(); } }); }
}
document.querySelectorAll('.tab-btn').forEach(btn => { document.querySelectorAll('.tab-btn').forEach(btn => {
btn.onclick = () => { btn.onclick = () => switchTab(btn.dataset.tab);
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); });
btn.classList.add('active');
const tab = btn.dataset.tab; window.addEventListener('hashchange', () => {
Object.entries(tabContents).forEach(([k, el]) => { const tab = location.hash.replace('#', '');
el.style.display = k === tab ? '' : 'none'; switchTab(tab);
});
if (tab === 'events') loadEvents();
if (tab === 'stats') loadStats();
if (tab === 'intelligence') { intelOffset = 0; loadIntelligenceStats().then(ok => { if (ok) { loadIntelligenceCompanies(); loadIntelligence(); } }); }
};
}); });
// close overlays on backdrop click // close overlays on backdrop click
@ -923,9 +989,12 @@ document.getElementById('eventOverlay').onclick = function(e) {
// ── init ─────────────────────────────────────────────────────────────────── // ── init ───────────────────────────────────────────────────────────────────
loadStats(); const initialTab = location.hash.replace('#', '') || 'articles';
switchTab(initialTab);
loadSources(); loadSources();
loadArticles(); if (initialTab === 'articles') loadArticles();
loadStats();
</script> </script>
</body> </body>
</html> </html>

View file

@ -82,11 +82,53 @@ function seedCompanies(db) {
); );
const companies = [ const companies = [
{ name: "NVIDIA", ticker: "NVDA", aliases: ["Nvidia Corporation", "NVDA"] }, // semiconductors
{ name: "TSMC", ticker: "TSM", aliases: ["Taiwan Semiconductor", "Taiwan Semiconductor Manufacturing"] }, { name: "NVIDIA", ticker: "NVDA", aliases: ["Nvidia Corporation"] },
{ name: "ASML", ticker: "ASML", aliases: ["ASML Holding", "ASML Holdings"] }, { name: "TSMC", ticker: "TSM", aliases: ["Taiwan Semiconductor", "Taiwan Semiconductor Manufacturing Company"] },
{ name: "ASML", ticker: "ASML", aliases: ["ASML Holding"] },
{ name: "Intel", ticker: "INTC", aliases: ["Intel Corporation"] }, { name: "Intel", ticker: "INTC", aliases: ["Intel Corporation"] },
{ name: "AMD", ticker: "AMD", aliases: ["Advanced Micro Devices"] },
{ name: "Qualcomm", ticker: "QCOM", aliases: ["Qualcomm Incorporated"] },
{ name: "Broadcom", ticker: "AVGO", aliases: ["Broadcom Inc"] },
{ name: "Micron", ticker: "MU", aliases: ["Micron Technology"] },
{ name: "Texas Instruments", ticker: "TXN", aliases: ["TI"] },
{ name: "Applied Materials", ticker: "AMAT", aliases: ["Applied Materials Inc"] },
{ name: "Lam Research", ticker: "LRCX", aliases: ["Lam Research Corporation"] },
{ name: "KLA Corporation", ticker: "KLAC", aliases: ["KLA"] },
{ name: "Samsung", ticker: "005930.KS", aliases: ["Samsung Electronics", "Samsung Group"] }, { name: "Samsung", ticker: "005930.KS", aliases: ["Samsung Electronics", "Samsung Group"] },
{ name: "SK Hynix", ticker: "000660.KS", aliases: ["Hynix"] },
// big tech / cloud
{ name: "Microsoft", ticker: "MSFT", aliases: ["Microsoft Corporation"] },
{ name: "Apple", ticker: "AAPL", aliases: ["Apple Inc"] },
{ name: "Alphabet", ticker: "GOOGL", aliases: ["Google", "Google LLC", "DeepMind"] },
{ name: "Amazon", ticker: "AMZN", aliases: ["Amazon Web Services", "AWS"] },
{ name: "Meta", ticker: "META", aliases: ["Meta Platforms", "Facebook"] },
{ name: "Tesla", ticker: "TSLA", aliases: ["Tesla Inc", "Tesla Motors"] },
// AI / infrastructure
{ name: "OpenAI", ticker: "OPENAI", aliases: ["Open AI"] },
{ name: "Anthropic", ticker: "ANTHROPIC", aliases: [] },
{ name: "xAI", ticker: "XAI", aliases: ["x.AI"] },
{ name: "Palantir", ticker: "PLTR", aliases: ["Palantir Technologies"] },
{ name: "Super Micro Computer", ticker: "SMCI", aliases: ["Supermicro", "SMCI"] },
{ name: "Arista Networks", ticker: "ANET", aliases: ["Arista"] },
// networking / hardware
{ name: "Cisco", ticker: "CSCO", aliases: ["Cisco Systems"] },
{ name: "Marvell Technology", ticker: "MRVL", aliases: ["Marvell"] },
{ name: "Arm Holdings", ticker: "ARM", aliases: ["Arm", "ARM Ltd"] },
// enterprise software
{ name: "Oracle", ticker: "ORCL", aliases: ["Oracle Corporation"] },
{ name: "Salesforce", ticker: "CRM", aliases: ["Salesforce Inc"] },
{ name: "SAP", ticker: "SAP", aliases: ["SAP SE"] },
{ name: "ServiceNow", ticker: "NOW", aliases: [] },
// storage / infra
{ name: "Western Digital", ticker: "WDC", aliases: ["WD", "Western Digital Corporation"] },
{ name: "Seagate", ticker: "STX", aliases: ["Seagate Technology"] },
{ name: "Pure Storage", ticker: "PSTG", aliases: [] },
]; ];
for (const c of companies) { for (const c of companies) {