Skip to content

Instantly share code, notes, and snippets.

@maly
Created June 13, 2026 10:48
Show Gist options
  • Select an option

  • Save maly/c9a1f3d4b7ca91f32c75dfb9ba57bbcf to your computer and use it in GitHub Desktop.

Select an option

Save maly/c9a1f3d4b7ca91f32c75dfb9ba57bbcf to your computer and use it in GitHub Desktop.
Ollama Model Filter

Ollama Model Filter – Installation and Usage Guide

A bookmarklet is a small JavaScript program stored as a regular browser bookmark. After opening the model search page, click the bookmark to display the filtering panel.

1. Show the bookmarks bar

If the bookmarks bar is hidden:

  • Chrome / Edge / Brave: press Ctrl+Shift+B
  • Firefox: press Ctrl+Shift+B
  • macOS: use Cmd instead of Ctrl

2. Create the bookmarklet

  1. Right-click the bookmarks bar.

  2. Select Add page, Add bookmark, or a similar option.

  3. Enter a name, for example:

    Ollama Filter
    
  4. Open the file ollama-filter-bookmarklet.txt.

  5. Copy its entire contents. It starts with:

    javascript:
    
  6. Paste the copied code into the bookmark’s URL, Address, or Location field.

  7. Save the bookmark.

Important: the code must be pasted into the bookmark address field, not into its name.

3. Use the filter

  1. Open:

    https://ollama.com/search
    
  2. Click the Ollama Filter bookmark.

  3. A control panel will appear on the page.

  4. Set:

    • the maximum model size, for example 12b,
    • whether to show all models, cloud-only models, or local-only models,
    • whether models without a size tag should remain visible.
  5. The model list is filtered immediately.

A model passes the size filter if it has at least one available variant that does not exceed the selected limit.

Tags such as e2b and e4b are treated as effective sizes of 2B and 4B.

4. Disable the filter

You can remove the filter in any of these ways:

  • click the close button in the filter panel,
  • run the bookmarklet again,
  • reload the page with F5 or Ctrl+R.

Troubleshooting

Nothing happens after clicking the bookmark

Check that the bookmark URL really starts with:

javascript:

Some browsers may remove this prefix when pasting. If that happens, add it manually.

The browser performs a search instead of running the filter

The code was probably pasted into the browser address bar instead of the saved bookmark’s URL field.

The filter disappears after changing or reloading the page

This is expected. The bookmarklet modifies only the currently open page. After reloading or reopening the page, run the bookmarklet again.

Security note

A bookmarklet runs JavaScript in the context of the currently open page. Use only code from a source you trust. This bookmarklet only reads model tags on the page and hides or shows model cards.

Ollama Model Filter – návod k instalaci a použití

Bookmarklet je malý JavaScript uložený jako běžná záložka v prohlížeči. Po otevření stránky s modely stačí na tuto záložku kliknout a zobrazí se panel pro filtrování.

1. Zobrazení lišty záložek

Pokud lištu záložek nevidíte:

  • Chrome / Edge / Brave: stiskněte Ctrl+Shift+B
  • Firefox: stiskněte Ctrl+Shift+B
  • macOS: místo Ctrl použijte Cmd

2. Vytvoření bookmarkletu

  1. Vytvořte novou záložku:

    • klikněte pravým tlačítkem na lištu záložek,
    • zvolte Přidat stránku, Přidat záložku nebo podobnou volbu.
  2. Jako název zadejte například:

    Ollama filtr
    
  3. Otevřete soubor ollama-filter-bookmarklet.txt.

  4. Zkopírujte celý jeho obsah. Začíná textem:

    javascript:
    
  5. Zkopírovaný kód vložte do pole URL, Adresa nebo Umístění záložky.

  6. Záložku uložte.

Důležité: kód musí být vložen do pole adresy záložky, nikoli do jejího názvu.

3. Použití filtru

  1. Otevřete stránku:

    https://ollama.com/search
    
  2. Klikněte na záložku Ollama filtr.

  3. Na stránce se zobrazí ovládací panel.

  4. Nastavte:

    • maximální velikost modelu, například 12b,
    • zda chcete zobrazit všechny modely, pouze cloudové nebo pouze lokální,
    • zda mají zůstat zobrazené modely bez uvedené velikosti.
  5. Seznam modelů se filtruje okamžitě.

Model projde velikostním filtrem, pokud má alespoň jednu dostupnou variantu, která nepřekračuje nastavený limit.

Tagy jako e2b a e4b se vyhodnocují jako efektivní velikost 2B a 4B.

4. Vypnutí filtru

Filtr odstraníte jedním z těchto způsobů:

  • kliknutím na zavírací tlačítko v panelu,
  • opětovným spuštěním bookmarkletu,
  • obnovením stránky pomocí F5 nebo Ctrl+R.

Řešení problémů

Po kliknutí se nic nestane

Zkontrolujte, zda obsah pole URL skutečně začíná:

javascript:

Některé prohlížeče při kopírování tento začátek odstraní. V takovém případě jej doplňte ručně.

Otevře se vyhledávání místo spuštění filtru

Kód byl pravděpodobně vložen do adresního řádku prohlížeče místo do URL uložené záložky.

Filtr po změně stránky zmizel

To je normální. Bookmarklet upravuje pouze právě otevřenou stránku. Po jejím obnovení nebo novém otevření je nutné záložku spustit znovu.

Bezpečnostní poznámka

Bookmarklet spouští JavaScript v kontextu otevřené stránky. Používejte pouze kód, jehož původ znáte. Tento bookmarklet pouze čte tagy modelů na stránce a skrývá nebo zobrazuje jejich karty.

javascript:(()=>{const e="ollama-model-filter",t="__ollamaModelFilterObserver",n=()=>{document.querySelectorAll("[data-omf-original-display]").forEach(e=>{e.style.display=e.dataset.omfOriginalDisplay,delete e.dataset.omfOriginalDisplay}),window[t]?.disconnect(),delete window[t],document.getElementById(e)?.remove()};if(document.getElementById(e))return void n();const a=document.createElement("div");a.id=e,a.innerHTML='\n <div style="display:flex;align-items:center;gap:10px;margin-bottom:9px">\n <strong style="font-size:14px">Ollama filter</strong>\n <span data-count style="margin-left:auto;color:#888"></span>\n <button data-close title="Zavřít a obnovit seznam" style="border:0;background:none;color:inherit;font-size:18px;cursor:pointer;padding:0 2px">×</button>\n </div>\n <label style="display:flex;align-items:center;gap:8px;margin:6px 0">\n <span style="width:72px">Max. B</span>\n <input data-max type="number" min="0" step="0.1" placeholder="bez limitu" style="width:110px;padding:4px 6px;border:1px solid #888;border-radius:5px;background:inherit;color:inherit">\n </label>\n <label style="display:flex;align-items:center;gap:8px;margin:6px 0">\n <span style="width:72px">Cloud</span>\n <select data-cloud style="width:124px;padding:4px 6px;border:1px solid #888;border-radius:5px;background:inherit;color:inherit">\n <option value="all">všechny</option>\n <option value="yes">jen cloud</option>\n <option value="no">bez cloud</option>\n </select>\n </label>\n <label style="display:flex;align-items:center;gap:7px;margin-top:8px">\n <input data-unknown type="checkbox">\n ponechat modely bez B tagu\n </label>',Object.assign(a.style,{position:"fixed",top:"16px",right:"16px",zIndex:"2147483647",width:"245px",padding:"12px 14px",border:"1px solid #777",borderRadius:"9px",background:"Canvas",color:"CanvasText",boxShadow:"0 6px 24px rgba(0,0,0,.25)",font:"13px system-ui,sans-serif"}),document.body.append(a);const l=a.querySelector("[data-max]"),o=a.querySelector("[data-cloud]"),i=a.querySelector("[data-unknown]"),r=a.querySelector("[data-count]"),s=()=>{const e=Number.parseFloat(l.value),t=Number.isFinite(e),n=o.value;let a=0,s=0;(()=>{const e=[...document.querySelectorAll("li")].filter(e=>{const t=e.innerText||"";return/\bPulls\b/.test(t)&&/\bTags?\b/.test(t)&&/\bUpdated\b/.test(t)});return e.length?e:[...new Set([...document.querySelectorAll('a[href^="/library/"]')].map(e=>e.closest("li")||e))]})().forEach(l=>{s+=1,"omfOriginalDisplay"in l.dataset||(l.dataset.omfOriginalDisplay=l.style.display||"");const{cloud:o,sizes:r}=(e=>{const t=[...e.querySelectorAll("*")].map(e=>(e.textContent||"").trim().toLowerCase()).filter(e=>e.length<=16),n=[...new Set(t.map(e=>e.match(/^e?(\d+(?:\.\d+)?)b$/)).filter(Boolean).map(e=>Number(e[1])).filter(Number.isFinite))];return{cloud:t.includes("cloud"),sizes:n}})(l),d="all"===n||("yes"===n?o:!o),p=!t||r.some(t=>t<=e)||i.checked&&0===r.length,c=d&&p;l.style.display=c?l.dataset.omfOriginalDisplay:"none",c&&(a+=1)}),r.textContent=`${a}/${s}`};a.addEventListener("input",s),a.addEventListener("change",s),a.querySelector("[data-close]").addEventListener("click",n);let d=!1;window[t]=new MutationObserver(e=>{e.some(e=>!a.contains(e.target))&&(d||(d=!0,requestAnimationFrame(()=>{d=!1,s()})))}),window[t].observe(document.body,{childList:!0,subtree:!0}),s()})();
(() => {
const ID = 'ollama-model-filter';
const OBSERVER_KEY = '__ollamaModelFilterObserver';
const restore = () => {
document.querySelectorAll('[data-omf-original-display]').forEach((card) => {
card.style.display = card.dataset.omfOriginalDisplay;
delete card.dataset.omfOriginalDisplay;
});
window[OBSERVER_KEY]?.disconnect();
delete window[OBSERVER_KEY];
document.getElementById(ID)?.remove();
};
if (document.getElementById(ID)) {
restore();
return;
}
const getCards = () => {
const cards = [...document.querySelectorAll('li')].filter((el) => {
const text = el.innerText || '';
return /\bPulls\b/.test(text) && /\bTags?\b/.test(text) && /\bUpdated\b/.test(text);
});
if (cards.length) return cards;
return [...new Set(
[...document.querySelectorAll('a[href^="/library/"]')]
.map((a) => a.closest('li') || a)
)];
};
const getTags = (card) => {
const exactTexts = [...card.querySelectorAll('*')]
.map((el) => (el.textContent || '').trim().toLowerCase())
.filter((text) => text.length <= 16);
const sizes = [...new Set(exactTexts
.map((text) => text.match(/^e?(\d+(?:\.\d+)?)b$/))
.filter(Boolean)
.map((match) => Number(match[1]))
.filter(Number.isFinite))];
return {
cloud: exactTexts.includes('cloud'),
sizes,
};
};
const panel = document.createElement('div');
panel.id = ID;
panel.innerHTML = `
<div style="display:flex;align-items:center;gap:10px;margin-bottom:9px">
<strong style="font-size:14px">Ollama filter</strong>
<span data-count style="margin-left:auto;color:#888"></span>
<button data-close title="Zavřít a obnovit seznam" style="border:0;background:none;color:inherit;font-size:18px;cursor:pointer;padding:0 2px">×</button>
</div>
<label style="display:flex;align-items:center;gap:8px;margin:6px 0">
<span style="width:72px">Max. B</span>
<input data-max type="number" min="0" step="0.1" placeholder="bez limitu" style="width:110px;padding:4px 6px;border:1px solid #888;border-radius:5px;background:inherit;color:inherit">
</label>
<label style="display:flex;align-items:center;gap:8px;margin:6px 0">
<span style="width:72px">Cloud</span>
<select data-cloud style="width:124px;padding:4px 6px;border:1px solid #888;border-radius:5px;background:inherit;color:inherit">
<option value="all">všechny</option>
<option value="yes">jen cloud</option>
<option value="no">bez cloud</option>
</select>
</label>
<label style="display:flex;align-items:center;gap:7px;margin-top:8px">
<input data-unknown type="checkbox">
ponechat modely bez B tagu
</label>`;
Object.assign(panel.style, {
position: 'fixed',
top: '16px',
right: '16px',
zIndex: '2147483647',
width: '245px',
padding: '12px 14px',
border: '1px solid #777',
borderRadius: '9px',
background: 'Canvas',
color: 'CanvasText',
boxShadow: '0 6px 24px rgba(0,0,0,.25)',
font: '13px system-ui,sans-serif',
});
document.body.append(panel);
const maxInput = panel.querySelector('[data-max]');
const cloudSelect = panel.querySelector('[data-cloud]');
const unknownInput = panel.querySelector('[data-unknown]');
const count = panel.querySelector('[data-count]');
const apply = () => {
const max = Number.parseFloat(maxInput.value);
const hasMax = Number.isFinite(max);
const cloudMode = cloudSelect.value;
let visible = 0;
let total = 0;
getCards().forEach((card) => {
total += 1;
if (!('omfOriginalDisplay' in card.dataset)) {
card.dataset.omfOriginalDisplay = card.style.display || '';
}
const { cloud, sizes } = getTags(card);
const cloudOK = cloudMode === 'all' || (cloudMode === 'yes' ? cloud : !cloud);
const sizeOK = !hasMax || sizes.some((size) => size <= max) || (unknownInput.checked && sizes.length === 0);
const show = cloudOK && sizeOK;
card.style.display = show ? card.dataset.omfOriginalDisplay : 'none';
if (show) visible += 1;
});
count.textContent = `${visible}/${total}`;
};
panel.addEventListener('input', apply);
panel.addEventListener('change', apply);
panel.querySelector('[data-close]').addEventListener('click', restore);
let scheduled = false;
window[OBSERVER_KEY] = new MutationObserver((mutations) => {
if (!mutations.some((mutation) => !panel.contains(mutation.target))) return;
if (scheduled) return;
scheduled = true;
requestAnimationFrame(() => {
scheduled = false;
apply();
});
});
window[OBSERVER_KEY].observe(document.body, { childList: true, subtree: true });
apply();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment