/** * The index page: the five questions, in the order they come up. * * The list is rendered from the shared registry in `tools.js` rather * than written out here — the same registry the five tools link each * other with. A landing page that lists the tools from its own copy is * the first place a rename goes stale, and it is the one page where a * dead link costs the most. */ import { ORDER, TOOLS, url } from './tools.js'; import { DIAGRAMS, ensureDiagramStyles } from './diagrams.js'; const $ = (id) => document.getElementById(id); ensureDiagramStyles(); const esc = (s) => String(s).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c])); /** What each step is for, in the words somebody arrives with. */ const SAYS = { search: 'Filter the Hub by what decides usability rather than by task and ' + 'licence: real size, how much of a pack is genuinely quantized, mixture ' + 'of experts or dense, and whether serving it needs a reasoning parser.', context: 'Weights fitting is not the same as the model running. The KV cache ' + 'grows with context, and how fast depends on an attention topology most ' + 'estimates assume rather than read. This gives you a starting ' + '--max-model-len.', parser: 'A model that thinks needs vLLM to split that thinking out of the ' + 'answer. Guess wrong in one direction and users see the thinking; wrong ' + 'in the other and the reply comes back empty with no error at all.', precision: 'A pack named 4-bit is never 4-bit throughout — embeddings, the ' + 'output head and the norms are usually kept whole. This says how much ' + 'was really compressed and, more usefully, what was not.', integrity: 'Quantization can drop or disable part of a model without ' + 'failing: the pack loads, serves, answers correctly, and something its ' + 'card promises is missing. This compares what it claims against what is ' + 'in it.', }; /** The question each step answers, phrased as the visitor would ask it. */ const ASKS = { search: 'Which model should I even try?', context: 'How much context can I actually serve?', parser: 'How do I run it correctly?', precision: 'What did this quantized pack really compress?', integrity: 'Is the pack what it claims to be?', }; function render(repo) { $('steps').innerHTML = ORDER.map((key) => { const t = TOOLS[key]; const href = url(key, repo); const label = repo && t.takes === 'repo' ? `open for ${repo}` : repo && t.takes === 'query' ? `search for ${repo}` : 'open'; // The diagram is drawn from a real measurement this toolkit // produced, never a shape picked to look right — see diagrams.js. const figure = DIAGRAMS[key] ? `
${DIAGRAMS[key]()}
` : ''; return `
  • ${esc(ASKS[key])} ${esc(t.title)}

    ${esc(SAYS[key])}

    ${esc(label)} →
    ${figure}
  • `; }).join(''); } // Every link re-renders as the box is typed in, so the page never offers // a link that carries a model the visitor has since changed. $('repo').addEventListener('input', () => render($('repo').value.trim())); $('form').addEventListener('submit', (e) => e.preventDefault()); document.querySelectorAll('[data-fill]').forEach((a) => a.addEventListener('click', (e) => { e.preventDefault(); $('repo').value = a.dataset.fill; render(a.dataset.fill); })); // A model can be handed to this page too, so a link into the toolkit // from anywhere lands with it already set. const params = new URLSearchParams(window.location.search); const initial = (params.get('repo') || '').trim(); if (initial) $('repo').value = initial; render(initial || null);