Overhaul docs retrieval and web search quality
Replace the abandoned llms-txt-mcp/Chroma docs backend with an in-repo MCP service: SQLite WAL + FTS5 + sentence-transformer embeddings, transactional source replacement, persisted state across restarts, singleflight refresh with conditional requests, hybrid lexical/semantic ranking with exact-duplicate collapse, source/host filters, and explicit-by-default content retrieval. Add docs_rebuild and a docs-rebuild CLI command. Add deterministic llms-full.txt snapshot generation for machine-local menus with hash-validated provenance manifests; lifecycle commands promote a local menu to its snapshot only when the manifest validates. Switch public source profiles to content-bearing llms-full.txt feeds. Improve web search: bounded provider fallback with per-attempt diagnostics and cancellation, an optional Brave Search API provider, strict SearXNG engine selection, capped link/media extraction, and a real engine=browser renderer that routes every request through the existing SSRF vetting while blocking WebSockets, non-GET traffic, and private destinations. Extend release checks with offline unit suites and isolated candidate container tests for both images.
This commit is contained in:
61
scripts/test-web-search-quality.mjs
Normal file
61
scripts/test-web-search-quality.mjs
Normal file
@@ -0,0 +1,61 @@
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import { boundFetchCollections } from "../docker/web-search/overrides/bounds.mjs";
|
||||
import {
|
||||
attemptProvider,
|
||||
classifyProviderError
|
||||
} from "../docker/web-search/overrides/diagnostics.mjs";
|
||||
|
||||
assert.deepEqual(classifyProviderError(new Error("HTTP 429 rate limit")), {
|
||||
category: "rate_limited",
|
||||
message: "HTTP 429 rate limit"
|
||||
});
|
||||
assert.equal(classifyProviderError(new Error("captcha challenge")).category, "blocked");
|
||||
|
||||
const unavailable = await attemptProvider({ name: "brave", configured: false }, "q", 3, "en");
|
||||
assert.equal(unavailable.diagnostic.status, "unavailable");
|
||||
assert.equal(unavailable.diagnostic.result_count, 0);
|
||||
|
||||
const empty = await attemptProvider({
|
||||
name: "empty",
|
||||
async search() { return []; }
|
||||
}, "q", 3, "en");
|
||||
assert.equal(empty.diagnostic.status, "empty");
|
||||
|
||||
const failed = await attemptProvider({
|
||||
name: "failed",
|
||||
async search() { throw new Error("network socket failed"); }
|
||||
}, "q", 3, "en");
|
||||
assert.equal(failed.diagnostic.status, "error");
|
||||
assert.equal(failed.diagnostic.error.category, "network");
|
||||
|
||||
let underlyingAborted = false;
|
||||
const timedOut = await attemptProvider({
|
||||
name: "slow",
|
||||
async search(_query, _limit, _lang, signal) {
|
||||
await new Promise((resolve, reject) => {
|
||||
signal.addEventListener("abort", () => {
|
||||
underlyingAborted = true;
|
||||
reject(signal.reason);
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
}, "q", 3, "en", { timeoutMs: 20 });
|
||||
assert.equal(timedOut.diagnostic.error.category, "timeout");
|
||||
assert.equal(underlyingAborted, true);
|
||||
|
||||
const result = boundFetchCollections({
|
||||
links: Array.from({ length: 550 }, (_, index) => ({ url: `https://example.test/${index}` })),
|
||||
media: {
|
||||
images: Array.from({ length: 250 }, (_, index) => ({ url: `https://example.test/${index}.png` })),
|
||||
videos: [],
|
||||
audio: []
|
||||
},
|
||||
warnings: []
|
||||
});
|
||||
assert.equal(result.links.length, 500);
|
||||
assert.equal(result.media.images.length, 200);
|
||||
assert(result.warnings.some(warning => warning.includes("links truncated")));
|
||||
assert(result.warnings.some(warning => warning.includes("images truncated")));
|
||||
|
||||
console.log("pass web-search diagnostics and collection bounds tests");
|
||||
Reference in New Issue
Block a user