const hfFeedback = () => window.UIFeedback || {};
const $ = (id) => document.getElementById(id);
async function loadRegistry() {
try {
const [health, registry] = await Promise.all([
hfFeedback().fetchJSON?.('/api/hf/health', {}, 'HF health'),
hfFeedback().fetchJSON?.('/api/hf/registry?kind=models', {}, 'HF registry'),
]);
hfFeedback().setBadge?.(
$('hf-console-health'),
`HF ${health.status}`,
health.status === 'healthy' ? 'success' : health.status === 'degraded' ? 'warning' : 'danger',
);
$('hf-console-summary').textContent = `Models available: ${registry.items?.length || 0}`;
$('hf-console-models').innerHTML =
registry.items
?.map((model) => `
${model}Model`)
.join('') || 'No registry entries yet.';
} catch {
$('hf-console-models').innerHTML = 'Unable to load registry.';
hfFeedback().setBadge?.($('hf-console-health'), 'HF unavailable', 'warning');
}
}
async function runSentiment() {
const button = $('run-sentiment');
button.disabled = true;
const modelName = $('sentiment-model').value;
const texts = $('sentiment-texts').value
.split('\n')
.map((line) => line.trim())
.filter(Boolean);
hfFeedback().showLoading?.($('sentiment-results'), 'Running sentiment…');
try {
const payload = { model: modelName, texts };
const response = await hfFeedback().fetchJSON?.('/api/hf/models/sentiment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
$('sentiment-results').innerHTML =
response.results
?.map((entry) => `${entry.text}${JSON.stringify(entry.result, null, 2)} `)
.join('') || 'No sentiment data.
';
hfFeedback().toast?.('success', 'Sentiment complete', `${response.results?.length || 0} text(s)`);
} catch (err) {
$('sentiment-results').innerHTML = `${err.message}
`;
} finally {
button.disabled = false;
}
}
async function runForecast() {
const button = $('run-forecast');
button.disabled = true;
const series = $('forecast-series').value
.split(',')
.map((val) => val.trim())
.filter(Boolean);
const model = $('forecast-model').value;
const steps = parseInt($('forecast-steps').value, 10) || 3;
hfFeedback().showLoading?.($('forecast-results'), 'Requesting forecast…');
try {
const payload = { model, series, steps };
const response = await hfFeedback().fetchJSON?.('/api/hf/models/forecast', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
$('forecast-results').innerHTML = `${response.model}Predictions: ${response.predictions.join(', ')}
Volatility ${response.volatility} `;
hfFeedback().toast?.('success', 'Forecast ready', `${response.predictions.length} points`);
} catch (err) {
$('forecast-results').innerHTML = `${err.message}
`;
} finally {
button.disabled = false;
}
}
const datasetRoutes = {
'market-ohlcv': '/api/hf/datasets/market/ohlcv?symbol=BTC&interval=1h&limit=50',
'market-btc': '/api/hf/datasets/market/btc_technical?limit=60',
'news-semantic': '/api/hf/datasets/news/semantic?limit=10',
};
async function loadDataset(key) {
const route = datasetRoutes[key];
if (!route) return;
hfFeedback().showLoading?.($('dataset-output'), 'Loading dataset…');
try {
const data = await hfFeedback().fetchJSON?.(route, {}, 'HF dataset');
const items = data.items || data.data || [];
$('dataset-output').innerHTML =
items
.slice(0, 6)
.map((item) => `${JSON.stringify(item, null, 2)} `)
.join('') || 'Dataset returned no rows.
';
} catch (err) {
$('dataset-output').innerHTML = `${err.message}
`;
}
}
function wireDatasetButtons() {
document.querySelectorAll('[data-dataset]').forEach((button) => {
button.addEventListener('click', () => loadDataset(button.dataset.dataset));
});
}
function initHFConsole() {
loadRegistry();
$('run-sentiment').addEventListener('click', runSentiment);
$('run-forecast').addEventListener('click', runForecast);
wireDatasetButtons();
}
document.addEventListener('DOMContentLoaded', initHFConsole);