Skip to content

2026.11.8

Latest

Choose a tag to compare

@github-actions github-actions released this 08 Nov 04:41
79128cb

2026-11-08

  • A model download that was interrupted, for example by reloading the page halfway, no longer stops every model from loading. wllama 3.8.1 checks every model in its cache before loading any, and throws on the first one that misses a file; before each load, MiniSearch now deletes the files of models whose download did not finish, so only that model downloads again.
  • The default system prompt's citation example is now a placeholder, [example.com](https://example.com/page), instead of a real YouTube video link that small models copied as if it were a source. On the benchmark's eleven core questions, over 110 answers from five small models, links to URLs that are not among the results fell from 12 to 7, the YouTube link disappeared, and the share of answers citing a result stayed level (48% before, 50% after). A saved prompt that is exactly the previous default moves to the new one; an edited prompt stays as it is.
  • Four models leave the Wllama catalog because they answer worse than LittleLamb 290M, the default for browsers without WebGPU and the catalog's quality floor: StableLM 2 Zephyr 1.6B, SmolLM 2 135M, Granite 4.0 350M and Pints 1.5B (16 to 25 points out of 84 on the benchmark, against 38 for LittleLamb). Granite 4.0 1B goes too: on WebGPU it writes only @ characters until it is stopped, though it answers well on the CPU. docs/wllama-model-evaluation.md now holds the scores of every catalog model and the rule that decided.
  • A browser whose saved settings point at a model that left the catalog switches to the default model on its next answer, and records the switch in the logs. Before, it failed to answer at all.
  • Browsers with WebGPU now start on their own default model, Gemma 3 4B, set with the new WLLAMA_DEFAULT_GPU_MODEL_ID; browsers without it keep LittleLamb 290M from WLLAMA_DEFAULT_MODEL_ID, which runs well on the CPU. Both only seed a profile that never saved settings. The GPU variable does not fall back to the CPU one, because .env.example sets that one and most deployments would otherwise hand GPUs the CPU model; a deployment that pinned WLLAMA_DEFAULT_MODEL_ID and wants the same model on GPUs should set both. Gemma 3 4B scored highest of twelve GPU candidates on the benchmark (docs/wllama-model-evaluation.md), with every point in two runs of fifteen questions in eleven languages, and on WebGPU it started answering in about 8 seconds.
  • Qwen 3.5 0.8B (533 MB) joins the Wllama catalog. On the benchmark's eleven core questions it scored 70 of 84 (one run), above larger models such as Qwen 3 1.7B (66) and Granite 4.2 3B (59), and on WebGPU it writes about 32 tokens per second. Like Qwen 3.5 4B it ignores reasoning_effort, so it thinks for the full 1024 tokens before most answers (about 33 seconds on an Apple M1 Max).
  • The README and the docs no longer give a number of models or a size range, so adding or removing a model does not leave them out of date.
  • Thinking models get a 1024-token reasoning budget instead of 256, because a chain of thought cut off that early degraded the answer. Every model is also asked for reasoning_effort: "low", which Granite 4.2 and Spark X2.6 honor by thinking less; the other templates ignore it. Five models that think by default had no budget at all and now get the same 1024 tokens: LittleLamb 290M, Qwen 3 0.6B, Qwen 3 1.7B, Polaris 4B and DeepSeek R1 Distill Qwen 1.5B. LittleLamb, the default for browsers without WebGPU, thought for up to 3,663 tokens on a single answer and sometimes never answered; with the budget it answered all 33 questions of three benchmark runs.

2026-11-05

  • Relative month and year words in a query are anchored to absolute ones before the search leaves the browser: "next month" reaches the engines as "December 2026" and "明年" as "2027年". The anchor is appended rather than substituted, so a query that already names a year keeps its own phrasing, and two anchors per query is the ceiling. The typed query still drives the prompt, the UI, and the history entry; only the copy sent to the search engines changes, and the search cache key changes with it. Anchors skip titles and phrases that are not dates ("明年今日", "登上月球", "the last year of college") and leave "recent" and "latest" alone, because recency is what the engines already rank for. Day words ("tomorrow", "明天") stay as typed: their anchor would be an ISO date, which pages rarely write, and many queries use them as names ("usa today"). Only English and Chinese phrases are recognized. shared/relativeDates.ts holds the rules and client/modules/textGeneration.ts applies them.
  • The page reader drops structural navigation before it extracts text: nav, aside, header, footer and form blocks go, and so does any block whose text is mostly links (60% or more, in blocks of 120 characters and up), judged innermost-first so a page-wide wrapper cannot take the article down with it. Inside an <article>, a <main> or a role="main" block, link density removes nothing, because a list of linked titles there is usually the answer itself. The page's title and h1/h2 words also join the passage score at 0.15 weight, so a page whose heading names the query breaks ties against its own navigation. On the sortiraparis December page the extracted text fell from 57,160 to 2,128 characters and the answering passage moved from 10th of 61 to 3rd of 8, which is what puts it inside a page's excerpt share. A link-list home page now contributes far less body text, and the reader accepts that trade: a thin excerpt beats one made of navigation links.
  • A result from the site the query names gets a bonus on its semantic score before the score filter: +0.5 when a query word equals the domain's label ("disney" and disney.com, subdomains included), +0.75 when the label is the query's own words joined ("disney plus" and disneyplus.com, "coca cola" and coca-cola.com). The bonus is added rather than multiplied because the reranker returns a raw logit that is usually negative, where a factor above one would demote the named site instead of promoting it. Substrings do not count (disneyfan.com gets nothing), filler words never match on their own (plus.com, news.com), and a query that names a year will not promote a page that states a different year, so a brand's recap of last year's event cannot displace fresher reporting; a page that states no year at all keeps the bonus, because relative-time queries are anchored to a year before they reach the search. A label that spells only the start of the query leaves words unused and gets nothing (tesla investor relations and teslainvestor.com), a label that starts with a filler word is skipped (the disney store and thedisney.com), a split label counts from four characters, and a trailing dot on the hostname changes nothing. The site's name comes from the public suffix list, private section included (the tldts package), so bbc.co.uk answers "bbc" and a tenant of a shared host such as someone.github.io answers its own name, not "github". The pinned top result is never boosted, so the score spread the client reads relevance tags from keeps its shape. The reranker still never sees the URL, and a result the search did not return cannot be added here: the boost reorders and re-selects what the pipeline already holds, which is enough to move a page into the six the model reads. server/authorityRanking.ts holds the rule and docs/reranking.md records it.
  • A text search that asks for an official page can now reach the official site even when the engine's results never included it, behind a new setting, SEARCH_OFFICIAL_LANE_ENABLED, which is off by default because it sends the engines a second request. When it is on, the query carries navigation intent (官网, 排片, 营业时间, official, hours, showtimes and the like, in Chinese and English only), and one of the returned results names a site, the server sends a second, site:-scoped query to SearXNG and merges up to three of its results, deduplicated by URL and kept to that registrable domain, behind the pinned first result: the ranking re-sorts only what follows the top result, so a page appended past that window would never be re-sorted at all. The domain has to come from the results themselves, by the same rule the score bonus uses, because guessing <token>.com from the query would turn a search box into a scanner; a query that names a brand whose official site is absent from every result gets no second query. The second query is one request with no retry, and its failures count toward neither the SearXNG circuit nor the engine health in /status, so it cannot slow down or degrade the searches users are waiting on. SearXNG still sees the extra request, so an engine that suspends the instance after a CAPTCHA does so for every search. It runs only when SearXNG served the search (never after the fallback), never uses the last five seconds of the search deadline, and is canceled at eight seconds; a failure only logs and is counted, so it can add results but never turn a served search into a 502. /status reports searches.officialLane (searches, resultsAdded, failures), and server/officialLane.ts holds the rule.