feat(web): add stack web ask - #98
Conversation
|
Both halves of the plan's verification gate, live against the local model (Qwen3.6-35B-A3B). A question the snippets answer — grounded, cited, 8 real sources: A question they don't — the important one. It refuses, says what the results do contain, and still lists them: 7.5s end to end, which fits inside a chat round trip behind the existing 👀 ack. Architecture note. The work runs inside the bot-runner via the framework's existing Harness: Tests: 53 framework web tests green. |
|
Design correction, pushed as I tried moving It silently broke the model. Hand-rolling the call lost That knob was verified against oMLX after The invariant it was serving is not defensible. The plan said "host-native where possible". But every page we read is attacker-controlled input going into an HTML or XML parser, and soon a browser. On the host that runs as the user who owns the machine, with their SSH keys and the family vault. We already run Docker; isolation is free. The host should run only the Apple Silicon inference that cannot be containerised without losing Metal. Two consequences now in the plan:
Tests: 98 framework web tests green. |
Assessment of stealth fetching, extraction, search backends, standards and licence constraints behind the web plan. Corrects the plan's stated constraint. Image size is cheap and the stacklet is opt-in, so a larger image for a better fetcher is an acceptable trade. The binding constraint is resident memory, since a browser held warm competes with photo thumbnailing and OCR. The phase 4 gate is now a memory measurement rather than a disk budget. Scrapling no longer bundles Camoufox, so the fallback the plan named does not exist.
stack web ask searches, reads the top result snippets, and answers in a few sentences with a numbered source list. The sources are printed whether or not an answer was found. When the results do not cover the question, the answer says so and still lists what was consulted rather than presenting something unsupported. One search and one model call, with no page fetching and no tool loop. Refs docs/design/web/plan.md (phase 3).
Replaces the plan's "host-native where possible" rule. Pages are attacker-controlled input passed to an HTML or XML parser, and later to a browser. On the host a parser fault runs with the machine owner's privileges. The host should run only the Apple Silicon inference that cannot be containerised without losing Metal. Two consequences are recorded. Containers remove the arm64-only constraint, since Docker runs linux/amd64 images on this hardware, so candidates are judged on measured latency rather than wheel availability. And stack web fetch does not yet satisfy this rule. Also documents why stack web ask runs in the bot-runner.
The survey was written treating x86-only projects as disqualified, and rejected candidates on that basis. Since these components run in containers and Docker runs linux/amd64 on this hardware, that rule was too strict. Emulation is a cost to measure rather than a barrier: significant for a browser, negligible for a CPU-bound library. Candidates dismissed only for missing arm64 wheels are marked for re-assessment.
Re-assessed after the arm64 constraint was relaxed, and rejected. The project has a single contributor, has been inactive since April, remains at v0.1.1, and the benchmark it leads is published by its own author. It would also improve extraction where current results are already adequate. The one known extraction failure was a recipe with missing quantities, which structured data resolves; the remaining failures are sites declining to serve content, which no extractor addresses. Names magic-html as the cheaper candidate should extraction quality become a measured problem.
Sources often report several related figures under one loosely worded question, for different periods and under different definitions. Selecting one and labelling it with the questioner's term produces an answer that is wrong but well sourced. The prompt now takes the measure's name from the source rather than restating the question, reports both figures when the sources separate what the question conflates, and states the period each covers. It is also given the current date, and asked to answer in the language of the question.
Extraction requires trafilatura, which the host does not provide. A missing extractor and a page with no article body were indistinguishable, so the command reported pages as empty without having read them. Fetch now runs where the archivist runs, giving the CLI the same code and the same library versions as production. A missing extractor raises ExtractorUnavailable instead of resolving to a verdict about the page, and trafilatura is pinned to one minor line in both the container and the test environment, which had been resolving different versions.
Search-result and round-up pages carry no article body, so extraction returned almost nothing and the capture was rejected as empty. These pages publish their entries as schema.org ItemList markup. Tier 1 now renders that list as the entry, one line per item with its link. Readers are tried in priority order across the whole document so a breadcrumb trail cannot outrank the page's actual subject, and lists shorter than four entries are declined as probable breadcrumbs.
89d3ea5 to
a721c7e
Compare
87eda3a to
52270d1
Compare
stack web search names the command to run when the web stacklet is down; stack web ask reported the same condition as an open question. Both now give the same instruction.
SearXNG keeps no index and no state, so the declared data directory was never created. Removing it means teardown has nothing to clean up. The hints still told users that stack web fetch works with nothing running, which stopped being true when it moved into the bot-runner. It does not need this stacklet; it does need core.
Stacked on #97. Phase 3 of
docs/design/web/plan.md.stack web ask "does immich support raw files"searches, reads the top snippets, and answers in a few sentences with a numbered source list. One search, one model call, no page fetching and no tool loop.The sources print whether or not an answer was found, so a refusal is still useful.
Also carries the landscape survey (
docs/design/web/landscape.md) and the correction that the fetcher's constraint is resident memory, not image size.