A browser assistant has useful context close at hand: the page a person is already reading. WebLMS explores that proximity through a TypeScript extension, DOM extraction, OCR, local caching, and extractive question answering.
The public implementation is more specific than “AI chat over a web page.” It is a sequence of boundaries, and each boundary affects the answer.
Extract the page deliberately
The DOM parser uses a TreeWalker to collect text while rejecting scripts, styles, and hidden elements. Separate methods gather viewport-adjacent text, page metadata, and table rows. The intent is to preserve useful reading material without treating every element as equally relevant.
Images follow another path. A Comlink-exposed worker wraps Tesseract.js and returns recognized text with OCR confidence. That confidence describes recognition, not whether the extracted text answers the user's question.
IndexedDB stores page-context and model-related cache records. Caching can avoid repeating work, but a page URL is not a promise that its content never changes. Refresh behavior remains part of the product's correctness.
Describe the answer engine accurately
QAEngine classifies a question as summarization, extraction, specific, or general. It then uses sentence-scoring and selection routines to build the answer from the available context.
That is an extractive implementation. The model loader contains an ONNX integration placeholder, while the worker currently signals the main engine rather than running a downloaded generative model. Calling it a fully local LLM would describe an aspiration rather than the code.
This distinction helps explain both the strengths and the limits. Extractive answers can point directly to useful page sentences. They can also miss a question that requires a deeper synthesis than the current heuristics provide.
Make privacy claims fit the boundary
The privacy monitor wraps fetch and XMLHttpRequest in its execution context. It allows extension and blob URLs and local hosts, while rejecting other absolute hosts. That is an implemented request check, not proof of an extension-wide sandbox.
I want a project's description to preserve that distinction. The strongest engineering story is the one a reader can inspect: where the text comes from, how OCR runs, what is cached, how sentences are selected, and what the current privacy mechanism actually covers.
Read WebLMS's engineering notes or inspect the Q&A engine.