Roadmap P2: full-text grounding — open-access RAG with verbatim evidence - #37
Merged
Conversation
Implement the src/fulltext package end to end and add a fulltext pipeline stage between relevance scoring and clustering: - Resolver: metadata-first open-access PDF resolution (arXiv IDs from URLs/DOIs, OpenAlex OA locations already present in raw search metadata, CORE download URLs) with no extra API calls - CachingPDFDownloader: cached under data/fulltext with size and content-type guards - Parser: PyMuPDF extraction with heuristic section detection; the references section is truncated to keep bibliography noise out of retrieval - SectionAwareChunker: overlapping windows tagged with their section - InMemoryFulltextIndex: chunks embedded through the existing provider and searched by cosine similarity, with BM25 fallback when the embedding backend is unavailable - The stage retrieves query-relevant passages per paper into the fulltext_passages artifact, budgeted by the new fulltext config section; closed-access papers, failed downloads, or a missing pymupdf backend reduce coverage but never break the run - Registry now provisions the real downloader/index implementations - Add pymupdf to Pipfile and Pipfile.lock
Thread full-text passages through synthesis so claims carry checkable evidence: - PaperExtraction and PaperAnalysis gain an evidence field - Extraction prompts embed the retrieved passages and ask for short verbatim quotes; the extraction system prompt and schema include the new key, and heuristic extraction attaches trimmed passages directly - Synthesis stage and recovery path read the fulltext_passages artifact - Markdown reports render the quotes under each paper as 'Evidence (from full text)' blockquotes - Replace stub-era fulltext tests with tests of the implemented behavior; document the stage and register it in the docs navigation
…reference - .env.example gains the retrieval API keys added with the new providers (NCBI_API_KEY, CORE_API_KEY), provider enable toggles, console/setup controls (RA_CONSOLE_LOG_LEVEL, RA_SKIP_SETUP_CHECK), and the accuracy-stage switches (RA_SNOWBALL__*, RA_RERANK__*, RA_FULLTEXT__*) - RA_DEBUG is no longer active in the example file — copying it previously enabled debug mode for every new install - The stale Anthropic model example is replaced with a current model ID - The authoritative environment-variables reference gains the same additions, the updated stage-name list, and a table for the snowball/rerank/fulltext namespaces linking to the stage pages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements Phase 2 of the improvement roadmap — the largest single quality jump it identifies. The pipeline no longer reasons over abstracts alone: for the top relevance-filtered papers it resolves open-access PDFs, parses and chunks the full text, retrieves the query-relevant passages, and grounds synthesis in them. Reports now show verbatim evidence quotes under each paper, making claims checkable against sources.
The
src/fulltextpackage (previously interface stubs)CachingPDFDownloader— PDFs cached underdata/fulltext/keyed by paper ID, with size (15 MB default) and content-type guards.Abstract,Introduction,Methods, …); the references section is truncated so bibliography lines don't pollute retrieval.SectionAwareChunker— overlapping ~1400-char windows, each tagged with the section it came from.InMemoryFulltextIndex— chunks embedded through the existing embedding provider (reusing its disk cache) and searched by cosine similarity, with BM25 fallback when the embedding backend is unavailable — grounding works in every environment.The
fulltextpipeline stageRuns between relevance scoring and clustering, budgeted by a new
fulltextconfig section (papers attempted, PDF size cap, timeouts, chunk sizing, passages per paper). Query-relevant passages per paper land in thefulltext_passagesartifact. Best-effort throughout: closed-access papers, failed downloads, malformed PDFs, or a missingpymupdfreduce coverage but never break a run.Evidence in synthesis and reports
PaperExtractionandPaperAnalysisgain anevidencefield.Environment variable documentation
.env.exampleand the authoritative environment-variables reference now document everything the app reads: the new provider keys (NCBI_API_KEY,CORE_API_KEY), provider enable toggles, console/setup controls (RA_CONSOLE_LOG_LEVEL,RA_SKIP_SETUP_CHECK), and the accuracy-stage namespaces (RA_SNOWBALL__*,RA_RERANK__*,RA_FULLTEXT__*). Two hygiene fixes:RA_DEBUG=1is no longer active in the example (copying it previously enabled debug mode on every new install), and the stale Anthropic model example was replaced with a current model ID.Dependency
pymupdf(1.28.2) added to Pipfile and Pipfile.lock. The lock was updated with the package's PyPI hashes and re-synced via pipenv's own Pipfile-hash computation, andpipenv verifyconfirms it is up to date (fullpipenv lockcould not run in this environment because the pytorch-cpu index in the Pipfile sources is unreachable from it).Verification
pipenv run pytest tests/— 417 passed (19 new fulltext tests: resolver, a real PyMuPDF parse of a generated PDF with section detection and references truncation, chunker, BM25-fallback retrieval scoped per paper, stage artifact production, graceful-degradation paths, evidence in prompts/heuristics/rendering), 1 skipped — re-verified after mergingmain(Roadmap P1: implement PubMed, DBLP, and CORE providers #35)ruff check src tests setups— cleanscripts/check_docs_policy.py— passes (61 nav pages)pipenv verify— Pipfile.lock in sync