Skip to content

feat(intelligent-assistant): add DOM text extraction for deep context awareness (RHIDP-14317) - #4307

Open
its-mitesh-kumar wants to merge 11 commits into
redhat-developer:mainfrom
its-mitesh-kumar:feat/intelligent-assistant-dom-text-extraction
Open

feat(intelligent-assistant): add DOM text extraction for deep context awareness (RHIDP-14317)#4307
its-mitesh-kumar wants to merge 11 commits into
redhat-developer:mainfrom
its-mitesh-kumar:feat/intelligent-assistant-dom-text-extraction

Conversation

@its-mitesh-kumar

@its-mitesh-kumar its-mitesh-kumar commented Aug 13, 2026

Copy link
Copy Markdown
Member

Summary

Implements RHIDP-14317 — extracts structured page content from the visible RHDH page and sends it as context alongside user messages when screen context is enabled.

  • Adds dom-extractor.ts with priority-based extraction: page header → alerts → headings → tables → body text → Shadow DOM (TechDocs)
  • Integrates into sendMessage() flow as a text/plain attachment using the existing backend pipeline (zero backend changes)
  • Adds dom-extraction.enabled and dom-extraction.maxChars config options under screen-context
  • screen-context.enabled: true is already set in app-config.yaml for local testing
  • Includes 26 unit tests covering noise removal, table extraction, redaction, truncation, and header parsing

Why this approach over the PoC (innerHTML)?

Concern PoC (raw HTML) This PR (structured text)
Token efficiency HTML tags/classes waste ~60% of budget Clean text, zero waste
LLM quality PoC authors noted HTML noise confused the LLM Semantic structure (headings, tables)
Budget control No truncation strategy Priority-ordered with configurable maxChars (default 8000 ≈ 2000 tokens)
Sensitive data None Applies existing redactText() before sending

Fixed

UI after testing

S_.2026-08-14.at.4.mp4

Local Testing: Download Extracted DOM as .txt

To inspect the exact DOM context being extracted and sent, cherry-pick the debug commit:

git cherry-pick e84cc39b9

Commit: e84cc39b9 — chore: add DOM context debug download for local testing
Branch: feat/dom-extraction-debug-download

This adds:

  • console.debug('[DOM Extraction]', { chars, content }) on every message send
  • Auto-downloads a dom-context-<timestamp>.txt file so you can inspect the extracted content

Steps:

  1. Cherry-pick the commit above onto your local branch
  2. yarn start in the intelligent-assistant workspace
  3. Open any RHDH page and send a message in Lightspeed chat
  4. A .txt file will auto-download — open it to verify extracted content
  5. Check browser DevTools console for [DOM Extraction] log with char count

Test Scenarios

Basic Functionality

  • Send a message on a Catalog entity page → verify attachment includes page title, headings, and body text
  • Send a message on the API tab → verify active tab name appears in header (Tab: ...)
  • Send a message on a TechDocs page → verify Shadow DOM content is extracted
  • Verify extracted text does NOT contain HTML tags, class names, or style attributes

Header Extraction

  • Page shows Page: /catalog/default/component/... path
  • BUI plugin name appears as Plugin: <name> (if .bui-PluginHeaderToolbarName exists)
  • Page title appears as Title: <title> (if .bui-HeaderTitle exists)
  • Active tab appears as Tab: <tab-name> (if [role="tab"][aria-selected="true"] exists)
  • Document title appears as Document: <title>

Priority & Truncation

  • On a content-heavy page, output stays within ~8000 chars (check .txt file size)
  • Alerts appear before headings; headings before tables; tables before body text
  • If page content exceeds budget, lower-priority content (body text) is truncated first

Noise Removal

  • <script>, <style>, <svg>, <noscript> content is NOT present in output
  • Navigation elements (nav, [role="navigation"]) are excluded
  • Lightspeed chat panel itself is excluded (.lightspeed-chat-panel)
  • Hidden elements ([aria-hidden="true"], [hidden]) are excluded
  • Empty/whitespace-only sections are not included

Table Extraction

  • Tables render as | col1 | col2 | pipe-delimited format
  • Tables with >50 rows are truncated with ... (N more rows) indicator
  • Tables with >10 columns are truncated with ... column

Sensitive Data Redaction

  • If page contains visible tokens/secrets (e.g. in a config view), they appear as ***** in output
  • API keys, passwords, and connection strings are redacted

Configuration

  • With screen-context.dom-extraction.enabled: false → no DOM attachment is sent
  • With screen-context.enabled: false → no DOM or screenshot attachment is sent
  • Custom maxChars value (e.g. 2000) reduces output size accordingly

Edge Cases

  • Empty page / minimal content → attachment is still valid (or gracefully skipped)
  • Page with only images and no text → minimal/empty output, no crash
  • Very long single heading or alert → doesn't blow budget (gets truncated)

Unit Tests

cd workspaces/intelligent-assistant
yarn test --testPathPatterns dom-extractor

All 26 tests pass covering: noise removal, heading extraction, alert extraction, table formatting, body text extraction, redaction integration, truncation/budget, Shadow DOM, header parsing (BUI + tabs), and custom exclusion selectors.

its-mitesh-kumar and others added 8 commits August 9, 2026 23:37
…itive data redaction

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
- Fall back to original canvas when getContext('2d') returns null
- Add CSS.escape() to prevent selector injection in label lookup
- Remove redundant password type check (already in isSensitiveElement)
- Wrap element.matches() in try/catch for invalid selectors
- Use case-insensitive CSS attribute selectors for aria-label matching
- Convert html2canvas-pro to dynamic import for bundle size optimization
- Clear timeout timer in finally block to prevent resource leak
- Replace as-any casts with expect.objectContaining in tests
- Remove fragile index-based SECRET_PATTERNS tests
- Add JSDoc warning about stateful /g regexes

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
… awareness

Implements RHIDP-14317 - extracts structured page content (headings, tables,
alerts, body text) from the visible RHDH page and sends it as a text/plain
attachment alongside user messages when screen context is enabled.

Key decisions over the PoC (innerHTML) approach:
- No token waste: strips HTML tags/attributes that add zero semantic value
- Priority-based extraction: alerts > headings > tables > body text
- Configurable char budget (default 8000) to cap token usage
- Zero backend changes: uses existing attachment pipeline

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
…nt-dom-text-extraction

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>

# Conflicts:
#	workspaces/intelligent-assistant/plugins/intelligent-assistant/config.d.ts
#	workspaces/intelligent-assistant/plugins/intelligent-assistant/package.json
#	workspaces/intelligent-assistant/plugins/intelligent-assistant/src/utils/screen-capture.ts
#	workspaces/intelligent-assistant/yarn.lock
@rhdh-gh-app

rhdh-gh-app Bot commented Aug 14, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-intelligent-assistant workspaces/intelligent-assistant/plugins/intelligent-assistant minor v3.2.0

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.03401% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.31%. Comparing base (b2f8ea7) to head (d64df67).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4307      +/-   ##
==========================================
+ Coverage   61.27%   61.31%   +0.04%     
==========================================
  Files        2509     2510       +1     
  Lines      100516   100668     +152     
  Branches    28136    28205      +69     
==========================================
+ Hits        61594    61728     +134     
- Misses      37113    37135      +22     
+ Partials     1809     1805       -4     
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from 46d7e96
ai-integrations 71.04% <ø> (ø) Carriedforward from 46d7e96
app-defaults 69.79% <ø> (ø) Carriedforward from 46d7e96
augment 46.67% <ø> (ø) Carriedforward from 46d7e96
boost 78.64% <ø> (ø) Carriedforward from 46d7e96
bulk-import 72.79% <ø> (ø) Carriedforward from 46d7e96
cost-management 13.55% <ø> (ø) Carriedforward from 46d7e96
dcm 67.21% <ø> (ø) Carriedforward from 46d7e96
e2e-adoption-insights 60.00% <ø> (ø) Carriedforward from 46d7e96
e2e-extensions 62.13% <ø> (ø) Carriedforward from 46d7e96
e2e-global-header 49.45% <ø> (ø) Carriedforward from 46d7e96
e2e-homepage 43.49% <ø> (ø) Carriedforward from 46d7e96
e2e-intelligent-assistant 46.74% <ø> (ø) Carriedforward from 46d7e96
e2e-orchestrator 50.42% <ø> (ø) Carriedforward from 46d7e96
e2e-quickstart 55.21% <ø> (ø) Carriedforward from 46d7e96
e2e-scorecard 50.21% <ø> (ø) Carriedforward from 46d7e96
e2e-theme 17.11% <ø> (ø) Carriedforward from 46d7e96
extensions 56.59% <ø> (ø) Carriedforward from 46d7e96
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 46d7e96
global-header 66.50% <ø> (ø) Carriedforward from 46d7e96
homepage 47.50% <ø> (ø) Carriedforward from 46d7e96
install-dynamic-plugins 59.95% <ø> (ø) Carriedforward from 46d7e96
intelligent-assistant 76.08% <85.03%> (+0.21%) ⬆️
konflux 91.98% <ø> (ø) Carriedforward from 46d7e96
lightspeed 69.02% <ø> (ø) Carriedforward from 46d7e96
mcp-integrations 83.40% <ø> (ø) Carriedforward from 46d7e96
orchestrator 70.87% <ø> (ø) Carriedforward from 46d7e96
quickstart 63.74% <ø> (ø) Carriedforward from 46d7e96
sandbox 79.56% <ø> (ø) Carriedforward from 46d7e96
scorecard 87.09% <ø> (ø) Carriedforward from 46d7e96
theme 88.14% <ø> (ø) Carriedforward from 46d7e96
translations 5.12% <ø> (ø) Carriedforward from 46d7e96
x2a 79.20% <ø> (ø) Carriedforward from 46d7e96

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b2f8ea7...d64df67. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant