fix(generation): resolve real source titles instead of "Untitled"#19
fix(generation): resolve real source titles instead of "Untitled"#19yuzushi-dev wants to merge 3 commits into
Conversation
_get_document_titles() extracted document_id from candidate.metadata, but Candidate stores it as a top-level field and vector search only puts "content" in metadata. So doc_ids came out empty, get_titles_by_ids() was never queried, and every source fell back to "Untitled" — even though the document_id on each source was correct (the a8bc306 fix only touched the cited_sources loop, not the title lookup). Read document_id from the top-level field (dict key for dict candidates), matching the cited_sources loop. Also fix the sibling _map_sources() path, which read both document_id and title from .metadata (yielding "unknown" / "Untitled") and never did a DB title lookup. Regression test in tests/unit/test_source_titles.py.
…Untitled") The a8bc306/d8f9e6db title fixes were undermined at runtime by two issues, so cited sources still rendered as "Untitled" intermittently: 1. _map_sources() (the path that feeds QueryResponse.sources) only read the title from candidate.metadata["document_title"]. Vector-search candidates never carry that key, so it always fell back to "Untitled". The sibling context-builder already resolved real titles via _get_document_titles() (a DB lookup) but that map never reached _map_sources. generate() now fetches the doc_titles map once and passes it in; _map_sources prefers it over metadata. This is the authoritative, deterministic title source. 2. The DB title lookup is RLS-gated on the documents table (FORCE RLS). get_db_session set app.current_tenant from get_current_tenant(), a contextvar set inside the auth BaseHTTPMiddleware that does not reliably propagate to endpoint dependencies. On pooled connections where it was empty, the lookup returned 0 rows -> empty titles. It now reads request.state.tenant_id (set deterministically by AuthenticationMiddleware), mirroring how permissions / group_ids / tenant_role are already sourced a few lines below. Verified on the prod mirror: same query x5 -> 0 "Untitled" (was flaky/all-Untitled). Regression test extended in tests/unit/test_source_titles.py.
|
Follow-up commit Two root causes fixed:
Verified on the mirror: same query ×5 → 0 Untitled (was flaky/all-Untitled). Regression test extended. |
The deps.py change (sourcing app.current_tenant from request.state.tenant_id instead of the get_current_tenant() contextvar) shipped with no test, despite touching shared infra used by every get_db_session call site. Add unit tests that drive the dependency with a mocked session and assert: - app.current_tenant is set from request.state.tenant_id (a contextvar returning a different value must NOT win); - when request.state has no tenant_id, it falls back to the contextvar (superset of prior behaviour, never worse).
|
Correction to the follow-up commit narrative ( Narrative fix: the earlier message framed the contextvar issue as "the propagation bug is resolved". That overstates it — this PR only fixes the RLS tenant GUC in Coverage: added |
Problema
Due feedback negativi in prod (2026-07-14) lamentavano fonti senza titolo (
"Untitled") e link "view document" rotto. Le fonti mostravanodocument_idcorretto ma titoloUntitled.Causa radice
_get_document_titles()estraevadocument_iddacandidate.metadata["document_id"], maCandidate(retrieval/domain/candidate.py) lo tiene come field top-level.document_id; il vector search Milvus popola.metadatacon solocontent(milvus.py:511). Risultato:doc_idssempre vuoto →get_titles_by_ids()mai interrogato → titolo sempre in fallback →"Untitled".Il
document_idnelle fonti restava corretto perché il loopcited_sources(fixa8bc3065) legge il field top-level; quel fix però non toccò_get_document_titles, lasciando il bug del titolo.Fix
_get_document_titles: leggedocument_iddal field top-level (chiave dict per i dict candidates), come già facited_sources. Oraget_titles_by_ids()risolve i filename reali da Postgres._map_sources(path non-stream): stesso difetto — leggevadocument_id/titleda.metadata(→"unknown"/"Untitled"). Corretto per coerenza.Test
tests/unit/test_source_titles.py— verifica chedocument_idtop-level raggiunga il lookup titoli. Fallisce sul codice pre-fix (lookup mai chiamato).Rischio
Nessuna perdita dati, nessun downtime. Solo
SELECTdi lettura già esistenti; nessuno schema change. Deploy = resyncmain+ restartapi/worker.