feat: settings model selector for news summarizer
This commit is contained in:
parent
d93ad88956
commit
610666ef6a
1 changed files with 76 additions and 3 deletions
|
|
@ -979,6 +979,30 @@
|
|||
</div>
|
||||
<div class="set-saved" id="mkt-saved"></div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h3>News Summarizer</h3>
|
||||
<p class="set-note" style="margin-bottom:0.9rem">Takes effect on the next hourly run (:05). No container restart.</p>
|
||||
<div class="set-row">
|
||||
<label>Provider</label>
|
||||
<span>Nous Portal (inference-api.nousresearch.com)</span>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<label>API key</label>
|
||||
<span>set in API Keys as NOUS_API_KEY (never shown here)</span>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<label for="set-summary-model">Model</label>
|
||||
<select id="set-summary-model"></select>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<label>Current</label>
|
||||
<span id="set-summary-model-now">—</span>
|
||||
</div>
|
||||
<div class="set-actions">
|
||||
<button class="btn" onclick="saveSummaryModel()">Save model</button>
|
||||
</div>
|
||||
<div class="set-saved" id="sum-saved"></div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h3>Map Defaults</h3>
|
||||
<p class="set-note" style="margin-bottom:0.9rem">Applied to the live map on load.</p>
|
||||
|
|
@ -1025,7 +1049,7 @@
|
|||
<div class="sys-row"><span class="k">Active sources</span><span class="v" id="sys-sources">—</span></div>
|
||||
<div class="sys-row"><span class="k">Open alerts</span><span class="v" id="sys-alerts">—</span></div>
|
||||
<div class="sys-row"><span class="k">Tracked entities</span><span class="v" id="sys-entities">—</span></div>
|
||||
<div class="sys-row"><span class="k">News cycle</span><span class="v">15 min</span></div>
|
||||
<div class="sys-row"><span class="k">News cycle</span><span class="v">hourly :05</span></div>
|
||||
<div class="sys-row"><span class="k">Market feed</span><span class="v" id="sys-market">STANDBY</span></div>
|
||||
</div>
|
||||
<div class="set-actions">
|
||||
|
|
@ -1051,7 +1075,7 @@
|
|||
<div class="tick-wrap">
|
||||
<div class="tick-track" id="nt-track"></div>
|
||||
</div>
|
||||
<div class="tick-tag" id="nt-tag">15-MIN CYCLE</div>
|
||||
<div class="tick-tag" id="nt-tag">HOURLY</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
|
@ -1181,7 +1205,7 @@ function showView(name) {
|
|||
}
|
||||
if (name === 'news') loadNews(false);
|
||||
if (name === 'events') { loadSummary(); loadEvents(); }
|
||||
if (name === 'settings') { loadSummary(); renderSysInfo(); }
|
||||
if (name === 'settings') { loadSummary(); renderSysInfo(); loadSettings(); }
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
|
|
@ -1657,6 +1681,55 @@ function initSettings() {
|
|||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
async function loadSettings() {
|
||||
const sel = document.getElementById('set-summary-model');
|
||||
const now = document.getElementById('set-summary-model-now');
|
||||
try {
|
||||
const [setR, modR] = await Promise.all([
|
||||
fetch(`${API}/api/settings`),
|
||||
fetch(`${API}/api/news/models`),
|
||||
]);
|
||||
const settings = setR.ok ? await setR.json() : {};
|
||||
const catalog = modR.ok ? await modR.json() : {models: []};
|
||||
const saved = (settings.summary_model || '').trim();
|
||||
const ids = (catalog.models || []).map(m => m && m.id).filter(Boolean);
|
||||
if (saved && ids.indexOf(saved) === -1) ids.unshift(saved);
|
||||
if (sel) {
|
||||
sel.innerHTML = ids.map(id => `<option value="${esc(id)}">${esc(id)}</option>`).join('');
|
||||
if (saved) sel.value = saved;
|
||||
}
|
||||
if (now) now.textContent = saved || '—';
|
||||
} catch (e) {
|
||||
console.error('Settings load failed', e);
|
||||
}
|
||||
}
|
||||
async function saveSummaryModel() {
|
||||
const sel = document.getElementById('set-summary-model');
|
||||
const flash = document.getElementById('sum-saved');
|
||||
const now = document.getElementById('set-summary-model-now');
|
||||
const summary_model = ((sel && sel.value) || '').trim();
|
||||
if (!summary_model) {
|
||||
if (flash) flash.textContent = 'Choose a model to save.';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const r = await fetch(`${API}/api/settings`, {
|
||||
method: 'PUT',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({summary_model}),
|
||||
});
|
||||
const d = await r.json().catch(() => ({}));
|
||||
if (!r.ok) {
|
||||
if (flash) flash.textContent = (typeof d.detail === 'string' ? d.detail : 'Save failed');
|
||||
return;
|
||||
}
|
||||
if (now) now.textContent = d.summary_model || summary_model;
|
||||
if (sel && d.summary_model) sel.value = d.summary_model;
|
||||
if (flash) flash.textContent = 'Model saved.';
|
||||
} catch (e) {
|
||||
if (flash) flash.textContent = 'Network error.';
|
||||
}
|
||||
}
|
||||
|
||||
/* ═══════════════ MAP (NASA GIBS basemap + FIRMS + cameras + blips) ═══════
|
||||
The satellite map core is production-proven — preserved verbatim. */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue