Skip to content

Feat/phase 14 nemo retriever#15

Merged
DanielDeshmukh merged 4 commits into
mainfrom
feat/phase-14-nemo-retriever
Jun 28, 2026
Merged

Feat/phase 14 nemo retriever#15
DanielDeshmukh merged 4 commits into
mainfrom
feat/phase-14-nemo-retriever

Conversation

@DanielDeshmukh

@DanielDeshmukh DanielDeshmukh commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added support for NeMo Retriever-powered document OCR, embeddings, and reranking.
    • Document processing can now extract text from PDFs with smarter page handling and chunking.
    • Diagnostics now include a new check for NeMo Retriever availability.
  • Bug Fixes

    • Improved OCR fallback behavior so document processing can continue even when NeMo Retriever is unavailable.
    • Added safer handling for unavailable services and timeout scenarios.

…essing

Implement core/nemo_retriever.py wrapping NVIDIA's NeMo Retriever
capabilities into a single interface for HECTOR's ingestion pipeline.

NemoRetrieverProvider provides:
- OCR processing via Nemotron OCR API (nvidia/nemotron-ocr-v1)
  * ocr_page(): process raw image bytes to text
  * ocr_page_from_pdf(): render PDF page then OCR
  * Returns NemoOCRResult with text, markdown, confidence, timing
- Embedding generation via Nemotron embedding API
  * embed_documents(): batch embed document chunks (2048d)
  * embed_query(): single query embedding for search
- Reranking via Nemotron reranker API
  * rerank(): score and sort documents by query relevance
  * Returns NemoRerankResult with index, score, text, reasons
- Full document processing pipeline
  * process_document(): OCR → chunk → embed in one call
  * Intelligent chunking with sentence boundary detection
  * Automatic fallback from pypdf extraction to OCR

Data classes:
- NemoOCRResult: OCR output with confidence and timing
- NemoChunk: processed document chunk with metadata and embedding
- NemoRerankResult: reranked document with score and reasons

Factory function:
- get_nemo_retriever(): creates provider if HECTOR_NEMO_RETRIEVER_ENABLED=1
  * Checks NVIDIA_API_KEY availability
  * Performs health check before returning
  * Returns None if not enabled or unreachable

Env vars:
- HECTOR_NEMO_RETRIEVER_ENABLED: '1' to enable (default: '0')
- NVIDIA_API_KEY: Required for all NeMo operations
- HECTOR_NEMO_OCR_MODEL: OCR model override
- HECTOR_NEMO_EMBED_MODEL: Embedding model override
- HECTOR_NEMO_RERANK_MODEL: Rerank model override
Update utils/enhanced_ingestor.py to use NemoRetrieverProvider when
HECTOR_NEMO_RETRIEVER_ENABLED=1 and NVIDIA_API_KEY is set.

Changes:
- __init__(): initialize nemo_retriever via get_nemo_retriever()
  * Stores as self.nemo_retriever for use in OCR fallback
  * Logs availability status for debugging

- _nvidia_ocr_fallback(): try NeMo Retriever first
  * If nemo_retriever.is_available, use ocr_page_from_pdf()
  * Falls back to legacy direct API call on failure
  * Maintains backward compatibility when NeMo is disabled

The integration is opt-in and transparent:
- Default behavior unchanged (HECTOR_NEMO_RETRIEVER_ENABLED=0)
- When enabled, uses NeMo for OCR with automatic fallback
- Legacy OCR path preserved for environments without NeMo access

Env vars:
- HECTOR_NEMO_RETRIEVER_ENABLED: '1' to enable (default: '0')
- NVIDIA_API_KEY: Required for NeMo operations
Tests for the unified NemoRetriever provider covering all capabilities:

Data classes:
- NemoOCRResult: stores text, markdown, confidence, timing, model
- NemoChunk: stores text, metadata, optional embedding vector
- NemoRerankResult: stores index, score, text, reasons

Provider initialization:
- Default models (nemotron-ocr-v1, nemotron-embed-4b-v1, rerank-1b-v2)
- Custom model override via constructor arguments
- Environment variable configuration (NVIDIA_API_KEY, HECTOR_NEMO_*)

Health check:
- Returns False without API key
- Returns True on 200/401/405 responses
- Returns False on timeout/exception
- Result is cached after first call

OCR processing:
- Raises ValueError without API key
- Returns NemoOCRResult with text and confidence on success
- Propagates API errors

Embedding:
- Raises ValueError without API key
- Single document returns 2048-dimensional vector
- Batch embedding returns correct count
- Query embedding returns single vector

Reranking:
- Raises ValueError without API key
- Empty document list returns empty result
- Returns sorted NemoRerankResult list with scores

Document pipeline:
- Short text returns single chunk
- Empty/whitespace text returns empty list
- Long text produces multiple non-empty chunks

Factory:
- Returns None when disabled (default)
- Returns provider when enabled with valid API
- Returns None without API key
- Returns None when API unreachable

Integration:
- Source code verification for ingestor integration

All tests use explicit api_key=None + manual assignment to avoid
env var leakage from concurrent test execution (966 tests total).
Update utils/diagnostics.py to include a 4th diagnostic test for
the unified NeMo Retriever provider.

Changes:
- test_nemo_retriever(): new diagnostic method [4/4]
  * Imports get_nemo_retriever from core.nemo_retriever
  * Checks if HECTOR_NEMO_RETRIEVER_ENABLED=1
  * If enabled, verifies API reachability via is_available
  * Reports SKIPPED/SUCCESS/FAILED status
- Updated test counters from [1/3]-[3/3] to [1/4]-[4/4]
- Updated run_diagnostics() to include NeMo test in results

The NeMo Retriever test is non-blocking: returns True (pass) when
skipped, allowing the diagnostic suite to complete even when NeMo
is not configured.
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a2a26ef-cad3-4c0f-9e03-2cae90d81390

📥 Commits

Reviewing files that changed from the base of the PR and between d4ec3c8 and 5c5b3e4.

📒 Files selected for processing (4)
  • core/nemo_retriever.py
  • tests/test_nemo_retriever.py
  • utils/diagnostics.py
  • utils/enhanced_ingestor.py

📝 Walkthrough

Walkthrough

A new core/nemo_retriever.py module introduces NemoRetrieverProvider with OCR, embedding, reranking, and document processing capabilities backed by NVIDIA NeMo Retriever APIs. It is integrated into EnhancedHectorIngestor as a preferred OCR path and into HectorDiagnostics as a fourth test step. Unit tests cover all provider methods and factory logic.

Changes

NeMo Retriever Provider Integration

Layer / File(s) Summary
Data models, provider constructor, and health check
core/nemo_retriever.py
Defines NemoOCRResult, NemoChunk, NemoRerankResult dataclasses; implements NemoRetrieverProvider.__init__ loading API key and model names; adds lazy _check_available() health check against NVIDIA /chat/models exposed via is_available property.
OCR, embedding, and reranking methods
core/nemo_retriever.py
Implements ocr_page() and ocr_page_from_pdf() for image/PDF OCR with base64 encoding and timing; embed_documents() and embed_query() for batch and single-query embedding; rerank() converting document dicts to passages and parsing ranked NemoRerankResult entries.
Document processing pipeline and chunking
core/nemo_retriever.py
Adds process_document() for end-to-end PDF text extraction with OCR fallback for sparse pages, NemoChunk assembly with metadata, and batch embedding attachment; adds _chunk_text() for word-based overlapping chunking with sentence-boundary heuristics.
get_nemo_retriever factory
core/nemo_retriever.py
Adds get_nemo_retriever() gated on HECTOR_NEMO_RETRIEVER_ENABLED, NVIDIA_API_KEY presence, and provider health check; returns None when any condition fails.
EnhancedHectorIngestor integration
utils/enhanced_ingestor.py
Initializes self.nemo_retriever in __init__ via get_nemo_retriever(); prepends a NeMo-first OCR path in _nvidia_ocr_fallback that calls ocr_page_from_pdf() and returns markdown/text, falling back to legacy NVIDIA OCR on failure or unavailability.
Diagnostics
utils/diagnostics.py
Adds HectorDiagnostic.test_nemo_retriever() that dynamically imports and checks provider availability; includes it in run_diagnostics results list; updates 3-step progress labels to 4-step across existing tests.
Unit tests
tests/test_nemo_retriever.py
Covers dataclass construction, provider initialization and model defaults, health-check caching and error handling, OCR/embedding/reranking response parsing, _chunk_text edge cases, factory enablement via env vars, and importability.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • DanielDeshmukh/Hector#11: Modifies _nvidia_ocr_fallback in utils/enhanced_ingestor.py, which this PR also changes to add the NeMo-first OCR path.

Poem

🐇 Hopping through embeddings deep,
OCR pages while you sleep,
NeMo chunks and rankings too,
Reranked results fresh as dew,
The retriever hops anew! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/phase-14-nemo-retriever

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DanielDeshmukh DanielDeshmukh merged commit 26dcf5d into main Jun 28, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant