feat: Document Intelligence Layer — HTML/HTM file support + unified document pipeline - #19224
Open
chanmeimei wants to merge 1 commit into
Open
feat: Document Intelligence Layer — HTML/HTM file support + unified document pipeline#19224chanmeimei wants to merge 1 commit into
chanmeimei wants to merge 1 commit into
Conversation
…cument pipeline - Add .html/.htm to SUPPORTED_DOCUMENT_TYPES in gateway/platforms/base.py - New agent/document_processing/ module with 6 files: - types.py: DocumentResult canonical output format - html_parser.py: BeautifulSoup parser (strips script/style/noscript) - url_fetcher.py: HTTP fetcher with SSRF protection + 5MB limit - normalizer.py: Builds standardised DocumentResult - router.py: Single entry-point dispatcher for all document types - __init__.py: Public API exports - Refactor telegram.py document injection to use document_processing pipeline instead of inline parsing (with graceful fallback) - Add beautifulsoup4 to core dependencies in pyproject.toml - 21 acceptance tests covering all 7 scenarios: 1. .html upload → body text extraction 2. .htm upload → body text extraction 3. URL fetch → title + body extraction 4. Unsupported file → clear error message 5. SSRF protection (localhost/private IPs blocked) 6. Oversized HTML handling 7. script/style/noscript tag removal Designed for future extension: PDF, DOCX, XLSX parsers can be added to the router without touching any gateway code.
Collaborator
teknium1
reviewed
Jul 12, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for addressing HTML attachments. The original rejection is no longer present on current main: 4314d451c accepts every authorized inbound file type, and the active Telegram plugin includes .html/.htm in its text-injection set (gateway/platforms/base.py:1370-1383; plugins/platforms/telegram/adapter.py:7969-8002).
Problems
agent/document_processing/url_fetcher.py:79-87checks only the initial hostname and then follows redirects viarequests.get(..., allow_redirects=True). A public redirect can therefore reach a private target. Current main documents this exact SSRF class in500c2b1e4.- The PR edits
gateway/platforms/telegram.py, but that adapter was moved toplugins/platforms/telegram/adapter.pyin736ffb3bc; the PR is currently conflicting.
Suggested changes
- If HTML cleanup remains desired, port a narrow parser path to the active plugin adapter and cover
.htmland.htmthere. - Route any URL retrieval through the repository's redirect-safe URL validation pattern rather than the proposed standalone
requestsfetcher.
Automated hermes-sweeper review.
| chunks: list[bytes] = [] | ||
| total = 0 | ||
| for chunk in resp.iter_content(chunk_size=64 * 1024): | ||
| total += len(chunk) |
Contributor
There was a problem hiding this comment.
Blocking: _check_ssrf() validates only the original hostname, while allow_redirects=True can follow a public URL to a private target without revalidation. Current main's 500c2b1e4 fixes this exact SSRF redirect class; use an equivalent per-redirect guard before adding this fetch path.
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
Adds a Document Intelligence Layer (
agent/document_processing/) that enables Hermes to understand uploaded HTML files and other document types through a unified normalization pipeline.Problem
Currently,
.htmland.htmfiles sent via Telegram (and other platforms) are rejected with "Unsupported document type". Users sending API documentation, web pages, or exported HTML files cannot have Hermes read and understand them.Changes
A. File type whitelist (gateway/platforms/base.py)
.htmland.htmtoSUPPORTED_DOCUMENT_TYPESB. New module:
agent/document_processing/(6 files)types.pyDocumentResult— canonical output format for all parsershtml_parser.pyurl_fetcher.pynormalizer.pyDocumentResultfrom parser outputrouter.py__init__.pyC. Telegram gateway refactor (gateway/platforms/telegram.py)
document_processing.router.process_document()instead of inline UTF-8 decode.md/.txtD. Dependencies (pyproject.toml)
beautifulsoup4>=4.13.0,<5to core dependenciesSecurity
Architecture
Gateway platforms only handle receiving files — all understanding logic lives in
agent/document_processing/. Adding PDF/DOCX/XLSX parsers in the future requires only adding a new parser file + one router branch. No gateway code changes needed.Tests
21 test cases covering all 7 acceptance scenarios:
.htmlupload → body text extraction.htmupload → body text extractionStandard Output Format
All documents normalize to:
{ "source_type": "telegram_file | url | local_file", "document_type": "html | pdf | txt | md | json | csv", "title": "", "text": "", "links": [], "metadata": { "filename": "", "url": "", "mime_type": "", "size": 0 } }