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);