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:
2026-07-25 08:49:26 -07:00
parent 29bcb123fa
commit 51dceee224
60 changed files with 3207 additions and 107 deletions

View File

@@ -0,0 +1,105 @@
from __future__ import annotations
import tempfile
import unittest
from pathlib import Path
import numpy as np
from context_docs.models import PreparedDocument, SourceUpdate
from context_docs.search import HybridSearch
from context_docs.store import IndexStore
from .fakes import FakeEmbedder
def prepared(identifier: str, source: str, canonical: str, title: str, content: str, vector) -> PreparedDocument:
return PreparedDocument(
id=identifier,
configured_source=source,
resolved_source=source,
source_host="source.test",
canonical_url=canonical,
canonical_host=canonical.split("/")[2],
title=title,
description="",
heading_path=title,
content=content,
content_hash=__import__("hashlib").sha256(content.encode()).hexdigest(),
embedding=np.asarray(vector, dtype=np.float32),
)
def source_update(source: str, documents: list[PreparedDocument]) -> SourceUpdate:
return SourceUpdate(
configured_source=source,
resolved_source=source,
etag=None,
last_modified=None,
body_hash="body",
raw_body="# source",
parser_fingerprint="parser-v1",
embedding_fingerprint="fake-embedder-v1",
checked_at=1.0,
indexed_at=1.0,
stale_at=9999.0,
documents=documents,
)
class HybridSearchTest(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self) -> None:
self.tmp = tempfile.TemporaryDirectory()
self.store = IndexStore(Path(self.tmp.name) / "docs.sqlite3")
self.a = "https://a.test/llms.txt"
self.b = "https://b.test/llms.txt"
self.store.configure_sources([self.a, self.b])
duplicate = "Shared exact content."
self.store.replace_source(
source_update(
self.a,
[
prepared("exact", self.a, "https://rails.test/exact", "Environment", "IMMICH_IGNORE_MOUNT_CHECK_ERRORS identifier", [1, 0, 0, 0]),
prepared("duplicate-a", self.a, "https://docs.test/shared", "Shared", duplicate, [0, 1, 0, 0]),
],
)
)
self.store.replace_source(
source_update(
self.b,
[
prepared("persistence", self.b, "https://langgraph.test/persistence", "Persistence", "Durable checkpoint state", [0, 1, 0, 0]),
prepared("duplicate-b", self.b, "https://docs.test/shared-copy", "Shared copy", duplicate, [0, 1, 0, 0]),
],
)
)
self.search = HybridSearch(self.store, FakeEmbedder())
async def asyncTearDown(self) -> None:
self.store.close()
self.tmp.cleanup()
async def test_exact_identifier_is_ranked_first(self) -> None:
result = await self.search.search("IMMICH_IGNORE_MOUNT_CHECK_ERRORS", limit=5)
self.assertEqual("exact", result[0].id)
self.assertEqual(1, result[0].lexical_rank)
async def test_source_and_host_filters_apply_before_ranking(self) -> None:
by_source = await self.search.search("persistence", limit=5, sources=[self.b])
by_host = await self.search.search("identifier", limit=5, hosts=["rails.test"])
self.assertTrue(by_source)
self.assertTrue(all(item.configured_source == self.b for item in by_source))
self.assertEqual(["exact"], [item.id for item in by_host])
async def test_exact_duplicate_content_is_collapsed_with_alternates(self) -> None:
result = await self.search.search("Shared exact content", limit=10)
shared = [item for item in result if item.content_hash == __import__("hashlib").sha256("Shared exact content.".encode()).hexdigest()]
self.assertEqual(1, len(shared))
self.assertEqual(2, shared[0].duplicate_count)
self.assertEqual(1, len(shared[0].alternate_sources))
if __name__ == "__main__":
unittest.main()