Skip to content

refactor(documents): one extractor per format, Chunker takes a SourceDocument - #15

Merged
YBazanPro merged 3 commits into
mainfrom
refactor/source-extractors
Oct 17, 2026
Merged

YBazanPro merged 3 commits into
mainfrom
refactor/source-extractors

Conversation

@YBazanPro

Copy link
Copy Markdown
Owner

Why

Extraction and chunking were tangled. IngestionRunProcessor branched on the source format and held the PDF timeout and file-store access. Chunker parsed Markdown itself and had a second entry point for PDF blocks. Adding a format (DOCX, OCR) would have meant touching all of them.

What

  • ISourceExtractor per SourceFormat: MarkdownSourceExtractor, PlainTextSourceExtractor and PdfSourceExtractor each produce a SourceDocument. Sections are explicit (path plus raw heading line, since one heading can appear twice), and blocks carry Markdown-flavoured text and pages.
  • Chunker.Chunk(SourceDocument, options) is the only entry point and never sees the format. The Markdown syntax helpers move to MarkdownSyntax, shared by the extractor and the Chunker.
  • The PDF timeout, store access and extraction metrics move into PdfSourceExtractor. The processor keeps the run events, the progress channel and the pages-without-text update.
  • Registration: the extractors are registered in AddDocumentsModule, and a test checks that every SourceFormat has exactly one.
  • CLAUDE.md: one line in RAG Conventions on how to add a format and regenerate the golden files.

Behaviour unchanged

  • The first commit adds GoldenChunkingTests, which pins every passage of representative Markdown, plain-text and PDF inputs in Golden/*.txt. It was generated from the code before the refactoring.
  • The second commit does the refactoring. The golden files are untouched, and the existing ChunkerTests/ChunkerPageTests only changed their input lines, not their assertions.

Tests

  • 18 new tests: the Markdown, plain-text and PDF extractors (grouping, fences, tables, summary, progress, FileMissing, ExtractionTimeout) and the extractor registration.
  • dotnet test --solution RagAssistant.slnx: 1,176 passed, 0 failed.
  • dotnet format --verify-no-changes is clean.

Follow-up (not in this PR)

A deliberate behaviour change for PDFs (no minimum-size merge across a section boundary) sits on claude/sweet-kalam-5f70b6, on top of this branch.

🤖 Generated with Claude Code

YBazanPro and others added 3 commits October 16, 2026 23:00
Maintainer-only read side under /api/admin: request list and inspector,
summary with SQL percentiles, feedback list, corpus health, currently failed
ingestions, a metadata-only list of private documents and read-only
configuration. IDocumentTitles returns shared titles only, so the inspector
never names a private document. The RagAssistant.Chat meter is recorded from
the finished trace. /admin becomes tabs with a request side panel and a
?request= deep link; AppHost sets Admin:TraceUrlTemplate.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Pin every passage of representative Markdown, plain-text and PDF inputs
to files under Golden/, so the coming extractor refactoring can prove
that chunking output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Document

Extraction and chunking were tangled: the run processor branched on the
source format and held the PDF timeout and store access, and the Chunker
parsed Markdown itself next to a second entry point for PDF blocks.

- ISourceExtractor per SourceFormat (Markdown, PlainText, Pdf) produces a
  SourceDocument: explicit sections (path, heading line) of blocks with
  Markdown-flavoured text and pages.
- Chunker.Chunk(SourceDocument, options) is the single entry point and
  never sees the format; Markdown syntax helpers are shared.
- The PDF timeout, store access and extraction metrics move into
  PdfSourceExtractor; the processor keeps run events, progress and the
  pages-without-text update.

Behaviour is unchanged: the golden chunking files are untouched and the
existing chunking tests only changed their input lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@YBazanPro
YBazanPro merged commit 3a0ebd2 into main Oct 17, 2026
1 check passed
@YBazanPro
YBazanPro deleted the refactor/source-extractors branch October 17, 2026 14:06
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